Design Spec: Proxmox VM Configuration & Declarative Integration Testing for hl02
1. Goal
Configure hl02 as a fully defined NixOS Proxmox VM using DHCP, and implement a
Nix-native integration test framework to verify the configuration (system boot,
SSH, and QEMU Guest Agent) both locally and in GitHub Actions.
2. Rationale
Currently, the configuration for hl02 is incomplete and references a
non-existent ext4 role, which prevents it from building. Additionally,
verifying VM configurations manually or via ad-hoc shell scripts in CI is
brittle and hard to maintain. Transitioning to a declarative testing model using
NixOS's native testing framework (nixosTest) ensures that configuration
correctness is verified inside the Nix sandbox, providing reliable and
reproducible feedback.
3. Proposed Changes
3.1 Architectural Split of hl02 Configuration
To allow the integration test to run without triggering physical disk partitioning (which is handled by Disko and is not suitable for standard sandboxed NixOS tests), we split the host configuration:
config/nix/hosts/hl02/configuration.nix(Logical Config):- Imports
roles/commonandroles/proxmox-vm. - Configures logical settings:
networking.hostName = "hl02"networking.hostId = "92bbb1e6"networking.useDHCP = truesystem.stateVersion = "25.11"
- Imports
config/nix/hosts/hl02/default.nix(Physical/Target Config):- A clean, argument-free module entrypoint.
- Imports
./configuration.nix(logical settings). - Imports
./hardware.nix(hardware placeholder). - Imports
./disko.nix(filesystem configuration).
config/nix/hosts/hl02/disko.nix(Filesystem Config):- Accepts
{ inputs, ... }arguments globally viaspecialArgs. - Imports the core Disko module (
inputs.disko.nixosModules.disko) internally, encapsulating the dependency. - Defines the physical ext4 disk layout on
/dev/vda.
- Accepts
3.2 Declarative Integration Test (config/nix/hosts/hl02/test.nix)
We utilize a centralized, service-aware NixOS integration test generator at
config/nix/tests/make-test.nix.
The host-specific test file config/nix/hosts/hl02/test.nix simply imports this
generator and passes its logical configuration.nix.
The generator dynamically:
- Sets the test name to
${hostName}-testby reading the logical configuration. - Configures the required QEMU
virtio-serialhardware inside the sandbox ifservices.qemuGuestis enabled. - Constructs the Python test script dynamically based on active services (e.g.
waiting for
/dev/virtio-ports/org.qemu.guest_agent.0, verifyingqemu-guest-agent.serviceactivates, and checking that SSH port 22 is open).
3.3 Flake Integration (config/nix/flake.nix)
Expose the new test in the flake's checks output for the x86_64-linux
system:
- Dynamically discover and import tests to
checks.${system}. - This allows
nix flake checkto automatically run the integration test.
3.4 GitHub Actions Workflow Update (.github/workflows/nix.yaml)
- Maintain the
Check the main flakestep which runsnix flake check(this will now execute thenixosTestvia QEMU). - Maintain the
Build the hl02 configurationstep to ensure the full physical VM image (with Disko) builds. - Remove the legacy
Smoke test - boot hl02step which used a manual shell-based timeout.
4. Verification Plan
4.1 Automated Tests (CI)
- Push the branch to GitHub and verify that the
nix flake checkstep successfully executes and passes thehl02-testintegration test. - Verify that the build step successfully completes.
4.2 Manual Verification (Local/Dev)
- If Nix is available on the development machine, run
nix flake checkto run the test locally. (Note: Disallowed on the current host per user request).
5. Assumptions & Constraints
5.1 Disk Device Configuration (/dev/vda)
The physical Disko configuration (hosts/hl02/disko.nix) explicitly configures
the target disk as /dev/vda. This assumes that the Proxmox VM is provisioned
using a VirtIO Block controller. If the VM is provisioned using a SCSI
controller (which is common in Proxmox), the disk will present as /dev/sda and
the boot partition layout will fail to apply.
- Constraint: The VM must be created with a VirtIO Block disk controller, or
hosts/hl02/disko.nixmust be updated to/dev/sdato match a SCSI setup.
5.2 Empty hardware.nix Rationale
The file hosts/hl02/hardware.nix is currently an empty placeholder. This is
because all VM-specific hardware configurations (such as standard VirtIO
drivers, systemd-boot configuration, and kernel serial console parameters) are
generalized in roles/proxmox-vm/default.nix. If hl02 requires host-specific
hardware modifications in the future (e.g., PCI passthrough), they should be
declared in hosts/hl02/hardware.nix.
5.3 "For Now" Scope
- Networking: The host uses DHCP for convenience and simplicity in this
phase (
networking.useDHCP = true). Transitioning to static IPs can be done in a future specification. - User Access: SSH keys are left unconfigured for this host in the Nix
configuration. Initial login must be performed via console or by injecting
keys out-of-band, until secret management (such as
sops-nixor hardcoded public keys) is specified.