Declare the network interface a selected microvm archetype needs #33
No reviewers
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
bug
duplicate
enhancement
help wanted
invalid
question
wontfix
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
allod/archetypes!33
Loading…
Reference in a new issue
No description provided.
Delete branch "agent/microvm-guest-networking-v2"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
A machine that selects the microvm runtime now gets a network card. It declares exactly one TAP interface carrying its inventory MAC and a host device name derived from the machine name, and the change's own tests are what prove no address follows the MAC across the boundary. Nothing about libvirt machines changes: all four libvirt derivations are byte-identical to master. Nothing boots yet — this is an evaluation-time slice, and the interface is not proven to carry traffic until the boot milestone.
Before this,
microvm.interfacesstayed at upstream's[]default, so the generated QEMU command had no-netdevand no-device virtio-net-*at all. The host half inallod/nexuswas already readingguest.microvm.interfacesand waiting for the declaration.What the guest declares
One entry:
type = "tap",idderived asvm-<machine>and overridable throughallod.archetypes.microvm.hostInterfaceId,macfrom the inventory fact. Thatidis the host TAP device nameallod/nexushands toip tuntap add, not a guest-side name.The declaration is gated on the builders' module lists with
lib.optional (runtime == "microvm"), neverlib.mkIf, for the reason the volume declarations already record:microvm.interfacesis not declared under the libvirt guest module, so an ungated definition is an unmatched-option error on every libvirt machine, andmkIfdefers the value rather than the definition.What archetypes validates that nothing else does
Upstream checks duplicate ids, bridge consistency, and the 15-character name limit. It performs no MAC validation and no check that an
idis a usable interface name, and QEMU accepts a multicast or all-zero MAC and then strands the guest at boot with nothing having reported why. Inventory validates none of it either. So archetypes asserts per entry, over the mergedconfig.microvm.interfacesrather than its own definition: exactly one entry, typetap, the expected and structurally valid host id, the expected and structurally valid unicast non-zero MAC, no bridge, andtap.vhostoff. Reporting per entry is what lets one fixture carrying fourteen entries reach nineteen named diagnostics off a single evaluation, instead of costing fourteen fixtures.The address scanner and its limits
runtime-module-selectionscans eight surfaces for address-shaped values: the merged interface entry, the reconstructed QEMU command line, the generated host TAP scripts, a projected guest surface,boot.kernelParams, the renderedsystemd-networkdunits, the resolver files, and the/etc/hostsinputs. Two needle kinds run over them — every inventory machine's exactip, and a generic dotted-quad and IPv6 shape anchored outside store paths.Stated so the scanner is not read as a whole-system guarantee: activation scripts, non-networkd units,
environment.etcbeyond the named files, and firewall commands are not scanned, and an address planted there would pass. Closing that needs a sweep over a built artifact, which belongs to the slice that boots a real guest (parent acceptance test 8), not to an evaluation-time check. The generic shape is enforced clean on the privacy fixture; the moved dev fixture runs in expected-superset mode, where a stray finding would pass.Address sabotages are bound as a findings list rather than added to the sabotage list, because an address evaluates cleanly — there is no assertion for it to trip.
Risk
R2 Medium. Localized to
allod/archetypesflake.nix; no host, secret, or deployed state is touched, and rollback is a straight revert. The residual concern is not the libvirt path, which is pinned byte-for-byte below, but the scanner's stated blind spots: an address introduced through an activation script or a non-networkd unit passes this check and would first be caught at the boot milestone.The MAC is the only machine-derived value crossing into the guest.
machines.<name>.ipsits one attribute away frommachines.<name>.macin inventory, which is the specific accident the scanner exists to catch.Validation
Every libvirt derivation is byte-identical to master:
system.build.toplevel.drvPathallod-dev1lhcxfhy9iddfssp3df3r2zwkwnd3ilmprivacy-1zzzaralwv032jdmbqc1q6ms9fm15w7yfnexusfad4pq24f8iavzr3q369alz8932jq9q3installer2yj5038jnsgzbv6ghhmyafs5kspn9jrgnix build --rebuild .#checks.x86_64-linux.runtime-module-selectionpasses on this branch head and reproduces its output. It reports both fixtures matching their declared runtime and all 22 negative cases failing, of which these are this slice's:tap.vhost, wrong id, wrong MAC, empty/slash/space/colon/../overlong ids, a malformed MAC, a multicast MAC, the all-zero MAC, upstream's duplicate-id and length assertions, and a non-nullmicrovm.extraArgsScript— the one route into the QEMU command line no evaluation-time scan can follow, so it is closed by assertion instead;Each needle is anchored to its own reporter, so deleting one rule turns the fixture red for that rule alone rather than red for any reason.
A fresh evaluation of this check peaks at 4.83 GB — measured with
\time -vunbounded. That is inside the box's headroom today but is the cost that motivates allod/archetypes#31, which lands before the credentials slice.Review fixes in the second commit
An adversarial diff review returned a merge verdict with five fixes, applied in
8aa0fce: an unused option-name binding and a disjunct that can never hold deleted (the dev and privacy fixture names come fromfilterAttrsover disjointtypevalues); the assertion-rejection arm removed from the per-fixture reporter, because both consumers force the configuration first so a module rejection surfaces as NixOS's own failed-assertions throw and this arm could never be the reported diagnostic; the multicast sabotage MAC's first octet changed from53to03, since with53both hex digits are odd and the case passed whether the rule read the low digit or the high one; and the two comments above narrowed to state what the scanner does not cover.Closes allod/archetypes#28
Refs allod/strategy#20