Cache the expensive half of the build so iteration is cheap
The dnf transaction is essentially the whole cost of a build — emulated rpm scriptlets for 502 packages on minimal, 1929 on workstation. Everything after it is minutes. Getting this laptop to boot will take several attempts at the kernel command line and the dracut driver list, and paying for a reinstall each time is not tenable. Stage the post-dnf tree under <work>/base, keyed on a hash of the package lists, release and variant, and copy it per build with --reflink=auto (a CoW clone on btrfs). Config and overlay edits now reuse it; package list edits invalidate it on their own, so --fresh is only needed to force the issue. Keep downloaded rpms in a cachedir outside the install root, so even --fresh re-runs the scriptlets without re-downloading. keepcache=0 was exactly the wrong setting for a build meant to be run repeatedly. Add --work so CI can put both outside the job workspace, which is wiped between runs, and default the build container to the gongfoo aarch64 build base so the assembly tooling is not installed under emulation every time. That image is a speedup, not a dependency: fall back to stock Fedora when it is unreachable. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01XWRjNJMistCy6ngXH5aJLS
This commit is contained in:
33
README.md
33
README.md
@@ -65,6 +65,39 @@ filesystems from directory trees with `mke2fs -d` and `mcopy` rather than
|
||||
mounting loop devices, so it does not need `/dev/loop-control` — which CI
|
||||
runners generally will not hand out.
|
||||
|
||||
### Iterating
|
||||
|
||||
Every aarch64 binary runs under emulation, and the `dnf` transaction is
|
||||
essentially all of the cost — 500-odd packages' worth of rpm scriptlets for
|
||||
`minimal`, four times that for `workstation`. Everything after it takes
|
||||
minutes. Since getting this machine to boot will take a few attempts, the build
|
||||
is arranged so you only pay that once:
|
||||
|
||||
- The post-`dnf` root filesystem is staged under `<work>/base`, keyed on a hash
|
||||
of the package lists, release and variant. Editing `config/device.env`,
|
||||
`overlay/`, or the bootloader config reuses it. Editing `config/packages/`
|
||||
invalidates it automatically.
|
||||
- The working copy is made with `cp --reflink=auto`, so on btrfs or xfs it is
|
||||
a copy-on-write clone rather than a real copy.
|
||||
- Downloaded rpms live in `.cache/dnf`, outside the staged tree, so even
|
||||
`--fresh` re-runs the scriptlets without re-downloading.
|
||||
|
||||
In practice a kernel-command-line change rebuilds in a few minutes.
|
||||
|
||||
```sh
|
||||
./build/build-image.sh --variant minimal # reuses the staged base
|
||||
./build/build-image.sh --variant minimal --fresh # forces a reinstall
|
||||
./build/build-image.sh --variant minimal --keep-rootfs # keep the tree to poke at
|
||||
```
|
||||
|
||||
CI points `--work` and `--cache` at `/var/tmp/c630-build` so both survive
|
||||
between jobs. That is per-runner, so the first build on a given runner is cold.
|
||||
|
||||
The build container defaults to `git.lair.cafe/gongfoo/build-fedora-44-aarch64`,
|
||||
which ships the assembly tooling so it does not have to be installed under
|
||||
emulation on every run. If that image is not reachable the build falls back to
|
||||
stock Fedora and installs the tooling itself — slower, but it works.
|
||||
|
||||
## Repository layout
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user