Back up existing files before every service overwrites them
Confirmed live: install_frigate()'s fresh-install path overwrote a working, hand-crafted docker-compose.yml (Frigate + mosquitto + frigate-notify) with zero backup, because that file's shape didn't match what frigate.sh's own "existing install" detection knew how to recognize. Every service's own detection is a judgment call about what counts as "already installed" and can miss a real setup built outside this repo's conventions. lib/common.sh gains backup_if_exists(FILE) — copies FILE to FILE.bak.<timestamp> if it exists, no-ops otherwise (including DRY_RUN). Applied before every service's own `cat > docker-compose.yml`/`cat > .env` write across all 60 services that do one (115 call sites), plus a matching standalone-mode stub added to every service's own bootstrap block, same convention already used for port_in_use/find_free_port. This doesn't replace a service's own update/fresh-reinstall detection — it's the safety net underneath it, so a wrong detection costs a .bak file to restore from instead of the original silently disappearing. Also fixes the actual gap that surfaced this: services/frigate.sh's Authelia offer only checked for Authelia installed locally on Frigate's own box, which is never true for a dedicated NVR box with no local Caddy either (the common shape — Caddy lives elsewhere, snippet-generation mode already handles that). Now offers Authelia protection unconditionally and, when Authelia isn't local, asks whether it lives on the same machine as Caddy (still "import authelia", since that's local to wherever Caddy ends up) or on a genuinely separate third machine (the explicit header-pinned forward_auth form, per CLAUDE.md's "forward_auth to a remote Authelia" note, needed because a bare authelia:9091 shortcut only works one hop).
This commit is contained in:
@@ -802,6 +802,32 @@ write_readme() {
|
||||
chown "$ACTUAL_USER:$ACTUAL_USER" "$dir/README.md" 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Copies FILE to FILE.bak.<timestamp> if it already exists, right before a
|
||||
# caller is about to overwrite it with a fresh `cat > FILE` heredoc. No-ops
|
||||
# in DRY_RUN and silently no-ops if FILE doesn't exist yet (first install,
|
||||
# nothing to save) — safe to call unconditionally right before every such
|
||||
# write, fresh install or not.
|
||||
#
|
||||
# Confirmed live: install_frigate()'s fresh-install path overwrote a
|
||||
# working, hand-crafted multi-container docker-compose.yml (Frigate +
|
||||
# mosquitto + frigate-notify) with zero backup, because that file's shape
|
||||
# didn't match what the service's own "existing install" detection knew
|
||||
# how to recognize. Every service's own detection logic is a judgment call
|
||||
# about what counts as "already installed" and can miss a real setup built
|
||||
# outside this repo's own conventions — this exists as the safety net
|
||||
# underneath that judgment call, not a replacement for it: call it right
|
||||
# before any `cat > FILE` that could clobber something a user already has,
|
||||
# so a wrong detection costs a `.bak` file to restore from instead of the
|
||||
# original silently disappearing.
|
||||
backup_if_exists() {
|
||||
local file="$1"
|
||||
[ "$DRY_RUN" = true ] && return 0
|
||||
[ -f "$file" ] || return 0
|
||||
local backup="${file}.bak.$(date +%Y%m%d-%H%M%S)"
|
||||
cp -p "$file" "$backup" 2>/dev/null \
|
||||
&& log_info "Backed up existing $(basename "$file") to $(basename "$backup")"
|
||||
}
|
||||
|
||||
# ── Host port collision avoidance (shared by every service that publishes a
|
||||
# fixed host port) ────────────────────────────────────────────────────────────
|
||||
# With 70+ services in this repo, several ship the same default port (e.g.
|
||||
|
||||
Reference in New Issue
Block a user