pxe: reload dnsmasq on host create/delete
pxe.Supervisor.Reload() was defined but never wired up. After a host was registered in the UI or via the quick-register JSON endpoint, the dnsmasq conf still held only the hosts that existed at orchestrator startup. The new MAC wasn't tagged `known`, so when the host PXE'd, dnsmasq logged "PXE(eth0) <mac> proxy-ignored" and the boot timed out back to the BIOS. Add an optional PXEReloader interface to api.UI, wire it from main when pxe is enabled, and call u.reloadPXE() after successful Create and Delete. Logs-and-continues on failure — host registration itself has already committed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,34 @@ type UI struct {
|
||||
Runner *orchestrator.Runner
|
||||
Tiles *TileEnricher
|
||||
PublicURL string // user-visible base URL baked into the quick-register one-liner
|
||||
// PXE, when non-nil, gets Reload()ed after host create/delete so
|
||||
// dnsmasq's dhcp-host= allowlist reflects the current registry.
|
||||
// Without this, a newly-registered host PXE-boots and gets
|
||||
// "proxy-ignored" because its MAC isn't tagged `known`.
|
||||
PXE PXEReloader
|
||||
}
|
||||
|
||||
// PXEReloader rewrites dnsmasq.conf with the current host list and
|
||||
// SIGHUPs the subprocess. Satisfied by *pxe.Supervisor.
|
||||
type PXEReloader interface {
|
||||
Reload(hosts []model.Host) error
|
||||
}
|
||||
|
||||
// reloadPXE reads the full host list and hands it to the reloader.
|
||||
// Logs on failure; never returns an error — the HTTP request that
|
||||
// triggered the host change has already succeeded.
|
||||
func (u *UI) reloadPXE(ctx context.Context) {
|
||||
if u.PXE == nil {
|
||||
return
|
||||
}
|
||||
hosts, err := u.Hosts.List(ctx)
|
||||
if err != nil {
|
||||
log.Printf("pxe reload: list hosts: %v", err)
|
||||
return
|
||||
}
|
||||
if err := u.PXE.Reload(hosts); err != nil {
|
||||
log.Printf("pxe reload: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
var macRe = regexp.MustCompile(`^[0-9a-f]{2}(:[0-9a-f]{2}){5}$`)
|
||||
@@ -246,6 +274,7 @@ func (u *UI) CreateHost(w http.ResponseWriter, r *http.Request) {
|
||||
_ = templates.Registration(form).Render(r.Context(), w)
|
||||
return
|
||||
}
|
||||
u.reloadPXE(r.Context())
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
@@ -301,6 +330,7 @@ func (u *UI) CreateHostJSON(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
log.Printf("api: registered host %d (%s, %s)", id, form.Name, form.MAC)
|
||||
u.reloadPXE(r.Context())
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
_ = json.NewEncoder(w).Encode(map[string]any{
|
||||
@@ -456,6 +486,7 @@ func (u *UI) DeleteHost(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
u.reloadPXE(r.Context())
|
||||
http.Redirect(w, r, "/", http.StatusSeeOther)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user