← back to Nas Setup
chore(nas): commit root-daemon installer scripts (TK-10323 artifacts, session close)
17bd6cec886c5a4e4f971acc5d96b694e5251d59 · 2026-08-07 08:43:33 -0700 · Steve Abrams
gitleaks false positive: KEY=id_ed25519_wallco_20260530 is the SSH key FILENAME,
not key material — no secret in these scripts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Files touched
A scripts/install-root-daemon-dwdump.shA scripts/install-root-daemon.sh
Diff
commit 17bd6cec886c5a4e4f971acc5d96b694e5251d59
Author: Steve Abrams <steve@designerwallcoverings.com>
Date: Fri Aug 7 08:43:33 2026 -0700
chore(nas): commit root-daemon installer scripts (TK-10323 artifacts, session close)
gitleaks false positive: KEY=id_ed25519_wallco_20260530 is the SSH key FILENAME,
not key material — no secret in these scripts.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---
scripts/install-root-daemon-dwdump.sh | 67 ++++++++++++++++++++++++
scripts/install-root-daemon.sh | 97 +++++++++++++++++++++++++++++++++++
2 files changed, 164 insertions(+)
diff --git a/scripts/install-root-daemon-dwdump.sh b/scripts/install-root-daemon-dwdump.sh
new file mode 100644
index 0000000..f19c823
--- /dev/null
+++ b/scripts/install-root-daemon-dwdump.sh
@@ -0,0 +1,67 @@
+#!/bin/bash
+# install-root-daemon-dwdump.sh — one-paste, run as root:
+# sudo bash /Users/macstudio3/Projects/nas-setup/scripts/install-root-daemon-dwdump.sh
+#
+# Same fix as install-root-daemon.sh, applied to the dw_unified mirror job
+# (com.steve.nas-dwdump-mirror). The realestate installer already proved root can write
+# to /Volumes/Henry and set up /var/root/.ssh, so this one runs the dw_unified pull once
+# to verify, installs the root LaunchDaemon, and retires the old user agent.
+set -uo pipefail
+
+USER_HOME=/Users/macstudio3
+NAS=$USER_HOME/Projects/nas-setup
+HENRY=/Volumes/Henry/dw-backups/dw_unified
+KEY=id_ed25519_wallco_20260530
+LABEL=com.steve.nas-dwdump-mirror
+ROOT_LABEL=$LABEL-root
+DAEMON_SRC=$NAS/launchd/$ROOT_LABEL.plist
+DAEMON_DST=/Library/LaunchDaemons/$ROOT_LABEL.plist
+
+say(){ printf '\n=== %s ===\n' "$1"; }
+if [ "$(id -u)" -ne 0 ]; then echo "must run as root: sudo bash $0"; exit 1; fi
+
+# ── 1. ensure root ssh key (idempotent; realestate installer already did this) ──
+say "1. ensure root ssh (/var/root/.ssh)"
+install -d -m 700 /var/root/.ssh
+install -m 600 "$USER_HOME/.ssh/$KEY" /var/root/.ssh/$KEY
+if [ ! -f /var/root/.ssh/config ]; then
+cat > /var/root/.ssh/config <<CFG
+Host 45.61.58.125
+ HostName 45.61.58.125
+ User root
+ IdentityFile /var/root/.ssh/$KEY
+ IdentitiesOnly yes
+ StrictHostKeyChecking accept-new
+ UserKnownHostsFile /var/root/.ssh/known_hosts
+CFG
+chmod 600 /var/root/.ssh/config
+fi
+HOME=/var/root ssh -o BatchMode=yes -o ConnectTimeout=15 root@45.61.58.125 "echo ok" >/dev/null 2>&1 \
+ && echo "OK — root authenticates to Kamatera." || echo "WARN — ssh test failed; the pull below will surface it."
+
+# ── 2. run the dw_unified pull once as root (default GLOB + 100MB/100-TOC floors) ──
+say "2. run the dw_unified pull once as root"
+HOME=/var/root \
+ HENRY_BACKUP_DIR="$HENRY" \
+ NAS_BACKUP_DIR=/Volumes/DW-Backups/dw_unified \
+ PATH=/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin \
+ /opt/homebrew/bin/bash "$NAS/scripts/pull-dw-dump.sh"
+echo "pull exit rc=$? (0 = a destination verified)"
+
+# ── 3. install + bootstrap the root LaunchDaemon ──
+say "3. install + bootstrap the root LaunchDaemon"
+install -m 644 -o root -g wheel "$DAEMON_SRC" "$DAEMON_DST"
+launchctl bootout system/$ROOT_LABEL 2>/dev/null
+launchctl bootstrap system "$DAEMON_DST" && echo "bootstrapped $ROOT_LABEL into system/"
+launchctl print system/$ROOT_LABEL >/dev/null 2>&1 && echo "loaded OK (runs daily 03:45 as root)"
+
+# ── 4. retire the old user LaunchAgent ──
+say "4. retire the old user LaunchAgent"
+launchctl bootout gui/501/$LABEL 2>/dev/null && echo "booted out user agent gui/501/$LABEL"
+launchctl disable gui/501/$LABEL 2>/dev/null || true
+echo "user agent disabled"
+
+say "DONE"
+echo "Latest dw_unified on Henry:"; ls -la "$HENRY" 2>&1
+echo
+echo "If step 2 showed PASS + rc=0, the dw_unified nightly is now fixed too (the 41-day-stale gap is closed)."
diff --git a/scripts/install-root-daemon.sh b/scripts/install-root-daemon.sh
new file mode 100755
index 0000000..8cc6d84
--- /dev/null
+++ b/scripts/install-root-daemon.sh
@@ -0,0 +1,97 @@
+#!/bin/bash
+# install-root-daemon.sh — one-paste, run as root:
+# sudo bash /Users/macstudio3/Projects/nas-setup/scripts/install-root-daemon.sh
+#
+# Converts the realestate on-prem dump mirror from a user LaunchAgent (which EPERM'd on
+# /Volumes/Henry because macOS TCC won't honor Full Disk Access on the SIP bash responsible
+# process for launchd) to a root LaunchDaemon (runs outside the per-user TCC consent domain).
+#
+# Self-diagnosing + idempotent:
+# 1. PROBE — can root write to /Volumes/Henry? If NOT, root is TCC-gated too → bail, Option B
+# doesn't help, no infra installed. If yes, continue.
+# 2. SSH — give root its own copy of the Kamatera key (/var/root/.ssh) + config.
+# 3. RUN — execute the pull once as root, end-to-end, and show the result.
+# 4. INSTALL— drop the LaunchDaemon into /Library/LaunchDaemons, bootstrap it into system/.
+# 5. RETIRE — bootout the old user LaunchAgent so the two don't both run.
+# Re-running is safe (overwrites its own artifacts, re-bootstraps).
+set -uo pipefail
+
+USER_HOME=/Users/macstudio3
+NAS=$USER_HOME/Projects/nas-setup
+HENRY=/Volumes/Henry/dw-backups/realestate
+KEY=id_ed25519_wallco_20260530
+LABEL=com.steve.nas-realestate-dump-mirror
+ROOT_LABEL=$LABEL-root
+DAEMON_SRC=$NAS/launchd/$ROOT_LABEL.plist
+DAEMON_DST=/Library/LaunchDaemons/$ROOT_LABEL.plist
+
+say(){ printf '\n=== %s ===\n' "$1"; }
+
+if [ "$(id -u)" -ne 0 ]; then echo "must run as root: sudo bash $0"; exit 1; fi
+
+# ── 1. PROBE: can root write to the external volume? (the decisive TCC test) ──
+say "1. probe: root write to /Volumes/Henry"
+mkdir -p "$HENRY" 2>/dev/null
+PROBE="$HENRY/.root-tcc-probe.$$"
+if touch "$PROBE" 2>/tmp/root-probe.err; then
+ rm -f "$PROBE"
+ echo "OK — root CAN write to Henry. TCC does not gate the system LaunchDaemon domain here. Proceeding."
+else
+ echo "BLOCKED — root is ALSO TCC-gated on /Volumes/Henry:"
+ cat /tmp/root-probe.err
+ echo
+ echo "=> Option B (root daemon) does NOT bypass TCC on this box. Nothing was installed."
+ echo " Fall back to Option A: grant Full Disk Access to /opt/homebrew/bin/bash in System Settings."
+ exit 2
+fi
+
+# ── 2. SSH: give root its own copy of the Kamatera key + config ──
+say "2. root ssh setup (/var/root/.ssh)"
+install -d -m 700 /var/root/.ssh
+install -m 600 "$USER_HOME/.ssh/$KEY" /var/root/.ssh/$KEY
+cat > /var/root/.ssh/config <<CFG
+Host 45.61.58.125
+ HostName 45.61.58.125
+ User root
+ IdentityFile /var/root/.ssh/$KEY
+ IdentitiesOnly yes
+ StrictHostKeyChecking accept-new
+ UserKnownHostsFile /var/root/.ssh/known_hosts
+CFG
+chmod 600 /var/root/.ssh/config
+if HOME=/var/root ssh -o BatchMode=yes -o ConnectTimeout=15 root@45.61.58.125 "echo ok" >/dev/null 2>&1; then
+ echo "OK — root authenticates to Kamatera."
+else
+ echo "WARN — root ssh test to Kamatera failed; the daemon run below will surface the error."
+fi
+
+# ── 3. RUN once as root, end-to-end ──
+say "3. run the pull once as root"
+HOME=/var/root \
+ HENRY_BACKUP_DIR="$HENRY" \
+ NAS_BACKUP_DIR=/Volumes/DW-Backups/realestate \
+ PGDUMP_GLOB='/root/backups/db/realestate_*.dump' \
+ PGDUMP_FLOOR_MB=1 PGDUMP_TOC_FLOOR=5 \
+ PATH=/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin \
+ /opt/homebrew/bin/bash "$NAS/scripts/pull-dw-dump.sh"
+RUN_RC=$?
+echo "pull exit rc=$RUN_RC (0 = a destination verified)"
+
+# ── 4. INSTALL the LaunchDaemon ──
+say "4. install + bootstrap the root LaunchDaemon"
+install -m 644 -o root -g wheel "$DAEMON_SRC" "$DAEMON_DST"
+launchctl bootout system/$ROOT_LABEL 2>/dev/null
+launchctl bootstrap system "$DAEMON_DST" && echo "bootstrapped $ROOT_LABEL into system/"
+launchctl print system/$ROOT_LABEL >/dev/null 2>&1 && echo "loaded OK (runs daily 03:50 as root)"
+
+# ── 5. RETIRE the old user LaunchAgent so both don't run ──
+say "5. retire the old user LaunchAgent"
+launchctl bootout gui/501/$LABEL 2>/dev/null && echo "booted out user agent gui/501/$LABEL"
+# disable it from auto-reloading on next login (leave the plist file in place, just disabled)
+launchctl disable gui/501/$LABEL 2>/dev/null || true
+echo "user agent disabled (plist left on disk, no longer loads)"
+
+say "DONE"
+echo "Latest on Henry:"; ls -la "$HENRY"
+echo
+echo "If step 3 showed a PASS line and rc=0, the root daemon is the fix — realestate now mirrors nightly as root."
← fb2f00f docs(nas): add DW-Backups activation checklist (root-context
·
back to Nas Setup
·
pull-dw-dump: derive retention glob from $BASE so realestate 20be61d →