Skip to content

Commit ecc68a1

Browse files
authored
maintenance improvements (#19)
* Update image signing * remove redundant settings from containers that inherit them * update build pipelines * adjusting * add cuda for nvidia-smi * Add a build stage for akmods, since we can't install rpms on bootc systems
1 parent 7c62b50 commit ecc68a1

10 files changed

Lines changed: 442 additions & 551 deletions

.github/workflows/build-hypervisor.yml

Lines changed: 242 additions & 312 deletions
Large diffs are not rendered by default.
Lines changed: 105 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
name: Build Fedora Minimal Bootc
22

33
on:
4-
# Manual trigger with version selection
54
workflow_dispatch:
65
inputs:
76
fedora_version:
@@ -13,199 +12,162 @@ on:
1312
- '43'
1413
- '44'
1514
- 'rawhide'
16-
rechunk:
17-
description: 'Rechunk the image for better efficiency'
18-
required: false
19-
default: true
20-
type: boolean
2115

22-
# Weekly build (Saturdays at 2am UTC)
2316
schedule:
2417
- cron: '0 2 * * 6'
2518

26-
# Build on pushes to main that touch these files
2719
push:
28-
branches:
29-
- main
20+
branches: [main]
3021
paths:
3122
- 'fedora-bootc-minimal.Containerfile'
23+
- 'policy-minimal.json.template'
24+
- 'cosign.pub'
3225
- '.github/workflows/build-minimal-bootc.yml'
3326

27+
concurrency:
28+
group: build-minimal-bootc-${{ github.ref }}
29+
cancel-in-progress: false
30+
31+
env:
32+
STABLE_FEDORA_VERSION: '43'
33+
IMAGE_NAME: fedora-bootc-minimal
34+
3435
jobs:
35-
build-minimal-bootc:
36-
runs-on: ubuntu-24.04 # Required by rechunk action for advanced podman features
36+
build:
37+
runs-on: ubuntu-24.04
38+
timeout-minutes: 90
3739
permissions:
3840
contents: read
3941
packages: write
4042
id-token: write
4143

42-
strategy:
43-
matrix:
44-
# Build for multiple Fedora versions
45-
fedora_version:
46-
- '43'
47-
4844
steps:
49-
- name: Setup podman
45+
- name: Checkout repository
46+
uses: actions/checkout@v4
47+
48+
- name: Resolve build parameters
49+
id: params
50+
env:
51+
INPUT_VERSION: ${{ inputs.fedora_version }}
52+
OWNER_RAW: ${{ github.repository_owner }}
5053
run: |
51-
sudo apt-get update
52-
sudo apt-get install -y podman
53-
podman --version
54+
VERSION="${INPUT_VERSION:-${STABLE_FEDORA_VERSION}}"
55+
OWNER=$(echo "$OWNER_RAW" | tr '[:upper:]' '[:lower:]')
56+
TAG=$(date +%Y%m%d-%H%M)
57+
{
58+
echo "version=${VERSION}"
59+
echo "owner=${OWNER}"
60+
echo "tag=${TAG}"
61+
echo "image_base=ghcr.io/${OWNER}/${IMAGE_NAME}"
62+
} >> "$GITHUB_OUTPUT"
5463
5564
- name: Install cosign
5665
uses: sigstore/cosign-installer@v3.7.0
5766

58-
- name: Set Fedora version
59-
id: set_version
67+
- name: Install podman
6068
run: |
61-
# Use manual input if provided, otherwise use matrix version
62-
if [ "${{ github.event_name }}" == "workflow_dispatch" ]; then
63-
echo "version=${{ inputs.fedora_version }}" >> $GITHUB_OUTPUT
64-
else
65-
echo "version=${{ matrix.fedora_version }}" >> $GITHUB_OUTPUT
66-
fi
67-
68-
- name: Checkout repository
69-
uses: actions/checkout@v4
69+
sudo apt-get update
70+
sudo apt-get install -y podman
71+
podman --version
7072
71-
- name: Generate /etc/containers/policy.json for github keyless signing
72-
# owner needs to be lowercase, but workflow ref needs to preserve case
73+
- name: Render policy.json
74+
env:
75+
OWNER: ${{ steps.params.outputs.owner }}
7376
run: |
74-
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
75-
7677
sed -e "s|__REGISTRY_NAMESPACE__|${OWNER}|g" \
77-
-e "s|__MINIMAL_WORKFLOW_REF__|${{ github.workflow_ref }}|g" \
7878
policy-minimal.json.template > policy.json
79-
80-
echo "Generated policy.json for minimal:"
8179
cat policy.json
8280
83-
- name: Set build timestamp
84-
id: timestamp
85-
run: |
86-
echo "tag=$(date +%Y%m%d-%H%M)" >> $GITHUB_OUTPUT
87-
8881
- name: Clone Fedora bootc manifests
8982
run: |
9083
git clone --depth 1 https://gitlab.com/fedora/bootc/base-images.git manifests
91-
cd manifests
92-
git log -1
93-
echo "Using local podman 4-compatible Containerfile with upstream manifests"
94-
95-
- name: Copy policy.json into build context
96-
run: |
84+
git -C manifests log -1
9785
cp policy.json manifests/policy.json
98-
echo "Copied policy.json to manifests/ directory"
86+
cp cosign.pub manifests/cosign.pub
9987
100-
- name: Build minimal bootc container
88+
- name: Build minimal bootc image
89+
env:
90+
VERSION: ${{ steps.params.outputs.version }}
91+
TAG: ${{ steps.params.outputs.tag }}
10192
run: |
10293
sudo podman build \
10394
--security-opt=label=disable \
10495
--cap-add=all \
10596
--device /dev/fuse \
10697
-f fedora-bootc-minimal.Containerfile \
10798
--build-arg MANIFEST=minimal \
108-
--build-arg BUILDER_IMAGE=quay.io/fedora/fedora:${{ steps.set_version.outputs.version }} \
109-
--build-arg REPOS_IMAGE=quay.io/fedora/fedora:${{ steps.set_version.outputs.version }} \
110-
-t localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }} \
99+
--build-arg BUILDER_IMAGE=quay.io/fedora/fedora:${VERSION} \
100+
--build-arg REPOS_IMAGE=quay.io/fedora/fedora:${VERSION} \
101+
-t localhost/${IMAGE_NAME}:build \
111102
manifests
103+
sudo podman inspect localhost/${IMAGE_NAME}:build > /dev/null
112104
113-
- name: Test built image
114-
run: |
115-
sudo podman images | grep fedora-bootc-minimal
116-
sudo podman inspect localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }}
117-
118-
- name: Rechunk image with bootc-base-imagectl
105+
- name: Rechunk image
106+
env:
107+
VERSION: ${{ steps.params.outputs.version }}
119108
run: |
120-
# Use bootc-base-imagectl rechunk (official bootc method)
121109
sudo podman run --rm --privileged \
122110
-v /var/lib/containers:/var/lib/containers \
123-
quay.io/fedora/fedora-bootc:${{ steps.set_version.outputs.version }} \
111+
quay.io/fedora/fedora-bootc:${VERSION} \
124112
/usr/libexec/bootc-base-imagectl rechunk \
125-
localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }} \
126-
localhost/fedora-bootc-minimal:rechunked
113+
localhost/${IMAGE_NAME}:build \
114+
localhost/${IMAGE_NAME}:rechunked
127115
128-
# List all images to verify rechunk created the image
129-
echo "All images after rechunk:"
130-
sudo podman images
131-
132-
- name: Tag rechunked image
133-
run: |
134-
# Apply all the tags we need to the rechunked image
135-
sudo podman tag localhost/fedora-bootc-minimal:rechunked \
136-
localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }}
137-
sudo podman tag localhost/fedora-bootc-minimal:rechunked \
138-
localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}
139-
sudo podman tag localhost/fedora-bootc-minimal:rechunked \
140-
localhost/fedora-bootc-minimal:latest
141-
142-
# Clean up the temporary rechunked tag
143-
sudo podman rmi localhost/fedora-bootc-minimal:rechunked
144-
145-
- name: Login to GitHub Container Registry
116+
- name: Login to GHCR
117+
env:
118+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
119+
ACTOR: ${{ github.actor }}
146120
run: |
147-
echo "${{ secrets.GITHUB_TOKEN }}" | sudo podman login ghcr.io -u ${{ github.actor }} --password-stdin
148-
149-
- name: Push to GitHub Container Registry
121+
echo "$GH_TOKEN" | sudo podman login ghcr.io -u "$ACTOR" --password-stdin
122+
echo "$GH_TOKEN" | cosign login ghcr.io -u "$ACTOR" --password-stdin
123+
124+
- name: Tag and push
125+
id: push
126+
env:
127+
IMAGE_BASE: ${{ steps.params.outputs.image_base }}
128+
VERSION: ${{ steps.params.outputs.version }}
129+
TAG: ${{ steps.params.outputs.tag }}
150130
run: |
151-
# Lowercase repository owner for ghcr.io compatibility
152-
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
153-
154-
# Tag with timestamp and version
155-
sudo podman tag localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }} \
156-
ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }}
157-
158-
sudo podman tag localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }} \
159-
ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}
160-
161-
# Also tag 'latest' for the stable version
162-
if [ "${{ steps.set_version.outputs.version }}" == "43" ]; then
163-
sudo podman tag localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }} \
164-
ghcr.io/${OWNER}/fedora-bootc-minimal:latest
131+
TAGS=("${VERSION}-${TAG}" "${VERSION}")
132+
if [ "${VERSION}" = "${STABLE_FEDORA_VERSION}" ]; then
133+
TAGS+=("latest")
165134
fi
166135
167-
# Push all tags
168-
sudo podman push ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }}
169-
sudo podman push ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}
170-
171-
if [ "${{ steps.set_version.outputs.version }}" == "43" ]; then
172-
sudo podman push ghcr.io/${OWNER}/fedora-bootc-minimal:latest
173-
fi
174-
175-
- name: Login to GitHub Container Registry for cosign
176-
run: |
177-
echo "${{ secrets.GITHUB_TOKEN }}" | cosign login ghcr.io -u ${{ github.actor }} --password-stdin
178-
179-
- name: Sign images with cosign
136+
FIRST=true
137+
for t in "${TAGS[@]}"; do
138+
sudo podman tag localhost/${IMAGE_NAME}:rechunked "${IMAGE_BASE}:${t}"
139+
if [ "${FIRST}" = "true" ]; then
140+
sudo podman push --digestfile /tmp/digest.txt "${IMAGE_BASE}:${t}"
141+
FIRST=false
142+
else
143+
sudo podman push "${IMAGE_BASE}:${t}"
144+
fi
145+
done
146+
147+
DIGEST=$(cat /tmp/digest.txt)
148+
{
149+
printf 'tags<<EOF\n%s\nEOF\n' "${TAGS[*]}"
150+
echo "digest=${DIGEST}"
151+
} >> "$GITHUB_OUTPUT"
152+
153+
- name: Sign images
154+
env:
155+
COSIGN_PRIVATE_KEY: ${{ secrets.COSIGN_SECRET }}
156+
IMAGE_BASE: ${{ steps.params.outputs.image_base }}
157+
DIGEST: ${{ steps.push.outputs.digest }}
180158
run: |
181-
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
182-
183-
cosign sign --yes ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }}
184-
185-
cosign sign --yes ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}
159+
cosign sign -y --key env://COSIGN_PRIVATE_KEY "${IMAGE_BASE}@${DIGEST}"
186160
187-
if [ "${{ steps.set_version.outputs.version }}" == "43" ]; then
188-
cosign sign --yes ghcr.io/${OWNER}/fedora-bootc-minimal:latest
189-
fi
190-
191-
- name: Cleanup local images
161+
- name: Summary
162+
env:
163+
IMAGE_BASE: ${{ steps.params.outputs.image_base }}
164+
TAGS: ${{ steps.push.outputs.tags }}
192165
run: |
193-
OWNER=$(echo "${{ github.repository_owner }}" | tr '[:upper:]' '[:lower:]')
194-
195-
# Remove all local tags from root storage
196-
sudo podman rmi localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }} || true
197-
sudo podman rmi localhost/fedora-bootc-minimal:${{ steps.set_version.outputs.version }} || true
198-
sudo podman rmi localhost/fedora-bootc-minimal:latest || true
199-
sudo podman rmi ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }}-${{ steps.timestamp.outputs.tag }} || true
200-
sudo podman rmi ghcr.io/${OWNER}/fedora-bootc-minimal:${{ steps.set_version.outputs.version }} || true
201-
202-
# Also clean up :latest tag if it was pushed
203-
if [ "${{ steps.set_version.outputs.version }}" == "43" ]; then
204-
sudo podman rmi ghcr.io/${OWNER}/fedora-bootc-minimal:latest || true
205-
fi
206-
207-
# Prune root storage to remove dangling layers
208-
sudo podman system prune -af --volumes
209-
210-
# Show final disk usage
211-
df -h
166+
{
167+
echo "## Minimal bootc build complete"
168+
echo ""
169+
echo "Pushed and signed:"
170+
for t in $TAGS; do
171+
echo "- \`${IMAGE_BASE}:${t}\`"
172+
done
173+
} >> "$GITHUB_STEP_SUMMARY"

