fix(system): hostname rename updates /etc/hosts and re-announces mDNS
server.set-name ran hostnamectl but left Debian's 127.0.1.1 line on the old name (breaking sudo's 'unable to resolve host' and hostname -f) and waited on avahi to notice the change by itself. Sync /etc/hosts and avahi-set-host-name (fallback: try-restart avahi-daemon) right after a successful rename, so http(s)://<hostname>.local works immediately — best-effort, never blocks the rename. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
0f5ea9ae15
commit
178ba85c5c
@ -53,6 +53,7 @@ impl RpcHandler {
|
||||
// hit a hostname-mismatch warning on top of the usual self-signed one
|
||||
// the moment a node is renamed.
|
||||
if hostname_updated {
|
||||
sync_hostname_side_effects(&hostname).await;
|
||||
if let Err(e) = regenerate_tls_cert(&hostname).await {
|
||||
warn!(hostname = %hostname, "TLS cert regen after rename failed: {}", e);
|
||||
}
|
||||
@ -375,6 +376,46 @@ pub(super) fn hostname_from_server_name(name: &str) -> String {
|
||||
}
|
||||
}
|
||||
|
||||
/// Post-rename side effects that keep the OS consistent with the new
|
||||
/// hostname — all best-effort, the rename itself has already succeeded.
|
||||
/// Debian resolves the local hostname via the 127.0.1.1 line in /etc/hosts;
|
||||
/// leaving the old name there breaks `sudo` ("unable to resolve host") and
|
||||
/// `hostname -f`. And while avahi eventually follows the kernel hostname,
|
||||
/// re-announcing immediately makes http(s)://<hostname>.local links work
|
||||
/// right after the rename instead of minutes later.
|
||||
async fn sync_hostname_side_effects(hostname: &str) {
|
||||
// hostname_from_server_name guarantees [a-z0-9-], safe to interpolate.
|
||||
let script = format!(
|
||||
"if grep -q '^127\\.0\\.1\\.1' /etc/hosts; then sed -i 's/^127\\.0\\.1\\.1.*/127.0.1.1\\t{h}/' /etc/hosts; else printf '127.0.1.1\\t{h}\\n' >> /etc/hosts; fi",
|
||||
h = hostname
|
||||
);
|
||||
match tokio::process::Command::new("/usr/bin/sudo")
|
||||
.args(["-n", "/bin/sh", "-c", &script])
|
||||
.output()
|
||||
.await
|
||||
{
|
||||
Ok(o) if o.status.success() => {}
|
||||
Ok(o) => warn!(
|
||||
"/etc/hosts hostname sync failed: {}",
|
||||
String::from_utf8_lossy(&o.stderr).trim()
|
||||
),
|
||||
Err(e) => warn!("/etc/hosts hostname sync failed: {}", e),
|
||||
}
|
||||
|
||||
let republished = tokio::process::Command::new("/usr/bin/sudo")
|
||||
.args(["-n", "/usr/bin/avahi-set-host-name", hostname])
|
||||
.output()
|
||||
.await
|
||||
.map(|o| o.status.success())
|
||||
.unwrap_or(false);
|
||||
if !republished {
|
||||
let _ = tokio::process::Command::new("/usr/bin/sudo")
|
||||
.args(["-n", "/usr/bin/systemctl", "try-restart", "avahi-daemon"])
|
||||
.output()
|
||||
.await;
|
||||
}
|
||||
}
|
||||
|
||||
async fn set_system_hostname(hostname: &str) -> Result<()> {
|
||||
let output = tokio::process::Command::new("/usr/bin/sudo")
|
||||
.args(["-n", "/usr/bin/hostnamectl", "set-hostname", hostname])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user