From 08f35032c5a1263d66c37f76f37093b87aeca82b Mon Sep 17 00:00:00 2001 From: jknapp Date: Wed, 10 Jun 2026 09:25:05 -0700 Subject: [PATCH] =?UTF-8?q?fix(shared-ols):=20re-review=20hardening=20?= =?UTF-8?q?=E2=80=94=20bounded=20flock=20+=20stale-tmp=20sweep?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to the review fixes, from a second review pass: - flock now uses -w 30 (bounded wait) so a hung render can't block the panel's docker-exec (and the site-save request) indefinitely; the dead-code timeout error path is now reachable. - sweep stale .httpd_config.conf.tmp.* left by a prior SIGKILL (trap EXIT doesn't run on SIGKILL); safe under flock since each render uses a unique $$ suffix. Verified: render still produces a valid config + serves; stale tmp is swept. Co-Authored-By: Claude Opus 4.8 (1M context) --- scripts/render-shared-ols-config.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/scripts/render-shared-ols-config.sh b/scripts/render-shared-ols-config.sh index 8cbc6bc..873d121 100644 --- a/scripts/render-shared-ols-config.sh +++ b/scripts/render-shared-ols-config.sh @@ -43,8 +43,14 @@ mkdir -p "$SITES_ROOT" "$LSCACHE_ROOT" ## into $TMP and atomically `mv` into place at the end, so any concurrent OLS ## restart always sees a COMPLETE config (the old one until the instant of mv). exec 9>"$LSWS_CONF/.render.lock" -flock 9 || { echo "render-shared-ols: could not acquire render lock" >&2; exit 1; } +## Bounded wait (-w): if a previous render is hung, fail after 30s rather than +## blocking the panel's `docker exec` call (and thus the site-save request) +## indefinitely. The caller re-tries on the next change. +flock -w 30 9 || { echo "render-shared-ols: could not acquire render lock within 30s" >&2; exit 1; } trap 'rm -f "$TMP"' EXIT +## Sweep any stale temp configs left by a prior SIGKILL (trap EXIT doesn't run on +## SIGKILL); each render uses a unique $$ suffix so this never races a live render. +rm -f "$LSWS_CONF"/.httpd_config.conf.tmp.* 2>/dev/null || true ## From here on, build into $TMP (not $OUT). ## --- 1. start from a pristine stock config (idempotent) ---