daemon: auto --resync on first use after successful dry-run

Both RCLONE_TEST required. Never after a failed normal run. Partial
listings abort. Enables config after live resync.
This commit is contained in:
2026-09-10 01:14:53 +02:00
parent dc8f1e885a
commit e94fca5ae1
6 changed files with 53 additions and 22 deletions
+43 -11
View File
@@ -89,13 +89,43 @@ func escapePS(s string) string {
return strings.ReplaceAll(s, "'", "''")
}
func listingsExist(cfg Config) bool {
func listingFiles(cfg Config) (path1, path2 string) {
base := filepath.Join(cfg.Workdir, cfg.SessionName)
_, e1 := os.Stat(base + ".path1.lst")
_, e2 := os.Stat(base + ".path2.lst")
return base + ".path1.lst", base + ".path2.lst"
}
func listingsExist(cfg Config) bool {
p1, p2 := listingFiles(cfg)
_, e1 := os.Stat(p1)
_, e2 := os.Stat(p2)
return e1 == nil && e2 == nil
}
func listingsPartial(cfg Config) bool {
p1, p2 := listingFiles(cfg)
_, e1 := os.Stat(p1)
_, e2 := os.Stat(p2)
return (e1 == nil) != (e2 == nil)
}
func setEnabled(v bool) {
p := configPath()
b, err := os.ReadFile(p)
if err != nil {
return
}
var m map[string]any
if json.Unmarshal(b, &m) != nil {
return
}
m["enabled"] = v
out, err := json.MarshalIndent(m, "", " ")
if err != nil {
return
}
_ = os.WriteFile(p, append(out, '\n'), 0600)
}
func remoteHasCheckFile(cfg Config) bool {
cmd := exec.Command(cfg.Rclone, "lsf", cfg.Path2, "--include", cfg.CheckFilename)
out, err := cmd.CombinedOutput()
@@ -179,24 +209,26 @@ func runOnce(cfg Config, acceptResync bool) error {
return fmt.Errorf("missing %s on %s", cfg.CheckFilename, cfg.Path2)
}
if listingsPartial(cfg) {
return fmt.Errorf("incomplete listings in %s (one side missing) — not auto --resync; fix or delete both .lst files", cfg.Workdir)
}
if !listingsExist(cfg) {
if acceptResync {
_ = os.WriteFile(acceptPath(cfg), []byte("ok\n"), 0600)
}
if _, err := os.Stat(acceptPath(cfg)); err != nil && !acceptResync {
notify("rclone-bisync dry-run resync", "No listings yet. Inspect output, then: rclone-bisyncd --accept-resync")
// First use only: never auto --resync after a failed normal run.
if !acceptResync {
notify("rclone-bisync", "No listings — dry-run --resync")
if err := runRclone(cfg, "--dry-run", "--resync"); err != nil {
notify("rclone-bisync dry-run failed", err.Error())
return err
}
return nil
}
notify("rclone-bisync", "Live --resync starting (one-shot)")
notify("rclone-bisync", "Live --resync (first listings)")
if err := runRclone(cfg, "--resync"); err != nil {
notify("rclone-bisync resync failed", err.Error())
return err
}
notify("rclone-bisync", "Live resync finished")
_ = os.WriteFile(acceptPath(cfg), []byte("ok\n"), 0600)
setEnabled(true)
notify("rclone-bisync", "Resync finished; enabled=true")
return nil
}