true bidirectional with split truth modle set up. all scripts are fully bidirectional

This commit is contained in:
2026-04-21 18:20:47 -04:00
parent 6b36b8c07a
commit d4bf31a5f4
9 changed files with 846 additions and 161 deletions
+51 -23
View File
@@ -280,7 +280,14 @@ declare -A PROFILE_RSYNC_OPTS=(
[critical-data]="-av --human-readable --bwlimit=$BW_LIMIT --delete"
[gmer4lfe]="-av --info=progress2 --bwlimit=$BW_LIMIT"
[important-data]="-av --human-readable --bwlimit=$BW_LIMIT"
[emby]="-av --human-readable --bwlimit=$BW_LIMIT"
# emby — nightly clean sync, both Emby instances stopped
# WAL checkpointed on shutdown — full consistent mirror, minimal excludes
[emby]="-av --human-readable --bwlimit=$BW_LIMIT --delete --inplace --no-whole-file"
# emby-failover — frequent dirty sync every 30-60min, Emby stays running
# Only critical failover data — what users need immediately on failover
# WAL excluded — safe dirty write while Emby is running
# This is also the list written back during failover handback
[emby-failover]="-av --human-readable --bwlimit=$BW_LIMIT --delete --inplace --no-whole-file"
)
# Bandwidth limit in KB/s per profile — overrides global BW_LIMIT for this profile only
@@ -289,7 +296,8 @@ declare -A PROFILE_BW_LIMIT=(
[critical-data]=9500 # high — small data, get it synced fast
[gmer4lfe]=8000 # medium
[important-data]=9500 # high — database sync needs to be fast and clean
[emby]=8000 # medium — large files, steady sustained transfer
[emby]=8000 # medium — full mirror, steady transfer
[emby-failover]=9500 # high — small critical dataset, get it synced fast
)
# Retry attempts per profile before giving up — overrides global RETRY_COUNT
@@ -299,6 +307,7 @@ declare -A PROFILE_RETRY_COUNT=(
[gmer4lfe]=3
[important-data]=3
[emby]=3
[emby-failover]=3
)
# Seconds between retry attempts — overrides global SLEEP
@@ -308,64 +317,83 @@ declare -A PROFILE_SLEEP=(
[gmer4lfe]=300
[important-data]=300
[emby]=300
[emby-failover]=120 # shorter — frequent sync, retry faster
)
# Containers stopped on REMOTE before rsync and restarted after completion.
# Only include containers that need to be stopped for data consistency.
# Databases and auth stacks need clean state — media servers generally do not.
# Containers stopped on BOTH LOCAL and REMOTE servers before rsync.
# Local stops first — flushes databases cleanly before push.
# Remote stops next — prevents writes while receiving.
# Only containers that were running get restarted — stopped containers stay stopped.
# Same container names used on both HOST1 and HOST2 — naming scheme is consistent.
# If a container is not found on a server it is skipped gracefully, not errored.
# SPACE-SEPARATED STRINGS — converted to array at runtime
declare -A PROFILE_CRITICAL_CONTAINER_NAMES=(
[arrs_stack]="Sonarr Lidarr Readarr Radarr Prowlarr Bazarr Pinchflat"
[critical-data]="Mariadb-Authelia Redis-Authelia Lldap-Gmer4Lfe NginxProxyManager Authelia"
[critical-data]="Mariadb-Authelia Mariadb-Authelia-Secondary Redis-Authelia Redis-Authelia-Secondary Lldap-Gmer4Lfe NginxProxyManager Authelia Authelia-Secondary"
[gmer4lfe]="Organizrv2-Gmer4Lfe UptimeKuma-Gmer4Lfe VaultWarden-Gmer4Lfe"
[important-data]="Postgres-NextCloud NextCloud"
[emby]=""
[emby]="Emby" # nightly clean sync — Emby stopped both sides, WAL checkpointed
[emby-failover]="" # dirty sync — Emby stays running both sides
)
# Containers that need a delay before starting after rsync completes.
# Used when a container depends on another that was also stopped — it needs its
# dependency to be ready before it can start successfully.
# Used when a container depends on another that was also stopped.
# Startup order for critical-data:
# Immediate: Mariadb x2, Redis x2, Lldap, NginxProxyManager
# Delayed: Authelia, Authelia-Secondary (need databases ready)
# SPACE-SEPARATED STRINGS — converted to array at runtime
declare -A PROFILE_DELAYED_CONTAINERS=(
[arrs_stack]=""
[critical-data]="Authelia" # Authelia needs Mariadb + Redis ready before starting
[critical-data]="Authelia Authelia-Secondary"
[gmer4lfe]=""
[important-data]="NextCloud" # NextCloud needs Postgres accepting connections first
[emby]=""
[emby-failover]=""
)
# Seconds to wait before starting delayed containers — gives dependencies time to initialise
# Seconds to wait before starting delayed containers
declare -A PROFILE_CONTAINER_DELAY=(
[arrs_stack]=5
[critical-data]=10 # 10s gives Mariadb and Redis time to accept connections
[critical-data]=15 # 15s gives Mariadb, Redis, and LLDAP time to accept connections
[gmer4lfe]=5
[important-data]=10 # 10s gives Postgres time to accept connections
[important-data]=10
[emby]=5
[emby-failover]=5
)
# Directories excluded from rsync transfer per profile.
# logs and *.tmp are safe to exclude — they are ephemeral and regenerated on container start.
# SPACE-SEPARATED STRINGS — converted to array at runtime
declare -A PROFILE_EXCLUDE_DIRS=(
[arrs_stack]="logs *.tmp"
[critical-data]="logs *.tmp"
[gmer4lfe]="logs *.tmp"
[important-data]="logs *.tmp"
[emby]="logs *.tmp"
# Critical-Data — auth stack
# Containers stopped during sync — databases flush cleanly
# Generated configs, logs, and temp files excluded
[critical-data]="logs *.tmp *.log nginx/temp nginx/cache __pycache__ notification.txt"
# Emby nightly clean sync — both Emby instances stopped
# WAL checkpointed on shutdown — safe to push everything except true junk
# Full faithful mirror: metadata, plugins, config all included
[emby]="logs transcodes cache crash*"
# Emby failover dirty sync — Emby stays running
# Only what users need immediately on failover:
# users.db ← watch states, continue watching, next up, played state
# library.db ← library structure
# authentication.db ← API keys, sessions
# config/ ← server settings
# WAL and SHM excluded — unsafe while Emby is running
# Also the list written back during failover handback
[emby-failover]="logs transcodes cache metadata *.db-wal *.db-shm crash* plugins root"
)
# Per-disk check toggle — controls whether rsync.sh runs check_remote_disks() for this profile.
# true = skip per-disk check — use when remote share lives on a ZFS pool
# ZFS pools don't have /mnt/disk* structure so the check always fails incorrectly
# false = run per-disk check — use for traditional unRAID array with individual disk mounts
# Verifies all disks backing the share are online before syncing
# Note: rootfs and share existence checks always run regardless of this setting
# Per-disk check toggle
declare -A PROFILE_SKIP_DISK_CHECK=(
[arrs_stack]=true # remote uses ZFS pool — no individual disk mounts
[arrs_stack]=true
[critical-data]=true
[gmer4lfe]=true
[important-data]=true
[emby]=true
[emby-failover]=true
)
# ==============================================================================================