chore: retire .23 VPS mirror, promote .168 OVH to primary

The Hetzner VPS at 23.182.128.160 was decommissioned. Replace it
everywhere with the OVH VPS at 146.59.87.168, which was previously
the tertiary mirror.

  - update.rs: drop DEFAULT_TERTIARY_MIRROR_URL, promote .168 into
    the secondary slot as "Server 1 (OVH)"; tx1138 becomes Server 2.
    Default mirror list shrinks from 3 to 2.
  - container/registry.rs: default RegistryConfig drops .23, promotes
    .168 to Server 1 / priority 0, tx1138 stays Server 2 / priority 10.
  - api/rpc/package/config.rs: trusted-registry allowlist swaps .23
    for .168.
  - api/handler/mod.rs: app-catalog fallback URL uses .168.
  - neode-ui/views/marketplace/marketplaceData.ts: REGISTRY uses .168.
  - scripts/image-versions.sh: ARCHY_REGISTRY_FALLBACK uses .168.
  - image-recipe/build-auto-installer-iso.sh: installer ISO registries
    use .168 (both podman registries.conf and backend registries.json).

Tests updated to assert on the new 2-entry default lists (registry +
mirror). URL-parser fixture tests in update.rs retain .23 strings —
they exercise string-parsing logic, not mirror policy.

Git remotes: dropped `gitea-vps` and the .23 push URL on the `origin`
multi-push alias (not part of this commit — pure working-copy change).
This commit is contained in:
archipelago 2026-04-23 08:22:32 -04:00
parent 980c1b25f4
commit d9d5fa65e5
8 changed files with 26 additions and 42 deletions

View File

