fix(config): auto-purge decommissioned .23 VPS from saved registry/mirror configs

load_registries + load_mirrors normally only ADD missing defaults to
the persisted JSON — explicit removals stick. After retiring the .23
Hetzner VPS we need the opposite: existing nodes have .23 baked into
their saved configs and would spend seconds per install/update timing
out against a dead host until the operator manually removes it via
the Settings UI.

Add a targeted one-time migration in both loaders: if any saved entry
has 23.182.128.160 in its URL, drop it on load and rewrite the file.
This is an exception to the usual "explicit removals stick" rule —
the user never chose to add this mirror, it was a default.

Narrow-scope migration (one hardcoded IP match, no schema version)
because the cost/benefit of a general migration system isn't worth
it for a single decommissioned host. Future retirements can follow
the same pattern.
This commit is contained in:
archipelago
2026-04-23 08:51:26 -04:00
parent d9d5fa65e5
commit 28e38a36a9
2 changed files with 25 additions and 6 deletions
+13 -3
View File
@@ -107,6 +107,17 @@ pub async fn load_registries(data_dir: &Path) -> Result<RegistryConfig> {
let mut config: RegistryConfig =
serde_json::from_str(&content).unwrap_or_else(|_| RegistryConfig::default());
// One-time migration: the Hetzner VPS at 23.182.128.160 was
// decommissioned 2026-04-23. Existing nodes have it baked into
// their saved registry list (was the original Server 1). Strip it
// on load so every container pull doesn't pay a connection-refused
// timeout against a dead host. Exception to the usual "explicit
// removals stick" rule: the user never chose to add this — it
// was a default.
let before = config.registries.len();
config.registries.retain(|r| !r.url.contains("23.182.128.160"));
let mut changed = config.registries.len() != before;
// Migrate: any default registry URL that isn't already in the
// saved list gets appended at the end (so existing priority order
// is preserved for anything the operator already configured).
@@ -119,16 +130,15 @@ pub async fn load_registries(data_dir: &Path) -> Result<RegistryConfig> {
.map(|r| r.priority)
.max()
.unwrap_or(0);
let mut added = false;
for (i, def) in defaults.registries.iter().enumerate() {
if !known.contains(&def.url) {
let mut cloned = def.clone();
cloned.priority = max_priority.saturating_add(10 + i as u32);
config.registries.push(cloned);
added = true;
changed = true;
}
}
if added {
if changed {
// Persist so the next load doesn't have to re-merge.
let _ = save_registries(data_dir, &config).await;
}