update zfsnap behaviour
This commit is contained in:
parent
a0cd2cdbcc
commit
6c3cd690de
119
backup.go
119
backup.go
@ -165,7 +165,7 @@ func (c *Config) Load() error {
|
|||||||
|
|
||||||
var b bytes.Buffer
|
var b bytes.Buffer
|
||||||
session.Stdout = &b
|
session.Stdout = &b
|
||||||
err = session.Run("/usr/bin/uname -a")
|
err = session.Run("/usr/sbin/zfsnap --version")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("Config.Load : client.NewSession(%s) : %s", k, err)
|
log.Printf("Config.Load : client.NewSession(%s) : %s", k, err)
|
||||||
@ -307,7 +307,7 @@ func (s *SSHConfig) getNextSnapshot(snapshot Snapshot) (Snapshot, error) {
|
|||||||
|
|
||||||
func (s *SSHConfig) getSnapshotList() error {
|
func (s *SSHConfig) getSnapshotList() error {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("SSHConfig.getSnapshotList : Start %s", s.name)
|
log.Printf("SSHConfig.getSnapshotList : %s : Start", s.name)
|
||||||
}
|
}
|
||||||
if !s.logged {
|
if !s.logged {
|
||||||
return fmt.Errorf("Client %s not logged in.", s.name)
|
return fmt.Errorf("Client %s not logged in.", s.name)
|
||||||
@ -316,7 +316,7 @@ func (s *SSHConfig) getSnapshotList() error {
|
|||||||
session, err := s.client.NewSession()
|
session, err := s.client.NewSession()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("SSHConfig.getSnapshotList : client.NewSession(%s) : %s", s.name, err)
|
log.Printf("SSHConfig.getSnapshotList : %s : client.NewSession() : %s", s.name, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -326,7 +326,7 @@ func (s *SSHConfig) getSnapshotList() error {
|
|||||||
err = session.Run("/usr/sbin/zfs list -H -t snapshot -o name")
|
err = session.Run("/usr/sbin/zfs list -H -t snapshot -o name")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("SSHConfig.getSnapshotList : session.Run(%s) : %s", s.name, err)
|
log.Printf("SSHConfig.getSnapshotList : %s : session.Run() : %s", s.name, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -340,7 +340,7 @@ func (s *SSHConfig) getSnapshotList() error {
|
|||||||
csvData, err := csvReader.ReadAll()
|
csvData, err := csvReader.ReadAll()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("SSHConfig.getSnapshotList : csvReader.ReadAll(%s) : %s", s.name, err)
|
log.Printf("SSHConfig.getSnapshotList : %s : csvReader.ReadAll() : %s", s.name, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -503,7 +503,7 @@ func (s *SSHConfig) createZFS(path string) error {
|
|||||||
|
|
||||||
func (a AppConfig) RunAppSchedule(schedule string) error {
|
func (a AppConfig) RunAppSchedule(schedule string) error {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Running %s(%s)", a.Name, schedule)
|
log.Printf("RunAppSchedule(%s) : %s : Start", a.Name, schedule)
|
||||||
}
|
}
|
||||||
for _, src := range a.Sources {
|
for _, src := range a.Sources {
|
||||||
if !cfg.ssh[src.Box()].isZFS(src.Path()) {
|
if !cfg.ssh[src.Box()].isZFS(src.Path()) {
|
||||||
@ -514,7 +514,7 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
err := cfg.ssh[dest.Box()].createZFS(dest.Path() + "/" + src.Box() + "/" + src.Path())
|
err := cfg.ssh[dest.Box()].createZFS(dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Error creating %s on %s", dest.Path()+"/"+src.Box()+"/"+src.Path(), dest.Box())
|
log.Printf("RunAppSchedule(%s) : %s : Error creating %s on %s", a.Name, schedule, dest.Path()+"/"+src.Box()+"/"+src.Path(), dest.Box())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -527,7 +527,7 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
err := cfg.ssh[v.Box()].exec(v.Path())
|
err := cfg.ssh[v.Box()].exec(v.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Error executing %s", string(v))
|
log.Printf("RunAppSchedule(%s) : %s : Error executing %s", a.Name, schedule, string(v))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -536,19 +536,22 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
|
|
||||||
refreshSnapshot := make(map[string]bool)
|
refreshSnapshot := make(map[string]bool)
|
||||||
takeSnapshot := make(map[string]string)
|
takeSnapshot := make(map[string]string)
|
||||||
|
delSnapshot := make(map[string]string)
|
||||||
for _, v := range a.Sources {
|
for _, v := range a.Sources {
|
||||||
takeSnapshot[v.Box()] = takeSnapshot[v.Box()] + " " + v.Path()
|
takeSnapshot[v.Box()] = takeSnapshot[v.Box()] + " " + v.Path()
|
||||||
refreshSnapshot[v.Box()] = true
|
refreshSnapshot[v.Box()] = true
|
||||||
|
for _, v2 := range a.Destinations {
|
||||||
|
delSnapshot[v2.Box()] = delSnapshot[v2.Box()] + " " + v2.Path() + "/" + v.Box() + "/" + v.Path()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for k, v := range takeSnapshot {
|
for k, v := range takeSnapshot {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : taking %s snapshot on %s for%s", schedule, k, v)
|
log.Printf("RunAppSchedule(%s) : %s : taking snapshot on %s for %s", a.Name, schedule, k, v)
|
||||||
}
|
}
|
||||||
err := cfg.ssh[k].exec("/usr/sbin/zfsnap snapshot -p '" + schedule + "-' -a " + cfg.Zfsnap[schedule] + v)
|
err := cfg.ssh[k].exec("/usr/sbin/zfsnap snapshot -a " + cfg.Zfsnap[schedule] + v)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Error executing zfsnap on %s", k)
|
log.Printf("RunAppSchedule(%s) : %s : Error executing zfsnap on %s", a.Name, schedule, k)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -558,12 +561,12 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
}
|
}
|
||||||
for k, _ := range refreshSnapshot {
|
for k, _ := range refreshSnapshot {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : refreshing snapshots for source %s", k)
|
log.Printf("RunAppSchedule(%s) : %s : refreshing snapshots for source %s", a.Name, schedule, k)
|
||||||
}
|
}
|
||||||
err := cfg.ssh[k].getSnapshotList()
|
err := cfg.ssh[k].getSnapshotList()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Error getting snapshots on %s", k)
|
log.Printf("RunAppSchedule(%s) : %s : Error getting snapshots on %s", a.Name, schedule, k)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -571,53 +574,53 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
for _, src := range a.Sources {
|
for _, src := range a.Sources {
|
||||||
for _, dest := range a.Destinations {
|
for _, dest := range a.Destinations {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Sending snapshots from %s to %s", string(src), string(dest))
|
log.Printf("RunAppSchedule(%s) : %s : Sending snapshots from %s to %s", a.Name, schedule, string(src), string(dest))
|
||||||
}
|
}
|
||||||
dLastSnapshot, err := cfg.ssh[dest.Box()].getLastSnapshot(dest.Path() + "/" + src.Box() + "/" + src.Path())
|
dLastSnapshot, err := cfg.ssh[dest.Box()].getLastSnapshot(dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : No snapshot for %s on %s", string(src), dest.Box())
|
log.Printf("RunAppSchedule(%s) : %s : No snapshot for %s on %s", a.Name, schedule, string(src), dest.Box())
|
||||||
}
|
}
|
||||||
sFirstSnapshot, err := cfg.ssh[src.Box()].getFirstSnapshot(src.Path())
|
sFirstSnapshot, err := cfg.ssh[src.Box()].getFirstSnapshot(src.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : No snapshot for %s", string(src))
|
log.Printf("RunAppSchedule(%s) : %s : No snapshot for %s", a.Name, schedule, string(src))
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
} else {
|
}
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : Initializing snapshot on %s from %s", a.Name, schedule, dest.Box(), string(sFirstSnapshot))
|
||||||
|
}
|
||||||
|
err = cfg.ssh[dest.Box()].exec("/usr/bin/ssh root@" + src.Box() + " /sbin/zfs send " + string(sFirstSnapshot) + " | /sbin/zfs recv -F " + dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||||
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Initializing snapshot on %s from %s", dest.Box(), string(sFirstSnapshot))
|
log.Printf("RunAppSchedule(%s) : %s : Initializing snapshot on %s from %s failed (%s)", a.Name, schedule, dest.Box(), string(sFirstSnapshot), err)
|
||||||
}
|
}
|
||||||
err = cfg.ssh[dest.Box()].exec("/usr/bin/ssh root@" + src.Box() + " /sbin/zfs send " + string(sFirstSnapshot) + " | /sbin/zfs recv -F " + dest.Path() + "/" + src.Box() + "/" + src.Path())
|
return err
|
||||||
|
}
|
||||||
|
var sCurrSnapshot Snapshot
|
||||||
|
sNextSnapshot := sFirstSnapshot
|
||||||
|
for !cfg.ssh[src.Box()].isLastSnapshot(sNextSnapshot) {
|
||||||
|
sCurrSnapshot = sNextSnapshot
|
||||||
|
sNextSnapshot, err = cfg.ssh[src.Box()].getNextSnapshot(sNextSnapshot)
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : Sending incrementally %s to %s", a.Name, schedule, string(sNextSnapshot), dest.Box())
|
||||||
|
}
|
||||||
|
err = cfg.ssh[dest.Box()].exec("/usr/bin/ssh root@" + src.Box() + " /sbin/zfs send -I " + string(sCurrSnapshot) + " " + string(sNextSnapshot) + " | /sbin/zfs recv " + dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Initializing snapshot on %s from %s failed (%s)", dest.Box(), string(sFirstSnapshot), err)
|
log.Printf("RunAppSchedule(%s) : %s : Sending snapshot on %s from %s failed (%s)", a.Name, schedule, dest.Box(), string(sNextSnapshot), err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
var sCurrSnapshot Snapshot
|
|
||||||
sNextSnapshot := sFirstSnapshot
|
|
||||||
for !cfg.ssh[src.Box()].isLastSnapshot(sNextSnapshot) {
|
|
||||||
sCurrSnapshot = sNextSnapshot
|
|
||||||
sNextSnapshot, err = cfg.ssh[src.Box()].getNextSnapshot(sNextSnapshot)
|
|
||||||
if *debugFlag {
|
|
||||||
log.Printf("RunAppSchedule : Sending incrementally %s to %s", string(sNextSnapshot), dest.Box())
|
|
||||||
}
|
|
||||||
err = cfg.ssh[dest.Box()].exec("/usr/bin/ssh root@" + src.Box() + " /sbin/zfs send -I " + string(sCurrSnapshot) + " " + string(sNextSnapshot) + " | /sbin/zfs recv " + dest.Path() + "/" + src.Box() + "/" + src.Path())
|
|
||||||
if err != nil {
|
|
||||||
if *debugFlag {
|
|
||||||
log.Printf("RunAppSchedule : Sending snapshot on %s from %s failed (%s)", dest.Box(), string(sNextSnapshot), err)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if *debugFlag {
|
|
||||||
log.Printf("RunAppSchedule : All snapshots sent for %s", string(src))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : All snapshots sent for %s", a.Name, schedule, string(src))
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Last snapshot on %s is %s", dest.Box(), string(dLastSnapshot))
|
log.Printf("RunAppSchedule(%s) : %s : Last snapshot on %s is %s", a.Name, schedule, dest.Box(), string(dLastSnapshot))
|
||||||
}
|
}
|
||||||
var sCurrSnapshot Snapshot
|
var sCurrSnapshot Snapshot
|
||||||
sNextSnapshot := Snapshot(string(dLastSnapshot)[len(string(dest))+2:])
|
sNextSnapshot := Snapshot(string(dLastSnapshot)[len(string(dest))+2:])
|
||||||
@ -625,12 +628,12 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
sCurrSnapshot = sNextSnapshot
|
sCurrSnapshot = sNextSnapshot
|
||||||
sNextSnapshot, err = cfg.ssh[src.Box()].getNextSnapshot(sNextSnapshot)
|
sNextSnapshot, err = cfg.ssh[src.Box()].getNextSnapshot(sNextSnapshot)
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Sending incrementally %s to %s", string(sNextSnapshot), dest.Box())
|
log.Printf("RunAppSchedule(%s) : %s : Sending incrementally %s to %s", a.Name, schedule, string(sNextSnapshot), dest.Box())
|
||||||
}
|
}
|
||||||
err = cfg.ssh[dest.Box()].exec("/usr/bin/ssh root@" + src.Box() + " /sbin/zfs send -I " + string(sCurrSnapshot) + " " + string(sNextSnapshot) + " | /sbin/zfs recv " + dest.Path() + "/" + src.Box() + "/" + src.Path())
|
err = cfg.ssh[dest.Box()].exec("/usr/bin/ssh root@" + src.Box() + " /sbin/zfs send -I " + string(sCurrSnapshot) + " " + string(sNextSnapshot) + " | /sbin/zfs recv " + dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Sending snapshot on %s from %s failed (%s)", dest.Box(), string(sNextSnapshot), err)
|
log.Printf("RunAppSchedule(%s) : %s : Sending snapshot on %s from %s failed (%s)", a.Name, schedule, dest.Box(), string(sNextSnapshot), err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -638,13 +641,37 @@ func (a AppConfig) RunAppSchedule(schedule string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for k, v := range takeSnapshot {
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : cleaning snapshot on %s for %s", a.Name, schedule, k, v)
|
||||||
|
}
|
||||||
|
err := cfg.ssh[k].exec("/usr/sbin/zfsnap destroy" + v)
|
||||||
|
if err != nil {
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : Error executing zfsnap on %s", a.Name, schedule, k)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for k, v := range delSnapshot {
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : cleaning snapshot on %s for %s", a.Name, schedule, k, v)
|
||||||
|
}
|
||||||
|
err := cfg.ssh[k].exec("/usr/sbin/zfsnap destroy" + v)
|
||||||
|
if err != nil {
|
||||||
|
if *debugFlag {
|
||||||
|
log.Printf("RunAppSchedule(%s) : %s : Error executing zfsnap on %s", a.Name, schedule, k)
|
||||||
|
}
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
for k, v := range a.After {
|
for k, v := range a.After {
|
||||||
re := regexp.MustCompile(k)
|
re := regexp.MustCompile(k)
|
||||||
if re.MatchString(schedule) {
|
if re.MatchString(schedule) {
|
||||||
err := cfg.ssh[v.Box()].exec(v.Path())
|
err := cfg.ssh[v.Box()].exec(v.Path())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunAppSchedule : Error executing %s on %s", v.Path(), v.Box())
|
log.Printf("RunAppSchedule(%s) : %s : Error executing %s on %s", a.Name, schedule, v.Path(), v.Box())
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -687,7 +714,7 @@ func main() {
|
|||||||
//RunSchedule run all backup targets where schedule is registered
|
//RunSchedule run all backup targets where schedule is registered
|
||||||
func RunSchedule(schedule string) error {
|
func RunSchedule(schedule string) error {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunSchedule : Start %s", schedule)
|
log.Printf("RunSchedule(%s) : Start", schedule)
|
||||||
}
|
}
|
||||||
if _, ok := cfg.Zfsnap[schedule]; !ok {
|
if _, ok := cfg.Zfsnap[schedule]; !ok {
|
||||||
return fmt.Errorf("No retention defined for %s schedule", schedule)
|
return fmt.Errorf("No retention defined for %s schedule", schedule)
|
||||||
@ -699,7 +726,7 @@ func RunSchedule(schedule string) error {
|
|||||||
err := app.RunAppSchedule(schedule)
|
err := app.RunAppSchedule(schedule)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if *debugFlag {
|
if *debugFlag {
|
||||||
log.Printf("RunSchedule : Error running %s(%s)", app.Name, schedule)
|
log.Printf("RunSchedule(%s) : Error running %s", schedule, app.Name)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user