Fix LXD IPv4: retry DHCP 30s, fallback to static IP for privileged containers
Some checks failed
BotServer CI / build (push) Failing after 6m46s
Some checks failed
BotServer CI / build (push) Failing after 6m46s
This commit is contained in:
parent
03fe5bc94d
commit
16394aef01
1 changed files with 48 additions and 28 deletions
|
|
@ -377,43 +377,63 @@ impl PackageManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_container_ip(container_name: &str) -> Result<String> {
|
fn get_container_ip(container_name: &str) -> Result<String> {
|
||||||
std::thread::sleep(std::time::Duration::from_secs(2));
|
// Poll up to 30s for DHCP to assign an IPv4
|
||||||
|
for _ in 0..15 {
|
||||||
|
std::thread::sleep(std::time::Duration::from_secs(2));
|
||||||
|
|
||||||
let output = safe_lxc(&["list", container_name, "-c", "4", "--format", "csv"]);
|
if let Some(o) = safe_lxc(&["list", container_name, "-c", "4", "--format", "csv"]) {
|
||||||
|
if o.status.success() {
|
||||||
|
let out = String::from_utf8_lossy(&o.stdout).trim().to_string();
|
||||||
|
let ip = out.split([' ', '(']).next().unwrap_or("").trim();
|
||||||
|
if !ip.is_empty() && ip.contains('.') {
|
||||||
|
return Ok(ip.to_string());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let output = match output {
|
if let Some(o) = safe_lxc(&["exec", container_name, "--", "hostname", "-I"]) {
|
||||||
Some(o) => o,
|
if o.status.success() {
|
||||||
None => return Ok("unknown".to_string()),
|
let out = String::from_utf8_lossy(&o.stdout).trim().to_string();
|
||||||
};
|
if let Some(ip) = out.split_whitespace().find(|s| s.contains('.')) {
|
||||||
|
return Ok(ip.to_string());
|
||||||
if output.status.success() {
|
}
|
||||||
let ip_output = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
|
||||||
|
|
||||||
if !ip_output.is_empty() {
|
|
||||||
let ip = ip_output.split([' ', '(']).next().unwrap_or("").trim();
|
|
||||||
if !ip.is_empty() && ip.contains('.') {
|
|
||||||
return Ok(ip.to_string());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let output = safe_lxc(&["exec", container_name, "--", "hostname", "-I"]);
|
// DHCP failed (common in privileged containers where systemd-networkd can't run).
|
||||||
|
// Assign a static IP on the lxdbr0 bridge (10.43.228.0/24).
|
||||||
|
warn!("DHCP timeout for '{}', assigning static IP via lxdbr0", container_name);
|
||||||
|
let static_ip = Self::assign_static_ip(container_name)?;
|
||||||
|
Ok(static_ip)
|
||||||
|
}
|
||||||
|
|
||||||
let output = match output {
|
fn assign_static_ip(container_name: &str) -> Result<String> {
|
||||||
Some(o) => o,
|
// Pick a deterministic IP from the last 2 bytes of the MAC address to avoid collisions.
|
||||||
None => return Ok("unknown".to_string()),
|
let mac_out = safe_lxc(&["exec", container_name, "--", "cat", "/sys/class/net/eth0/address"]);
|
||||||
};
|
let last_octet = mac_out
|
||||||
|
.and_then(|o| o.status.success().then(|| String::from_utf8_lossy(&o.stdout).trim().to_string()))
|
||||||
|
.and_then(|mac| {
|
||||||
|
let parts: Vec<&str> = mac.split(':').collect();
|
||||||
|
let a = u8::from_str_radix(parts.get(4)?, 16).ok()?;
|
||||||
|
let b = u8::from_str_radix(parts.get(5)?, 16).ok()?;
|
||||||
|
// Map into 100-250 range to avoid gateway (.1) and broadcast (.255)
|
||||||
|
Some(100u16 + ((u16::from(a) * 256 + u16::from(b)) % 150) as u16)
|
||||||
|
})
|
||||||
|
.unwrap_or(100);
|
||||||
|
|
||||||
if output.status.success() {
|
let ip = format!("10.43.228.{last_octet}");
|
||||||
let ip_output = String::from_utf8_lossy(&output.stdout).trim().to_string();
|
let cidr = format!("{ip}/24");
|
||||||
if let Some(ip) = ip_output.split_whitespace().next() {
|
|
||||||
if ip.contains('.') {
|
|
||||||
return Ok(ip.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Ok("unknown".to_string())
|
safe_lxc(&["exec", container_name, "--", "ip", "addr", "add", &cidr, "dev", "eth0"]);
|
||||||
|
safe_lxc(&["exec", container_name, "--", "ip", "route", "add", "default", "via", "10.43.228.1"]);
|
||||||
|
safe_lxc(&["exec", container_name, "--", "bash", "-c",
|
||||||
|
&format!("printf 'nameserver 8.8.8.8\\nnameserver 8.8.4.4\\n' > /etc/resolv.conf && \
|
||||||
|
printf '#!/bin/sh\\nip addr add {cidr} dev eth0 2>/dev/null||true\\nip route add default via 10.43.228.1 2>/dev/null||true\\nexit 0\\n' > /etc/rc.local && \
|
||||||
|
chmod +x /etc/rc.local && systemctl enable rc-local 2>/dev/null||true")]);
|
||||||
|
|
||||||
|
info!("Assigned static IP {} to container '{}'", ip, container_name);
|
||||||
|
Ok(ip)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn initialize_vault(container_name: &str, ip: &str) -> Result<()> {
|
fn initialize_vault(container_name: &str, ip: &str) -> Result<()> {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue