2023-06-29 22:58:24 +02:00
|
|
|
package main
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
2023-07-31 10:13:36 +02:00
|
|
|
"fmt"
|
2023-06-29 22:58:24 +02:00
|
|
|
"regexp"
|
|
|
|
"strings"
|
|
|
|
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
)
|
|
|
|
|
|
|
|
type Addr string
|
|
|
|
|
|
|
|
var (
|
|
|
|
reBox = regexp.MustCompile(`^[a-zA-Z0-9\-_\.]+$`)
|
|
|
|
rePath = regexp.MustCompile(`^(/){0,1}[a-zA-Z0-9\-_\.]+(/[a-zA-Z0-9\-_\.]+)+$`)
|
|
|
|
)
|
|
|
|
|
|
|
|
func (a Addr) Box() string {
|
|
|
|
s := strings.Split(string(a), `:`)
|
|
|
|
box := s[0]
|
|
|
|
if reBox.MatchString(box) {
|
|
|
|
return box
|
|
|
|
} else {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) Path() string {
|
|
|
|
s := strings.Split(string(a), `:`)
|
|
|
|
path := s[1]
|
|
|
|
if rePath.MatchString(path) {
|
|
|
|
return path
|
|
|
|
} else {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) Append(path string) Addr {
|
|
|
|
newPath := a.Path() + path
|
|
|
|
if rePath.MatchString(newPath) {
|
|
|
|
return Addr(a.Box() + ":" + newPath)
|
|
|
|
} else {
|
|
|
|
return ""
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) BoxExec(cmd string) (string, error) {
|
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
if b, ok := cfg.box[a.Box()]; !ok {
|
|
|
|
err := errors.New("box doesn't exist")
|
2023-07-31 10:13:36 +02:00
|
|
|
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
|
2023-06-29 22:58:24 +02:00
|
|
|
return "", err
|
|
|
|
} else {
|
|
|
|
return b.Exec(cmd)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) Exec() (string, error) {
|
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
return a.BoxExec(a.Path())
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) ValidSnapshots() ([]*ZfsSnapshot, error) {
|
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
if b, ok := cfg.box[a.Box()]; !ok {
|
|
|
|
err := errors.New("box doesn't exist")
|
2023-07-31 10:13:36 +02:00
|
|
|
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
|
2023-06-29 22:58:24 +02:00
|
|
|
return nil, err
|
|
|
|
} else {
|
|
|
|
if fs, ok := b.zfs.filesystems[a.Path()]; ok {
|
|
|
|
return fs.ValidSnapshots(), nil
|
|
|
|
} else {
|
|
|
|
err := errors.New("path doesn't exist")
|
2023-07-31 10:13:36 +02:00
|
|
|
log.WithFields(log.Fields{"addr": a, "error": err}).Errorf("")
|
2023-06-29 22:58:24 +02:00
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-08-22 13:23:48 +02:00
|
|
|
func (a Addr) SetManaged(managed bool) error {
|
2023-07-31 10:13:36 +02:00
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
if b, ok := cfg.box[a.Box()]; !ok {
|
|
|
|
err := errors.New("box doesn't exist")
|
|
|
|
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
|
|
|
|
return err
|
|
|
|
} else if fs, ok := b.zfs.filesystems[a.Path()]; !ok {
|
|
|
|
err := errors.New("path doesn't exist")
|
|
|
|
log.WithFields(log.Fields{"addr": a, "path": a.Path(), "error": err}).Errorf("")
|
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
fs.mx.Lock()
|
|
|
|
defer fs.mx.Unlock()
|
2023-08-22 13:23:48 +02:00
|
|
|
if fs.managed != managed {
|
2023-07-31 10:13:36 +02:00
|
|
|
var cmd string
|
2023-08-22 13:23:48 +02:00
|
|
|
if managed {
|
2023-07-31 10:13:36 +02:00
|
|
|
cmd = fmt.Sprintf("zfs set %s=+ %s", zfsManagedPropertyName, a.Path())
|
|
|
|
} else {
|
|
|
|
cmd = fmt.Sprintf("zfs set %s=- %s", zfsManagedPropertyName, a.Path())
|
|
|
|
}
|
|
|
|
if _, err := b.Exec(cmd); err != nil {
|
|
|
|
log.WithFields(log.Fields{"addr": a, "call": "Exec", "attr": cmd, "error": err}).Errorf("")
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
2023-08-22 13:23:48 +02:00
|
|
|
fs.managed = managed
|
2023-07-31 10:13:36 +02:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) SetBackedUp(val bool) error {
|
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
if b, ok := cfg.box[a.Box()]; !ok {
|
|
|
|
err := errors.New("box doesn't exist")
|
|
|
|
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
|
|
|
|
return err
|
|
|
|
} else if fs, ok := b.zfs.filesystems[a.Path()]; !ok {
|
|
|
|
err := errors.New("path doesn't exist")
|
|
|
|
log.WithFields(log.Fields{"addr": a, "path": a.Path(), "error": err}).Errorf("")
|
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
fs.mx.Lock()
|
|
|
|
defer fs.mx.Unlock()
|
|
|
|
fs.backedUp = val
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-06-29 22:58:24 +02:00
|
|
|
func (a Addr) Mkdir() error {
|
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
if b, ok := cfg.box[a.Box()]; !ok {
|
|
|
|
err := errors.New("box doesn't exist")
|
2023-07-31 10:13:36 +02:00
|
|
|
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
|
2023-06-29 22:58:24 +02:00
|
|
|
return err
|
|
|
|
} else {
|
|
|
|
return b.zfs.Mkdir(a.Path())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) String() string {
|
|
|
|
return string(a)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (a Addr) Online() bool {
|
|
|
|
log.WithFields(log.Fields{"addr": a}).Debugf("starting")
|
|
|
|
defer log.WithFields(log.Fields{"addr": a}).Debugf("done")
|
|
|
|
|
|
|
|
if b, ok := cfg.box[a.Box()]; !ok {
|
|
|
|
return false
|
|
|
|
} else {
|
|
|
|
return b.online
|
|
|
|
}
|
|
|
|
}
|