From 0c3cf79157b28ca71841d972f0403c4859ee8c46 Mon Sep 17 00:00:00 2001 From: Philip Peterson <1326208+philip-peterson@users.noreply.github.com> Date: Sat, 26 Sep 2026 03:11:10 -0800 Subject: [PATCH] Add patched-Anaconda installer path via bootc-installer Adds installer/Containerfile (a separate Anaconda-webui environment container, distinct from the quine-linux OS image) plus build-installer-image/build-installer-iso tasks that drive bootc-image-builder's bootc-installer type against it. Lets a forked/ patched anaconda-webui (built via COPR) get baked into the install ISO instead of stock Fedora's. Co-Authored-By: Claude Sonnet 5 --- README.md | 5 ++ Taskfile.yml | 38 +++++++++++++ docs/patched-anaconda-installer.md | 87 ++++++++++++++++++++++++++++++ installer/Containerfile | 40 ++++++++++++++ 4 files changed, 170 insertions(+) create mode 100644 docs/patched-anaconda-installer.md create mode 100644 installer/Containerfile diff --git a/README.md b/README.md index 6dc97b2..64c56a7 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,11 @@ list what's available. Notably: - `task build-image` — builds the image locally (`podman build`, as root). - `task build-iso` — builds a bootable install ISO from that image via `bootc-image-builder`, landing in `output/bootiso/install.iso`. +- `task build-installer-iso` — builds an install ISO using a custom + Anaconda installer environment (`installer/Containerfile`) instead of + stock Fedora's, landing in `output/bootc-installer/install.iso`. See + [`docs/patched-anaconda-installer.md`](docs/patched-anaconda-installer.md) + for forking/patching Anaconda itself. - `task test:stage` / `task test:boot` — stage the locally-built image as this machine's next boot target (`bootc switch`), optionally rebooting into it immediately. The fast way to test a change — especially the diff --git a/Taskfile.yml b/Taskfile.yml index af30705..f990475 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -2,6 +2,8 @@ version: '3' vars: IMAGE: quine-linux + INSTALLER_IMAGE: quine-installer + COPR_REPO: philip-peterson/quine-anaconda-webui OUTPUT_DIR: ./output tasks: @@ -40,6 +42,42 @@ tasks: generates: - "{{.OUTPUT_DIR}}/bootiso/install.iso" + build-installer-image: + desc: >- + Build the patched-Anaconda installer-environment container (see + installer/Containerfile and docs/patched-anaconda-installer.md). This + is separate from the quine-linux OS image itself. Defaults to the + {{.COPR_REPO}} COPR project; override with + `task build-installer-image COPR_REPO=you/other-project`. + cmds: + - sudo podman build -t {{.INSTALLER_IMAGE}} --build-arg COPR_REPO={{.COPR_REPO}} -f installer/Containerfile installer/ + sources: + - installer/Containerfile + + build-installer-iso: + desc: >- + Build a bootable install ISO using the patched-Anaconda installer + image to install the quine-linux bootc image, via + bootc-image-builder's `bootc-installer` type. Output lands in + {{.OUTPUT_DIR}}/bootc-installer/install.iso. Uses the same COPR_REPO + default/override as build-installer-image. + deps: [build-image] + cmds: + - task: build-installer-image + vars: { COPR_REPO: "{{.COPR_REPO}}" } + - mkdir -p {{.OUTPUT_DIR}} + - >- + sudo podman run --rm --privileged --pull=newer + --security-opt label=type:unconfined_t + -v {{.OUTPUT_DIR}}:/output + -v /var/lib/containers/storage:/var/lib/containers/storage + quay.io/centos-bootc/bootc-image-builder:latest + --type bootc-installer + --bootc-installer-payload-ref localhost/{{.IMAGE}} + localhost/{{.INSTALLER_IMAGE}} + generates: + - "{{.OUTPUT_DIR}}/bootc-installer/install.iso" + status: desc: Show current bootc deployment status (what's booted, what's staged/rollback). cmds: diff --git a/docs/patched-anaconda-installer.md b/docs/patched-anaconda-installer.md new file mode 100644 index 0000000..8107227 --- /dev/null +++ b/docs/patched-anaconda-installer.md @@ -0,0 +1,87 @@ +# Patched Anaconda installer + +How to get a forked/patched Anaconda into the install ISO, instead of the +stock Fedora one. + +## Why this needs a second container + +`task build-iso` (the existing task) builds the ISO straight from RPMs via +bootc-image-builder's `iso` type -- there's no separate place to inject a +custom Anaconda build. + +bootc-image-builder's `bootc-installer` type is different: it takes **two** +containers -- an "installer environment" container that has Anaconda +installed in it, and (via `--bootc-installer-payload-ref`) the actual OS to +install. The installer environment is just a container you build with a +`Containerfile`, so that's the hook: build your own installer image with +your patched Anaconda `dnf install`ed instead of Fedora's, and point +bootc-image-builder at it. + +`installer/Containerfile` in this repo is that installer environment. It's +unrelated to the quine-linux OS image built by the root `Containerfile` -- +Anaconda only exists in this side container, never in the installed system. + +## Which Anaconda to fork + +Fedora's `anaconda` package resolves to one of two UIs depending on the +image's release-identity package: `anaconda-gui` (old GTK hub-and-spoke) on +server/basic/IoT identities, `anaconda-webui` (Cockpit + React/PatternFly) +everywhere else. All current upstream feature work happens on the WebUI, so +that's the one to fork: + +- https://github.com/rhinstaller/anaconda-webui, forked to + https://github.com/philip-peterson/anaconda-webui + +`installer/Containerfile` depends on `anaconda-webui` explicitly (not just +the bare `anaconda` metapackage) so the UI doesn't depend on incidentally +matching a release-identity package. + +## Workflow + +1. **Fork** `rhinstaller/anaconda-webui` to + `philip-peterson/anaconda-webui` on GitHub, make your panel/control + changes there. +2. **Get it built as an RPM your installer container can `dnf install`.** + Recommended: a Fedora COPR project. + - Create the COPR project `philip-peterson/quine-anaconda-webui` + (https://copr.fedorainfracloud.org/), point it at + `philip-peterson/anaconda-webui` (branch or a webhook), let COPR build + it against the Fedora release Aurora currently tracks. + - That name is already wired in as the `COPR_REPO` default in + `Taskfile.yml` and `installer/Containerfile`. Using a different COPR + project name means overriding `COPR_REPO=` on the `task` invocations + below instead. + - This publishes your fork's source and build logs on COPR's + infrastructure (marking a project "unlisted" hides it from browsing, + not from direct access) -- worth knowing before you push anything you + wouldn't want visible outside this machine. +3. **Build the installer image and ISO:** + ```sh + task build-installer-iso + ``` + This builds the quine-linux OS image (if needed), builds + `installer/Containerfile` with the `philip-peterson/quine-anaconda-webui` + COPR repo enabled, and produces `output/bootc-installer/install.iso`. +4. **Iterate:** push a change to your fork, wait for COPR to rebuild, rerun + `task build-installer-iso` -- podman/task will rebuild the installer + layer to pick up the new RPM. + +## Local alternative (no COPR) + +If you'd rather not publish the fork anywhere: build the RPM locally with +`mock` targeting the same Fedora release/arch as the installer base, +`createrepo_c` the output into a directory, and either bind-mount that +directory into `installer/Containerfile`'s build context and add it as a +`file://` repo, or drop the built RPMs into a `dnf localinstall` step. This +avoids any external service but means keeping the mock chroot's Fedora +release in sync with the installer base by hand. + +## Caveats + +- `anaconda-webui`'s package/dependency structure moves with each Fedora + release; if `dnf install anaconda-webui` starts failing, check what + `anaconda.spec.in` in your fork currently requires. +- The installer environment's Fedora release should stay close to whatever + release the actual `quine-linux` image (and thus the ISO's kernel/dracut) + is built against, to avoid mismatches between the boot environment and the + installed system. diff --git a/installer/Containerfile b/installer/Containerfile new file mode 100644 index 0000000..ef8ba7a --- /dev/null +++ b/installer/Containerfile @@ -0,0 +1,40 @@ +# Installer-environment container for bootc-image-builder's `bootc-installer` +# image type. This is NOT the quine-linux OS -- it's the throwaway Anaconda +# environment the ISO boots into, which then installs the real quine-linux +# bootc image (passed separately via --bootc-installer-payload-ref). See +# docs/patched-anaconda-installer.md for the full workflow this fits into. + +FROM quay.io/fedora/fedora-bootc:rawhide + +# Set to your COPR project (e.g. "yourname/quine-anaconda") holding a build +# of your patched anaconda-webui fork. Override at build time with +# --build-arg COPR_REPO=... instead of editing this file. +ARG COPR_REPO + +RUN set -eux; \ + dnf install -y dnf-plugins-core; \ + if [ -n "${COPR_REPO}" ]; then \ + dnf copr enable -y "${COPR_REPO}"; \ + fi; \ + dnf install -y \ + anaconda-webui \ + anaconda \ + anaconda-install-env-deps \ + anaconda-dracut \ + dracut-config-generic \ + dracut-network \ + net-tools \ + squashfs-tools \ + grub2-efi-x64-cdboot \ + python3-mako \ + lorax-templates-generic \ + biosdevname \ + prefixdevname; \ + dnf clean all + +# Fedora 43+ path fixup -- image-builder expects the EFI directory under +# /boot/efi, not wherever the fedora-bootc base puts it. +RUN mkdir -p /boot/efi && cp -ra /usr/lib/efi/*/*/EFI /boot/efi + +# lorax wants to symlink /mnt -> /var/mnt, which doesn't exist on this base. +RUN mkdir -p /var/mnt