update
This commit is contained in:
576
app.go
Normal file
576
app.go
Normal file
@@ -0,0 +1,576 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"regexp"
|
||||
"time"
|
||||
)
|
||||
|
||||
type AppConfig struct {
|
||||
Name string `json:"name"`
|
||||
Schedule []string `json:"schedule"`
|
||||
Sources []Location `json:"src"`
|
||||
Destinations []Location `json:"dest"`
|
||||
Before map[string]Location `json:"before"`
|
||||
After map[string]Location `json:"after"`
|
||||
}
|
||||
|
||||
func (a AppConfig) getTime() time.Time {
|
||||
for _, v := range a.Sources {
|
||||
return cfg.Box[v.Box()].ssh.now
|
||||
}
|
||||
for _, v := range a.Destinations {
|
||||
return cfg.Box[v.Box()].ssh.now
|
||||
}
|
||||
return time.Now()
|
||||
}
|
||||
|
||||
func (a AppConfig) getSchedule() (string, error) {
|
||||
var schedule string
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.getSchedule : %s : Start", a.Name)
|
||||
}
|
||||
|
||||
refreshSnapshot := make(map[string]bool)
|
||||
for _, v := range a.Sources {
|
||||
refreshSnapshot[v.Box()] = true
|
||||
}
|
||||
for k, _ := range refreshSnapshot {
|
||||
err := cfg.Box[k].ssh.getSnapshotList()
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.getSchedule : %s : getSnapshotList(%s) : %s", a.Name, k, err)
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
if *schedFlag != "" {
|
||||
schedule = *schedFlag
|
||||
} else if a.needYearlySnapshot() {
|
||||
schedule = "yearly"
|
||||
} else if a.needMonthlySnapshot() {
|
||||
schedule = "monthly"
|
||||
} else if a.needWeeklySnapshot() {
|
||||
schedule = "weekly"
|
||||
} else if a.needDailySnapshot() {
|
||||
schedule = "daily"
|
||||
} else if a.needHourlySnapshot() {
|
||||
schedule = "hourly"
|
||||
} else {
|
||||
return schedule, nil
|
||||
}
|
||||
|
||||
if ret, ok := cfg.Zfsnap[schedule]; !ok {
|
||||
return "", fmt.Errorf("no retention for %s", schedule)
|
||||
} else {
|
||||
re := regexp.MustCompile(`^([0-9]+[ymwdhMs]{1}|forever)$`)
|
||||
if !re.MatchString(ret) {
|
||||
return "", fmt.Errorf("wrong retention format for %s", schedule)
|
||||
}
|
||||
}
|
||||
return schedule, nil
|
||||
}
|
||||
|
||||
func (a AppConfig) needYearlySnapshot() bool {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needYearlySnapshot : %s : Start", a.Name)
|
||||
}
|
||||
ret := false
|
||||
|
||||
// schedule enabled for app ?
|
||||
for _, v := range a.Schedule {
|
||||
if v == "yearly" {
|
||||
ret = true
|
||||
}
|
||||
}
|
||||
if !ret {
|
||||
return false
|
||||
}
|
||||
|
||||
// finding out the timestamps existing
|
||||
timeSource := make(map[string]map[time.Time]struct{})
|
||||
timeTotal := make(map[time.Time]struct{})
|
||||
re := regexp.MustCompile(`^yearly-(?P<Date>[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}.[0-9]{2}.[0-9]{2})--([0-9]+[ymwdhMs]{1}|forever)$`)
|
||||
for _, src := range a.Sources {
|
||||
timeSource[string(src)] = make(map[time.Time]struct{})
|
||||
for _, snap := range cfg.Box[src.Box()].ssh.snapshot {
|
||||
if src.Path() == snap.Path() {
|
||||
if re.MatchString(snap.Name()) {
|
||||
dateString := re.ReplaceAllString(snap.Name(), "${Date}")
|
||||
dateTime, err := time.Parse("2006-01-02_15.04.05", dateString)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needYearlySnapshot : %s : time.Parse(%s) : %s", a.Name, dateString, err)
|
||||
}
|
||||
} else {
|
||||
timeSource[string(src)][dateTime] = struct{}{}
|
||||
timeTotal[dateTime] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up the available timestamps for common timestamps
|
||||
for t, _ := range timeTotal {
|
||||
for _, v := range timeSource {
|
||||
if _, ok := v[t]; !ok {
|
||||
delete(timeTotal, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finding an eligible timestamp
|
||||
now := a.getTime()
|
||||
for t, _ := range timeTotal {
|
||||
if t.Year() == now.Year() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// no timestamp => need the snapshot !
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (a AppConfig) needMonthlySnapshot() bool {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needMonthlySnapshot : %s : Start", a.Name)
|
||||
}
|
||||
ret := false
|
||||
|
||||
// schedule enabled for app ?
|
||||
for _, v := range a.Schedule {
|
||||
if v == "monthly" {
|
||||
ret = true
|
||||
}
|
||||
}
|
||||
if !ret {
|
||||
return false
|
||||
}
|
||||
|
||||
// finding out the timestamps existing
|
||||
timeSource := make(map[string]map[time.Time]struct{})
|
||||
timeTotal := make(map[time.Time]struct{})
|
||||
re := regexp.MustCompile(`^(yearly|monthly)-(?P<Date>[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}.[0-9]{2}.[0-9]{2})--([0-9]+[ymwdhMs]{1}|forever)$`)
|
||||
for _, src := range a.Sources {
|
||||
timeSource[string(src)] = make(map[time.Time]struct{})
|
||||
for _, snap := range cfg.Box[src.Box()].ssh.snapshot {
|
||||
if src.Path() == snap.Path() {
|
||||
if re.MatchString(snap.Name()) {
|
||||
dateString := re.ReplaceAllString(snap.Name(), "${Date}")
|
||||
dateTime, err := time.Parse("2006-01-02_15.04.05", dateString)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needYearlySnapshot : %s : time.Parse(%s) : %s", a.Name, dateString, err)
|
||||
}
|
||||
} else {
|
||||
timeSource[string(src)][dateTime] = struct{}{}
|
||||
timeTotal[dateTime] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up the available timestamps for common timestamps
|
||||
for t, _ := range timeTotal {
|
||||
for _, v := range timeSource {
|
||||
if _, ok := v[t]; !ok {
|
||||
delete(timeTotal, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finding an eligible timestamp
|
||||
now := a.getTime()
|
||||
for t, _ := range timeTotal {
|
||||
if t.Year() == now.Year() && t.Month() == now.Month() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// no timestamp => need the snapshot !
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (a AppConfig) needWeeklySnapshot() bool {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needWeeklySnapshot : %s : Start", a.Name)
|
||||
}
|
||||
ret := false
|
||||
|
||||
// schedule enabled for app ?
|
||||
for _, v := range a.Schedule {
|
||||
if v == "weekly" {
|
||||
ret = true
|
||||
}
|
||||
}
|
||||
if !ret {
|
||||
return false
|
||||
}
|
||||
|
||||
// finding out the timestamps existing
|
||||
timeSource := make(map[string]map[time.Time]struct{})
|
||||
timeTotal := make(map[time.Time]struct{})
|
||||
re := regexp.MustCompile(`^(yearly|monthly|weekly)-(?P<Date>[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}.[0-9]{2}.[0-9]{2})--([0-9]+[ymwdhMs]{1}|forever)$`)
|
||||
for _, src := range a.Sources {
|
||||
timeSource[string(src)] = make(map[time.Time]struct{})
|
||||
for _, snap := range cfg.Box[src.Box()].ssh.snapshot {
|
||||
if src.Path() == snap.Path() {
|
||||
if re.MatchString(snap.Name()) {
|
||||
dateString := re.ReplaceAllString(snap.Name(), "${Date}")
|
||||
dateTime, err := time.Parse("2006-01-02_15.04.05", dateString)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needYearlySnapshot : %s : time.Parse(%s) : %s", a.Name, dateString, err)
|
||||
}
|
||||
} else {
|
||||
timeSource[string(src)][dateTime] = struct{}{}
|
||||
timeTotal[dateTime] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up the available timestamps for common timestamps
|
||||
for t, _ := range timeTotal {
|
||||
for _, v := range timeSource {
|
||||
if _, ok := v[t]; !ok {
|
||||
delete(timeTotal, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finding an eligible timestamp
|
||||
now := a.getTime()
|
||||
nowYear, nowWeek := now.ISOWeek()
|
||||
for t, _ := range timeTotal {
|
||||
snapYear, snapWeek := t.ISOWeek()
|
||||
if nowYear == snapYear && nowWeek == snapWeek {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// no timestamp => need the snapshot !
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (a AppConfig) needDailySnapshot() bool {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needDailySnapshot : %s : Start", a.Name)
|
||||
}
|
||||
ret := false
|
||||
|
||||
// schedule enabled for app ?
|
||||
for _, v := range a.Schedule {
|
||||
if v == "daily" {
|
||||
ret = true
|
||||
}
|
||||
}
|
||||
if !ret {
|
||||
return false
|
||||
}
|
||||
|
||||
// finding out the timestamps existing
|
||||
timeSource := make(map[string]map[time.Time]struct{})
|
||||
timeTotal := make(map[time.Time]struct{})
|
||||
re := regexp.MustCompile(`^(yearly|monthly|weekly|daily)-(?P<Date>[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}.[0-9]{2}.[0-9]{2})--([0-9]+[ymwdhMs]{1}|forever)$`)
|
||||
for _, src := range a.Sources {
|
||||
timeSource[string(src)] = make(map[time.Time]struct{})
|
||||
for _, snap := range cfg.Box[src.Box()].ssh.snapshot {
|
||||
if src.Path() == snap.Path() {
|
||||
if re.MatchString(snap.Name()) {
|
||||
dateString := re.ReplaceAllString(snap.Name(), "${Date}")
|
||||
dateTime, err := time.Parse("2006-01-02_15.04.05", dateString)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needYearlySnapshot : %s : time.Parse(%s) : %s", a.Name, dateString, err)
|
||||
}
|
||||
} else {
|
||||
timeSource[string(src)][dateTime] = struct{}{}
|
||||
timeTotal[dateTime] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up the available timestamps for common timestamps
|
||||
for t, _ := range timeTotal {
|
||||
for _, v := range timeSource {
|
||||
if _, ok := v[t]; !ok {
|
||||
delete(timeTotal, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finding an eligible timestamp
|
||||
now := a.getTime()
|
||||
for t, _ := range timeTotal {
|
||||
if t.Year() == now.Year() && t.Month() == now.Month() && t.Day() == now.Day() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// no timestamp => need the snapshot !
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (a AppConfig) needHourlySnapshot() bool {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needHourlySnapshot : %s : Start", a.Name)
|
||||
}
|
||||
ret := false
|
||||
|
||||
// schedule enabled for app ?
|
||||
for _, v := range a.Schedule {
|
||||
if v == "hourly" {
|
||||
ret = true
|
||||
}
|
||||
}
|
||||
if !ret {
|
||||
return false
|
||||
}
|
||||
|
||||
// finding out the timestamps existing
|
||||
timeSource := make(map[string]map[time.Time]struct{})
|
||||
timeTotal := make(map[time.Time]struct{})
|
||||
re := regexp.MustCompile(`^(yearly|monthly|weekly|daily|hourly)-(?P<Date>[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}.[0-9]{2}.[0-9]{2})--([0-9]+[ymwdhMs]{1}|forever)$`)
|
||||
for _, src := range a.Sources {
|
||||
timeSource[string(src)] = make(map[time.Time]struct{})
|
||||
for _, snap := range cfg.Box[src.Box()].ssh.snapshot {
|
||||
if src.Path() == snap.Path() {
|
||||
if re.MatchString(snap.Name()) {
|
||||
dateString := re.ReplaceAllString(snap.Name(), "${Date}")
|
||||
dateTime, err := time.Parse("2006-01-02_15.04.05", dateString)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.needYearlySnapshot : %s : time.Parse(%s) : %s", a.Name, dateString, err)
|
||||
}
|
||||
} else {
|
||||
timeSource[string(src)][dateTime] = struct{}{}
|
||||
timeTotal[dateTime] = struct{}{}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// cleaning up the available timestamps for common timestamps
|
||||
for t, _ := range timeTotal {
|
||||
for _, v := range timeSource {
|
||||
if _, ok := v[t]; !ok {
|
||||
delete(timeTotal, t)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// finding an eligible timestamp
|
||||
now := a.getTime()
|
||||
for t, _ := range timeTotal {
|
||||
if t.Year() == now.Year() && t.Month() == now.Month() && t.Day() == now.Day() && t.Hour() == now.Hour() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// no timestamp => need the snapshot !
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (a AppConfig) RunAppBackup() error {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Start", a.Name)
|
||||
}
|
||||
schedule, err := a.getSchedule()
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error getting schedule : %s", a.Name, err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
if schedule == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, src := range a.Sources {
|
||||
if !cfg.Box[src.Box()].ssh.isZFS(src.Path()) {
|
||||
return fmt.Errorf("No path %s on source", string(src))
|
||||
}
|
||||
for _, dest := range a.Destinations {
|
||||
if !cfg.Box[dest.Box()].ssh.isZFS(dest.Path() + "/" + src.Box() + "/" + src.Path()) {
|
||||
err := cfg.Box[dest.Box()].ssh.createZFS(dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error creating %s on %s", a.Name, dest.Path()+"/"+src.Box()+"/"+src.Path(), dest.Box())
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, v := range a.Before {
|
||||
re := regexp.MustCompile(k)
|
||||
if re.MatchString(schedule) {
|
||||
err := cfg.Box[v.Box()].ssh.exec(v.Path())
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error executing %s", a.Name, string(v))
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
refreshSnapshot := make(map[string]bool)
|
||||
takeSnapshot := make(map[string]string)
|
||||
delSnapshot := make(map[string]string)
|
||||
for _, v := range a.Sources {
|
||||
takeSnapshot[v.Box()] = takeSnapshot[v.Box()] + " " + v.Path()
|
||||
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 {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : taking snapshot on %s for %s", a.Name, k, v)
|
||||
}
|
||||
err := cfg.Box[k].ssh.exec("/usr/sbin/zfsnap snapshot -p " + schedule + "- -a " + cfg.Zfsnap[schedule] + v)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error executing zfsnap on %s", a.Name, k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, v := range a.Destinations {
|
||||
refreshSnapshot[v.Box()] = true
|
||||
}
|
||||
for k, _ := range refreshSnapshot {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : refreshing snapshots for source %s", a.Name, k)
|
||||
}
|
||||
err := cfg.Box[k].ssh.getSnapshotList()
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error getting snapshots on %s", a.Name, k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
for _, src := range a.Sources {
|
||||
for _, dest := range a.Destinations {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Sending snapshots from %s to %s", a.Name, string(src), string(dest))
|
||||
}
|
||||
dLastSnapshot, err := cfg.Box[dest.Box()].ssh.getLastSnapshot(dest.Path() + "/" + src.Box() + "/" + src.Path())
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : No snapshot for %s on %s", a.Name, string(src), dest.Box())
|
||||
}
|
||||
sFirstSnapshot, err := cfg.Box[src.Box()].ssh.getFirstSnapshot(src.Path())
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : No snapshot for %s", a.Name, string(src))
|
||||
}
|
||||
return err
|
||||
}
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Initializing snapshot on %s from %s", a.Name, dest.Box(), string(sFirstSnapshot))
|
||||
}
|
||||
err = cfg.Box[dest.Box()].ssh.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 {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Initializing snapshot on %s from %s failed (%s)", a.Name, dest.Box(), string(sFirstSnapshot), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
var sCurrSnapshot Snapshot
|
||||
sNextSnapshot := sFirstSnapshot
|
||||
for !cfg.Box[src.Box()].ssh.isLastSnapshot(sNextSnapshot) {
|
||||
sCurrSnapshot = sNextSnapshot
|
||||
sNextSnapshot, err = cfg.Box[src.Box()].ssh.getNextSnapshot(sNextSnapshot)
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Sending incrementally %s to %s", a.Name, string(sNextSnapshot), dest.Box())
|
||||
}
|
||||
err = cfg.Box[dest.Box()].ssh.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("AppConfig.RunAppBackup : %s : Sending snapshot on %s from %s failed (%s)", a.Name, dest.Box(), string(sNextSnapshot), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : All snapshots sent for %s", a.Name, string(src))
|
||||
}
|
||||
|
||||
} else {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Last snapshot on %s is %s", a.Name, dest.Box(), string(dLastSnapshot))
|
||||
}
|
||||
var sCurrSnapshot Snapshot
|
||||
sNextSnapshot := Snapshot(string(dLastSnapshot)[len(string(dest))+2:])
|
||||
for !cfg.Box[src.Box()].ssh.isLastSnapshot(sNextSnapshot) {
|
||||
sCurrSnapshot = sNextSnapshot
|
||||
sNextSnapshot, err = cfg.Box[src.Box()].ssh.getNextSnapshot(sNextSnapshot)
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Sending incrementally %s to %s", a.Name, string(sNextSnapshot), dest.Box())
|
||||
}
|
||||
err = cfg.Box[dest.Box()].ssh.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("AppConfig.RunAppBackup : %s : Sending snapshot on %s from %s failed (%s)", a.Name, dest.Box(), string(sNextSnapshot), err)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for k, v := range takeSnapshot {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : cleaning snapshot on %s for %s", a.Name, k, v)
|
||||
}
|
||||
err := cfg.Box[k].ssh.exec("/usr/sbin/zfsnap destroy -p hourly- -p daily- -p weekly- -p monthly- -p yearly- " + v)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error executing zfsnap on %s", a.Name, k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
for k, v := range delSnapshot {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : cleaning snapshot on %s for %s", a.Name, k, v)
|
||||
}
|
||||
err := cfg.Box[k].ssh.exec("/usr/sbin/zfsnap destroy -p hourly- -p daily- -p weekly- -p monthly- -p yearly- " + v)
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error executing zfsnap on %s", a.Name, k)
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
for k, v := range a.After {
|
||||
re := regexp.MustCompile(k)
|
||||
if re.MatchString(schedule) {
|
||||
err := cfg.Box[v.Box()].ssh.exec(v.Path())
|
||||
if err != nil {
|
||||
if *debugFlag {
|
||||
log.Printf("AppConfig.RunAppBackup : %s : Error executing %s on %s", a.Name, v.Path(), v.Box())
|
||||
}
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
Reference in New Issue
Block a user