restic-scheduler/run.go

170 lines
3.2 KiB
Go

package main
import (
"fmt"
"log"
"os"
"os/exec"
"strings"
"time"
)
var defaultFlags = log.LstdFlags | log.Lmsgprefix
type ResticCmd struct {
LogPrefix string
Repo string
Env map[string]string
Passphrase string
}
func (rcmd ResticCmd) BuildEnv() []string {
rcmd.Env["RESTIC_PASSWORD"] = rcmd.Passphrase
envList := []string{}
for name, value := range rcmd.Env {
envList = append(envList, fmt.Sprintf("%s=%s", name, value))
}
return envList
}
func (rcmd ResticCmd) RunRestic(args []string) error {
cmd := exec.Command("restic", args...)
cmd.Stdout = rcmd.Logger().Writer()
cmd.Stderr = cmd.Stdout
cmd.Env = rcmd.BuildEnv()
err := cmd.Run()
return err
}
func (rcmd ResticCmd) Logger() *log.Logger {
logger := log.New(os.Stderr, rcmd.LogPrefix, defaultFlags)
return logger
}
func (rcmd ResticCmd) Backup(path string, args []string) error {
args = append([]string{"--repo", rcmd.Repo, "backup"}, args...)
args = append(args, path)
err := rcmd.RunRestic(args)
return err
}
type ForgetOpts struct {
KeepLast int
KeepHourly int
KeepDaily int
KeepWeekly int
KeepMonthly int
KeepYearly int
KeepWithin time.Duration
KeepWithinHourly time.Duration
KeepWithinDaily time.Duration
KeepWithinWeekly time.Duration
KeepWithinMonthly time.Duration
KeepWithinYearly time.Duration
Tags []string
KeepTags []string
Prune bool
}
func (fo ForgetOpts) ToArgs() []string {
args := []string{}
// Add keep-*
if fo.KeepLast > 0 {
args = append(args, "--keep-last", fmt.Sprint(fo.KeepLast))
}
if fo.KeepHourly > 0 {
args = append(args, "--keep-hourly", fmt.Sprint(fo.KeepHourly))
}
if fo.KeepDaily > 0 {
args = append(args, "--keep-daily", fmt.Sprint(fo.KeepDaily))
}
if fo.KeepWeekly > 0 {
args = append(args, "--keep-weekly", fmt.Sprint(fo.KeepWeekly))
}
if fo.KeepMonthly > 0 {
args = append(args, "--keep-monthly", fmt.Sprint(fo.KeepMonthly))
}
if fo.KeepYearly > 0 {
args = append(args, "--keep-yearly", fmt.Sprint(fo.KeepYearly))
}
if fo.KeepWithin > 0 {
args = append(args, "--keep-within", fmt.Sprint(fo.KeepWithin))
}
// Add keep-within-*
if fo.KeepWithinHourly > 0 {
args = append(args, "--keep-within-hourly", fo.KeepWithinHourly.String())
}
if fo.KeepWithinDaily > 0 {
args = append(args, "--keep-within-daily", fo.KeepWithinDaily.String())
}
if fo.KeepWithinWeekly > 0 {
args = append(args, "--keep-within-weekly", fo.KeepWithinWeekly.String())
}
if fo.KeepWithinMonthly > 0 {
args = append(args, "--keep-within-monthly", fo.KeepWithinMonthly.String())
}
if fo.KeepWithinYearly > 0 {
args = append(args, "--keep-within-yearly", fo.KeepWithinYearly.String())
}
// Add tags
if len(fo.Tags) > 0 {
args = append(args, "--tag", strings.Join(fo.Tags, ","))
}
if len(fo.KeepTags) > 0 {
args = append(args, "--keep-tag", strings.Join(fo.Tags, ","))
}
// Add prune options
if fo.Prune {
args = append(args, "--prune")
}
return args
}
func (rcmd ResticCmd) Cleanup(forgetOpts ForgetOpts) error {
args := append([]string{"--repo", rcmd.Repo, "forget"}, forgetOpts.ToArgs()...)
err := rcmd.RunRestic(args)
return err
}
func (rcmd ResticCmd) Check() error {
args := []string{"--repo", rcmd.Repo, "check"}
err := rcmd.RunRestic(args)
return err
}