From d89aeb7d261b6cd0e09c6db2a0a6a66573a2f921 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sat, 19 Sep 2026 13:34:37 -0400 Subject: [PATCH] vault_sync_daemon: drop unreliable finally-block stop ntfy, add ExecStopPost notify script --- vault-sync-daemon-notify.sh | 35 +++++++++++++++++++++++++++++++++++ vault_sync_daemon.py | 5 ++++- 2 files changed, 39 insertions(+), 1 deletion(-) create mode 100755 vault-sync-daemon-notify.sh diff --git a/vault-sync-daemon-notify.sh b/vault-sync-daemon-notify.sh new file mode 100755 index 0000000..911d45d --- /dev/null +++ b/vault-sync-daemon-notify.sh @@ -0,0 +1,35 @@ +#!/bin/sh +# vault-sync-daemon-notify.sh — fired unconditionally by ExecStopPost= on +# EVERY exit of vault-sync-daemon.service (clean stop, restart, crash, kill, +# OOM). Distinguishes clean vs. unexpected via systemd's own $SERVICE_RESULT +# so routine `systemctl stop/restart` doesn't page like a real failure would. +# +# systemd passes SERVICE_RESULT / EXIT_CODE / EXIT_STATUS as env vars to +# ExecStopPost= (documented in systemd.exec(5) "Environment Variables Set for +# Executed Processes" -> systemd.service(5) "Process exit codes"). +TOKEN_PATH="/home/hermes/.hermes/secrets/ntfy-vault-token" +NTFY_URL="https://ntfy.pandu.ski/vault" + +TOKEN=$(cat "$TOKEN_PATH" 2>/dev/null) || exit 0 +[ -n "$TOKEN" ] || exit 0 + +RESULT="${SERVICE_RESULT:-unknown}" +HOST=$(hostname) +NOW=$(date -u +'%Y-%m-%dT%H:%M:%SZ') + +if [ "$RESULT" = "success" ]; then + TITLE="Vault sync daemon stopped" + BODY="Clean stop on $HOST at $NOW (manual stop/restart)." + TAGS="octagonal_sign" + PRIORITY="low" +else + TITLE="Vault sync daemon DIED" + BODY="Unexpected exit on $HOST at $NOW. result=$RESULT exit_code=${EXIT_CODE:-?} exit_status=${EXIT_STATUS:-?}. Restart=always will retry in 5s. Check: journalctl -u vault-sync-daemon -n 50" + TAGS="skull,rotating_light" + PRIORITY="urgent" +fi + +curl -fsS --max-time 5 -X POST \ + -H "Authorization: Bearer $TOKEN" \ + -H "Title: $TITLE" -H "Tags: $TAGS" -H "Priority: $PRIORITY" \ + -d "$BODY" "$NTFY_URL" >/dev/null 2>&1 || true diff --git a/vault_sync_daemon.py b/vault_sync_daemon.py index 9b3f3e2..ad1e120 100644 --- a/vault_sync_daemon.py +++ b/vault_sync_daemon.py @@ -504,7 +504,10 @@ def main(): observer.stop() observer.join() log("vault_sync_daemon stopped") - ntfy_post("Vault sync daemon stopped", "", tags="octagonal_sign", priority="high") + # NOTE: no ntfy_post here — a hard kill/OOM/crash skips this `finally` + # entirely, so relying on it for "stopped" alerts is unreliable. The + # systemd unit's ExecStopPost= hook fires unconditionally on every + # exit (clean or not) and is the actual source of stop notifications. if __name__ == "__main__":