07 · install
Install
Boot a live environment under Secure Boot, install a sealed cairn image, add a recovery passphrase, and choose a TPM posture.
Boot URL, typed at the board’s HTTP Boot setting:
https://cairn.dunn.dev/ipxe-shim.efi
http://cairn.dunn.dev/ipxe-shim.efi # a board without HTTPS boot
Every cairn host installs the same way: boot a live environment under
Secure Boot, then run one helper against one universal Ignition at
https://cairn.dunn.dev/ignition.
1. Boot the live environment
Secure Boot stays on, under the board’s factory keys, through this step.
Network (primary). Type the boot URL above at the board. It loads
ipxe.efi beside it: iPXE v2.0.0’s release, unmodified and
signature-checked before it runs, so plain http suits these two alone.
iPXE then reads autoexec.ipxe there,
fetches the FCOS kernel and initramfs over https, and boots through Fedora’s
signed shim.
USB stick (fallback).
media-check
verifies both install ISOs in CI and publishes each one’s URL and sha256.
Play it on main, then fetch, check, and burn Stick A:
mkdir -p ~/cairn-media && cd ~/cairn-media
curl -fLO "$(cat fcos-live.url)" && shasum -a 256 -c fcos-live.sha256
diskutil unmountDisk /dev/diskN
sudo dd if=<iso> of=/dev/rdiskN bs=4m
sudo cmp -n "$(stat -f%z <iso>)" <iso> /dev/diskN
Boot the host off it, press e at the menu, and append
ignition.config.url=https://cairn.dunn.dev/ignition. (Stick B, Fedora
Workstation, is a rescue stick only.)
All three postures wait behind the passphrase.
2. Choose an image
Only sealed tags install to disk: a bare install of an unsealed tag finishes
with loader entries and nothing to load them. Those tags are what instances
build on
(D27).
The example installs base:stable-sealed; your
host installs its repo’s sealed tag
(running it).
3. Install
Resolve the tag to a digest, then hand both to the helper:
REPO=registry.gitlab.com/dunn.dev/cairn/base/base
DIGEST=$(skopeo inspect --no-tags "docker://$REPO:stable-sealed" | jq -r .Digest)
cairn-install "$REPO@$DIGEST" "$REPO:stable-sealed" /dev/disk/by-id/...
cairn-install logs in, pulls the digest, re-checks it against the tag,
has you type the disk path back, then runs only this:
sudo podman run --rm --privileged --pid=host \
--security-opt label=type:unconfined_t \
-v /var/lib/containers:/var/lib/containers -v /dev:/dev \
"$REPO@$DIGEST" \
bootc install to-disk \
--composefs-backend --filesystem ext4 --wipe \
--block-setup tpm2-luks --generic-image --skip-fetch-check \
--source-imgref "containers-storage:$REPO@$DIGEST" \
--target-imgref "$REPO:stable-sealed" \
/dev/disk/by-id/...
--composefs-backend lays down the verity-enforced composefs the sealed
root needs (sealing); --block-setup tpm2-luks
binds the LUKS2 root to the TPM instead of the unencrypted direct default.
The supported bake is this install run --via-loopback, not
bootc-image-builder (running it).
Enrolment on metal is manual, by design: loader.conf keeps systemd-boot’s
default if-safe, which enrols only in a VM. Add secure-boot-enroll force
in this session, or pick the enrol entry in Setup Mode.
Only now enter Setup Mode: delete the Platform Key in firmware setup and reboot.
4. First boot
The installed system boots in Setup Mode and enrolls our own keys, through
the force line or the menu entry from step 3
(D19),
off the TPM2 slot bootc install enrolled. A fresh tpm2-luks install runs
systemd-cryptenroll --wipe-slot=all, so that slot is the only one the
header holds. --generic-image writes no firmware boot entry, so it boots via the
\EFI\BOOT\BOOTX64.EFI fallback or a hand-added efibootmgr entry.
5. Recovery passphrase, then a posture
Add a recovery passphrase first: it is the only door back in if the TPM path breaks. Then pick a posture.
- bind-tpm: swap the plain TPM binding for the signed-PCR11 policy sealing is built around, the posture the edge lane shows.
- password-only: retire the TPM keyslot and unlock by passphrase every boot, as the attended lane does.
- skip: keep the binding
bootc installset up.
docs/tpm-rebind.md
carries the command-exact procedure for all three, run by hand as a
documented operator step by deliberate choice
(D14).