cosign.pub

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-----BEGIN PUBLIC KEY-----
2+
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE1tsMEtSTv5qyeHuDzrsH1OKi5+9q
3+
pTwpSBwtGluq8NyAkoNxCJHR0TuL9UbdMjHd37mk6AI4bVyPskxbeD6WIg==
4+
-----END PUBLIC KEY-----

fedora-bootc-minimal.Containerfile

Lines changed: 7 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -27,40 +27,20 @@ RUN --mount=type=cache,id=bootc-base-image-cache,target=/cache sh -c 'set -xeuo
2727
/usr/libexec/bootc-base-imagectl list >/dev/null && \
2828
/usr/libexec/bootc-base-imagectl build-rootfs --cachedir=/cache --reinject --manifest=${MANIFEST} /repos /target-rootfs'
2929

30-
# get the keys for github keyless signing
31-
FROM alpine AS keyless-keys
32-
33-
RUN apk add curl jq openssl
34-
35-
# writes to ~/.sigstore/root/
36-
RUN curl -o cosign -L "https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64" && \
37-
chmod +x cosign && \
38-
./cosign initialize
39-
40-
# Extract the base64-encoded cosign public key from trusted_root.json,
41-
# decode it from base64, convert from DER to PEM format
42-
RUN mkdir -p /etc/pki/rekor && \
43-
cat ~/.sigstore/root/tuf-repo-cdn.sigstore.dev/targets/trusted_root.json | \
44-
jq -r '.tlogs[0].publicKey.rawBytes' | \
45-
base64 -d > rekor_temp.pub && \
46-
openssl pkey -pubin -inform DER -in rekor_temp.pub -outform PEM -out /etc/pki/rekor/rekor.pub
47-
48-
# same with the fulcio cert
49-
RUN mkdir -p /etc/pki/fulcio && \
50-
cat ~/.sigstore/root/tuf-repo-cdn.sigstore.dev/targets/trusted_root.json | \
51-
jq -r '.certificateAuthorities[0].certChain.certificates[0].rawBytes' | \
52-
base64 -d > fulcio_temp.crt && \
53-
openssl x509 -inform DER -in fulcio_temp.crt -outform PEM -out /etc/pki/fulcio/fulcio.crt.pem
54-
55-
5630
FROM scratch
5731
COPY --from=builder /target-rootfs/ /
58-
COPY --from=keyless-keys /etc/pki /etc/pki
32+
COPY cosign.pub /etc/pki/containers/cosign.pub
5933
COPY policy.json /etc/containers/policy.json
6034

