170 lines
3.2 KiB
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
|
|
}
|