Build Aurora from source as stage 0
stage-0/ is a submodule holding our fork of Aurora (upstream for now),
built with Aurora's own `just build` by the new `task build-base` into
localhost/aurora:stable. The Containerfile (stage 1) now builds FROM
${BASE_IMAGE}, which defaults to that image, instead of a pinned upstream
digest; the pin is now the submodule commit. build-image builds stage 0
first when needed, and BASE_IMAGE=ghcr.io/ublue-os/aurora:stable skips it
(the only option on macOS).
CI checks out submodules, fetches just, yq and cosign, and gets a longer
timeout for the Aurora build.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
8ad5e45dc2
commit
a3316eb2a4
6 changed files with 106 additions and 16 deletions
|
|
@ -6,7 +6,9 @@ name: Installer ISO
|
||||||
#
|
#
|
||||||
# Runs on a runner labelled `iso-builder`: bootc-image-builder needs an
|
# Runs on a runner labelled `iso-builder`: bootc-image-builder needs an
|
||||||
# x86_64 host with root podman (the job runs as root, or with sudo) and
|
# x86_64 host with root podman (the job runs as root, or with sudo) and
|
||||||
# ~30 GB of free disk.
|
# ~30 GB of free disk. Stage 0 (the stage-0/ Aurora fork) also needs
|
||||||
|
# buildah, cpp, skopeo and jq from the runner's distro; just, yq and cosign
|
||||||
|
# are fetched below.
|
||||||
#
|
#
|
||||||
# Secrets: MINIO_ACCESS_KEY, MINIO_SECRET_KEY.
|
# Secrets: MINIO_ACCESS_KEY, MINIO_SECRET_KEY.
|
||||||
# Variables (optional): MINIO_ENDPOINT (default https://s3.quineglobal.com),
|
# Variables (optional): MINIO_ENDPOINT (default https://s3.quineglobal.com),
|
||||||
|
|
@ -28,14 +30,20 @@ env:
|
||||||
jobs:
|
jobs:
|
||||||
iso:
|
iso:
|
||||||
runs-on: iso-builder
|
runs-on: iso-builder
|
||||||
timeout-minutes: 180
|
timeout-minutes: 300
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: true
|
||||||
|
|
||||||
- name: Install task and mc
|
- name: Install task, mc, just, yq and cosign
|
||||||
run: |
|
run: |
|
||||||
mkdir -p "$HOME/.local/bin"
|
mkdir -p "$HOME/.local/bin"
|
||||||
curl -fsSL https://taskfile.dev/install.sh | sh -s -- -d -b "$HOME/.local/bin"
|
curl -fsSL https://taskfile.dev/install.sh | sh -s -- -d -b "$HOME/.local/bin"
|
||||||
|
curl -fsSL https://just.systems/install.sh | bash -s -- --to "$HOME/.local/bin"
|
||||||
|
curl -fsSL -o "$HOME/.local/bin/yq" https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64
|
||||||
|
curl -fsSL -o "$HOME/.local/bin/cosign" https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64
|
||||||
|
chmod +x "$HOME/.local/bin/yq" "$HOME/.local/bin/cosign"
|
||||||
curl -fsSL -o "$HOME/.local/bin/mc" https://dl.min.io/client/mc/release/linux-amd64/mc
|
curl -fsSL -o "$HOME/.local/bin/mc" https://dl.min.io/client/mc/release/linux-amd64/mc
|
||||||
chmod +x "$HOME/.local/bin/mc"
|
chmod +x "$HOME/.local/bin/mc"
|
||||||
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
|
||||||
|
|
|
||||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
[submodule "stage-0"]
|
||||||
|
path = stage-0
|
||||||
|
url = https://github.com/ublue-os/aurora
|
||||||
|
|
@ -1,12 +1,17 @@
|
||||||
ARG BASE_DIGEST=sha256:fbcef6075541eec7c2ca4a91c87c7012455cfba4e5e748d0cf2013d6aa3e66d3
|
# Stage 1 of the build. BASE_IMAGE is stage 0: our Aurora fork, built from the
|
||||||
|
# stage-0/ submodule by `task build-base` into root's containers-storage. Its
|
||||||
|
# pin is the submodule commit. Pass e.g.
|
||||||
|
# --build-arg BASE_IMAGE=ghcr.io/ublue-os/aurora:stable to build on stock
|
||||||
|
# upstream Aurora instead.
|
||||||
|
ARG BASE_IMAGE=localhost/aurora:stable
|
||||||
|
|
||||||
# --- Builds the out-of-tree snd-hda-codec-cs8409 module (iMac19,2 mic fix). ---
|
# --- Builds the out-of-tree snd-hda-codec-cs8409 module (iMac19,2 mic fix). ---
|
||||||
# See docs/imac19-2-mic-fix.md and patches/snd-hda-codec-cs8409/ for the full
|
# See docs/imac19-2-mic-fix.md and patches/snd-hda-codec-cs8409/ for the full
|
||||||
# story. Kept as its own stage so the build toolchain never lands in the
|
# story. Kept as its own stage so the build toolchain never lands in the
|
||||||
# final image, and pinned to the same BASE_DIGEST as the final stage so the
|
# final image, and built FROM the same BASE_IMAGE as the final stage so the
|
||||||
# kernel-devel headers installed here can never drift out of sync with the
|
# kernel-devel headers installed here can never drift out of sync with the
|
||||||
# kernel that actually ships below.
|
# kernel that actually ships below.
|
||||||
FROM ghcr.io/ublue-os/aurora@${BASE_DIGEST} AS kmod-builder
|
FROM ${BASE_IMAGE} AS kmod-builder
|
||||||
|
|
||||||
RUN set -eux; \
|
RUN set -eux; \
|
||||||
NVR="$(rpm -q kernel-core --qf '%{VERSION}-%{RELEASE}.%{ARCH}')"; \
|
NVR="$(rpm -q kernel-core --qf '%{VERSION}-%{RELEASE}.%{ARCH}')"; \
|
||||||
|
|
@ -31,7 +36,7 @@ RUN set -eux; \
|
||||||
cp snd-hda-codec-cs8409.ko /output/
|
cp snd-hda-codec-cs8409.ko /output/
|
||||||
|
|
||||||
# --- Final image. ---
|
# --- Final image. ---
|
||||||
FROM ghcr.io/ublue-os/aurora@${BASE_DIGEST} AS final
|
FROM ${BASE_IMAGE} AS final
|
||||||
|
|
||||||
COPY overlay/ /
|
COPY overlay/ /
|
||||||
|
|
||||||
|
|
|
||||||
32
README.md
32
README.md
|
|
@ -4,16 +4,35 @@ Quine distro of Linux based on uBlue Aurora
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
|
|
||||||
`Containerfile` builds a custom bootc image on top of `ghcr.io/ublue-os/aurora:stable`,
|
The image is built in two stages:
|
||||||
layering in everything under `overlay/`, plus a `kmod-builder` stage that
|
|
||||||
compiles the CS8409 mic-fix kernel module (see
|
- **Stage 0: `stage-0/`**, a git submodule holding our fork of
|
||||||
[Hardware-specific patches](#hardware-specific-patches) below).
|
[Aurora](https://github.com/ublue-os/aurora). It's built with Aurora's own
|
||||||
|
`just build` into `localhost/aurora:stable`. Changes that have to happen
|
||||||
|
*inside* Aurora's build (its package set, build scripts, the Kinoite base
|
||||||
|
it starts from) go here, as commits on the fork; bump the submodule to ship
|
||||||
|
them. Needs a Linux host with buildah, cpp, just (>= 1.46), skopeo, jq, yq
|
||||||
|
and cosign.
|
||||||
|
- **Stage 1: `Containerfile`**, which builds the quine-linux bootc image on
|
||||||
|
top of stage 0, layering in everything under `overlay/`, plus a
|
||||||
|
`kmod-builder` stage that compiles the CS8409 mic-fix kernel module (see
|
||||||
|
[Hardware-specific patches](#hardware-specific-patches) below). Anything a
|
||||||
|
`RUN` step on top of Aurora can do belongs here, not in stage 0.
|
||||||
|
|
||||||
|
Clone with `git clone --recurse-submodules`, or run
|
||||||
|
`git submodule update --init` in an existing checkout.
|
||||||
|
|
||||||
[`Taskfile.yml`](Taskfile.yml) (requires [`task`](https://taskfile.dev)) is
|
[`Taskfile.yml`](Taskfile.yml) (requires [`task`](https://taskfile.dev)) is
|
||||||
the supported way to drive all of this — run `task` with no arguments to
|
the supported way to drive all of this — run `task` with no arguments to
|
||||||
list what's available. Notably:
|
list what's available. Notably:
|
||||||
|
|
||||||
- `task build-image` — builds the image locally, as root, with podman, or
|
- `task build-base` — builds stage 0. It's skipped when `stage-0/` is
|
||||||
|
unchanged and the image exists. Run `task build-base --force` to rebuild
|
||||||
|
anyway, e.g. to pick up upstream kernel and package updates, which Aurora's
|
||||||
|
build resolves at build time.
|
||||||
|
- `task build-image` — builds stage 0 if needed, then stage 1. To skip stage 0
|
||||||
|
and build on stock upstream Aurora (the only option on macOS), pass
|
||||||
|
`BASE_IMAGE=ghcr.io/ublue-os/aurora:stable`. Builds locally, as root, with podman, or
|
||||||
docker if podman isn't installed (force either with
|
docker if podman isn't installed (force either with
|
||||||
`CONTAINER_RUNTIME=docker|podman`). Every task below works with either;
|
`CONTAINER_RUNTIME=docker|podman`). Every task below works with either;
|
||||||
under docker, images are copied via skopeo into a
|
under docker, images are copied via skopeo into a
|
||||||
|
|
@ -37,7 +56,8 @@ list what's available. Notably:
|
||||||
Equivalently, by hand:
|
Equivalently, by hand:
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
podman build -t quine-linux -f Containerfile .
|
(cd stage-0 && sudo just build --image aurora --tag stable --flavor main)
|
||||||
|
sudo podman build -t quine-linux -f Containerfile .
|
||||||
```
|
```
|
||||||
|
|
||||||
An ISO can then be generated from the built image with `bootc-image-builder`
|
An ISO can then be generated from the built image with `bootc-image-builder`
|
||||||
|
|
|
||||||
59
Taskfile.yml
59
Taskfile.yml
|
|
@ -3,6 +3,16 @@ version: '3'
|
||||||
vars:
|
vars:
|
||||||
IMAGE: quine-linux
|
IMAGE: quine-linux
|
||||||
INSTALLER_IMAGE: quine-installer
|
INSTALLER_IMAGE: quine-installer
|
||||||
|
# Stage 0: our Aurora fork (the stage-0/ submodule), built with its own
|
||||||
|
# Justfile. AURORA_TAG picks the stream (stable/latest/testing) and is also
|
||||||
|
# the local tag the image gets.
|
||||||
|
AURORA_TAG: stable
|
||||||
|
STAGE0_IMAGE: localhost/aurora:{{.AURORA_TAG}}
|
||||||
|
# What stage 1 (Containerfile) builds FROM. Defaults to stage 0; override to
|
||||||
|
# skip stage 0 and build on a prebuilt image, e.g.
|
||||||
|
# `task build-image BASE_IMAGE=ghcr.io/ublue-os/aurora:stable` (the only
|
||||||
|
# option on macOS, where stage 0's buildah build can't run).
|
||||||
|
BASE_IMAGE: '{{.STAGE0_IMAGE}}'
|
||||||
OUTPUT_DIR: '{{.ROOT_DIR}}/output'
|
OUTPUT_DIR: '{{.ROOT_DIR}}/output'
|
||||||
# Root is needed for the container builds and bootc; skip {{.SUDO}} when already
|
# Root is needed for the container builds and bootc; skip {{.SUDO}} when already
|
||||||
# root (e.g. on a CI runner, which may not have {{.SUDO}} at all).
|
# root (e.g. on a CI runner, which may not have {{.SUDO}} at all).
|
||||||
|
|
@ -34,17 +44,60 @@ tasks:
|
||||||
- task --list
|
- task --list
|
||||||
silent: true
|
silent: true
|
||||||
|
|
||||||
|
build-base:
|
||||||
|
desc: >-
|
||||||
|
Stage 0: build our Aurora fork from the stage-0/ submodule with its own
|
||||||
|
`just build`, as root, into {{.STAGE0_IMAGE}}. Needs a Linux host with
|
||||||
|
buildah, cpp, just (>= 1.46), skopeo, jq, yq and cosign. Skipped when
|
||||||
|
stage-0/ is unchanged and the image exists; use --force to rebuild
|
||||||
|
anyway (e.g. to pick up upstream kernel and package updates, which
|
||||||
|
Aurora's build resolves at build time).
|
||||||
|
preconditions:
|
||||||
|
- sh: '[ "$(uname -s)" = Linux ]'
|
||||||
|
msg: >-
|
||||||
|
Stage 0 (Aurora's own buildah build) only runs on Linux. To build
|
||||||
|
on stock upstream Aurora instead, pass
|
||||||
|
BASE_IMAGE=ghcr.io/ublue-os/aurora:{{.AURORA_TAG}}.
|
||||||
|
- sh: 'for t in buildah cpp just skopeo jq yq cosign; do command -v "$t" >/dev/null || { echo "missing: $t"; exit 1; }; done'
|
||||||
|
msg: 'Stage 0 needs buildah, cpp, just (>= 1.46), skopeo, jq, yq and cosign on PATH.'
|
||||||
|
dir: stage-0
|
||||||
|
cmds:
|
||||||
|
# sudo resets PATH (just/yq/cosign often live in ~/.local/bin or brew),
|
||||||
|
# and git refuses to read a repo owned by another user unless told it's
|
||||||
|
# safe; Aurora's Justfile runs `git status` / `git rev-parse` here.
|
||||||
|
- >-
|
||||||
|
{{.SUDO}} env "PATH=$PATH"
|
||||||
|
GIT_CONFIG_COUNT=1 GIT_CONFIG_KEY_0=safe.directory GIT_CONFIG_VALUE_0='*'
|
||||||
|
${GITHUB_TOKEN:+"GITHUB_TOKEN=$GITHUB_TOKEN"}
|
||||||
|
just build --image aurora --tag {{.AURORA_TAG}} --flavor main
|
||||||
|
# buildah builds into root's containers-storage; docker needs it copied
|
||||||
|
# into its daemon for stage 1 to build FROM it.
|
||||||
|
- cmd: '{{.SUDO}} skopeo copy containers-storage:{{.STAGE0_IMAGE}} docker-daemon:{{.STAGE0_IMAGE}}'
|
||||||
|
if: '[ "{{.CONTAINER_RUNTIME}}" != podman ]'
|
||||||
|
# Relative to dir (stage-0/): the fork's whole checked-out tree.
|
||||||
|
sources:
|
||||||
|
- '**/*'
|
||||||
|
status:
|
||||||
|
- '{{.SUDO}} {{.CONTAINER_RUNTIME}} image inspect {{.STAGE0_IMAGE}} >/dev/null 2>&1'
|
||||||
|
|
||||||
build-image:
|
build-image:
|
||||||
desc: >-
|
desc: >-
|
||||||
Build the quine-linux bootc container image, as root (under podman
|
Stage 1: build the quine-linux bootc container image on top of
|
||||||
this lands in root's containers-storage, which bootc and
|
BASE_IMAGE (stage 0 by default, built first if needed), as root
|
||||||
|
(under podman this lands in root's containers-storage, which bootc and
|
||||||
bootc-image-builder read; under docker, the ISO tasks copy it over).
|
bootc-image-builder read; under docker, the ISO tasks copy it over).
|
||||||
cmds:
|
cmds:
|
||||||
- '{{.SUDO}} {{.CONTAINER_RUNTIME}} build --platform {{.PLATFORM}} -t {{.IMAGE}} -f Containerfile .'
|
- task: build-base
|
||||||
|
if: '[ "{{.BASE_IMAGE}}" = "{{.STAGE0_IMAGE}}" ]'
|
||||||
|
- >-
|
||||||
|
{{.SUDO}} {{.CONTAINER_RUNTIME}} build --platform {{.PLATFORM}}
|
||||||
|
--build-arg BASE_IMAGE={{.BASE_IMAGE}}
|
||||||
|
-t {{.IMAGE}} -f Containerfile .
|
||||||
sources:
|
sources:
|
||||||
- Containerfile
|
- Containerfile
|
||||||
- overlay/**/*
|
- overlay/**/*
|
||||||
- patches/**/*
|
- patches/**/*
|
||||||
|
- stage-0/**/*
|
||||||
|
|
||||||
build-iso:
|
build-iso:
|
||||||
desc: >-
|
desc: >-
|
||||||
|
|
|
||||||
1
stage-0
Submodule
1
stage-0
Submodule
|
|
@ -0,0 +1 @@
|
||||||
|
Subproject commit 6f5aa60aa5584f847a58953c96b047a8fc2d26c4
|
||||||
Loading…
Reference in a new issue