release(v1.7.4-alpha): fix Install Update tar extraction + progress overshoot
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Has been cancelled
Some checks failed
Build Archipelago ISO (dev) / build-iso (push) Has been cancelled
apply_update was extracting the frontend tarball with `tar -xzf -C /opt/archipelago`, but the tar contents are the *inside* of web-ui/ (root entries are ./test-aiui.html, ./assets/, etc.). So the files landed directly in /opt/archipelago instead of under web-ui/, and tar bailed on nginx-owned paths mid-extraction. First end-to-end OTA test (.198) found it: "tar: ./assets/SystemUpdate-…js: Cannot open: No such file or directory". Now extracts into web-ui.new, chowns, then atomically swaps: move existing web-ui → web-ui.bak, then web-ui.new → web-ui. Same pattern as the manual sideload that's been working. Frontend: SystemUpdate.vue fake download progress was capped at "<90" with a Math.random()*15 increment — the last tick could push to ~104.99%. Capped at 95% with a smaller step so it stops at 95 and the real RPC completion jumps it to 100. Artefacts: archipelago a14ad7e4…2a2be3 40361984 archipelago-frontend-1.7.4-alpha.tar.gz 4fb79664…0172e9 76984615 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2
core/Cargo.lock
generated
2
core/Cargo.lock
generated
@@ -80,7 +80,7 @@ checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
||||
|
||||
[[package]]
|
||||
name = "archipelago"
|
||||
version = "1.7.3-alpha"
|
||||
version = "1.7.4-alpha"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"archipelago-container",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "archipelago"
|
||||
version = "1.7.3-alpha"
|
||||
version = "1.7.4-alpha"
|
||||
edition = "2021"
|
||||
description = "Archipelago Bitcoin Node OS - Native backend"
|
||||
authors = ["Archipelago Team"]
|
||||
|
||||
@@ -305,42 +305,60 @@ pub async fn apply_update(data_dir: &Path) -> Result<()> {
|
||||
info!(name = %name, "Backend binary applied");
|
||||
}
|
||||
_ if name.contains("frontend") && name.ends_with(".tar.gz") => {
|
||||
let web_ui_dir = Path::new("/opt/archipelago/web-ui");
|
||||
// Back up current frontend. /opt/archipelago is root-owned;
|
||||
// the backup goes under our data_dir where we can write.
|
||||
let frontend_backup = backup_dir.join("web-ui-backup.tar.gz");
|
||||
if web_ui_dir.exists() {
|
||||
let status = tokio::process::Command::new("sudo")
|
||||
.args([
|
||||
"tar",
|
||||
"-czf",
|
||||
&frontend_backup.to_string_lossy(),
|
||||
"-C",
|
||||
"/opt/archipelago",
|
||||
"web-ui",
|
||||
])
|
||||
.status()
|
||||
.await
|
||||
.context("Failed to backup frontend")?;
|
||||
if status.success() {
|
||||
info!("Frontend backed up");
|
||||
}
|
||||
// The tarball contents are the *inside* of web-ui/ — root
|
||||
// entries are `./test-aiui.html`, `./assets/`, etc. Extract
|
||||
// into a sibling staging dir, then swap atomically so
|
||||
// nginx never sees a half-written tree.
|
||||
let new_dir = "/opt/archipelago/web-ui.new";
|
||||
let backup_path = "/opt/archipelago/web-ui.bak";
|
||||
// Wipe any previous attempt's staging / backup dirs.
|
||||
let _ = tokio::process::Command::new("sudo")
|
||||
.args(["rm", "-rf", new_dir, backup_path])
|
||||
.status()
|
||||
.await;
|
||||
let mk = tokio::process::Command::new("sudo")
|
||||
.args(["mkdir", "-p", new_dir])
|
||||
.status()
|
||||
.await
|
||||
.context("Failed to create frontend staging dir")?;
|
||||
if !mk.success() {
|
||||
anyhow::bail!("mkdir {} failed", new_dir);
|
||||
}
|
||||
// Extract new frontend into /opt/archipelago (root-owned dir).
|
||||
// Extract INTO the staging dir — tar's ./ entries land at
|
||||
// the right place (web-ui.new/assets/... etc.).
|
||||
let status = tokio::process::Command::new("sudo")
|
||||
.args(["tar", "-xzf", &src.to_string_lossy(), "-C", "/opt/archipelago"])
|
||||
.args(["tar", "-xzf", &src.to_string_lossy(), "-C", new_dir])
|
||||
.status()
|
||||
.await
|
||||
.with_context(|| format!("Failed to extract {}", name))?;
|
||||
if !status.success() {
|
||||
anyhow::bail!("tar extraction failed for {}", name);
|
||||
}
|
||||
// nginx serves this tree; keep ownership consistent with
|
||||
// what first-boot + the ISO layout expect.
|
||||
// Ownership: match what first-boot + the ISO expect.
|
||||
let _ = tokio::process::Command::new("sudo")
|
||||
.args(["chown", "-R", "archipelago:archipelago", "/opt/archipelago/web-ui"])
|
||||
.args(["chown", "-R", "archipelago:archipelago", new_dir])
|
||||
.status()
|
||||
.await;
|
||||
// Atomic-ish swap: move old aside, new into place.
|
||||
let web_ui = "/opt/archipelago/web-ui";
|
||||
if Path::new(web_ui).exists() {
|
||||
let mv_old = tokio::process::Command::new("sudo")
|
||||
.args(["mv", web_ui, backup_path])
|
||||
.status()
|
||||
.await
|
||||
.context("Failed to rotate old web-ui")?;
|
||||
if !mv_old.success() {
|
||||
anyhow::bail!("failed to move old web-ui aside");
|
||||
}
|
||||
}
|
||||
let mv_new = tokio::process::Command::new("sudo")
|
||||
.args(["mv", new_dir, web_ui])
|
||||
.status()
|
||||
.await
|
||||
.context("Failed to swap new web-ui into place")?;
|
||||
if !mv_new.success() {
|
||||
anyhow::bail!("failed to move new web-ui into place");
|
||||
}
|
||||
info!(name = %name, "Frontend archive extracted to /opt/archipelago/web-ui");
|
||||
}
|
||||
_ => {
|
||||
|
||||
@@ -345,10 +345,12 @@ async function downloadUpdate() {
|
||||
downloadPercent.value = 0
|
||||
statusMessage.value = ''
|
||||
|
||||
// Simulate incremental progress while waiting for the RPC
|
||||
// Simulate incremental progress while waiting for the RPC. Capped at
|
||||
// 95% so the bar never shows >100% before the real completion jumps it
|
||||
// to 100 — previously the random increment could overshoot.
|
||||
const progressInterval = setInterval(() => {
|
||||
if (downloadPercent.value < 90) {
|
||||
downloadPercent.value += Math.random() * 15
|
||||
if (downloadPercent.value < 95) {
|
||||
downloadPercent.value = Math.min(95, downloadPercent.value + Math.random() * 3)
|
||||
}
|
||||
}, 500)
|
||||
|
||||
|
||||
@@ -1,28 +1,26 @@
|
||||
{
|
||||
"version": "1.7.3-alpha",
|
||||
"version": "1.7.4-alpha",
|
||||
"release_date": "2026-04-20",
|
||||
"changelog": [
|
||||
"The version number in the sidebar now always matches the actual running version — no more lying to you about being on an older release after an update.",
|
||||
"FIPS Mesh card on the server page: cleaner layout on desktop (no more awkward gaps), and a one-click Reconnect button when the public anchor is unreachable — it restarts the FIPS daemon so it can re-bootstrap from the anchor.",
|
||||
"Profile pictures now show correctly in the identity list and editor. Before, uploaded images silently failed to render because the URL was only reachable over Tor; the UI now rewrites them to a local path while keeping the external URL for other Nostr clients.",
|
||||
"Identity rows now show your Display Name first (from your Nostr profile) with the internal identity name beside it in parentheses, so you see the name other people will see — not just the one you picked when creating it."
|
||||
"Install Update actually installs now. Before, the final step extracted the new UI into the wrong folder and bailed with 'Failed to apply update' — your node ended up backing up cleanly but never swapping in the new files. Fixed.",
|
||||
"Download progress no longer overshoots 100%. You'll see the bar climb smoothly to 95% and then jump to 100% when the download actually finishes."
|
||||
],
|
||||
"components": [
|
||||
{
|
||||
"name": "archipelago",
|
||||
"current_version": "1.7.2-alpha",
|
||||
"new_version": "1.7.3-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.3-alpha/archipelago",
|
||||
"sha256": "99184b95f8d3041b7714ec9e58a194e466fa470c117992a4715c40980022dc1b",
|
||||
"size_bytes": 40350664
|
||||
"current_version": "1.7.3-alpha",
|
||||
"new_version": "1.7.4-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.4-alpha/archipelago",
|
||||
"sha256": "a14ad7e4dbcb8f74377d44a4bd5e600b285481df3b30c08f8bea2cd17e2a2be3",
|
||||
"size_bytes": 40361984
|
||||
},
|
||||
{
|
||||
"name": "archipelago-frontend-1.7.3-alpha.tar.gz",
|
||||
"current_version": "1.7.2-alpha",
|
||||
"new_version": "1.7.3-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.3-alpha/archipelago-frontend-1.7.3-alpha.tar.gz",
|
||||
"sha256": "7b933cf458754faba18224d12b4793d7e152fc8296c3ee0441240fdc2374a8bc",
|
||||
"size_bytes": 76987031
|
||||
"name": "archipelago-frontend-1.7.4-alpha.tar.gz",
|
||||
"current_version": "1.7.3-alpha",
|
||||
"new_version": "1.7.4-alpha",
|
||||
"download_url": "https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/v1.7.4-alpha/archipelago-frontend-1.7.4-alpha.tar.gz",
|
||||
"sha256": "4fb796643cc9dc8469078ca3392f7cc5541071f6849979922b3259e5f20172e9",
|
||||
"size_bytes": 76984615
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
BIN
releases/v1.7.4-alpha/archipelago
Executable file
BIN
releases/v1.7.4-alpha/archipelago
Executable file
Binary file not shown.
BIN
releases/v1.7.4-alpha/archipelago-frontend-1.7.4-alpha.tar.gz
Normal file
BIN
releases/v1.7.4-alpha/archipelago-frontend-1.7.4-alpha.tar.gz
Normal file
Binary file not shown.
Reference in New Issue
Block a user