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:
parent
d9d5fa65e5
commit
28e38a36a9
@ -107,6 +107,17 @@ pub async fn load_registries(data_dir: &Path) -> Result<RegistryConfig> {
|
|||||||
let mut config: RegistryConfig =
|
let mut config: RegistryConfig =
|
||||||
serde_json::from_str(&content).unwrap_or_else(|_| RegistryConfig::default());
|
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
|
// Migrate: any default registry URL that isn't already in the
|
||||||
// saved list gets appended at the end (so existing priority order
|
// saved list gets appended at the end (so existing priority order
|
||||||
// is preserved for anything the operator already configured).
|
// 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)
|
.map(|r| r.priority)
|
||||||
.max()
|
.max()
|
||||||
.unwrap_or(0);
|
.unwrap_or(0);
|
||||||
let mut added = false;
|
|
||||||
for (i, def) in defaults.registries.iter().enumerate() {
|
for (i, def) in defaults.registries.iter().enumerate() {
|
||||||
if !known.contains(&def.url) {
|
if !known.contains(&def.url) {
|
||||||
let mut cloned = def.clone();
|
let mut cloned = def.clone();
|
||||||
cloned.priority = max_priority.saturating_add(10 + i as u32);
|
cloned.priority = max_priority.saturating_add(10 + i as u32);
|
||||||
config.registries.push(cloned);
|
config.registries.push(cloned);
|
||||||
added = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if added {
|
if changed {
|
||||||
// Persist so the next load doesn't have to re-merge.
|
// Persist so the next load doesn't have to re-merge.
|
||||||
let _ = save_registries(data_dir, &config).await;
|
let _ = save_registries(data_dir, &config).await;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -143,18 +143,27 @@ pub async fn load_mirrors(data_dir: &Path) -> Result<Vec<UpdateMirror>> {
|
|||||||
return Ok(default_mirrors());
|
return Ok(default_mirrors());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// One-time migration: the Hetzner VPS at 23.182.128.160 was
|
||||||
|
// decommissioned 2026-04-23. Existing nodes have it baked into their
|
||||||
|
// saved mirror list (was the original Server 1). Strip it on load so
|
||||||
|
// we don't spend seconds per install timing out 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 = list.len();
|
||||||
|
list.retain(|m| !m.url.contains("23.182.128.160"));
|
||||||
|
let mut changed = list.len() != before;
|
||||||
|
|
||||||
// Merge in any default URLs the saved config is missing.
|
// Merge in any default URLs the saved config is missing.
|
||||||
let known: std::collections::HashSet<String> =
|
let known: std::collections::HashSet<String> =
|
||||||
list.iter().map(|m| m.url.clone()).collect();
|
list.iter().map(|m| m.url.clone()).collect();
|
||||||
let defaults = default_mirrors();
|
let defaults = default_mirrors();
|
||||||
let mut added = false;
|
|
||||||
for def in &defaults {
|
for def in &defaults {
|
||||||
if !known.contains(&def.url) {
|
if !known.contains(&def.url) {
|
||||||
list.push(def.clone());
|
list.push(def.clone());
|
||||||
added = true;
|
changed = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if added {
|
if changed {
|
||||||
let _ = save_mirrors(data_dir, &list).await;
|
let _ = save_mirrors(data_dir, &list).await;
|
||||||
}
|
}
|
||||||
Ok(list)
|
Ok(list)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user