Some checks failed
Build veilor-os OCI (BlueBuild) / Build + sign + push OCI (push) Failing after 1m10s
Initial scaffold for the v0.7 hybrid path. Spike branch only — does
NOT land in main until success criteria pass (see bluebuild/README.md).
## What this commits
- bluebuild/recipe.yml — BlueBuild recipe extending
ghcr.io/secureblue/securecore-kinoite-hardened-userns:latest with:
* veilor branding overlay (overlay/, assets/, scripts/ at /usr/share/veilor-os)
* sudo restored (revert secureblue's run0-only)
* Xwayland restored (some apps still need it)
* mullvad-browser layered alongside Trivalent (default browser kept)
* tailscale + yggdrasil packages (mesh stack layers 1 + 2)
* tailscaled.service pre-disabled (awaits first-boot prompt)
* yggdrasil.service enabled (idle warm-fallback per STRATEGY.md)
* veilor-firstboot.service + veilor-modules-lock.service enabled
* cosign signing module configured
- bluebuild/config/just/60-veilor.just — ujust recipes:
* install-reticulum (RetiNet AGPL fork — mesh layer 3)
* install-reticulum-rnode (LoRa hardware)
* install-thorium (opt-in browser with explicit CVE-lag warning)
* veilor-mesh-join (token paste / QR for tailscale onboarding)
- bluebuild/README.md — spike doc + smoke-test commands + 5-item
success criteria checklist
- kickstart/install-ostreecontainer.ks — install kickstart template
for the v0.7 path. No %packages block; uses
`ostreecontainer --url=ghcr.io/veilor-org/veilor-os:43 --transport=registry`
to populate / from the OCI image directly during anaconda's install
pass. No first-boot rebase, no transition window. Keeps existing
LUKS+btrfs partitioning verbatim.
- .github/workflows/build-bluebuild.yml — GH Actions workflow:
* Triggered on push to v0.7-bluebuild-spike, weekly cron, dispatch
* Uses blue-build/github-action@v1 (TODO: pin to commit SHA per
CI hardening agent 8 follow-up)
* Builds + cosign-signs (keyless via Sigstore) + pushes to GHCR
* Smoke-tests the OCI image (sudo, mullvad-browser, yggdrasil,
tailscale all present)
* Generates SBOM (SPDX) via anchore/sbom-action
* Publishes SLSA build provenance attestation
## What this does NOT change
- main branch is untouched. v0.5.x kickstart path keeps shipping.
- kickstart/veilor-os.ks (the live-ISO ks) is untouched — the v0.7
hybrid uses the existing live-ISO build path; only the install-time
ks (install-ostreecontainer.ks) is new.
- overlay/, scripts/, assets/ are untouched on this branch — the
recipe pulls them in via `type: files` modules at build time.
## Spike success criteria (reproduced from bluebuild/README.md)
- [ ] `bluebuild build recipe.yml` exits 0
- [ ] `bootc container lint` exits 0 on resulting image
- [ ] `podman run` smoke-test passes
- [ ] CI workflow builds + cosign-signs + pushes to GHCR
- [ ] Installer ISO using `ostreecontainer` against this OCI reaches
SDDM with admin login on first boot
If all 5 land, merge v0.7-bluebuild-spike → main as v0.7.0.
## Reference
- docs/STRATEGY.md (full plan)
- docs/ROADMAP.md v0.7 (schedule)
- docs/THREAT-MODEL.md (publish before v0.7 ship)
- secureblue: https://github.com/secureblue/secureblue
- BlueBuild: https://blue-build.org
- ostreecontainer: https://docs.fedoraproject.org/en-US/bootc/anaconda-install/
80 lines
No EOL
3.3 KiB
Text
80 lines
No EOL
3.3 KiB
Text
# 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 |