Add daily timezone drift check

tz-drift-check.sh + sky-cam-tzcheck timer notify when TIMEZONE no longer
matches the machine's timezone (timers follow the machine, scripts follow TIMEZONE).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013wi3ZRpfenCe2TRwT4JFMG
This commit is contained in:
Claude
2026-11-02 02:54:07 +00:00
parent 63bbe5c2ab
commit 5e1cb8857d
2 changed files with 68 additions and 0 deletions
+19
View File
@@ -296,6 +296,25 @@ for cam in "${CAMERAS[@]}"; do
fi
done
# ── Timezone drift check ─────────────────────────────────────────────────────
# Daily + shortly after boot: notify if TIMEZONE no longer matches the
# machine's timezone (systemd timers follow the machine, scripts follow TIMEZONE).
write_service "sky-cam-tzcheck" "timezone drift check" "tz-drift-check.sh"
cat > "$UNIT_DIR/sky-cam-tzcheck.timer" <<EOF2
[Unit]
Description=Sky-Cam — timezone drift check
[Timer]
OnBootSec=3min
OnCalendar=*-*-* 12:00:00
Persistent=true
[Install]
WantedBy=timers.target
EOF2
echo " wrote sky-cam-tzcheck.timer"
timers+=("sky-cam-tzcheck")
# ── Generate .env.example ────────────────────────────────────────────────────
env_example="$HERE/.env.example"
{
+49
View File
@@ -0,0 +1,49 @@
#!/bin/bash
# tz-drift-check.sh — warn if TIMEZONE (sky-cam.conf / .env) no longer matches
# the machine's own timezone.
#
# systemd timers fire on the machine's clock, but sunrise.py, the capture
# scripts and the per-day folder names use TIMEZONE. If the two drift apart
# (someone ran `timedatectl set-timezone`, a cloud-init reset, a restored
# image, a typo in .env...) every scheduled job runs at the wrong local time
# and the sunrise capture window is off by the zone difference.
#
# Run daily by sky-cam-tzcheck.timer (and shortly after boot). Sends one
# notify.sh message per run while the mismatch persists; silent when fine.
# Exit 0 either way — a mismatch is a notification, not a job failure.
set -uo pipefail
SCRIPT_DIR="$(dirname "$(realpath "$0")")"
source "$SCRIPT_DIR/sky-cam.conf"
source "$SCRIPT_DIR/.env" 2>/dev/null || true
# Machine's zone — read WITHOUT any TZ override so we see the real system value.
sys_tz="$(env -u TZ timedatectl show -p Timezone --value 2>/dev/null)"
[ -z "$sys_tz" ] && sys_tz="$(cat /etc/timezone 2>/dev/null)"
[ -z "$sys_tz" ] && sys_tz="$(readlink /etc/localtime 2>/dev/null | sed 's|.*/zoneinfo/||')"
if [ -z "$sys_tz" ]; then
echo "tz-drift-check: could not determine the machine's timezone — skipping"
exit 0
fi
# Compare by real UTC offsets across the year so aliases (US/Eastern vs
# America/New_York) and identical-rule zones are not reported as drift.
same=true
if [ "$sys_tz" != "$TIMEZONE" ]; then
for m in 01 04 07 10; do
a="$(TZ="$sys_tz" date -d "2026-$m-15 12:00 UTC" +%z)"
b="$(TZ="$TIMEZONE" date -d "2026-$m-15 12:00 UTC" +%z)"
[ "$a" = "$b" ] || { same=false; break; }
done
fi
if $same; then
echo "Timezone OK: sky-cam TIMEZONE=$TIMEZONE, machine=$sys_tz"
exit 0
fi
msg="sky-cam TIMEZONE is $TIMEZONE but this machine's timezone is $sys_tz. Scheduled jobs run on the machine clock, so sunrise/seasons/moon jobs will fire at the wrong local time. Fix: set TIMEZONE=$sys_tz in $SCRIPT_DIR/.env and re-run ./install.sh, or run: sudo timedatectl set-timezone $TIMEZONE"
echo "WARNING: $msg"
"$SCRIPT_DIR/notify.sh" "WARNING: sky-cam timezone mismatch" "$msg" || true
exit 0