fix: release v1.7.50-alpha OTA runtime repair
This commit is contained in:
@@ -571,15 +571,10 @@ pub async fn check_for_updates(data_dir: &Path) -> Result<UpdateState> {
|
||||
mirror = %manifest_url,
|
||||
"No newer version in manifest"
|
||||
);
|
||||
if state.available_update.is_some() {
|
||||
// A later mirror might still have a
|
||||
// newer version — don't clobber what an
|
||||
// earlier mirror told us. But also don't
|
||||
// break: another mirror could be ahead.
|
||||
continue 'mirrors;
|
||||
}
|
||||
state.manifest_mirror = None;
|
||||
state.available_update = None;
|
||||
handled = true;
|
||||
continue 'mirrors;
|
||||
}
|
||||
handled = true;
|
||||
break 'mirrors;
|
||||
@@ -1173,6 +1168,125 @@ pub async fn apply_update(data_dir: &Path) -> Result<()> {
|
||||
}
|
||||
info!(name = %name, "Frontend archive extracted to /opt/archipelago/web-ui");
|
||||
}
|
||||
_ if name.contains("runtime") && name.ends_with(".tar.gz") => {
|
||||
let ts = chrono::Utc::now().timestamp_millis();
|
||||
let staging_new = format!("/opt/archipelago/runtime.new.{}", ts);
|
||||
let archive = src.to_string_lossy().to_string();
|
||||
|
||||
let mk = host_sudo(&["mkdir", "-p", &staging_new])
|
||||
.await
|
||||
.context("Failed to create runtime staging dir")?;
|
||||
if !mk.success() {
|
||||
anyhow::bail!("mkdir {} failed", staging_new);
|
||||
}
|
||||
|
||||
let extract = host_sudo(&["tar", "-xzf", &archive, "-C", &staging_new])
|
||||
.await
|
||||
.with_context(|| format!("Failed to extract {}", name))?;
|
||||
if !extract.success() {
|
||||
let _ = host_sudo(&["rm", "-rf", &staging_new]).await;
|
||||
anyhow::bail!("tar extraction failed for {}", name);
|
||||
}
|
||||
|
||||
let runtime_paths = [
|
||||
("apps", "apps"),
|
||||
("scripts", "scripts"),
|
||||
("docker", "docker"),
|
||||
(
|
||||
"image-recipe/configs/archipelago-doctor.service",
|
||||
"archipelago-doctor.service",
|
||||
),
|
||||
(
|
||||
"image-recipe/configs/archipelago-doctor.timer",
|
||||
"archipelago-doctor.timer",
|
||||
),
|
||||
];
|
||||
|
||||
for (relative, label) in runtime_paths {
|
||||
let staged_path = format!("{}/{}", staging_new, relative);
|
||||
if !Path::new(&staged_path).exists() {
|
||||
tracing::debug!(path = %relative, "Runtime artifact path absent, skipping");
|
||||
continue;
|
||||
}
|
||||
|
||||
match label {
|
||||
"apps" | "scripts" | "docker" => {
|
||||
let dest = format!("/opt/archipelago/{}", label);
|
||||
let tmp_dest =
|
||||
format!("{}.new.{}", dest, chrono::Utc::now().timestamp_millis());
|
||||
let _ = host_sudo(&["mkdir", "-p", &tmp_dest]).await;
|
||||
let staged_dot = format!("{}/.", staged_path);
|
||||
let copy = host_sudo(&["cp", "-a", &staged_dot, &tmp_dest])
|
||||
.await
|
||||
.with_context(|| format!("Failed to copy runtime {}", label))?;
|
||||
if !copy.success() {
|
||||
let _ = host_sudo(&["rm", "-rf", &tmp_dest]).await;
|
||||
anyhow::bail!("runtime copy failed for {}", label);
|
||||
}
|
||||
let _ = host_sudo(&["mkdir", "-p", &dest]).await;
|
||||
let clean = host_sudo(&[
|
||||
"find",
|
||||
&dest,
|
||||
"-mindepth",
|
||||
"1",
|
||||
"-maxdepth",
|
||||
"1",
|
||||
"-exec",
|
||||
"rm",
|
||||
"-rf",
|
||||
"{}",
|
||||
"+",
|
||||
])
|
||||
.await
|
||||
.with_context(|| format!("Failed to clean runtime {}", label))?;
|
||||
if !clean.success() {
|
||||
let _ = host_sudo(&["rm", "-rf", &tmp_dest]).await;
|
||||
anyhow::bail!("runtime clean failed for {}", label);
|
||||
}
|
||||
let tmp_dot = format!("{}/.", tmp_dest);
|
||||
let promote = host_sudo(&["cp", "-a", &tmp_dot, &dest])
|
||||
.await
|
||||
.with_context(|| format!("Failed to promote runtime {}", label))?;
|
||||
let _ = host_sudo(&["rm", "-rf", &tmp_dest]).await;
|
||||
if !promote.success() {
|
||||
anyhow::bail!("runtime promote failed for {}", label);
|
||||
}
|
||||
if label == "scripts" {
|
||||
let _ = host_sudo(&[
|
||||
"find", &dest, "-type", "f", "-name", "*.sh", "-exec", "chmod",
|
||||
"755", "{}", "+",
|
||||
])
|
||||
.await;
|
||||
}
|
||||
}
|
||||
"archipelago-doctor.service" | "archipelago-doctor.timer" => {
|
||||
let dest = format!("/etc/systemd/system/{}", label);
|
||||
let install = host_sudo(&["install", "-m", "644", &staged_path, &dest])
|
||||
.await
|
||||
.with_context(|| format!("Failed to install {}", label))?;
|
||||
if !install.success() {
|
||||
anyhow::bail!("runtime unit install failed for {}", label);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
if Path::new(&format!("{}/scripts/image-versions.sh", staging_new)).exists() {
|
||||
let _ = host_sudo(&[
|
||||
"cp",
|
||||
&format!("{}/scripts/image-versions.sh", staging_new),
|
||||
"/opt/archipelago/image-versions.sh",
|
||||
])
|
||||
.await;
|
||||
}
|
||||
|
||||
let _ = host_sudo(&["systemctl", "daemon-reload"]).await;
|
||||
let _ =
|
||||
host_sudo(&["systemctl", "enable", "--now", "archipelago-doctor.timer"]).await;
|
||||
let _ = host_sudo(&["rm", "-rf", &staging_new]).await;
|
||||
info!(name = %name, "Runtime assets applied to /opt/archipelago");
|
||||
}
|
||||
_ => {
|
||||
debug!(name = %name, "Unknown component, skipping");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user