Skip to content

chore: global fixups ahead of the next microvm guest - #119

Merged
devusb merged 3 commits into
mainfrom
chore/global-fixups
Aug 30, 2026
Merged

chore: global fixups ahead of the next microvm guest#119
devusb merged 3 commits into
mainfrom
chore/global-fixups

Conversation

@devusb

@devusb devusb commented Aug 30, 2026

Copy link
Copy Markdown
Owner

Three changes that belong to the microvm foundation rather than to any one guest, split out so the guest that motivated them stays reviewable on its own. All are no-ops for every host that exists today.

Factor the mhelton user into its own module

The user and its authorized keys lived in hosts/common/default.nix, which is a full host baseline — sops with the attic_pull secret feeding nix.settings.netrc-file, the substituter list, a node exporter, systemPackages. A microvm guest wants the user and none of the rest, and importing the baseline would mean adding every guest as a sops recipient and re-encrypting.

hosts/common/mhelton.nix now carries the user, wheel, the keys, and passwordless sudo as a mkDefault. The baseline imports it and keeps only its host-specific groups, which merge on top; its existing mkForce false for sudo still wins. Guests import the same file directly.

Passwordless sudo comes along because the account has no password in a guest, so sudo would otherwise prompt for something that does not exist — and setting one would pull sops back in.

hosts/common/darwin.nix still has its own copy of the keys. It is nix-darwin with a different users.users schema, so folding it in is not a no-op and is left alone.

Drop the root key from guests

With the mhelton user and passwordless sudo in place the root key is redundant. Tailscale SSH authenticates against tailnet identity rather than authorized_keys, so tailnet access is unaffected.

The one behaviour change: microvm -s <name> defaults to -l root, so VSOCK sessions now need microvm -s <name> -- -l mhelton.

Raise the guest state volume to 16G

/var/lib is where NixOS modules put their state, so any guest running an ordinary service writes there whether or not it was planned for, and #118 sized it for identity alone. Volumes are sparse, and microvm only creates them when missing — a guest that boots with a small /var/lib cannot be grown from Nix afterwards, only by hand with truncate and resize2fs.

The declared size is not entirely free, since mkfs.ext4 preallocates metadata proportional to it — measured at roughly 0.8%:

declared on disk
1G 33M
16G 133M
64G 517M
256G 1.1G

16G is meant as a sane default rather than a ceiling. Guests needing more should append their own volume, which requires no mkForce because microvm.volumes is a list and merges by concatenation. Overriding /var/lib itself is possible with lib.mkForce on the whole list, but discards anything added here later.

Verification

system.build.toplevel.drvPath was captured for all seven hosts on main, the changes applied, and re-evaluated:

chopper gaia0 gaia1 sophia spdr superintendent the-doctor
→ identical

Byte-identical derivations across every host, so the extraGroups merge reproduces the original exactly. Re-checked after each commit. The microvm/common.nix changes are additionally unreferenced on main, since microvm/default.nix does not import it until a guest exists.

devusb added 3 commits August 30, 2026 12:26
The user and its authorized keys were defined in the common host baseline,
which also pulls in sops, the substituter list and a node exporter. MicroVM
guests want the user without any of that, so it moves to a module both can
import. Host-specific groups stay in the baseline and merge on top.
NixOS modules put their state under /var/lib, so any guest running an
ordinary service writes there whether or not it was planned for. Guest
volumes are sparse, so the larger size costs nothing until it is used, and
microvm only creates them when missing — a guest that boots with a small
/var/lib cannot be grown from Nix afterwards.

Genuinely bulky or recreatable storage still belongs on a per-guest volume.
Guests get the mhelton user with passwordless sudo, so the root key is
redundant. Tailscale SSH authenticates against tailnet identity rather than
authorized_keys and is unaffected; VSOCK sessions now need an explicit login
user, as `microvm -s <name>` defaults to root.
@devusb
devusb merged commit 38103d9 into main Aug 30, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant