From c5b75c245c84ac9d0a1a0552bae6bfdd3a71a987 Mon Sep 17 00:00:00 2001 From: shoopea Date: Mon, 11 Oct 2021 10:33:30 +0800 Subject: [PATCH] select snapshots to send --- backup.go | 134 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 133 insertions(+), 1 deletion(-) diff --git a/backup.go b/backup.go index 3883095..7b00859 100644 --- a/backup.go +++ b/backup.go @@ -35,6 +35,7 @@ type AppConfig struct { Before map[string]Location `json:"before"` After map[string]Location `json:"after"` } + type SSHConfig struct { signer ssh.Signer config *ssh.ClientConfig @@ -74,6 +75,16 @@ func (l Location) Valid() bool { return len(s) == 2 } +func (s Snapshot) Path() string { + s2 := strings.Split(string(s), `@`) + return s2[0] +} + +func (s Snapshot) Name() string { + s2 := strings.Split(string(s), `@`) + return s2[1] +} + //Load config from file func (c *Config) Load() error { b, err := ioutil.ReadFile(*cfgFile) @@ -221,6 +232,62 @@ func (c *Config) Close() error { return nil } +func (s *SSHConfig) getLastSnapshot(path string) (Snapshot, error) { + var last Snapshot + for _, v := range s.snapshot { + if v.Path() == path { + last = v + } else { + if len(string(last)) > 0 { + return last, nil + } + } + } + if len(string(last)) > 0 { + return last, nil + } + return last, fmt.Errorf("no snapshot") +} + +func (s *SSHConfig) isLastSnapshot(snapshot Snapshot) bool { + _, err := s.getNextSnapshot(snapshot) + if err != nil { + return true + } else { + return false + } +} + +func (s *SSHConfig) getFirstSnapshot(path string) (Snapshot, error) { + var first Snapshot + for _, v := range s.snapshot { + if v.Path() == path { + first = v + return first, nil + } + } + return first, fmt.Errorf("no snapshot") +} + +func (s *SSHConfig) getNextSnapshot(snapshot Snapshot) (Snapshot, error) { + var next Snapshot + for id, v := range s.snapshot { + if v == snapshot { + if len(s.snapshot) > id+1 { + next = s.snapshot[id+1] + if next.Path() == snapshot.Path() { + return next, nil + } else { + return next, fmt.Errorf("no snapshot") + } + } else { + return next, fmt.Errorf("no snapshot") + } + } + } + return next, fmt.Errorf("no snapshot") +} + func (s *SSHConfig) getSnapshotList() error { if *debugFlag { log.Printf("SSHConfig.getSnapshotList : Start %s", s.name) @@ -480,7 +547,72 @@ func (a AppConfig) RunAppSchedule(schedule string) error { for _, dest := range a.Destinations { if *debugFlag { log.Printf("RunAppSchedule : Sending snapshots from %s to %s", string(src), string(dest)) - + } + dLastSnapshot, err := cfg.ssh[dest.Box()].getLastSnapshot(dest.Path() + "/" + src.Path()) + if err != nil { + if *debugFlag { + log.Printf("RunAppSchedule : No snapshot for %s on %s", string(src), dest.Box()) + } + sFirstSnapshot, err := cfg.ssh[src.Box()].getFirstSnapshot(src.Path()) + if err != nil { + if *debugFlag { + log.Printf("RunAppSchedule : No snapshot for %s", string(src)) + } + return err + } else { + if *debugFlag { + log.Printf("RunAppSchedule : Initializing snapshot on %s from %s", dest.Box(), string(sFirstSnapshot)) + } + sNextSnapshot, err := cfg.ssh[src.Box()].getNextSnapshot(sFirstSnapshot) + if err != nil { + if *debugFlag { + log.Printf("RunAppSchedule : All snapshots sent for %s", string(src)) + } + } else { + if *debugFlag { + log.Printf("RunAppSchedule : Sending %s to %s", string(sNextSnapshot), dest.Box()) + } + for !cfg.ssh[src.Box()].isLastSnapshot(sNextSnapshot) { + sNextSnapshot, err = cfg.ssh[src.Box()].getNextSnapshot(sNextSnapshot) + if *debugFlag { + log.Printf("RunAppSchedule : Sending %s to %s", string(sNextSnapshot), dest.Box()) + } + } + if *debugFlag { + log.Printf("RunAppSchedule : All snapshots sent for %s", string(src)) + } + } + } + } else { + if *debugFlag { + log.Printf("RunAppSchedule : Last snapshot on %s is %s", dest.Box(), string(dLastSnapshot)) + } + if !cfg.ssh[src.Box()].isLastSnapshot(dLastSnapshot) { + sNextSnapshot, err := cfg.ssh[src.Box()].getNextSnapshot(dLastSnapshot) + if err != nil { + if *debugFlag { + log.Printf("RunAppSchedule : No snapshot for %s", string(src)) + } + return err + } else { + if *debugFlag { + log.Printf("RunAppSchedule : Sending %s to %s", string(sNextSnapshot), dest.Box()) + } + for !cfg.ssh[src.Box()].isLastSnapshot(sNextSnapshot) { + sNextSnapshot, err = cfg.ssh[src.Box()].getNextSnapshot(sNextSnapshot) + if *debugFlag { + log.Printf("RunAppSchedule : Sending %s to %s", string(sNextSnapshot), dest.Box()) + } + } + if *debugFlag { + log.Printf("RunAppSchedule : All snapshots sent for", string(src)) + } + } + } else { + if *debugFlag { + log.Printf("RunAppSchedule : Last snapshot sent for", string(src)) + } + } } } }