@ -146,7 +146,7 @@ impl ApiHandler {
}
if upstreams.is_empty() {
upstreams.push(
"http://23.182.128.160:3000/lfg2025/app-catalog/raw/branch/main/catalog.json"
"http://146.59.87.168:3000/lfg2025/app-catalog/raw/branch/main/catalog.json"
.to_string(),
);
upstreams.push(

View File

@ -9,7 +9,7 @@ pub(super) const TRUSTED_REGISTRIES: &[&str] = &[
"ghcr.io/",
"localhost/",
"git.tx1138.com/",
"23.182.128.160:3000/",
"146.59.87.168:3000/",
];
/// Validate Docker image against trusted registry allowlist.
@ -29,7 +29,7 @@ pub(super) fn is_valid_docker_image(image: &str) -> bool {
};
matches!(
registry,
"docker.io" | "ghcr.io" | "localhost" | "git.tx1138.com" | "23.182.128.160:3000"
"docker.io" | "ghcr.io" | "localhost" | "git.tx1138.com" | "146.59.87.168:3000"
)
}

View File

@ -1589,7 +1589,7 @@ server {
.unwrap_or(true);
// Registries are configured as `host[:port]/namespace` (for
// example `23.182.128.160:3000/lfg2025`), but the Docker V2
// example `146.59.87.168:3000/lfg2025`), but the Docker V2
// registry API lives at `/v2/` on the ROOT of the host — NOT
// under the namespace. Strip the namespace before appending
// `/v2/` so the reachability probe hits the correct URL.

View File

@ -15,7 +15,7 @@ const REGISTRY_FILE: &str = "config/registries.json";
/// A single container registry.
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Registry {
/// Registry URL (e.g., "git.tx1138.com/lfg2025" or "23.182.128.160:3000/lfg2025").
/// Registry URL (e.g., "git.tx1138.com/lfg2025" or "146.59.87.168:3000/lfg2025").
pub url: String,
/// Human-readable name.
pub name: String,
@ -44,8 +44,8 @@ impl Default for RegistryConfig {
Self {
registries: vec![
Registry {
url: "23.182.128.160:3000/lfg2025".to_string(),
name: "Server 1 (VPS)".to_string(),
url: "146.59.87.168:3000/lfg2025".to_string(),
name: "Server 1 (OVH)".to_string(),
tls_verify: false,
enabled: true,
priority: 0,
@ -57,13 +57,6 @@ impl Default for RegistryConfig {
enabled: true,
priority: 10,
},
Registry {
url: "146.59.87.168:3000/lfg2025".to_string(),
name: "Server 3 (OVH)".to_string(),
tls_verify: false,
enabled: true,
priority: 20,
},
],
}
}
@ -78,8 +71,8 @@ impl RegistryConfig {
}
/// Rewrite an image reference to use a specific registry.
/// E.g., "git.tx1138.com/lfg2025/bitcoin-knots:latest" with registry "23.182.128.160:3000/lfg2025"
/// becomes "23.182.128.160:3000/lfg2025/bitcoin-knots:latest".
/// E.g., "git.tx1138.com/lfg2025/bitcoin-knots:latest" with registry "146.59.87.168:3000/lfg2025"
/// becomes "146.59.87.168:3000/lfg2025/bitcoin-knots:latest".
pub fn rewrite_image(&self, image: &str, registry: &Registry) -> String {
// Extract the image name (last component after the org/namespace)
// Handles: "registry/org/image:tag" -> "image:tag"
@ -178,12 +171,12 @@ mod tests {
#[test]
fn test_rewrite_image() {
let config = RegistryConfig::default();
// Default primary is now VPS (index 0). A tx1138-hardcoded image
// rewrites to VPS when asked for the primary mirror.
// Default primary is now the OVH VPS (index 0). A tx1138-hardcoded
// image rewrites to OVH when asked for the primary mirror.
let primary = &config.registries[0];
assert_eq!(
config.rewrite_image("git.tx1138.com/lfg2025/bitcoin-knots:latest", primary),
"23.182.128.160:3000/lfg2025/bitcoin-knots:latest"
"146.59.87.168:3000/lfg2025/bitcoin-knots:latest"
);
}
@ -191,16 +184,15 @@ mod tests {
fn test_active_registries_sorted() {
let config = RegistryConfig::default();
let active = config.active_registries();
assert_eq!(active.len(), 3);
assert_eq!(active.len(), 2);
assert!(active[0].priority <= active[1].priority);
assert!(active[1].priority <= active[2].priority);
}
#[tokio::test]
async fn test_load_default() {
let tmp = TempDir::new().unwrap();
let config = load_registries(tmp.path()).await.unwrap();
assert_eq!(config.registries.len(), 3);
assert_eq!(config.registries.len(), 2);
}
#[tokio::test]
@ -216,6 +208,6 @@ mod tests {
});
save_registries(tmp.path(), &config).await.unwrap();
let loaded = load_registries(tmp.path()).await.unwrap();
assert_eq!(loaded.registries.len(), 4);
assert_eq!(loaded.registries.len(), 3);
}
}

View File

@ -63,14 +63,11 @@ fn is_newer(candidate: &str, current: &str) -> bool {
const DEFAULT_UPDATE_MANIFEST_URL: &str =
"https://git.tx1138.com/lfg2025/archy/raw/branch/main/releases/manifest.json";
/// Secondary mirror: same manifest, served from the VPS. Added as a
/// default mirror so nodes automatically fall through when the primary
/// is slow or unreachable.
/// Secondary mirror on an OVH VPS — independent network path so a
/// single-provider outage doesn't knock out both mirrors. Promoted to
/// primary default on 2026-04-23 after the Hetzner .160 VPS was
/// decommissioned.
const DEFAULT_SECONDARY_MIRROR_URL: &str =
"http://23.182.128.160:3000/lfg2025/archy/raw/branch/main/releases/manifest.json";
/// Tertiary mirror on a separate OVH VPS — independent network path so
/// a single-provider outage doesn't knock out all three mirrors.
const DEFAULT_TERTIARY_MIRROR_URL: &str =
"http://146.59.87.168:3000/lfg2025/archy/raw/branch/main/releases/manifest.json";
const UPDATE_STATE_FILE: &str = "update_state.json";
const UPDATE_MIRRORS_FILE: &str = "update-mirrors.json";
@ -112,16 +109,12 @@ fn default_mirrors() -> Vec<UpdateMirror> {
vec![
UpdateMirror {
url: DEFAULT_SECONDARY_MIRROR_URL.to_string(),
label: "Server 1 (VPS)".to_string(),
label: "Server 1 (OVH)".to_string(),
},
UpdateMirror {
url: DEFAULT_UPDATE_MANIFEST_URL.to_string(),
label: "Server 2 (tx1138)".to_string(),
},
UpdateMirror {
url: DEFAULT_TERTIARY_MIRROR_URL.to_string(),
label: "Server 3 (OVH)".to_string(),
},
]
}
@ -1473,10 +1466,9 @@ mod tests {
async fn test_load_mirrors_returns_defaults_when_absent() {
let dir = tempfile::tempdir().unwrap();
let list = load_mirrors(dir.path()).await.unwrap();
assert_eq!(list.len(), 3);
assert!(list[0].url.contains("23.182.128.160"));
assert_eq!(list.len(), 2);
assert!(list[0].url.contains("146.59.87.168"));
assert!(list[1].url.contains("git.tx1138.com"));
assert!(list[2].url.contains("146.59.87.168"));
}
#[tokio::test]

View File

@ -2241,7 +2241,7 @@ location = "git.tx1138.com"
insecure = true
[[registry]]
location = "23.182.128.160:3000"
location = "146.59.87.168:3000"
insecure = true
REGCONF
chown -R 1000:1000 /mnt/target/home/archipelago/.config
@ -2252,7 +2252,7 @@ cat > /mnt/target/var/lib/archipelago/config/registries.json <<'DYNREG'
{
"registries": [
{"url": "git.tx1138.com/lfg2025", "name": "Archipelago Primary", "tls_verify": true, "enabled": true, "priority": 0},
{"url": "23.182.128.160:3000/lfg2025", "name": "Archipelago Fallback", "tls_verify": false, "enabled": true, "priority": 10}
{"url": "146.59.87.168:3000/lfg2025", "name": "Archipelago Fallback", "tls_verify": false, "enabled": true, "priority": 10}
]
}
DYNREG

View File

@ -33,7 +33,7 @@ export interface InstallProgress {
}
/** Archipelago app registry — all app images are mirrored here */
const REGISTRY = '23.182.128.160:3000/lfg2025'
const REGISTRY = '146.59.87.168:3000/lfg2025'
/** Marketplace app ID -> backend package keys (for "Already Installed" when first-boot/deploy created them) */
export const INSTALLED_ALIASES: Record<string, string[]> = {

View File

@ -11,7 +11,7 @@
# Archipelago app registries (primary + fallback)
ARCHY_REGISTRY="git.tx1138.com/lfg2025"
ARCHY_REGISTRY_FALLBACK="23.182.128.160:3000/lfg2025"
ARCHY_REGISTRY_FALLBACK="146.59.87.168:3000/lfg2025"
# Bitcoin stack
BITCOIN_KNOTS_IMAGE="$ARCHY_REGISTRY/bitcoin-knots:latest"