166 lines
		
	
	
		
			4.1 KiB
		
	
	
	
		
			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.Lock()
 | 
						|
		defer fs.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.Lock()
 | 
						|
		defer fs.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
 | 
						|
	}
 | 
						|
}
 |