package main import ( "fmt" "io/ioutil" "local/args" "local/storage" "log" "os" "os/exec" "path" "path/filepath" "sort" "time" ) type Config struct { n int conf string rclone string ns string root string store string } func main() { conf := config() log.Println(conf) store, err := storage.New(storage.TypeFromString(conf.store), conf.conf, path.Join(conf.rclone+":", conf.ns)) if err != nil { panic(err) } if err := push(conf.root, store); err != nil { panic(err) } if err := clean(conf.n, store); err != nil { panic(err) } } func config() Config { as := args.NewArgSet() as.Append(args.INT, "n", "number of backups to retain", 5) as.Append(args.STRING, "conf", "path to rclone conf", path.Join(os.Getenv("HOME"), "/.config/rclone/rclone.conf")) as.Append(args.STRING, "root", "path to root", "./public") as.Append(args.STRING, "ns", "ns for backups", path.Join("lastn", "dev")) as.Append(args.STRING, "rclone", "rclone backend name", "blapointe-drive-enc") as.Append(args.STRING, "store", "type of store, like [map rclone]", "map") if err := as.Parse(); err != nil { panic(err) } return Config{ n: as.Get("n").GetInt(), conf: as.Get("conf").GetString(), rclone: as.Get("rclone").GetString(), root: as.Get("root").GetString(), ns: as.Get("ns").GetString(), store: as.Get("store").GetString(), } } func push(root string, store storage.DB) error { root, err := filepath.Abs(root) if err != nil { return err } archive := path.Join( os.TempDir(), fmt.Sprintf( "%s.tar", time.Now().Format("2006.01.02.15.04.05"), ), ) cmd := exec.Command( "tar", "-C", path.Dir(root), "-czf", archive, root, ) out, err := cmd.CombinedOutput() if err != nil { return fmt.Errorf("%v: %s", err, out) } b, err := ioutil.ReadFile(archive) if err != nil { return err } log.Println("Created backup", path.Base(archive)) return store.Set(path.Base(archive), b) } func clean(n int, store storage.DB) error { backups, err := store.List(nil) if err != nil { return err } sort.Strings(backups) for i := 0; i < len(backups)-n; i++ { log.Println("Pruning old backup", backups[i]) err := store.Set(backups[i], nil) if err != nil { return err } } return nil }