Compare commits

...

2 Commits

Author SHA1 Message Date
Dorian
5818541721 chore: release v1.7.56-alpha 2026-05-14 09:13:58 -04:00
Dorian
b8053c00ca fix: clear stale health notifications 2026-05-14 08:57:54 -04:00
10 changed files with 84 additions and 42 deletions

View File

@ -1,5 +1,12 @@
# Changelog
## v1.7.56-alpha (2026-05-14)
- Health notifications now clear when an app is no longer unhealthy, including stale alerts for removed containers such as Portainer.
- Quadlet environment values with spaces or shell metacharacters are quoted consistently, preventing env drift recreate loops for apps like nostr-rs-relay and Grafana.
- Boot/bootstrap reconcile avoids restarting running Bitcoin containers while repairing RPC config, preserving IBD progress on active nodes.
- Exit code 137 is labeled as SIGKILL instead of assuming OOM, avoiding false OOM alerts for orchestrator-managed recreates.
## v1.7.55-alpha (2026-05-13)
- Container reconcile now force-recreates Podman records stuck in `Stopping`, preserving bind-mounted app data while recovering wedged containers automatically.

2
core/Cargo.lock generated
View File

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

View File

@ -1,6 +1,6 @@
[package]
name = "archipelago"
version = "1.7.55-alpha"
version = "1.7.56-alpha"
edition = "2021"
description = "Archipelago Bitcoin Node OS - Native backend"
authors = ["Archipelago Team"]

View File

@ -65,7 +65,9 @@ pub async fn ensure_doctor_installed() {
Err(e) => warn!("Nginx bootstrap failed (non-fatal): {:#}", e),
}
match run_bitcoin_rpc_repair().await {
Ok(true) => info!("Repaired Bitcoin RPC bind settings; running Bitcoin containers left untouched"),
Ok(true) => {
info!("Repaired Bitcoin RPC bind settings; running Bitcoin containers left untouched")
}
Ok(false) => debug!("Bitcoin RPC bind settings already usable"),
Err(e) => warn!("Bitcoin RPC repair failed (non-fatal): {:#}", e),
}

View File

