2026-01-24 22:59:20 +00:00
|
|
|
{
|
|
|
|
|
"name": "neode-ui",
|
|
|
|
|
"private": true,
|
release(v1.7.41-alpha): post-OTA auto-rollback so a bad release cannot strand the fleet
Closes failure mode FM5 from docs/bulletproof-containers.md: the v1.7.38 +
v1.7.39 rollouts left every affected node on an unreachable UI (nginx 500)
with no recovery path short of SSH. This release adds a self-check
guardrail to the update flow.
What changed:
- apply_update() writes a pending-verify marker with old+new version and
a 150s deadline immediately before scheduling the service restart.
- verify_pending_update() runs from main.rs startup. If the marker is
present and within its freshness window, the new binary waits 15s for
nginx + backend to settle, then probes https://127.0.0.1/ every 5s for
up to 90s (self-signed certs accepted).
- On any probe success within the window, the marker is cleared and
nothing else happens.
- On window-exhaust, the new binary:
1. Moves the broken /opt/archipelago/web-ui to web-ui.failed.<ts>
(quarantined, not deleted, so we can post-mortem).
2. Restores web-ui.bak on top of web-ui.
3. Calls rollback_update() to restore the previous binary.
4. Updates state.current_version to reflect the rollback.
5. systemctl --no-block restart archipelago so the OLD binary boots.
- Markers older than 10 minutes are treated as stale and cleared without
probing, so a crashed-during-startup marker from weeks ago cannot
spontaneously roll back a healthy node on a later reboot.
- rollback_update() binary copy now goes through host_sudo instead of
tokio::fs::copy, so it escapes the service's ProtectSystem=strict
mount namespace. Without this, the rollback silently failed with
EROFS on /usr/local/bin and orphaned the rollback - the exact
opposite of what auto-rollback is for.
Tests: 4 new unit tests in update::tests covering marker round-trip,
absent-marker noop, no-panic on verify_pending_update with nothing to
verify, and an invariant assert that the 90s probe window stays below
the 600s stale threshold. All passing.
Side fix: scripts/create-release-manifest.sh was dying with exit 141
(SIGPIPE from tar tvzf pipe head pipe awk) under set -euo pipefail.
Replaced with a single awk NR==1 that doesn't short-circuit the upstream
pipe, so the release-build flow is idempotent again.
2026-04-22 16:14:35 -04:00
|
|
|
"version": "1.7.41-alpha",
|
2026-01-24 22:59:20 +00:00
|
|
|
"type": "module",
|
|
|
|
|
"scripts": {
|
|
|
|
|
"start": "./start-dev.sh",
|
|
|
|
|
"stop": "./stop-dev.sh",
|
2026-03-10 23:34:14 +00:00
|
|
|
"test": "vitest run",
|
|
|
|
|
"test:watch": "vitest",
|
2026-01-24 22:59:20 +00:00
|
|
|
"dev": "vite",
|
2026-03-22 03:30:21 +00:00
|
|
|
"dev:mock": "concurrently --raw \"node mock-backend.js\" \"VITE_AIUI_URL=http://localhost:5173 vite\" \"cd ../../AIUI && perl -MPOSIX -e 'POSIX::setsid(); exec @ARGV' -- pnpm dev 2>/dev/null || echo '[AIUI] Not found at ../../AIUI — chat will show placeholder'\"",
|
2026-03-18 21:06:14 +00:00
|
|
|
"dev:boot": "VITE_DEV_MODE=boot concurrently --raw \"VITE_DEV_MODE=boot node mock-backend.js\" \"VITE_DEV_MODE=boot vite\"",
|
2026-01-24 22:59:20 +00:00
|
|
|
"dev:real": "echo 'Start backend: cd ../core && cargo run --release' && vite",
|
|
|
|
|
"backend:mock": "node mock-backend.js",
|
|
|
|
|
"backend:real": "cd ../core && cargo run --release",
|
release(v1.7.38-alpha): onboarding auto-heal + silent returning logins + app-store trim
- auth.rs now infers onboarding-complete from setup_complete + password_hash so
nodes stop bouncing users through the intro wizard after browser clear / update
/ reboot; the flag self-heals to disk on next check
- frontend: "backend uncertain" no longer defaults to /onboarding/intro —
useOnboarding returns null + callers poll / retry instead of flashing the wizard
- login sounds (synthwave, welcome voice, pop, whoosh, oomph) gated by
isFirstInstallPhase(); typing sounds unaffected
- removed FIPS app, Nostr Relay, Nostr VPN, Routstr, Penpot from catalog,
frontend config, Rust AppMetadata + install dispatch + install_penpot_stack;
docker/fips-ui + docker/nostr-vpn-ui + apps/penpot dirs and 5 icons deleted;
15 image versions deleted from tx1138, .168, gitea-local registries (.160
Gitea was 502 at release time — follow-up)
- AIUI baked into frontend release tarball via demo/aiui/; deploy-to-target
falls back to demo/aiui/ when the AIUI sibling checkout is missing
- prebuild hook syncs app-catalog/catalog.json → public/catalog.json so the
two copies can no longer drift (was the source of the "apps still visible"
bug — public/ had stale data)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-22 13:02:24 -04:00
|
|
|
"prebuild": "cp ../app-catalog/catalog.json public/catalog.json",
|
2026-01-24 22:59:20 +00:00
|
|
|
"build": "vue-tsc -b && vite build",
|
|
|
|
|
"build:docker": "vite build",
|
2026-01-28 11:12:19 +00:00
|
|
|
"build:production": "NODE_ENV=production vue-tsc -b && vite build --mode production",
|
2026-01-24 22:59:20 +00:00
|
|
|
"preview": "vite preview",
|
2026-02-17 19:42:59 +00:00
|
|
|
"type-check": "vue-tsc --noEmit",
|
2026-02-18 10:10:12 +00:00
|
|
|
"generate-pwa-icons": "pwa-assets-generator --preset minimal-2023 public/assets/icon/favico-black.svg && cp public/assets/icon/favicon.ico public/favicon.ico",
|
2026-02-18 08:18:14 +00:00
|
|
|
"generate-welcome-speech": "node scripts/generate-welcome-speech.js"
|
2026-01-24 22:59:20 +00:00
|
|
|
},
|
|
|
|
|
"dependencies": {
|
2026-03-18 00:55:00 +00:00
|
|
|
"@types/dompurify": "^3.0.5",
|
2026-03-19 16:12:01 +00:00
|
|
|
"@vue-leaflet/vue-leaflet": "^0.10.1",
|
2026-03-13 02:55:16 +00:00
|
|
|
"d3": "^7.9.0",
|
2026-03-18 00:55:00 +00:00
|
|
|
"dompurify": "^3.3.3",
|
2026-01-24 22:59:20 +00:00
|
|
|
"fast-json-patch": "^3.1.1",
|
2026-02-17 15:03:34 +00:00
|
|
|
"fuse.js": "^7.1.0",
|
2026-03-19 16:12:01 +00:00
|
|
|
"leaflet": "^1.9.4",
|
2026-01-24 22:59:20 +00:00
|
|
|
"pinia": "^3.0.4",
|
2026-03-16 15:34:04 +00:00
|
|
|
"qrcode": "^1.5.4",
|
2026-01-24 22:59:20 +00:00
|
|
|
"vue": "^3.5.24",
|
2026-03-11 13:45:59 +00:00
|
|
|
"vue-i18n": "^11.3.0",
|
2026-01-24 22:59:20 +00:00
|
|
|
"vue-router": "^4.6.3"
|
|
|
|
|
},
|
|
|
|
|
"devDependencies": {
|
2026-03-11 13:45:59 +00:00
|
|
|
"@playwright/test": "^1.58.2",
|
2026-03-13 02:55:16 +00:00
|
|
|
"@types/d3": "^7.4.3",
|
2026-03-19 16:12:01 +00:00
|
|
|
"@types/leaflet": "^1.9.21",
|
2026-01-24 22:59:20 +00:00
|
|
|
"@types/node": "^24.10.0",
|
2026-03-16 15:34:04 +00:00
|
|
|
"@types/qrcode": "^1.5.6",
|
2026-02-18 10:10:12 +00:00
|
|
|
"@vite-pwa/assets-generator": "^1.0.2",
|
2026-01-24 22:59:20 +00:00
|
|
|
"@vitejs/plugin-vue": "^6.0.1",
|
2026-03-11 13:45:59 +00:00
|
|
|
"@vitest/coverage-v8": "^3.2.4",
|
|
|
|
|
"@vue/test-utils": "^2.4.6",
|
2026-01-24 22:59:20 +00:00
|
|
|
"@vue/tsconfig": "^0.8.1",
|
|
|
|
|
"autoprefixer": "^10.4.22",
|
|
|
|
|
"concurrently": "^9.1.2",
|
|
|
|
|
"cookie-parser": "^1.4.7",
|
|
|
|
|
"cors": "^2.8.5",
|
2026-03-16 12:58:35 +00:00
|
|
|
"dockerode": "^4.0.9",
|
2026-01-24 22:59:20 +00:00
|
|
|
"express": "^4.21.2",
|
2026-03-11 13:45:59 +00:00
|
|
|
"jsdom": "^25.0.1",
|
2026-01-24 22:59:20 +00:00
|
|
|
"postcss": "^8.5.6",
|
|
|
|
|
"tailwindcss": "^3.4.18",
|
|
|
|
|
"typescript": "~5.9.3",
|
|
|
|
|
"vite": "^7.2.2",
|
|
|
|
|
"vite-plugin-pwa": "^1.2.0",
|
2026-03-11 13:45:59 +00:00
|
|
|
"vitest": "^3.1.1",
|
2026-01-24 22:59:20 +00:00
|
|
|
"vue-tsc": "^3.1.3",
|
|
|
|
|
"ws": "^8.18.0"
|
|
|
|
|
}
|
2026-02-18 10:10:12 +00:00
|
|
|
}
|