backup/addr.go

166 lines
4.1 KiB
Go

package main
import (
"errors"
"fmt"
"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")
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
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")
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
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")
log.WithFields(log.Fields{"addr": a, "error": err}).Errorf("")
return nil, err
}
}
}
func (a Addr) SetManaged(managed 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()
if fs.managed != managed {
var cmd string
if managed {
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
}
}
fs.managed = managed
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
}
}
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")
log.WithFields(log.Fields{"addr": a, "box": a.Box(), "error": err}).Errorf("")
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
}
}