diff --git a/app.go b/app.go index e60929f..b8fd63f 100644 --- a/app.go +++ b/app.go @@ -668,7 +668,7 @@ func (a AppConfig) CleanupSnapshot() error { for k, v := range cleanupSnapshot { if *debugFlag { - log.Printf("AppConfig.CleanupSnapshot : %s : cleaning snapshots on %s for%s", a.Name, k, v) + log.Printf("AppConfig.CleanupSnapshot : %s : cleaning snapshots on %s for %s", a.Name, k, v) } _, err := cfg.Box[k].SSHExec("zfsnap destroy -p hourly- -p daily- -p weekly- -p monthly- -p yearly-" + v) if err != nil { @@ -704,6 +704,14 @@ func (a AppConfig) RunAppBackup() error { } } + err = a.CleanupSnapshot() + if err != nil { + if *debugFlag { + log.Printf("AppConfig.RunAppBackup : %s : CleanupSnapshot : %s", a.Name, err) + } + return err + } + if schedule != "" { err = a.ExecBefore(schedule) if err != nil { @@ -748,13 +756,5 @@ func (a AppConfig) RunAppBackup() error { } } - err = a.CleanupSnapshot() - if err != nil { - if *debugFlag { - log.Printf("AppConfig.RunAppBackup : %s : RefreshSnapshot : %s", a.Name, err) - } - return err - } - return nil } diff --git a/backup.go b/backup.go index fefe39a..4360ad6 100644 --- a/backup.go +++ b/backup.go @@ -5,6 +5,7 @@ import ( "fmt" "log" "os" + "time" ) var ( @@ -15,6 +16,7 @@ var ( testFlag = flag.Bool("test", false, "test run") debugFlag = flag.Bool("debug", false, "debug") cfg Config + email *Email ) func main() { @@ -22,6 +24,9 @@ func main() { fmt.Printf("backup (%s)\n", version) + email = new(Email) + email.startTime = time.Now() + err := cfg.Load() if err != nil { log.Printf("Cannot load config (%s)", err) @@ -33,6 +38,10 @@ func main() { log.Printf("Cannot run schedule (%s)", err) os.Exit(1) } + + if len(email.items) > 0 { + SendMail(cfg.Email.smtpHost, cfg.Email.fromEmail, "Autobackup report", fmt.Sprintf("%v", email.items), cfg.Email.toEmail) + } } //RunBackup run all backup targets where schedule is registered diff --git a/config.go b/config.go index 524944a..8204157 100644 --- a/config.go +++ b/config.go @@ -15,8 +15,9 @@ import ( type Config struct { Zfsnap map[string]string `json:"zfsnap"` Box map[string]*Box `json:"box"` - Apps []AppConfig `json:apps` + Apps []AppConfig `json:"apps"` Timezone string `json:"timezone"` + Email EmailConfig `json:"email"` Now time.Time `json:"-"` } @@ -135,7 +136,7 @@ func (c *Config) Load() error { return fmt.Errorf("No box defined for source : %s", string(src)) } if !cfg.Box[src.Box()].online { - return fmt.Errorf("Source box offline for app : %s", app.Name) + email.items = append(email.items, fmt.Sprintf("Source box offline for app : %s", app.Name)) } } var allOffline bool = true @@ -151,7 +152,7 @@ func (c *Config) Load() error { } } if allOffline { - return fmt.Errorf("No online destination box for app : %s", app.Name) + email.items = append(email.items, fmt.Sprintf("No online destination box for app : %s", app.Name)) } for val, before := range app.Before { @@ -169,7 +170,7 @@ func (c *Config) Load() error { return fmt.Errorf("No box defined for before : %s", string(before)) } if !cfg.Box[before.Box()].online { - return fmt.Errorf("Before box offline for app : %s", app.Name) + email.items = append(email.items, fmt.Sprintf("Before box offline for app : %s", app.Name)) } } for val, after := range app.After { @@ -187,7 +188,7 @@ func (c *Config) Load() error { return fmt.Errorf("No box defined for after : %s", string(after)) } if !cfg.Box[after.Box()].online { - return fmt.Errorf("After box offline for app : %s", app.Name) + email.items = append(email.items, fmt.Sprintf("After box offline for app : %s", app.Name)) } } } diff --git a/email.go b/email.go new file mode 100644 index 0000000..d097bbb --- /dev/null +++ b/email.go @@ -0,0 +1,60 @@ +package main + +import ( + "encoding/base64" + "net/smtp" + "strings" + "time" +) + +type Email struct { + startTime time.Time + items []string +} + +type EmailConfig struct { + smtpHost string `json:"smtp"` + fromEmail string `json:"email_from"` + toEmail []string `json:"email_to"` +} + +func SendMail(addr, from, subject, body string, to []string) error { + r := strings.NewReplacer("\r\n", "", "\r", "", "\n", "", "%0a", "", "%0d", "") + + c, err := smtp.Dial(addr) + if err != nil { + return err + } + defer c.Close() + if err = c.Mail(r.Replace(from)); err != nil { + return err + } + for i := range to { + to[i] = r.Replace(to[i]) + if err = c.Rcpt(to[i]); err != nil { + return err + } + } + + w, err := c.Data() + if err != nil { + return err + } + + msg := "To: " + strings.Join(to, ",") + "\r\n" + + "From: " + from + "\r\n" + + "Subject: " + subject + "\r\n" + + "Content-Type: text/html; charset=\"UTF-8\"\r\n" + + "Content-Transfer-Encoding: base64\r\n" + + "\r\n" + base64.StdEncoding.EncodeToString([]byte(body)) + + _, err = w.Write([]byte(msg)) + if err != nil { + return err + } + err = w.Close() + if err != nil { + return err + } + return c.Quit() +} diff --git a/version.go b/version.go index a493389..4ccd461 100644 --- a/version.go +++ b/version.go @@ -1,6 +1,6 @@ // Code generated by version.sh (@generated) DO NOT EDIT. package main -var githash = "2ae1737" -var buildstamp = "2022-05-21_15:22:30" -var commits = "33" -var version = "2ae1737-b33 - 2022-05-21_15:22:30" +var githash = "41d56eb" +var buildstamp = "2022-06-17_12:53:48" +var commits = "34" +var version = "41d56eb-b34 - 2022-06-17_12:53:48"