Take the foundation's ports as genesis inputs, check them free, and hand them to the controller as the node's settings (hq ADR 0100)

This commit is contained in:
2026-09-22 17:28:36 +02:00
parent 770f589401
commit 3964d9da0a
10 changed files with 902 additions and 14 deletions
+40 -1
View File
@@ -185,6 +185,20 @@ type Options struct {
Prompt func(Choice) (string, error)
// Extras are catalogue modules beyond the floor, asked for by name.
Extras []string
// Ports are the ports the foundation binds on this machine (novox/hq ADR 0100). Inputs to
// genesis, each checked free before anything is raised, and then the node's settings for the
// foundation's modules — so adopting the foundation as modules leaves it where it was raised.
// Zero means the catalogue's defaults.
Ports FoundationPorts
// OverlayRange is the private network's address range, checked against every interface and
// route the machine already has. Empty means the mesh's default.
OverlayRange string
// Adopted raises this machine as an adopted node (novox/hq ADR 0100): what is on it is kept
// until each module is taken, its firewall stays in force, and the mesh guards its own ports
// in a table that only refuses. Without it, a machine in use is refused.
Adopted bool
}
// pivots reports whether this run goes past the foundation.
@@ -287,6 +301,14 @@ type Result struct {
// Stopped names why a run went no further. Empty on a run that pivoted.
Stopped string `json:"stopped,omitempty"`
// Adopted, the firewall found, and the ports the foundation was raised on (novox/hq ADR 0100).
Adopted bool `json:"adopted,omitempty"`
Firewall string `json:"firewall,omitempty"`
Ports FoundationPorts `json:"ports"`
// Filter is the packet filter chosen for when the node converges; an adopted genesis loads
// none, and the flip assigns this one.
Filter string `json:"filter-on-converge,omitempty"`
}
// Run performs the bootstrap, saying what it is doing as it goes.
@@ -339,7 +361,12 @@ func Run(ctx context.Context, o Options, d Deps, say func(string)) (Result, erro
if say == nil {
say = func(string) {}
}
result := Result{DryRun: o.DryRun}
result := Result{DryRun: o.DryRun, Adopted: o.Adopted}
o.Ports = o.Ports.orDefaults()
result.Ports = o.Ports
if err := o.Ports.Check(); err != nil {
return result, failed(StepPreflight, err)
}
// ---- 1. preflight -------------------------------------------------------------------
say("preflight — what has to be true before anything is changed")
@@ -399,12 +426,24 @@ func Run(ctx context.Context, o Options, d Deps, say func(string)) (Result, erro
if err := RefuseExistingServers(ctx, d.Run, creds); err != nil {
return result, failed(StepBundle, err)
}
// The foundation's ports, its private network's range and its containers' names are checked
// free before anything is raised (novox/hq ADR 0100), each refusal naming what holds it.
if err := CheckTheMachine(ctx, o, d.Run, rewritten.Declaration, say); err != nil {
return result, failed(StepBundle, err)
}
// From here on nothing this installer says contains the values it just made.
say = Masking(say, creds)
root, err := RewriteRoot(&rewritten, creds)
if err != nil {
return result, failed(StepBundle, err)
}
moved, err := RewritePorts(&rewritten, o.Ports, o.OverlayRange)
if err != nil {
return result, failed(StepBundle, err)
}
if moved.Places > 0 {
say(fmt.Sprintf(" ports %d place(s) rewritten to this node's foundation ports", moved.Places))
}
for _, c := range []struct {
what, path string
made bool