a73x

internal/agent/run/reservations.go

Ref:   Size: 1.4 KiB   History

package run

import (
	"log/slog"

	"github.com/a73x/eitri/internal/agent/state"
)

// reservations is the slice of a host's networking the startup replay needs:
// pinning one guest's address. Consumer-owned and minimal (arch R5) so a
// platform whose networking is nothing like a bridge and a DHCP responder can
// still be handed the surviving guests' addresses.
type reservations interface {
	AddReservation(vmID, ip string)
	AdoptNetwork(vmID, network, ip string)
}

// replayReservations rebuilds net's reservation table from durable records. A
// platform's wiring must call it BEFORE its DHCP responder starts, so a
// surviving guest's renewal is never answered from an empty table (fail-closed
// plus this preload close the gap). It is also the only thing that carries an
// address across an agent restart: the table is in memory, so a guest whose
// reservation is not replayed is renumbered at its next boot.
func replayReservations(st *state.Store, net reservations) {
	recs, err := st.LoadVMs()
	if err != nil {
		slog.Warn("state load failed; surviving guests' DHCP reservations are not rebuilt (they may fail to renew until reconcile reboots them)", "err", err)
		return
	}
	for _, rec := range recs {
		if rec.IP != "" {
			net.AddReservation(rec.Spec.VMID, rec.IP)
		}
		if rec.Spec.Network != "" {
			net.AdoptNetwork(rec.Spec.VMID, rec.Spec.Network, rec.NetworkIP)
		}
	}
}