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:
@@ -16,9 +16,9 @@ Linux:
|
|||||||
|
|
||||||
curl -fsSL https://git.denkena-consulting.com/f-denkena/rclone-dropbox-bisync/raw/branch/master/linux/install.sh | bash
|
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 after a successful first resync, or if dropbox: already has
|
||||||
|
RCLONE_TEST at install. Looping daemon sleeps 15 min after each run.
|
||||||
enabled=true only after RCLONE_TEST exists on dropbox:. Looping daemon sleeps
|
|
||||||
15 min after each finished run (no overlapping 15-min tasks).
|
|
||||||
|
|||||||
+43
-11
@@ -89,13 +89,43 @@ func escapePS(s string) string {
|
|||||||
return strings.ReplaceAll(s, "'", "''")
|
return strings.ReplaceAll(s, "'", "''")
|
||||||
}
|
}
|
||||||
|
|
||||||
func listingsExist(cfg Config) bool {
|
func listingFiles(cfg Config) (path1, path2 string) {
|
||||||
base := filepath.Join(cfg.Workdir, cfg.SessionName)
|
base := filepath.Join(cfg.Workdir, cfg.SessionName)
|
||||||
_, e1 := os.Stat(base + ".path1.lst")
|
return base + ".path1.lst", base + ".path2.lst"
|
||||||
_, e2 := os.Stat(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
|
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 {
|
func remoteHasCheckFile(cfg Config) bool {
|
||||||
cmd := exec.Command(cfg.Rclone, "lsf", cfg.Path2, "--include", cfg.CheckFilename)
|
cmd := exec.Command(cfg.Rclone, "lsf", cfg.Path2, "--include", cfg.CheckFilename)
|
||||||
out, err := cmd.CombinedOutput()
|
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)
|
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 !listingsExist(cfg) {
|
||||||
if acceptResync {
|
// First use only: never auto --resync after a failed normal run.
|
||||||
_ = os.WriteFile(acceptPath(cfg), []byte("ok\n"), 0600)
|
if !acceptResync {
|
||||||
}
|
notify("rclone-bisync", "No listings — dry-run --resync")
|
||||||
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")
|
|
||||||
if err := runRclone(cfg, "--dry-run", "--resync"); err != nil {
|
if err := runRclone(cfg, "--dry-run", "--resync"); err != nil {
|
||||||
notify("rclone-bisync dry-run failed", err.Error())
|
notify("rclone-bisync dry-run failed", err.Error())
|
||||||
return err
|
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 {
|
if err := runRclone(cfg, "--resync"); err != nil {
|
||||||
notify("rclone-bisync resync failed", err.Error())
|
notify("rclone-bisync resync failed", err.Error())
|
||||||
return err
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -97,5 +97,5 @@ esac
|
|||||||
|
|
||||||
echo "Configured path1=$DROPBOX workdir=$WORKDIR (~/DataStorage)"
|
echo "Configured path1=$DROPBOX workdir=$WORKDIR (~/DataStorage)"
|
||||||
echo "Startup: looping systemd --user service (sleeps 15 min after each run)"
|
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)"
|
echo "enabled=$ENABLED (true only if dropbox: already has RCLONE_TEST)"
|
||||||
|
|||||||
@@ -3,5 +3,5 @@ set -eu
|
|||||||
systemctl --user daemon-reload 2>/dev/null || true
|
systemctl --user daemon-reload 2>/dev/null || true
|
||||||
systemctl --user enable --now rclone-bisync.service 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
|
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
|
fi
|
||||||
|
|||||||
+1
-1
@@ -37,4 +37,4 @@ Start-Process powershell.exe -WindowStyle Hidden -ArgumentList @(
|
|||||||
Start-Process $daemon -WindowStyle Hidden
|
Start-Process $daemon -WindowStyle Hidden
|
||||||
|
|
||||||
Add-Type -AssemblyName PresentationFramework
|
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')
|
||||||
|
|||||||
@@ -97,7 +97,6 @@ Configured:
|
|||||||
workdir $Workdir
|
workdir $Workdir
|
||||||
session datastorage-dropbox (shared with Linux)
|
session datastorage-dropbox (shared with Linux)
|
||||||
daemon looping; 15 min after each run; mkdir lock
|
daemon looping; 15 min after each run; mkdir lock
|
||||||
Copy RCLONE_TEST to dropbox:, set enabled=true, then:
|
If dropbox: has RCLONE_TEST and listings are missing, the daemon
|
||||||
rclone-bisyncd --accept-resync
|
dry-run --resync then live --resync on its own. Never after a failed run.
|
||||||
(first run is --dry-run --resync until then)
|
|
||||||
"@
|
"@
|
||||||
|
|||||||
Reference in New Issue
Block a user