From 0f71013952a09c5c26c895f05d4501c897e279c7 Mon Sep 17 00:00:00 2001 From: Dorian Date: Sun, 12 Apr 2026 11:40:52 -0400 Subject: [PATCH] fix: registry fallback skips dead primary, WireGuard first-boot, Gitea port 3001 Registry fallback now only tries DIFFERENT registries (skips original that already failed). 120s timeout per fallback attempt. WireGuard keys generated on unbundled first-boot. Gitea ROOT_URL uses port 3001. Co-Authored-By: Claude Opus 4.6 (1M context) --- .../src/api/rpc/package/install.rs | 6 ++-- core/archipelago/src/container/registry.rs | 29 +++++++++++++------ scripts/first-boot-containers.sh | 20 +++++++++++++ 3 files changed, 43 insertions(+), 12 deletions(-) diff --git a/core/archipelago/src/api/rpc/package/install.rs b/core/archipelago/src/api/rpc/package/install.rs index e0e6ff87..8ee0cf85 100644 --- a/core/archipelago/src/api/rpc/package/install.rs +++ b/core/archipelago/src/api/rpc/package/install.rs @@ -1099,13 +1099,13 @@ server { // Set ROOT_URL in Gitea config let host_ip = &self.config.host_ip; - let root_url = format!("GITEA__server__ROOT_URL=http://{}:3000/", host_ip); + let root_url = format!("GITEA__server__ROOT_URL=http://{}:3001/", host_ip); let _ = tokio::process::Command::new("podman") .args(["exec", "gitea", "sh", "-c", - &format!("grep -q ROOT_URL /data/gitea/conf/app.ini && sed -i 's|ROOT_URL.*|ROOT_URL = http://{}:3000/|' /data/gitea/conf/app.ini || true", host_ip)]) + &format!("grep -q ROOT_URL /data/gitea/conf/app.ini && sed -i 's|ROOT_URL.*|ROOT_URL = http://{}:3001/|' /data/gitea/conf/app.ini || true", host_ip)]) .output() .await; - info!("Gitea: ROOT_URL set to http://{}:3000/", host_ip); + info!("Gitea: ROOT_URL set to http://{}:3001/", host_ip); } if package_id == "nextcloud" { diff --git a/core/archipelago/src/container/registry.rs b/core/archipelago/src/container/registry.rs index caca5d33..5f2b532b 100644 --- a/core/archipelago/src/container/registry.rs +++ b/core/archipelago/src/container/registry.rs @@ -80,14 +80,11 @@ impl RegistryConfig { format!("{}/{}", registry.url, image_name) } - /// Generate all image URLs to try for a given image, in priority order. + /// Generate fallback image URLs to try (excludes the original since it already failed). pub fn image_candidates(&self, image: &str) -> Vec<(String, bool)> { let mut candidates = Vec::new(); - // First: the original image as-is - candidates.push((image.to_string(), true)); - - // Then: rewritten for each active registry + // Rewrite for each active registry (skip if identical to original) for reg in self.active_registries() { let rewritten = self.rewrite_image(image, reg); if rewritten != image { @@ -154,15 +151,29 @@ pub async fn pull_from_registries( args.push("--tls-verify=false".to_string()); } - let status = tokio::process::Command::new("podman") + let mut child = tokio::process::Command::new("podman") .args(&args) .env("TMPDIR", tmpdir) .stdout(std::process::Stdio::null()) .stderr(std::process::Stdio::null()) - .status() - .await; + .spawn() + .ok(); - if status.map(|s| s.success()).unwrap_or(false) { + let status = if let Some(ref mut c) = child { + match tokio::time::timeout(std::time::Duration::from_secs(120), c.wait()).await { + Ok(Ok(s)) => Some(s.success()), + _ => { + let _ = c.kill().await; + let _ = c.wait().await; + debug!("Fallback pull timed out: {}", candidate); + None + } + } + } else { + None + }; + + if status == Some(true) { // If we pulled from a non-original registry, tag it with the original name if candidate != image { let _ = tokio::process::Command::new("podman") diff --git a/scripts/first-boot-containers.sh b/scripts/first-boot-containers.sh index d85b6abc..da2783b8 100644 --- a/scripts/first-boot-containers.sh +++ b/scripts/first-boot-containers.sh @@ -141,6 +141,26 @@ FBEOF chown -R 1000:1000 /var/lib/archipelago/secrets fi + # Generate WireGuard keys for VPN + if [ ! -f /var/lib/archipelago/wireguard/wg0.conf ]; then + log "Generating WireGuard keys..." + mkdir -p /var/lib/archipelago/wireguard /etc/wireguard + PRIVKEY=$(wg genkey) + PUBKEY=$(echo "$PRIVKEY" | wg pubkey) + cat > /var/lib/archipelago/wireguard/wg0.conf </dev/null || true + wg-quick up wg0 2>>"$LOG" || true + log " WireGuard configured: pubkey=$PUBKEY" + fi + log "Unbundled first-boot complete" exit 0 fi