fix: bug: disinto-edge hard-fails on missing age key / secrets even when collect-engagement feature is not configured (#1038) #1045

Merged
dev-qwen2 merged 1 commit from fix/issue-1038 into main 2026-04-19 15:43:12 +00:00
Showing only changes of commit 1c0ec3c7ec - Show all commits

View file

@ -173,11 +173,15 @@ PROJECT_TOML="${PROJECT_TOML:-projects/disinto.toml}"
sleep 1200 # 20 minutes sleep 1200 # 20 minutes
done) & done) &
# ── Load required secrets from secrets/*.enc (#777) ──────────────────── # ── Load optional secrets from secrets/*.enc (#777) ────────────────────
# Edge container declares its required secrets; missing ones cause a hard fail. # Engagement collection (collect-engagement.sh) requires CADDY_ secrets to
# SCP access logs from a remote edge host. When age key or secrets dir is
# missing, or any secret fails to decrypt, log a warning and skip the cron.
# Caddy itself does not depend on these secrets.
_AGE_KEY_FILE="${HOME}/.config/sops/age/keys.txt" _AGE_KEY_FILE="${HOME}/.config/sops/age/keys.txt"
_SECRETS_DIR="/opt/disinto/secrets" _SECRETS_DIR="/opt/disinto/secrets"
EDGE_REQUIRED_SECRETS="CADDY_SSH_KEY CADDY_SSH_HOST CADDY_SSH_USER CADDY_ACCESS_LOG" EDGE_REQUIRED_SECRETS="CADDY_SSH_KEY CADDY_SSH_HOST CADDY_SSH_USER CADDY_ACCESS_LOG"
EDGE_ENGAGEMENT_READY=0 # Assume not ready until proven otherwise
_edge_decrypt_secret() { _edge_decrypt_secret() {
local enc_path="${_SECRETS_DIR}/${1}.enc" local enc_path="${_SECRETS_DIR}/${1}.enc"
@ -192,22 +196,25 @@ if [ -f "$_AGE_KEY_FILE" ] && [ -d "$_SECRETS_DIR" ]; then
export "$_secret_name=$_val" export "$_secret_name=$_val"
done done
if [ -n "$_missing" ]; then if [ -n "$_missing" ]; then
echo "FATAL: required secrets missing from secrets/*.enc:${_missing}" >&2 echo "WARN: required engagement secrets missing from secrets/*.enc:${_missing}" >&2
echo " Run 'disinto secrets add <NAME>' for each missing secret." >&2 echo " collect-engagement cron will be skipped. Run 'disinto secrets add <NAME>' to enable." >&2
echo " If migrating from .env.vault.enc, run 'disinto secrets migrate-from-vault' first." >&2 EDGE_ENGAGEMENT_READY=0
exit 1 else
echo "edge: loaded required engagement secrets: ${EDGE_REQUIRED_SECRETS}" >&2
EDGE_ENGAGEMENT_READY=1
fi fi
echo "edge: loaded required secrets: ${EDGE_REQUIRED_SECRETS}" >&2
else else
echo "FATAL: age key (${_AGE_KEY_FILE}) or secrets dir (${_SECRETS_DIR}) not found — cannot load required secrets" >&2 echo "WARN: age key (${_AGE_KEY_FILE}) or secrets dir (${_SECRETS_DIR}) not found — engagement secrets unavailable" >&2
echo " Ensure age is installed and secrets/*.enc files are present." >&2 echo " collect-engagement cron will be skipped. Run 'disinto secrets add <NAME>' to enable." >&2
exit 1 EDGE_ENGAGEMENT_READY=0
fi fi
# Start daily engagement collection cron loop in background (#745) # Start daily engagement collection cron loop in background (#745)
# Runs collect-engagement.sh daily at ~23:50 UTC via a sleep loop that # Runs collect-engagement.sh daily at ~23:50 UTC via a sleep loop that
# calculates seconds until the next 23:50 window. SSH key from secrets/*.enc (#777). # calculates seconds until the next 23:50 window. SSH key from secrets/*.enc (#777).
(while true; do # Guarded: only start if EDGE_ENGAGEMENT_READY=1.
if [ "$EDGE_ENGAGEMENT_READY" -eq 1 ]; then
(while true; do
# Calculate seconds until next 23:50 UTC # Calculate seconds until next 23:50 UTC
_now=$(date -u +%s) _now=$(date -u +%s)
_target=$(date -u -d "today 23:50" +%s 2>/dev/null || date -u -d "23:50" +%s 2>/dev/null || echo 0) _target=$(date -u -d "today 23:50" +%s 2>/dev/null || date -u -d "23:50" +%s 2>/dev/null || echo 0)
@ -232,7 +239,10 @@ fi
echo "edge: collect-engagement: fetched log is empty, skipping parse" >&2 echo "edge: collect-engagement: fetched log is empty, skipping parse" >&2
fi fi
rm -f "$_fetch_log" rm -f "$_fetch_log"
done) & done) &
else
echo "edge: collect-engagement cron skipped (EDGE_ENGAGEMENT_READY=0)" >&2
fi
# Nomad template renders Caddyfile to /local/Caddyfile via service discovery; # Nomad template renders Caddyfile to /local/Caddyfile via service discovery;
# copy it into the expected location if present (compose uses the mounted path). # copy it into the expected location if present (compose uses the mounted path).