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
+5 -5
View File
@@ -16,9 +16,9 @@ Linux:
curl -fsSL https://git.denkena-consulting.com/f-denkena/rclone-dropbox-bisync/raw/branch/master/linux/install.sh | bash
First run is --dry-run --resync until:
Missing listings + RCLONE_TEST on both sides: dry-run --resync, then live
--resync (install/daemon, not after a failed normal run). --accept-resync
skips the dry-run. Partial listings (one .lst) abort instead of resync.
rclone-bisyncd --accept-resync
enabled=true only after RCLONE_TEST exists on dropbox:. Looping daemon sleeps
15 min after each finished run (no overlapping 15-min tasks).
enabled=true after a successful first resync, or if dropbox: already has
RCLONE_TEST at install. Looping daemon sleeps 15 min after each run.
+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
}
+1 -1
View File
@@ -97,5 +97,5 @@ esac
echo "Configured path1=$DROPBOX workdir=$WORKDIR (~/DataStorage)"
echo "Startup: looping systemd --user service (sleeps 15 min after each run)"
echo "If listings are empty: dry-run --resync only. Then: rclone-bisyncd --accept-resync"
echo "No listings + RCLONE_TEST on both sides → dry-run --resync then live --resync"
echo "enabled=$ENABLED (true only if dropbox: already has RCLONE_TEST)"
+1 -1
View File
@@ -3,5 +3,5 @@ set -eu
systemctl --user daemon-reload 2>/dev/null || true
systemctl --user enable --now rclone-bisync.service 2>/dev/null || true
if command -v notify-send >/dev/null 2>&1; then
notify-send -a rclone-bisync "rclone-bisync" "Looping bisync started. First run is dry-run --resync until rclone-bisyncd --accept-resync."
notify-send -a rclone-bisync "rclone-bisync" "Looping bisync started. First use: dry-run then live --resync if both RCLONE_TEST exist."
fi
+1 -1
View File
@@ -37,4 +37,4 @@ Start-Process powershell.exe -WindowStyle Hidden -ArgumentList @(
Start-Process $daemon -WindowStyle Hidden
Add-Type -AssemblyName PresentationFramework
[System.Windows.MessageBox]::Show("Installed to $Dest`r`nCopy RCLONE_TEST to dropbox:, set enabled=true, then rclone-bisyncd --accept-resync.", 'rclone-dropbox-bisync')
[System.Windows.MessageBox]::Show("Installed to $Dest`r`nCopy RCLONE_TEST to dropbox: if missing. First run dry-runs then live --resync when both markers exist.", 'rclone-dropbox-bisync')
+2 -3
View File
@@ -97,7 +97,6 @@ Configured:
workdir $Workdir
session datastorage-dropbox (shared with Linux)
daemon looping; 15 min after each run; mkdir lock
Copy RCLONE_TEST to dropbox:, set enabled=true, then:
rclone-bisyncd --accept-resync
(first run is --dry-run --resync until then)
If dropbox: has RCLONE_TEST and listings are missing, the daemon
dry-run --resync then live --resync on its own. Never after a failed run.
"@