Pause autoinstall on network screen
This commit is contained in:
parent
9217511f84
commit
e589e48511
@ -10,6 +10,8 @@ sudo bash install.sh
|
||||
|
||||
Server reboots automatically after NVIDIA drivers install. Phase 2 runs on its own after reboot.
|
||||
|
||||
On the custom ISO, Ubuntu autoinstall now pauses on the installer network screen so the operator can choose the final IP address from the VM console before installation continues.
|
||||
|
||||
## What Gets Installed (Entry Tier)
|
||||
|
||||
| Service | Port | Notes |
|
||||
|
||||
@ -1,14 +1,18 @@
|
||||
#cloud-config
|
||||
autoinstall:
|
||||
version: 1
|
||||
interactive-sections:
|
||||
- network
|
||||
|
||||
# ── Locale & keyboard ──────────────────────────
|
||||
locale: en_IN.UTF-8
|
||||
keyboard:
|
||||
layout: us
|
||||
|
||||
# ── Network: DHCP on first ethernet ───────────
|
||||
# Final network config is set by the web setup UI (browser on port 80)
|
||||
# ── Network: stop on installer network screen ─
|
||||
# Subiquity will show the network UI and use the values below as defaults.
|
||||
# This lets the operator set the final static IP from the VM console before
|
||||
# installation completes.
|
||||
network:
|
||||
network:
|
||||
version: 2
|
||||
|
||||
@ -58,6 +58,19 @@ def validate_static_network(ip, prefix, gateway, dns):
|
||||
raise ValueError("CIDR prefix must be between 1 and 32")
|
||||
return str(prefix_int)
|
||||
|
||||
def is_ip_in_use(ip):
|
||||
"""Best-effort conflict check before taking a static IP."""
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["ping", "-c", "1", "-W", "1", ip],
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
check=False,
|
||||
)
|
||||
return result.returncode == 0
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def apply_static_ip(iface, ip, prefix, gateway, dns):
|
||||
prefix = validate_static_network(ip, prefix, gateway, dns)
|
||||
config = f"""network:
|
||||
@ -270,6 +283,9 @@ HTML = r"""<!DOCTYPE html>
|
||||
</div>
|
||||
|
||||
<div class="static-fields" id="static-fields">
|
||||
<div class="alert alert-info">
|
||||
We will ping the IP before applying it. If it replies, we will block the change to avoid taking an address that is already in use.
|
||||
</div>
|
||||
<div class="ip-row">
|
||||
<div class="form-group">
|
||||
<label>IP Address</label>
|
||||
@ -437,7 +453,15 @@ function applyStaticIP() {
|
||||
dns: document.getElementById('ip-dns').value,
|
||||
};
|
||||
fetch('/api/network', { method:'POST', headers:{'Content-Type':'application/json'}, body: JSON.stringify(body) })
|
||||
.then(r=>r.json()).then(d=>{ if(!d.ok) alert('Network config failed: ' + d.error); });
|
||||
.then(r=>r.json()).then(d=>{
|
||||
if(!d.ok) {
|
||||
alert('Network config failed: ' + d.error);
|
||||
return;
|
||||
}
|
||||
if (d.warning) {
|
||||
alert(d.warning);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// ── Tier ───────────────────────────────────────────────────
|
||||
@ -663,7 +687,20 @@ class Handler(BaseHTTPRequestHandler):
|
||||
if body.get("mode") == "static":
|
||||
ifaces = get_interfaces()
|
||||
iface = ifaces[0] if ifaces else "eth0"
|
||||
validate_static_network(body["ip"], body["prefix"], body["gateway"], body["dns"])
|
||||
if is_ip_in_use(body["ip"]):
|
||||
self.send_json({
|
||||
"ok": False,
|
||||
"error": f"IP address {body['ip']} is already replying to ping. Choose a different address."
|
||||
}, 409)
|
||||
return
|
||||
apply_static_ip(iface, body["ip"], body["prefix"], body["gateway"], body["dns"])
|
||||
self.send_json({
|
||||
"ok": True,
|
||||
"ip": get_ip(),
|
||||
"warning": "Ping check passed before applying the static IP. Note: a non-reply does not guarantee the address is unused if another host blocks ICMP."
|
||||
})
|
||||
return
|
||||
self.send_json({"ok": True, "ip": get_ip()})
|
||||
except Exception as e:
|
||||
self.send_json({"ok": False, "error": str(e)}, 500)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user