First boot on a fresh home volume leaves home-manager failed and the system degraded #35

Open
opened 2026-08-02 23:03:36 +01:00 by vnprc-agent · 0 comments

A dev microvm guest's first boot on a freshly provisioned home volume leaves home-manager-<user>.service failed and the system degraded: the fresh ext4 filesystem's root is owned by root, an early root-context writer creates /home/<user>/.config root-owned, and the home-manager unit — running as the user — then cannot write its own configuration.

Symptom

Cold boot of an archetypes-built dev microvm guest on a fresh ext4 home image, provisioned exactly as contract 13 assigns to the deployer (create at declared size, mkfs.ext4 with the declared label, no further preparation):

hm-activate-<user>[739]: mkdir: cannot create directory /home/<user>/.config/environment.d: Permission denied

systemctl is-system-running reports degraded; home-manager-<user>.service is failed. The guest is otherwise usable (sshd up, nix-daemon up, builds work), but every first boot of every fresh dev microvm ships broken user configuration and a degraded system until someone intervenes.

Why only microvm guests

On libvirt guests this never shows because the home directory is provisioned together with the machine by the installer. The microvm path is the first one where a home filesystem arrives empty and root-owned at boot, and nothing in the boot sequence currently establishes the user's ownership of the volume root before user-context units run.

Proposed fix and interim

The volume declaration is framework-owned (the dev archetype composes the home volume and asserts its shape), so first-mount ownership belongs with the framework too: an archetype-owned root-context step ordered after the home mount and before home-manager activation that establishes <user>:<group> ownership of the volume root when it is not already correct — a tmpfiles d/Z entry for the home mount point or an ordered oneshot are both candidate shapes. That makes a freshly formatted image sufficient, keeping the deployer's provisioning contract exactly what contract 13 says it is.

Interim, deployer-side: after formatting, mount the home image once on the host and chown its filesystem root to the guest user's uid/gid before the first start. This works (the failure does not occur with correct ownership) but silently re-widens the deployer contract that the volume modules otherwise keep narrow, and every deployment has to rediscover it at its first fresh boot.

Measured at archetypes 8aa0fce, vm 8a1eb0f, microvm.nix 39a499ab, nixpkgs b6018f87.

Refs allod/strategy#20

A dev microvm guest's first boot on a freshly provisioned home volume leaves `home-manager-<user>.service` failed and the system `degraded`: the fresh ext4 filesystem's root is owned by root, an early root-context writer creates `/home/<user>/.config` root-owned, and the home-manager unit — running as the user — then cannot write its own configuration. ### Symptom Cold boot of an archetypes-built dev microvm guest on a fresh ext4 home image, provisioned exactly as contract 13 assigns to the deployer (create at declared size, `mkfs.ext4` with the declared label, no further preparation): ``` hm-activate-<user>[739]: mkdir: cannot create directory /home/<user>/.config/environment.d: Permission denied ``` `systemctl is-system-running` reports `degraded`; `home-manager-<user>.service` is failed. The guest is otherwise usable (sshd up, nix-daemon up, builds work), but every first boot of every fresh dev microvm ships broken user configuration and a degraded system until someone intervenes. ### Why only microvm guests On libvirt guests this never shows because the home directory is provisioned together with the machine by the installer. The microvm path is the first one where a home filesystem arrives empty and root-owned at boot, and nothing in the boot sequence currently establishes the user's ownership of the volume root before user-context units run. ### Proposed fix and interim The volume declaration is framework-owned (the dev archetype composes the home volume and asserts its shape), so first-mount ownership belongs with the framework too: an archetype-owned root-context step ordered after the home mount and before home-manager activation that establishes `<user>:<group>` ownership of the volume root when it is not already correct — a tmpfiles `d`/`Z` entry for the home mount point or an ordered oneshot are both candidate shapes. That makes a freshly formatted image sufficient, keeping the deployer's provisioning contract exactly what contract 13 says it is. Interim, deployer-side: after formatting, mount the home image once on the host and chown its filesystem root to the guest user's uid/gid before the first start. This works (the failure does not occur with correct ownership) but silently re-widens the deployer contract that the volume modules otherwise keep narrow, and every deployment has to rediscover it at its first fresh boot. Measured at archetypes `8aa0fce`, vm `8a1eb0f`, microvm.nix `39a499ab`, nixpkgs `b6018f87`. Refs allod/strategy#20
Sign in to join this conversation.
No description provided.