Files
bc250-console/BUILD-CONSOLE.md
T
ckochandClaude Fable 5 20cad3e12b Add ISO user config: unattended install needs baked accounts
VM smoke test of the first ISO reached GDM but no user existed
(bootc-image-builder ISOs install unattended; gnome-initial-setup is
not in the bazzite base). iso-config.toml creates parent (wheel) and
kid with placeholder passwords to change on first login.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 19:48:22 -04:00

135 lines
5.6 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# BC-250 Console — local build → ISO
Custom recipe: `recipes/bc250-console-gnome.yml` (Bazzite GNOME + cyan-skillfish
governor + SSH/RDP remote admin + BC-250 ttm kargs). Build path is **local**
(no CI, no registry push, no cosign needed).
Two working paths: **podman** (BlueBuild's native path, use on a Fedora box)
or **docker** (what was actually used for the first successful build,
2026-07-06, on Ubuntu 24.04 with a native dockerd). The docker path needs a
few workarounds, all captured below.
## Path A: podman (Fedora/bootc box)
```bash
bluebuild build ./recipes/bc250-console-gnome.yml
mkdir -p output
sudo podman run --rm -it --privileged \
--security-opt label=type:unconfined_t \
-v ./output:/output \
-v ./iso-config.toml:/config.toml:ro \
-v /var/lib/containers/storage:/var/lib/containers/storage \
quay.io/centos-bootc/bootc-image-builder:latest \
--type iso --rootfs btrfs \
localhost/bc250-console-gnome:latest
```
Note: mount the image's GPG keys as in Path A step 4 if depsolve fails on
`terra-mesa` (see below) — the same failure mode applies under podman.
## Path B: docker (verified working)
**Use a native dockerd, not Docker Desktop.** Under Docker Desktop's VM,
podman-in-docker cannot exec anything ("Invalid argument") and bind mounts
outside the file-sharing allowlist are denied. A stock `docker-ce` daemon on
the host kernel works. (Plain `docker` may point at the Desktop context —
force the native daemon with `docker -H unix:///var/run/docker.sock` or
`docker context use default`.)
```bash
# 1. Generate the Containerfile from the recipe (note: 'bluebuild' must be
# given explicitly — the image entrypoint is dumb-init)
docker run --rm -v "$PWD":/bluebuild -w /bluebuild \
ghcr.io/blue-build/cli:latest \
bluebuild generate -o Containerfile ./recipes/bc250-console-gnome.yml
# 2. Build the image
docker buildx build -f Containerfile -t localhost/bc250-console-gnome:latest .
# 3. bootc-image-builder reads podman containers-storage, not the docker
# store — copy the image over with skopeo via a throwaway local registry:
docker network create bibnet
docker run -d --name registry --network bibnet -p 127.0.0.1:5000:5000 registry:2
docker tag localhost/bc250-console-gnome:latest localhost:5000/bc250-console-gnome:latest
docker push localhost:5000/bc250-console-gnome:latest
docker volume create bib-storage
docker run --rm --privileged --network host \
-v bib-storage:/var/lib/containers/storage \
quay.io/skopeo/stable:latest \
copy --src-tls-verify=false \
docker://127.0.0.1:5000/bc250-console-gnome:latest \
containers-storage:localhost/bc250-console-gnome:latest
# 4. Bazzite's terra repos reference GPG keys by file:// path; the depsolve
# runs inside the bib container, so those keys must be mounted in:
cid=$(docker create localhost/bc250-console-gnome:latest true)
docker cp "$cid":/etc/pki/rpm-gpg ./rpm-gpg-keys
docker rm "$cid"
# 5. Build the ISO (--rootfs required: the image sets no root-fs-type;
# iso-config.toml REQUIRED — the ISO installs unattended and the image has
# no first-boot account wizard, so without baked users the install is
# unloginable)
mkdir -p iso-output
docker run --rm --privileged --security-opt label=type:unconfined_t \
-v "$PWD"/iso-output:/output \
-v "$PWD"/rpm-gpg-keys:/etc/pki/rpm-gpg:ro \
-v "$PWD"/iso-config.toml:/config.toml:ro \
-v bib-storage:/var/lib/containers/storage \
quay.io/centos-bootc/bootc-image-builder:latest \
--type iso --rootfs btrfs \
localhost/bc250-console-gnome:latest
```
**Heads-up: the ISO wipes and auto-installs to the first disk with no
prompts.** Accounts come from `iso-config.toml` (placeholder passwords —
change on first login: `passwd`, and `sudo passwd kid`).
ISO lands at `iso-output/bootiso/install.iso` (~5 GB), owned by root — fix
with `docker run --rm -v "$PWD"/iso-output:/o alpine chown -R 1000:1000 /o`.
### Kernel sanity check (before flashing)
Avoid kernels 6.15.06.15.6 and 6.17.86.17.10; prefer 6.18.x LTS / 6.17.11+.
```bash
docker run --rm localhost/bc250-console-gnome:latest rpm -q kernel
```
First successful build shipped `kernel-7.0.9-ogc3.2.fc44` — fine.
## Smoke test + install
1. **VM test**: boot the ISO in a VM (KVM works headless:
`qemu-system-x86_64 -enable-kvm -m 8192 -drive file=vm.qcow2,if=virtio -cdrom <iso> -boot once=d`).
The embedded kickstart installs unattended. Validates composition and the
installer only — not the BC-250 GPU/governor/Mesa path.
2. Flash to USB (Fedora Media Writer / Impression / `dd`), install on the
board. Black screen at install → "Install in Basic Graphics Mode".
3. First boot, in the child's desktop session: run `bc250-remote-setup`,
log into Steam, set Steam Family View, `sudo tailscale up` if using it.
## On-hardware validation (board, not VM)
```bash
vulkaninfo | grep deviceName # RADV GFX1013, NOT llvmpipe
systemctl status cyan-skillfish-governor-smu # active
cat /sys/class/drm/card0/device/pp_dpm_sclk # scaling present (may be card1)
sensors # sane temps; watch backplate airflow
cat /proc/cmdline | tr ' ' '\n' | grep ttm # ttm.pages_limit / page_pool_size
```
Then a real game for 30+ minutes for thermal/power stability.
## Not baked into the image (per-board/per-user)
Modded BIOS + BIOS settings (512 MB dynamic VRAM, IOMMU off, auto power-on),
RDP password/TLS cert, Steam login, Tailscale auth.
## Security
- SSH/RDP LAN- or tailnet-only. Never port-forward 22/3389.
- If this ever moves to a registry (Gitea) for OTA updates: generate your own
cosign keypair, re-add the `signing` module, and never reuse upstream's key.