# veilor-os install kickstart — v0.7 spike (ostreecontainer path) # # This is the install-time kickstart for the v0.7 hybrid path. The live # ISO boots; the gum TUI collects user answers (disk, LUKS pw, admin pw); # this template gets the answers substituted in and is fed to anaconda. # # Anaconda partitions the disk + creates LUKS + btrfs subvols + mounts # /boot/efi + /boot, then `ostreecontainer` populates `/` directly from # the cosign-signed veilor-os OCI image at `ghcr.io/veilor-org/veilor-os:43`. # # No `%packages` block. No first-boot rebase. No # `veilor-firstboot-rebase.service`. The ostreecontainer install pass is # the entire transition from "Fedora live ISO" to "veilor-os on disk". # # Reference: pykickstart docs ostreecontainer command; # https://docs.fedoraproject.org/en-US/bootc/anaconda-install/ # ── Locale / keyboard / time ── keyboard --xlayouts='us' lang en_US.UTF-8 timezone Europe/London --utc # ── Install mode / behaviour ── firstboot --disable eula --agreed # SELinux state inherited from the OCI image; --enforcing is implicit # since secureblue's image ships /etc/selinux/config = enforcing. selinux --enforcing # ── Network / hostname ── network --bootproto=dhcp --device=link --activate --hostname=__HOSTNAME__ firewall --enabled --service=ssh # ── Identity (single LUKS prompt asked at install via gum TUI) ── rootpw --lock user --name=admin --groups=wheel --gecos="veilor admin" --password=__ADMIN_PW__ --plaintext # ── Bootloader ── # fbcon=nodefer for laptop KMS handoff (real-hardware audit, agent 9 of # 2026-05-05 wave). rd.luks.options=tries=5,timeout=0 for UX. # rd.luks.uuid is auto-injected by anaconda based on the encrypted # part directive below. # # All other hardening kargs (lockdown=integrity, slab_nomerge, etc.) # come from /usr/lib/bootc/kargs.d/ inside the OCI image — bootc # applies them at install time. We only add what the OCI image can't # know (laptop-specific KMS flag). bootloader --append="fbcon=nodefer" # ── Disk: LUKS2 (argon2id) + btrfs subvols ── zerombr clearpart --all --initlabel --drives=__DISK_BASENAME__ part /boot/efi --fstype=efi --size=600 part /boot --fstype=ext4 --size=1024 part btrfs.veilor --grow --encrypted --luks-version=luks2 --pbkdf=argon2id --passphrase=__LUKS_PW__ btrfs none --label=veilor btrfs.veilor btrfs / --subvol --name=root LABEL=veilor btrfs /home --subvol --name=home LABEL=veilor # ── ostreecontainer: populate / from the veilor-os OCI image ── # `--transport=registry` pulls from ghcr.io directly. Authentication # token can be supplied via /etc/ostree/auth.json baked into the live # rootfs OR via a kickstart `--remote-token` if the registry is private. # At v0.7 spike the OCI image is public, so no auth needed. # # DO NOT migrate to the new `bootc` kickstart command until v1.0 — it # blocks multi-disk and authenticated registries (per parent-operator # handoff 2026-05-05). ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry # ── %post (chroot) — minimal; OCI image already has everything ── # What we keep: # - chage -d 0 admin so first SDDM login forces password change # - hostname write (anaconda's --hostname doesn't always survive) # - veilor-firstboot.service is enabled in the OCI image already %post set -uo pipefail echo veilor > /etc/hostname chage -d 0 admin || true %end