| 1 |
# The image under test. Not Alloy: a minimal bootc image carrying one |
| 2 |
# stand-in component, so a run costs a 200 MB build rather than a 5 GB one. |
| 3 |
# What is being measured is rpm-ostree and bootc behaviour, which does not |
| 4 |
# depend on what else the image holds. |
| 5 |
# |
| 6 |
# SHAPE is the whole point. The three values are the three ways a first-party |
| 7 |
# component can reach an image, and they behave differently enough that the |
| 8 |
# answer to "can we hotfix this" changes with them: |
| 9 |
# |
| 10 |
# rpm the component is an RPM installed at build time, so it is a base |
| 11 |
# package. This is what an RPM channel would want. |
| 12 |
# loose the component is a file copied into /usr/bin owned by no package. |
| 13 |
# What Alloy did until 2026-08-14, and what this measurement ended. |
| 14 |
# none the image does not carry the component at all, so a hotfix is a |
| 15 |
# plain layered package rather than a replacement. |
| 16 |
# carry the image carries the component's RPM as a FILE, in a file:// repo |
| 17 |
# under /usr/share, and does not install it. The component is still |
| 18 |
# absent from @System, so it is layered exactly as in `none`, but the |
| 19 |
# package it layers from travels with the image and needs no network. |
| 20 |
# This is the shape Alloy takes: it makes an offline install work, and |
| 21 |
# because @System never holds the component there is no version of it |
| 22 |
# for a layer to conflict with, which is the wedge that `rpm` and the |
| 23 |
# n4 case run into. |
| 24 |
# |
| 25 |
# The build context is state/, which holds the RPMs and the ssh key that |
| 26 |
# build.sh puts there. Nothing in the context is tracked. |
| 27 |
FROM quay.io/fedora/fedora-bootc:43 |
| 28 |
|
| 29 |
ARG SHAPE=none |
| 30 |
ARG DEMO_VERSION=0.0.1 |
| 31 |
ARG BASE_MARK=n1 |
| 32 |
|
| 33 |
COPY alloy-demo.repo /etc/yum.repos.d/alloy-demo.repo |
| 34 |
COPY registries.conf /etc/containers/registries.conf.d/010-alloy-demo.conf |
| 35 |
|
| 36 |
COPY rpms /tmp/rpms |
| 37 |
# Per-version repos, each holding one RPM and its metadata. `carry` takes the |
| 38 |
# one matching DEMO_VERSION, so moving the base from one carry variant to |
| 39 |
# another is what "the image shipped a newer component" looks like. |
| 40 |
COPY repos /tmp/repos |
| 41 |
RUN case "$SHAPE" in \ |
| 42 |
rpm) \ |
| 43 |
dnf -y install "/tmp/rpms/alloy-demo-${DEMO_VERSION}-1.fc43.x86_64.rpm" ;; \ |
| 44 |
loose) \ |
| 45 |
printf '#!/bin/sh\necho "alloy-demo %s"\n' "$DEMO_VERSION" > /usr/bin/alloy-demo \ |
| 46 |
&& chmod 0755 /usr/bin/alloy-demo ;; \ |
| 47 |
carry) \ |
| 48 |
mkdir -p /usr/share/alloy-demo \ |
| 49 |
&& cp -r "/tmp/repos/$DEMO_VERSION" /usr/share/alloy-demo/rpm \ |
| 50 |
&& printf '[alloy-demo-local]\nname=carried on the medium\nbaseurl=file:///usr/share/alloy-demo/rpm\nenabled=1\ngpgcheck=0\n' \ |
| 51 |
> /etc/yum.repos.d/alloy-demo-local.repo ;; \ |
| 52 |
none) \ |
| 53 |
: ;; \ |
| 54 |
*) echo "unknown SHAPE: $SHAPE" >&2; exit 1 ;; \ |
| 55 |
esac \ |
| 56 |
&& rm -rf /tmp/rpms /tmp/repos \ |
| 57 |
&& dnf clean all |
| 58 |
|
| 59 |
# Which base is running, readable from the guest without trusting a tag. The |
| 60 |
# registry tag is rewritten on every case, so the tag says nothing about what |
| 61 |
# actually booted. |
| 62 |
RUN echo "$BASE_MARK" > /usr/share/base-mark |
| 63 |
|
| 64 |
# Key-only root ssh, because the harness drives the guest from outside. The |
| 65 |
# authorized keys file lives under /usr rather than in /root: on an ostree |
| 66 |
# system /root is /var/roothome, which is not part of the image. |
| 67 |
COPY authorized_keys /usr/share/alloy-demo/authorized_keys |
| 68 |
RUN printf 'PermitRootLogin prohibit-password\nAuthorizedKeysFile /usr/share/alloy-demo/authorized_keys\n' \ |
| 69 |
> /etc/ssh/sshd_config.d/10-alloy-demo.conf \ |
| 70 |
&& systemctl enable sshd |
| 71 |
|