From 6b846653474ee5a5a0d2b01916d0c7ae28795f50 Mon Sep 17 00:00:00 2001 From: c4ch3c4d3 Date: Sat, 22 Aug 2026 19:18:42 -0600 Subject: [PATCH] fix(deploy): no dangling symlink on first-deploy failure, deadline-capped health poll, release pruning, honest commit rc --- .../remote_access/pager-webui/mk8_profiles.py | 5 +++- scripts/deploy.sh | 24 +++++++++++++++---- tests/test_reliability_api.py | 3 --- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/payload/user/remote_access/pager-webui/mk8_profiles.py b/payload/user/remote_access/pager-webui/mk8_profiles.py index 5e11ba0..be25c42 100644 --- a/payload/user/remote_access/pager-webui/mk8_profiles.py +++ b/payload/user/remote_access/pager-webui/mk8_profiles.py @@ -79,7 +79,10 @@ def restore(name): if rc != 0: return {'ok': False, 'restored': restored, 'error': 'import failed'} - run_cmd(['uci', 'commit', cfg]) + crc, _, cerr = run_cmd(['uci', 'commit', cfg]) + if crc != 0: + return {'ok': False, 'restored': restored, + 'error': 'commit failed: %s' % (cerr or cfg)} restored.append(cfg) return {'ok': True, 'restored': restored} diff --git a/scripts/deploy.sh b/scripts/deploy.sh index 8a9088b..343ba17 100755 --- a/scripts/deploy.sh +++ b/scripts/deploy.sh @@ -228,7 +228,11 @@ ln -sfn \"\$RELDIR\" \"\$CURRENT\" rollback_install() { rm -rf \"\$LIVE\" [ ! -d \"\$BACKUP\" ] || mv \"\$BACKUP\" \"\$LIVE\" - [ -z \"\$PREV\" ] || ln -sfn \"\$PREV\" \"\$CURRENT\" + if [ -n \"\$PREV\" ]; then + ln -sfn \"\$PREV\" \"\$CURRENT\" + else + rm -f \"\$CURRENT\" + fi } if [ -d \"\$LIVE\" ]; then mv \"\$LIVE\" \"\$BACKUP\"; fi if ! mkdir -p \"\$LIVE\" || ! cp -a \"\$NEW/.\" \"\$LIVE/\"; then @@ -243,16 +247,16 @@ chmod 755 /etc/init.d/mk8-guard /etc/init.d/mk8-guard enable /etc/init.d/pagerwebui start -# Post-deploy verification: API must answer within 60s or we roll back. -i=0 +# Post-deploy verification: API must answer within ~60s (deadline-capped so +# hung connections cannot stretch the window) or we roll back. +DEADLINE=\$((SECONDS + 60)) HEALTH_OK='' -while [ \$i -lt 60 ]; do +while [ \$SECONDS -lt \$DEADLINE ]; do if curl -fsS -m 3 http://127.0.0.1:8080/ >/dev/null 2>&1; then HEALTH_OK=1 break fi sleep 1 - i=\$((i+1)) done if [ -z \"\$HEALTH_OK\" ]; then echo 'post-deploy health check failed; rolling back' >&2 @@ -263,6 +267,16 @@ if [ -z \"\$HEALTH_OK\" ]; then exit 1 fi rm -rf \"\$BACKUP\" +# Prune old releases; keep the newest 3 including current. +ALL=\$(ls -1d /mmc/mk8/releases/2* 2>/dev/null | sort) +TOTAL=\$(printf '%s\\n' \"\$ALL\" | grep -c .) +KEEP_FROM=\$((TOTAL - 2)) +if [ \"\$KEEP_FROM\" -gt 1 ]; then + printf '%s\\n' \"\$ALL\" | awk -v kf=\"\$KEEP_FROM\" 'NR < kf' | while read r; do + CUR=\$(readlink \$CURRENT 2>/dev/null || true) + [ \"\$r\" = \"\$CUR\" ] || rm -rf \"\$r\" + done +fi echo RELEASE_OK@\"\$RELDIR\"" if run_ssh "$TARGET" "$REMOTE_COMMAND"; then printf 'Release active: /mmc/mk8/releases/%s\n' "$RELEASE_TS" diff --git a/tests/test_reliability_api.py b/tests/test_reliability_api.py index 8241bd6..533eac8 100644 --- a/tests/test_reliability_api.py +++ b/tests/test_reliability_api.py @@ -221,9 +221,6 @@ class ReliabilityApiTest(unittest.TestCase): self.assertTrue(raises) self.assertEqual(calls['events'][-1][0], 'profile_restore') - status, result = server.h_profile_restore( - _Ctx({'name': 'missing'})) - def missing_restore(name): calls['restored'] = name return {'ok': False, 'restored': [], 'error': 'not found'}