6135
# Bootc labels and metadata
6236
LABEL containers.bootc 1
37+
LABEL ostree.bootable 1
6338
LABEL bootc.diskimage-builder quay.io/centos-bootc/bootc-image-builder
39+
40+
LABEL org.opencontainers.image.title="Minimal Fedora bootc Image"
41+
LABEL org.opencontainers.image.description="Build of Fedora bootc minimal"
42+
6443
ENV container=oci
44+
6545
STOPSIGNAL SIGRTMIN+3
6646
CMD ["/usr/sbin/init"]

hypervisor-amd.Containerfile

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,5 @@ RUN mkdir -p /etc/cdi && \
3131
# rocm-smi tries to use libdrm_amdgpu.so, this is a workaround to provide it
3232
RUN ln -s /usr/lib64/libdrm_amdgpu.so.1 /usr/lib64/libdrm_amdgpu.so
3333

34-
# Define required labels for this bootc image to be recognized as such
35-
LABEL containers.bootc 1
36-
LABEL ostree.bootable 1
3734
LABEL org.opencontainers.image.title="Hypervisor Bootc Image - AMD GPU"
3835
LABEL org.opencontainers.image.description="Bootc-based hypervisor with AMD GPU support (ROCm)"
39-
40-
# https://pagure.io/fedora-kiwi-descriptions/pull-request/52
41-
ENV container=oci
42-
43-
# Optional labels that only apply when running this image as a container. These keep the default entry point running under systemd.
44-
STOPSIGNAL SIGRTMIN+3
45-
CMD ["/usr/sbin/init"]

0 commit comments

Comments
 (0)