release(v1.7.20-alpha): stop auto-apply scheduler killing the service

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) <noreply@anthropic.com>
This commit is contained in:
Dorian 2026-04-21 04:33:11 -04:00
parent 9fc9696dbd
commit 4d8a9e66e3
8 changed files with 76 additions and 26 deletions

View File

@ -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

2
core/Cargo.lock generated
View File

@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
[[package]]
name = "archipelago"
version = "1.7.19-alpha"
version = "1.7.20-alpha"
dependencies = [
"anyhow",
"archipelago-container",

View File

@ -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"]

View File

@ -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");

View File

@ -180,6 +180,17 @@ init()
</button>
</div>
<div class="overflow-y-auto flex-1 min-h-0 space-y-6 pr-1">
<!-- v1.7.20-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">
<span class="text-xs font-mono px-2 py-0.5 rounded bg-orange-500/20 text-orange-300">v1.7.20-alpha</span>
<span class="text-xs text-white/40">Apr 21, 2026</span>
</div>
<div class="space-y-3 text-sm text-white/80 pl-3 border-l border-white/10">
<p>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.</p>
<p>Applies to any node configured for 'Check &amp; Apply Daily' no change required on your end, the fix ships with this update.</p>
</div>
</div>
<!-- v1.7.19-alpha -->
<div>
<div class="flex items-center gap-2 mb-3">

View File

@ -1,27 +1,26 @@
{
"version": "1.7.19-alpha",
"version": "1.7.20-alpha",
"release_date": "2026-04-21",
"changelog": [
"Your node no longer offers a version you've already passed as an 'available update'. If you sideload or skip a release, any stored pointer to an older version is dropped on next restart — the System Update page only offers genuinely newer releases.",
"Version comparison is now numeric rather than alphabetic. 1.7.10 correctly outranks 1.7.9 (the old string-order would've got this backwards once patch numbers hit double digits), so update prompts stay accurate past the nines.",
"A stale manifest from a slow cache or proxy can no longer downgrade your node. If the manifest reports a version equal to or behind what's running, the node treats that as 'up to date' rather than offering the older version as an update."
"Fixed a critical bug where nodes on 'Check & Apply Daily' could end up offline after their nightly update. The scheduler was killing the service a moment too early, before the built-in restart handler could bring the new version back up — leaving the node dead until someone SSH'd in. The scheduler now uses the same restart path as the 'Install Update' button, so auto-applied updates come back online on their own.",
"Applies automatically — no action needed on your end beyond taking this update."
],
"components": [
{
"name": "archipelago",
"current_version": "1.7.18-alpha",
"new_version": "1.7.19-alpha",
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.19-alpha/archipelago",
"sha256": "c6ffb65ea999c5212e0f93201a9ad77941810c00ea91dfb7397a07358a8a464e",
"size_bytes": 40648312
"current_version": "1.7.19-alpha",
"new_version": "1.7.20-alpha",
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.20-alpha/archipelago",
"sha256": "bf4f8b91b021cad445a868f454707e0fa005446f755604f8c3e072bb7a059e6f",
"size_bytes": 40640016
},
{
"name": "archipelago-frontend-1.7.19-alpha.tar.gz",
"current_version": "1.7.18-alpha",
"new_version": "1.7.19-alpha",
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.19-alpha/archipelago-frontend-1.7.19-alpha.tar.gz",
"sha256": "5f70534a3df7012d20ccd8b4134a84a197a082910a9cd45774af249eae9f8d6c",
"size_bytes": 162081700
"name": "archipelago-frontend-1.7.20-alpha.tar.gz",
"current_version": "1.7.19-alpha",
"new_version": "1.7.20-alpha",
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.20-alpha/archipelago-frontend-1.7.20-alpha.tar.gz",
"sha256": "a82f187b597c51e5f3d8753529914651ab2d8e8bb3ad9c36d287b335e4d386a9",
"size_bytes": 162082209
}
]
}

Binary file not shown.