Fetch appliance layers from the mirror instead of building them #3

Merged
marcos-mendez merged 1 commit from ci/appliance-from-mirror into main 2026-09-26 15:34:17 -03:00
marcos-mendez commented 2026-09-26 15:33:52 -03:00 (Migrated from github.com)

The self-hosted runner keel-lxc-1 runs on the public services VM, which has
lxc, kcov, bats, zstd and python3-yaml but no fab, deck, buildtasks or
/turnkey trees. bt-layer cannot run there, so the previous
test-appliance.yml would have failed on its first step for every caller. The
build host builds and publishes layers; this runner consumes them over IPv6
from https://mirror.keellinux.org/layers.

What the job does now, in order: check out the appliance repository, check out
keel-linux/keel at main and put a wrapper on PATH, probe the mirror for
<appliance>.manifest, check the published parent against the caller's
input, keel pull into a scratch cache, keel verify, then assemble, boot and
run the repository's tests/boot-test.sh as root through
/usr/local/sbin/keel-ci-boot-test, and finally destroy the container and the
scratch tree in a step that runs after a failure too.

Choices worth reviewing:

  • keel from a checkout, not a package. Decision 0005 is open, nothing is
    signed and archive.keellinux.org serves only a README, so there is no keel
    package to install. The checkout needs python3 and PyYAML, both already on
    the runner, and the resolved commit is printed in the job summary.
  • parent kept and now used. keel pull follows the manifest chain
    itself, so the input is not needed to fetch anything. It is checked against
    the parent the published manifest records, which catches a mirror serving a
    layer built on something other than what the repository declares.
  • Skip, not fail, when the layer is unpublished. A missing manifest gives a
    notice and an "Appliance test skipped" section in the job summary, and the
    job succeeds, so a repository can carry the gate before its first layer
    exists.
  • keel verify exit codes. 0, 8 (hash file present, not signed) and 9
    (packages half not implemented) pass; 6 and 7 fail.
  • Privileges. Assembling a rootfs and starting a container need root. The
    runner user has no blanket sudo: it may run two root-owned entry points,
    keel-ci-boot-test and keel-ci-cleanup, each of which checks that it is
    acting on a CI workspace and a CI scratch directory.

Test plan:

  • The whole sequence was run by hand on keel-lxc-1 as the runner user
    against core: pull 2.7 s, assemble 13 s, boot and first boot 10 s,
    keel diff clean, 23 s in total.
  • One real appliance / build-and-boot run in keel-core.
  • One real appliance / build-and-boot run in keel-nodebb.
The self-hosted runner `keel-lxc-1` runs on the public services VM, which has lxc, kcov, bats, zstd and python3-yaml but no fab, deck, buildtasks or `/turnkey` trees. `bt-layer` cannot run there, so the previous `test-appliance.yml` would have failed on its first step for every caller. The build host builds and publishes layers; this runner consumes them over IPv6 from `https://mirror.keellinux.org/layers`. What the job does now, in order: check out the appliance repository, check out `keel-linux/keel` at `main` and put a wrapper on `PATH`, probe the mirror for `<appliance>.manifest`, check the published `parent` against the caller's input, `keel pull` into a scratch cache, `keel verify`, then assemble, boot and run the repository's `tests/boot-test.sh` as root through `/usr/local/sbin/keel-ci-boot-test`, and finally destroy the container and the scratch tree in a step that runs after a failure too. Choices worth reviewing: - **keel from a checkout, not a package.** Decision 0005 is open, nothing is signed and `archive.keellinux.org` serves only a README, so there is no keel package to install. The checkout needs python3 and PyYAML, both already on the runner, and the resolved commit is printed in the job summary. - **`parent` kept and now used.** `keel pull` follows the manifest chain itself, so the input is not needed to fetch anything. It is checked against the `parent` the published manifest records, which catches a mirror serving a layer built on something other than what the repository declares. - **Skip, not fail, when the layer is unpublished.** A missing manifest gives a notice and an "Appliance test skipped" section in the job summary, and the job succeeds, so a repository can carry the gate before its first layer exists. - **`keel verify` exit codes.** 0, 8 (hash file present, not signed) and 9 (packages half not implemented) pass; 6 and 7 fail. - **Privileges.** Assembling a rootfs and starting a container need root. The runner user has no blanket sudo: it may run two root-owned entry points, `keel-ci-boot-test` and `keel-ci-cleanup`, each of which checks that it is acting on a CI workspace and a CI scratch directory. Test plan: - [x] The whole sequence was run by hand on `keel-lxc-1` as the `runner` user against `core`: pull 2.7 s, assemble 13 s, boot and first boot 10 s, `keel diff` clean, 23 s in total. - [ ] One real `appliance / build-and-boot` run in keel-core. - [ ] One real `appliance / build-and-boot` run in keel-nodebb.
Sign in to join this conversation.
No description provided.