diff --git a/opentofu/modules/node-vm/main.tf b/opentofu/modules/node-vm/main.tf index 5cb59bc..c4cbf0c 100644 --- a/opentofu/modules/node-vm/main.tf +++ b/opentofu/modules/node-vm/main.tf @@ -127,5 +127,34 @@ boot = i == 0 ? { order = 1 } : null } ] + + # SERIAL CONSOLE + BOOT LOG. Added 2026-07-20 because its ABSENCE blocked a + # real diagnosis: six of nine vr1-dc0 nodes stalled in MAAS's `Loading + # ephemeral` and, with no console and no agent, a stuck node was a sealed + # box -- nothing to read, nothing to attach to. Contention, boot-image sync + # and DHCP were all refuted by measurement; the boot itself could not be + # observed at all. + # + # This is the SAME pattern modules/opnsense-edge already carries, and for + # the same reason: that module's log is what made the 2026-07-12 boot bugs + # legible. A PXE-booting node is exactly the case where the interesting + # output happens BEFORE anything you could ssh into exists. + # + # log -> the full boot capture, including everything emitted before an + # operator could possibly attach (`virsh console` only shows from + # the moment you attach). + # NO `source` -> libvirt's default ``, which is what + # `virsh console` requires. A pty's /dev/pts/N path is allocated at + # start time and cannot be known in advance, so it must not be set. + # + # Unconditional, not opt-in: these node VMs are MAAS-managed and rebuilt at + # will, so there is no live-router bounce risk of the kind that made the + # D-129 qga channel opt-in. Every node should be observable by default. + serials = [ + { + log = { file = "${var.serial_log_dir}/${var.vm_name}-serial.log", append = "on" } + target = { port = "0" } + } + ] } } diff --git a/opentofu/modules/node-vm/variables.tf b/opentofu/modules/node-vm/variables.tf index 5451fe8..ee58e5f 100644 --- a/opentofu/modules/node-vm/variables.tf +++ b/opentofu/modules/node-vm/variables.tf @@ -38,3 +38,21 @@ type = bool default = false } + +variable "serial_log_dir" { + description = <<-EOT + Directory ON THE LIBVIRT HOST for this node's serial boot log. + + PARAMETERIZED, not hardcoded: modules/opnsense-edge bakes + "/var/lib/libvirt/vr1/staging" into its serial path, which is a vcloud-only + literal and silently wrong on any other libvirt host -- under D-123 Model B + the node VMs live inside vvr1-dc0, a different host entirely. (Backporting + this parameterization to opnsense-edge is a queued finding.) + + The directory MUST exist and be writable by libvirt on that host, or the + domain fails to START with "Unable to open file: ... No such file or + directory" -- measured on the dc0 edge, 2026-07-20. + EOT + type = string + default = "/var/lib/libvirt/vr1/staging" +}