Set up tschingel host with encrypted ZFS, measured boot and disko VM test #126

Open
fabianhauser wants to merge 11 commits from tschingel-setup into main
Owner

Sets up the new tschingel host (ThinkPad X1 Gen13) with a native-ZFS encrypted disko layout, TPM-based measured boot, and an on-demand VM test for the disk layout.

Host setup

  • Native-ZFS encrypted disko layout: LUKS keystore holding the raw ZFS key, LUKS swap with hibernation support, TPM2 unlock via measured boot (lanzaboote + pcrlock)
  • Opt-in lanzaboote measured-boot module and pcrlock support in dotfiles-enroll-tpm
  • ThinkPad X1 Gen13 hardware module (gen9 minus the EM120R-GL modem)

Disko/ZFS VM test

New tests/ directory with a disko install test for tschingel's full disk layout (format, mount idempotency, install, real encrypted boot, assertions on pools/datasets/mounts/swap/LUKS). Runs on demand via nix run .#slow-checks — deliberately not part of nix flake check. The disko config is parameterized (dotfiles.tschingel.disko.*) so the test uses small disk sizes.

Bugs the test caught (all would have broken the real install/boot)

  1. Partition regions off by one — sgdisk end sectors are inclusive, contiguous regions failed to create
  2. disko's own mount flow never mounted the keystore, so zpool import -l could not find the ZFS key
  3. The raw ZFS key was regenerated on every format re-run, orphaning the key from the dataset
  4. RequiresMountsFor=/keystore chained up through sysroot.mount, so the initrd-switch-root conflict with keystore.mount made systemd unmount /sysroot and drop the switch-root job — boot hung forever
  5. Dataset mountpoints were undeclared in disko options, so disko-zfs stripped them every boot (unmounting /home)

A follow-up TPM2/lanzaboote reboot test is designed in TPM_TEST.md for a future session.

Sets up the new tschingel host (ThinkPad X1 Gen13) with a native-ZFS encrypted disko layout, TPM-based measured boot, and an on-demand VM test for the disk layout. ## Host setup - Native-ZFS encrypted disko layout: LUKS keystore holding the raw ZFS key, LUKS swap with hibernation support, TPM2 unlock via measured boot (lanzaboote + pcrlock) - Opt-in lanzaboote measured-boot module and pcrlock support in dotfiles-enroll-tpm - ThinkPad X1 Gen13 hardware module (gen9 minus the EM120R-GL modem) ## Disko/ZFS VM test New `tests/` directory with a disko install test for tschingel's full disk layout (format, mount idempotency, install, real encrypted boot, assertions on pools/datasets/mounts/swap/LUKS). Runs on demand via `nix run .#slow-checks` — deliberately not part of `nix flake check`. The disko config is parameterized (`dotfiles.tschingel.disko.*`) so the test uses small disk sizes. ## Bugs the test caught (all would have broken the real install/boot) 1. Partition regions off by one — sgdisk end sectors are inclusive, contiguous regions failed to create 2. disko's own mount flow never mounted the keystore, so `zpool import -l` could not find the ZFS key 3. The raw ZFS key was regenerated on every format re-run, orphaning the key from the dataset 4. `RequiresMountsFor=/keystore` chained up through `sysroot.mount`, so the initrd-switch-root conflict with `keystore.mount` made systemd unmount /sysroot and drop the switch-root job — boot hung forever 5. Dataset mountpoints were undeclared in disko `options`, so disko-zfs stripped them every boot (unmounting /home) A follow-up TPM2/lanzaboote reboot test is designed in `TPM_TEST.md` for a future session.
Partition regions were off by one (sgdisk end sectors are inclusive),
disko's own mount flow never mounted the keystore for zpool import -l,
the ZFS raw key was regenerated on every format re-run, and the
create-time mountpoint properties were undeclared in options, so
disko-zfs stripped them (unmounting /home) on every boot.
RequiresMountsFor=/keystore chained up through sysroot.mount, so the
initrd-switch-root conflict with keystore.mount made systemd unmount
/sysroot and drop the switch-root job, hanging boot forever.
Document TPM reboot test design for a future session
All checks were successful
CI / build (push) Successful in 26s
538ef740df
All checks were successful
CI / build (push) Successful in 26s
This pull request can be merged automatically.
This branch is out-of-date with the base branch
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin tschingel-setup:tschingel-setup
git switch tschingel-setup

Merge

Merge the changes and update on Forgejo.

Warning: The "Autodetect manual merge" setting is not enabled for this repository, you will have to mark this pull request as manually merged afterwards.

git switch main
git merge --no-ff tschingel-setup
git switch tschingel-setup
git rebase main
git switch main
git merge --ff-only tschingel-setup
git switch tschingel-setup
git rebase main
git switch main
git merge --no-ff tschingel-setup
git switch main
git merge --squash tschingel-setup
git switch main
git merge --ff-only tschingel-setup
git switch main
git merge tschingel-setup
git push origin main
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
fabianhauser/dotfiles!126
No description provided.