@ -298,7 +298,11 @@ fn shell_join(parts: &[String]) -> String {
fn quote_environment(env: &str) -> String {
let env = env.replace(['\r', '\n'], " ");
if env.is_empty() || env.chars().any(|c| c.is_whitespace() || "\"\\$`".contains(c)) {
if env.is_empty()
|| env
.chars()
.any(|c| c.is_whitespace() || "\"\\$`".contains(c))
{
let escaped = env
.replace('\\', "\\\\")
.replace('"', "\\\"")
@ -793,7 +797,10 @@ mod tests {
#[test]
fn quote_environment_quotes_values_with_spaces() {
assert_eq!(quote_environment("BITCOIN_RPC_PASS=secret"), "BITCOIN_RPC_PASS=secret");
assert_eq!(
quote_environment("BITCOIN_RPC_PASS=secret"),
"BITCOIN_RPC_PASS=secret"
);
assert_eq!(
quote_environment("RELAY_NAME=Archipelago Nostr Relay"),
"\"RELAY_NAME=Archipelago Nostr Relay\""

View File

@ -514,7 +514,14 @@ async fn cleanup_stale_podman_healthcheck_units(live_container_ids: &HashSet<Str
async fn stale_healthcheck_units_from_systemd(live_container_ids: &HashSet<String>) -> Vec<String> {
let mut units = Vec::new();
for args in [
["--user", "list-timers", "--all", "--no-legend", "--no-pager"].as_slice(),
[
"--user",
"list-timers",
"--all",
"--no-legend",
"--no-pager",
]
.as_slice(),
["--user", "list-units", "--all", "--no-legend", "--no-pager"].as_slice(),
] {
let output = match tokio::time::timeout(
@ -833,6 +840,21 @@ pub fn spawn_health_monitor(state: Arc<StateManager>, data_dir: PathBuf) {
}
}
let unhealthy_app_ids: HashSet<&str> = unhealthy
.iter()
.map(|container| container.app_id.as_str())
.collect();
let before = data.notifications.len();
data.notifications.retain(|n| {
!n.id.starts_with("health-")
|| n.app_id
.as_deref()
.is_some_and(|app_id| unhealthy_app_ids.contains(app_id))
});
if data.notifications.len() != before {
state_changed = true;
}
// Sort by startup tier: databases first, then core, then dependent, then apps, then UIs
unhealthy.sort_by_key(|c| container_tier(&c.name));
@ -1346,7 +1368,9 @@ mod tests {
);
assert_eq!(parse_podman_healthcheck_unit("grafana.service"), None);
assert_eq!(
parse_podman_healthcheck_unit("nothexzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz-x.timer"),
parse_podman_healthcheck_unit(
"nothexzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz-x.timer"
),
None
);
}

View File

@ -1,12 +1,12 @@
{
"name": "neode-ui",
"version": "1.7.55-alpha",
"version": "1.7.56-alpha",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "neode-ui",
"version": "1.7.55-alpha",
"version": "1.7.56-alpha",
"dependencies": {
"@types/dompurify": "^3.0.5",
"@vue-leaflet/vue-leaflet": "^0.10.1",

View File

@ -1,7 +1,7 @@
{
"name": "neode-ui",
"private": true,
"version": "1.7.55-alpha",
"version": "1.7.56-alpha",
"type": "module",
"scripts": {
"start": "./start-dev.sh",

View File

@ -1,27 +1,28 @@
{
"version": "1.7.55-alpha",
"release_date": "2026-05-13",
"version": "1.7.56-alpha",
"release_date": "2026-05-14",
"changelog": [
"Container reconcile now force-recreates Podman records stuck in `Stopping`, preserving bind-mounted app data while recovering wedged containers automatically.",
"`.198` is green after the container-layer hardening pass: focused and broad non-destructive lifecycle audits pass, raw Podman health/state sweep is clean, and direct app probes return healthy responses.",
"Release-candidate artifacts are staged separately from live update publishing while Gitea artifact hosting is repaired."
"Health notifications now clear when an app is no longer unhealthy, including stale alerts for removed containers such as Portainer.",
"Quadlet environment values with spaces or shell metacharacters are quoted consistently, preventing env drift recreate loops for apps like nostr-rs-relay and Grafana.",
"Boot/bootstrap reconcile avoids restarting running Bitcoin containers while repairing RPC config, preserving IBD progress on active nodes.",
"Exit code 137 is labeled as SIGKILL instead of assuming OOM, avoiding false OOM alerts for orchestrator-managed recreates."
],
"components": [
{
"name": "archipelago",
"current_version": "1.7.55-alpha",
"new_version": "1.7.55-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.55-alpha/archipelago",
"sha256": "f2caba778f63c7435431fb1b95cf6470bd43c4769ebe6adee2cbd2721707a663",
"size_bytes": 42580880
"current_version": "1.7.56-alpha",
"new_version": "1.7.56-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.56-alpha/archipelago",
"sha256": "11217a0e40c1704ee9f5bbcdeb59e38c9efc5e00ea7c673c5c3f0f69de720109",
"size_bytes": 42647960
},
{
"name": "archipelago-frontend-1.7.55-alpha.tar.gz",
"current_version": "1.7.55-alpha",
"new_version": "1.7.55-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.55-alpha/archipelago-frontend-1.7.55-alpha.tar.gz",
"sha256": "fe37425aad25724db49ec2be8d602342cfdc5fb99f08b4a3f04709751a3ed560",
"size_bytes": 166464949
"name": "archipelago-frontend-1.7.56-alpha.tar.gz",
"current_version": "1.7.56-alpha",
"new_version": "1.7.56-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.56-alpha/archipelago-frontend-1.7.56-alpha.tar.gz",
"sha256": "9cee503e260891267fed33e4c97f067a4a592b10695ecea4cbf730d517ff6c8b",
"size_bytes": 166493666
}
]
}

View File

@ -1,27 +1,28 @@
{
"version": "1.7.55-alpha",
"release_date": "2026-05-13",
"version": "1.7.56-alpha",
"release_date": "2026-05-14",
"changelog": [
"Container reconcile now force-recreates Podman records stuck in `Stopping`, preserving bind-mounted app data while recovering wedged containers automatically.",
"`.198` is green after the container-layer hardening pass: focused and broad non-destructive lifecycle audits pass, raw Podman health/state sweep is clean, and direct app probes return healthy responses.",
"Release-candidate artifacts are staged separately from live update publishing while Gitea artifact hosting is repaired."
"Health notifications now clear when an app is no longer unhealthy, including stale alerts for removed containers such as Portainer.",
"Quadlet environment values with spaces or shell metacharacters are quoted consistently, preventing env drift recreate loops for apps like nostr-rs-relay and Grafana.",
"Boot/bootstrap reconcile avoids restarting running Bitcoin containers while repairing RPC config, preserving IBD progress on active nodes.",
"Exit code 137 is labeled as SIGKILL instead of assuming OOM, avoiding false OOM alerts for orchestrator-managed recreates."
],
"components": [
{
"name": "archipelago",
"current_version": "1.7.55-alpha",
"new_version": "1.7.55-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.55-alpha/archipelago",
"sha256": "f2caba778f63c7435431fb1b95cf6470bd43c4769ebe6adee2cbd2721707a663",
"size_bytes": 42580880
"current_version": "1.7.56-alpha",
"new_version": "1.7.56-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.56-alpha/archipelago",
"sha256": "11217a0e40c1704ee9f5bbcdeb59e38c9efc5e00ea7c673c5c3f0f69de720109",
"size_bytes": 42647960
},
{
"name": "archipelago-frontend-1.7.55-alpha.tar.gz",
"current_version": "1.7.55-alpha",
"new_version": "1.7.55-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.55-alpha/archipelago-frontend-1.7.55-alpha.tar.gz",
"sha256": "fe37425aad25724db49ec2be8d602342cfdc5fb99f08b4a3f04709751a3ed560",
"size_bytes": 166464949
"name": "archipelago-frontend-1.7.56-alpha.tar.gz",
"current_version": "1.7.56-alpha",
"new_version": "1.7.56-alpha",
"download_url": "http://146.59.87.168:3000/lfg2025/archy/releases/download/v1.7.56-alpha/archipelago-frontend-1.7.56-alpha.tar.gz",
"sha256": "9cee503e260891267fed33e4c97f067a4a592b10695ecea4cbf730d517ff6c8b",
"size_bytes": 166493666
}
]
}