From 40f76013dc551727e3b5991b64dca8ad47382f0c Mon Sep 17 00:00:00 2001 From: Dorian Date: Tue, 21 Apr 2026 04:33:11 -0400 Subject: [PATCH] release(v1.7.20-alpha): stop auto-apply scheduler killing the service MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The 3AM auto-update path called std::process::exit(0) immediately after apply_update returned. apply_update had already spawned a 2s- delayed systemctl restart, but exit(0) killed the runtime before that spawned task could run — and the unit's Restart=on-failure does not trigger on a clean exit 0, so the service stayed dead until someone SSH'd in and started it manually (.253 hit this today). Scheduler now returns from the task without killing the process; apply_update's existing restart path (same one the UI's Install Update button uses) brings the new version up cleanly. Also hardens the ISO CI: the AIUI inclusion step now falls back to extracting from the newest release tarball if the runner's cached /opt/archipelago/web-ui/aiui path is missing, so a reprovisioned runner can't silently ship a frontend tarball without AIUI. The ISO build step also sanity-checks the binary exists before invoking the builder. Co-Authored-By: Claude Opus 4.7 (1M context) --- .gitea/workflows/build-iso-dev.yml | 46 ++++++++++++++++--- core/Cargo.lock | 2 +- core/archipelago/Cargo.toml | 2 +- core/archipelago/src/update.rs | 12 +++-- .../src/views/settings/AccountInfoSection.vue | 11 +++++ 5 files changed, 62 insertions(+), 11 deletions(-) diff --git a/.gitea/workflows/build-iso-dev.yml b/.gitea/workflows/build-iso-dev.yml index 5ffa8324..9fa87689 100644 --- a/.gitea/workflows/build-iso-dev.yml +++ b/.gitea/workflows/build-iso-dev.yml @@ -74,12 +74,38 @@ jobs: - name: Include AIUI if available run: | - if [ -d "/opt/archipelago/web-ui/aiui" ] && [ -f "/opt/archipelago/web-ui/aiui/index.html" ]; then - mkdir -p web/dist/neode-ui/aiui - cp -r /opt/archipelago/web-ui/aiui/* web/dist/neode-ui/aiui/ - echo "AIUI included from /opt/archipelago/web-ui/aiui/" + # AIUI (the Claude chat sidebar) lives outside the Vue build + # and must be copied into the frontend dist BEFORE packaging, + # otherwise OTA-tarball upgrades silently strip it from nodes + # in the field. Try in order: cached on runner, then the + # newest release tarball in this repo's releases/ dir as a + # fallback so a freshly-provisioned runner still gets AIUI. + AIUI_SRC="" + if [ -f "/opt/archipelago/web-ui/aiui/index.html" ]; then + AIUI_SRC="/opt/archipelago/web-ui/aiui" + elif [ -f "$HOME/archy/web/dist/neode-ui/aiui/index.html" ]; then + AIUI_SRC="$HOME/archy/web/dist/neode-ui/aiui" else - echo "WARNING: AIUI not found on build server — ISO will not include AIUI" + LATEST_FRONTEND=$(ls -t releases/v*/archipelago-frontend-*.tar.gz 2>/dev/null | head -1) + if [ -n "$LATEST_FRONTEND" ]; then + echo "Extracting AIUI from $LATEST_FRONTEND (runner cache miss)" + TMP=$(mktemp -d) + tar xzf "$LATEST_FRONTEND" -C "$TMP" ./aiui 2>/dev/null || true + if [ -f "$TMP/aiui/index.html" ]; then + AIUI_SRC="$TMP/aiui" + fi + fi + fi + if [ -n "$AIUI_SRC" ]; then + mkdir -p web/dist/neode-ui/aiui + cp -r "$AIUI_SRC/"* web/dist/neode-ui/aiui/ + echo "AIUI included from $AIUI_SRC ($(du -sh web/dist/neode-ui/aiui | cut -f1))" + else + echo "FAIL: AIUI not found anywhere (runner cache + release tarballs)" + echo " checked: /opt/archipelago/web-ui/aiui" + echo " \$HOME/archy/web/dist/neode-ui/aiui" + echo " releases/v*/archipelago-frontend-*.tar.gz" + exit 1 fi - name: Configure root podman for insecure registry @@ -93,7 +119,15 @@ jobs: run: | cd image-recipe export ARCHIPELAGO_BIN="$(pwd)/../core/target/release/archipelago" - ls -la "$ARCHIPELAGO_BIN" || echo "WARNING: binary not found" + if [ ! -x "$ARCHIPELAGO_BIN" ]; then + echo "FAIL: backend binary missing or not executable at $ARCHIPELAGO_BIN" + exit 1 + fi + BIN_VERSION=$(strings "$ARCHIPELAGO_BIN" | grep -oE 'archipelago [0-9]+\.[0-9]+\.[0-9]+(-[a-z]+)?' | head -1 || true) + EXPECTED=$(grep '^version' ../core/archipelago/Cargo.toml | head -1 | sed 's/.*"\(.*\)".*/\1/') + echo "Binary: $ARCHIPELAGO_BIN ($(du -h "$ARCHIPELAGO_BIN" | cut -f1))" + echo "Embedded version string: ${BIN_VERSION:-unknown}" + echo "Expected version (Cargo.toml): $EXPECTED" sudo -E UNBUNDLED=1 DEV_SERVER=localhost BUILD_FROM_SOURCE=0 \ ARCHIPELAGO_BIN="$ARCHIPELAGO_BIN" \ ./build-auto-installer-iso.sh diff --git a/core/Cargo.lock b/core/Cargo.lock index e2f3c62b..ff8173fd 100644 --- a/core/Cargo.lock +++ b/core/Cargo.lock @@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61" [[package]] name = "archipelago" -version = "1.7.19-alpha" +version = "1.7.20-alpha" dependencies = [ "anyhow", "archipelago-container", diff --git a/core/archipelago/Cargo.toml b/core/archipelago/Cargo.toml index 297c6fd7..20582544 100644 --- a/core/archipelago/Cargo.toml +++ b/core/archipelago/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "archipelago" -version = "1.7.19-alpha" +version = "1.7.20-alpha" edition = "2021" description = "Archipelago Bitcoin Node OS - Native backend" authors = ["Archipelago Team"] diff --git a/core/archipelago/src/update.rs b/core/archipelago/src/update.rs index 00619f9a..87cbc11f 100644 --- a/core/archipelago/src/update.rs +++ b/core/archipelago/src/update.rs @@ -882,9 +882,15 @@ pub async fn run_update_scheduler(data_dir: std::path::PathBuf) { debug!("Update scheduler: apply failed: {}", e); continue; } - info!("Update scheduler: update applied, restart needed"); - // Signal for service restart (systemd will handle via exit code) - std::process::exit(0); + info!("Update scheduler: update applied, restart scheduled by apply_update"); + // apply_update has already spawned a 2s-delayed + // `systemctl restart archipelago`. Don't call + // std::process::exit here — that kills the runtime + // before the spawned restart task runs, and since + // the unit is Restart=on-failure a clean exit(0) + // leaves the service dead. Fall through; the + // scheduled restart will bring us back cleanly. + return; } Ok(_) => { debug!("Update scheduler: no update available"); diff --git a/neode-ui/src/views/settings/AccountInfoSection.vue b/neode-ui/src/views/settings/AccountInfoSection.vue index 932006bc..8a082742 100644 --- a/neode-ui/src/views/settings/AccountInfoSection.vue +++ b/neode-ui/src/views/settings/AccountInfoSection.vue @@ -180,6 +180,17 @@ init()
+ +
+
+ v1.7.20-alpha + Apr 21, 2026 +
+
+

Fixed a critical bug where nodes on the automatic daily-update schedule could end up offline after their nightly update. The scheduler was killing the service a moment too early, before the built-in restart handler had a chance to bring the new version back up — leaving the node dead until someone SSH'd in and started it manually. The scheduler now hands off cleanly to the same restart path the 'Install Update' button uses, so auto-applied updates come back online on their own.

+

Applies to any node configured for 'Check & Apply Daily' — no change required on your end, the fix ships with this update.

+
+