diff --git a/README.md b/README.md index 887dee1..1ef7b73 100644 --- a/README.md +++ b/README.md @@ -131,11 +131,11 @@ as sync targets and mount points — a mismatch is a broken path. # the share on HOST2 must have the exact same name. # # Same name on both servers: - /mnt/user/Movies # HOST1 source of truth, HOST2 mirror - /mnt/user/Tv_Shows # HOST1 source of truth, HOST2 mirror - /mnt/user/Music # HOST1 source of truth, HOST2 mirror - /mnt/user/Anime_Shows # HOST2 source of truth, HOST1 mirror - /mnt/user/Anime_Movies # HOST2 source of truth, HOST1 mirror + /mnt/user/Movies # both servers — arr_sync.sh keeps Radarr in union + /mnt/user/Tv_Shows # both servers — arr_sync.sh keeps Sonarr in union + /mnt/user/Music # both servers — arr_sync.sh keeps Lidarr in union + /mnt/user/Anime_Shows # both servers — arr_sync.sh keeps Sonarr in union + /mnt/user/Anime_Movies # both servers — arr_sync.sh keeps Radarr in union # # rsync.sh syncs /mnt/user/Movies on HOST1 → /mnt/user/Movies on HOST2. # If HOST2 has it at /mnt/user/Movies-Mirror → rsync aborts: path not found. @@ -168,46 +168,61 @@ across separate shares per-user or per-application. --- -### ── Never Two Arrs Against the Same Share Simultaneously ─────────────────── +### ── Both Arrs Manage All Shares — arr_sync.sh Is the Source of Truth ─────── ```bash # ───────────────────────────────────────────────────────────────────────────── -# This rule is absolute. No exceptions. +# Both servers run Sonarr, Radarr, and Lidarr — all pointing at the same +# share names. Either server can download anything to any share at any time. # -# Correct: HOST1 Sonarr manages /mnt/user/Tv_Shows -# HOST2 Sonarr manages /mnt/user/Anime_Shows -# Different shares — no conflict +# How it stays coherent: +# arr_sync.sh runs first (before rsync) — bidirectional library union. +# Both Sonarr instances know about every TV episode on either server. +# Both Radarr instances know about every movie on either server. +# Both Lidarr instances know about every album on either server. # -# Correct: HOST1 Tdarr transcodes from /mnt/user/Anime_Shows -# HOST2 Sonarr downloads into /mnt/user/Anime_Shows -# But: they run in non-overlapping time windows +# Then rsync spreads the files additively (no --delete). +# Any file downloaded on HOST1 propagates to HOST2 on the next cycle. +# Any file downloaded on HOST2 propagates to HOST1 on the next cycle. # -# WRONG: HOST1 Sonarr AND HOST2 Sonarr both managing /mnt/user/Tv_Shows -# Two arrs managing the same library = rename conflicts, double imports, -# deletion battles, corrupted databases. +# HOST1 downloads Tv_Shows episode: +# → HOST1 Sonarr tracks it immediately +# → arr_sync.sh runs → HOST2 Sonarr now tracks it +# → daily rsync → file lands on HOST2 # -# This is why source of truth is split: - HOST1 owns: Movies (Radarr), Tv_Shows (Sonarr), Music (Lidarr) - HOST2 owns: Anime_Movies (Radarr), Anime_Shows (Sonarr) +# HOST2 downloads the same show's next episode that same night: +# → HOST2 Sonarr tracks it immediately +# → arr_sync.sh runs → HOST1 Sonarr now tracks it +# → daily rsync → file lands on HOST1 # -# When HOST2 enters failover and starts HOST1's arr containers — those arrs -# point at /mnt/user/Movies etc. HOST2's own arrs point at /mnt/user/Anime_*. -# Different shares, no conflict. This is by design. +# Both servers converge. Neither owns the share. The union is the truth. # ───────────────────────────────────────────────────────────────────────────── ``` --- -### ── Source of Truth ────────────────────────────────────────────────────────── +### ── How arr_sync.sh Keeps the Union Stable ──────────────────────────────── ```bash # ───────────────────────────────────────────────────────────────────────────── -# Every share has exactly one server that owns it. -# That server's arr manages it. That server pushes it to the other via daily sync. -# The receiving server treats it as read-only. +# arr_sync.sh runs as the fixed first step of intermediate_sync_maintenance.sh +# (every 4 hours). It syncs all arr libraries bidirectionally before any rsync. # -# Rule: never add content to a mirrored share on the non-owning server. -# It will be overwritten on the next sync. +# What it does: +# Reads each arr's full library via the local API +# SSHes to the remote, reads the remote arr library via its API +# Adds anything missing on either side — union, not overwrite +# Blocked items (blocklist) are excluded from sync +# +# What this means in practice: +# No share has an owner. No server is read-only. +# Either server can download content to any share at any time. +# arr_sync.sh guarantees both arrs agree on what exists before files move. +# rsync then spreads the files to make storage match what arrs already know. +# +# arr_cleanup.sh (daily) removes true orphans — files no arr tracks. +# arr_cleanup uses the union model too: a file is only an orphan if +# neither arr on either server has it indexed. # ───────────────────────────────────────────────────────────────────────────── ```