Skip to content

Commit b4dc968

Browse files
Signed-off-by: Brad House <bhouse@nexthop.ai>
1 parent 48db661 commit b4dc968

695 files changed

Lines changed: 14564 additions & 91059 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/onie-build/Dockerfile

Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# ONIE build environment for CI.
2+
#
3+
# Debian 13 (trixie) host for the modernized toolchain. Required because
4+
# kernel 6.18's objtool needs a newer host libelf than Debian 11 ships
5+
# (0.183 fails with "elf_update: invalid section alignment"), and
6+
# crosstool-NG 1.28 / GCC 14 align with the trixie host toolchain. (The
7+
# old crosstool-NG 1.24 / GCC 8.3 toolchain could NOT build on trixie.)
8+
#
9+
# This image builds the generic kvm_x86_64 target with secure boot
10+
# enabled. It includes the secure-boot tooling needed to exercise the SB
11+
# build path -- pesign, efitools, sbsigntool and gnupg2 (for key
12+
# generation and EFI signing).
13+
FROM debian:13
14+
WORKDIR /onie
15+
16+
# Tolerate transient Debian mirror hiccups (connection resets mid-fetch).
17+
RUN echo 'Acquire::Retries "5";' > /etc/apt/apt.conf.d/80-retries
18+
19+
# Build dependencies for crosstool-NG and the ONIE image.
20+
RUN apt-get update && apt-get install -y \
21+
autoconf \
22+
autoconf-archive \
23+
automake \
24+
autopoint \
25+
bc \
26+
bison \
27+
bsdextrautils \
28+
build-essential \
29+
coreutils \
30+
cpio \
31+
curl \
32+
device-tree-compiler \
33+
dosfstools \
34+
efitools \
35+
fakeroot \
36+
flex \
37+
gawk \
38+
git \
39+
gnupg2 \
40+
gperf \
41+
help2man \
42+
libefivar-dev \
43+
libelf-dev \
44+
libexpat1 \
45+
libexpat1-dev \
46+
libncurses-dev \
47+
libpopt-dev \
48+
libssl-dev \
49+
libtool \
50+
libtool-bin \
51+
locales \
52+
mtools \
53+
pesign \
54+
pkgconf \
55+
python3-all-dev \
56+
python3-sphinx \
57+
python3-venv \
58+
rst2pdf \
59+
rsync \
60+
sbsigntool \
61+
stgit \
62+
texinfo \
63+
tree \
64+
u-boot-tools \
65+
unzip \
66+
util-linux \
67+
uuid-dev \
68+
uuid-runtime \
69+
wget \
70+
zip \
71+
xorriso \
72+
&& rm -rf /var/lib/apt/lists/*
73+
74+
# Generate UTF-8 locale (needed for the uclibc / crosstool-NG build).
75+
RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \
76+
locale-gen
77+
78+
# Create the build user with the same UID/GID as the host invoker so
79+
# build artifacts are not left owned by root. Override at build time
80+
# with --build-arg UID=$(id -u) --build-arg GID=$(id -g).
81+
#
82+
# NOTE: -l avoids docker layer-export hangs for large UIDs.
83+
# (https://github.com/moby/moby/issues/5419#issuecomment-41478290)
84+
ARG UID=1000
85+
ARG GID=1000
86+
RUN groupadd -g $GID build && \
87+
useradd -l -m -u $UID -g $GID -s /bin/bash build && \
88+
chown -R build:build /onie
89+
90+
USER build
91+
92+
# /sbin and /usr/sbin hold tools the build invokes.
93+
RUN echo 'export PATH="/sbin:/usr/sbin:$PATH"' >> ~/.bashrc
94+
95+
# The build runs git commands; give it a default identity.
96+
RUN git config --global user.email "build@example.com" && \
97+
git config --global user.name "Build User"
98+
99+
CMD ["/bin/bash", "--login"]

.github/workflows/build-onie.yml

Lines changed: 241 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,241 @@
1+
name: Build ONIE (kvm_x86_64)
2+
3+
# Builds the generic amd64 ONIE image for the kvm_x86_64 target, intended
4+
# to run as a VM under KVM/QEMU. The build follows the upstream-recommended
5+
# containerized flow (see contrib/build-env and machine/kvm_x86_64/INSTALL),
6+
# with secure boot enabled: the workflow generates demonstration signing
7+
# keys and self-signs the shim before building.
8+
9+
# Run on every push and pull request: the point of this workflow is to
10+
# confirm the change still builds, and the kvm_x86_64 image depends on far
11+
# more than the build files (installer/, rootconf/, patches/, ...), so path
12+
# filtering would risk skipping validation on build-affecting changes.
13+
on:
14+
workflow_dispatch:
15+
push:
16+
pull_request:
17+
18+
# Cancel an in-progress run when a newer commit is pushed to the same ref,
19+
# so stacked pushes don't pile up concurrent builds.
20+
concurrency:
21+
group: ${{ github.workflow }}-${{ github.ref }}
22+
cancel-in-progress: true
23+
24+
jobs:
25+
build:
26+
name: Build kvm_x86_64
27+
runs-on: ubuntu-latest
28+
steps:
29+
- name: Checkout
30+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
31+
32+
- name: Set up Docker Buildx
33+
uses: docker/setup-buildx-action@d7f5e7f509e45cec5c76c4d5afdd7de93d0b3df5 # v4.1.0
34+
35+
- name: Determine host UID/GID
36+
id: ids
37+
run: |
38+
echo "uid=$(id -u)" >> "$GITHUB_OUTPUT"
39+
echo "gid=$(id -g)" >> "$GITHUB_OUTPUT"
40+
41+
- name: Build the ONIE build-environment image
42+
uses: docker/build-push-action@f9f3042f7e2789586610d6e8b85c8f03e5195baf # v7.2.0
43+
with:
44+
context: .github/onie-build
45+
tags: onie-build-env:latest
46+
build-args: |
47+
UID=${{ steps.ids.outputs.uid }}
48+
GID=${{ steps.ids.outputs.gid }}
49+
load: true
50+
cache-from: type=gha
51+
cache-to: type=gha,mode=max
52+
53+
# Cache the crosstool-NG cross toolchain -- the long pole of a cold
54+
# build. We cache the whole stamp chain (so make does not rebuild on a
55+
# missing root stamp) but only the parts the warm, no-op path actually
56+
# needs -- NOT the multi-GB crosstool-NG build scratch or ct-ng source
57+
# tree, which are only used while building the toolchain. On a cache
58+
# hit "make xtools" is a no-op and the real build only uses the
59+
# installed toolchain, so dropping the scratch keeps the cache blob
60+
# small and fast/reliable to restore.
61+
#
62+
# build/stamp-project -- top-of-chain project stamp
63+
# build/download -- toolchain tarballs + download stamps
64+
# build/crosstool-ng/stamp -- crosstool-NG build stamps
65+
# build/x-tools/*/stamp -- xtools build stamps
66+
# build/x-tools/*/install -- the installed cross toolchain
67+
# build/x-tools/*/build/.config -- xtools config (an xtools-build prereq)
68+
#
69+
# The key is tied to every input that can change the toolchain --
70+
# including the Dockerfile, since it defines the compiler/host
71+
# environment the toolchain is built in. No loose restore-keys: any
72+
# input change forces a clean rebuild rather than restoring a
73+
# mismatched toolchain.
74+
- name: Restore cross-toolchain cache
75+
id: xtools-cache
76+
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
77+
with:
78+
path: |
79+
build/stamp-project
80+
build/download
81+
build/crosstool-ng/stamp
82+
build/x-tools/*/stamp
83+
build/x-tools/*/install
84+
build/x-tools/*/build/.config
85+
key: onie-xtools-kvm_x86_64-${{ hashFiles('build-config/make/xtools.make', 'build-config/make/crosstool-ng.make', 'build-config/make/compiler.make', 'build-config/conf/crosstool/**', 'patches/crosstool-NG/**', '.github/onie-build/Dockerfile') }}
86+
87+
# ONIE drives its build with stamp files compared by mtime. A fresh
88+
# checkout gives every repo source file a current mtime, which is newer
89+
# than the restored stamps -- so make would consider the toolchain
90+
# stale and rebuild it (e.g. build/.../.config depends on the
91+
# checked-out conf/crosstool config). A cache hit means the key
92+
# matched, i.e. every toolchain input is unchanged and the restored
93+
# toolchain is valid, so bump the restored artifacts ahead of the
94+
# checkout to make "make xtools" a genuine no-op.
95+
- name: Mark restored toolchain up to date
96+
if: steps.xtools-cache.outputs.cache-hit == 'true'
97+
# Restoring build/stamp-project makes make skip the project-stamp
98+
# recipe, which is what normally creates the project output dirs --
99+
# so recreate them (build/images is an output, not part of the
100+
# cache, and the kernel install copies vmlinuz into it).
101+
#
102+
# Then touch only the files make compares -- the stamp files and the
103+
# toolchain .config. Do NOT touch the toolchain tree itself: it
104+
# contains read-only binaries and symlinks to host tools (bash,
105+
# make, ...) that touch would follow and fail to update.
106+
run: |
107+
mkdir -p build build/images build/download
108+
find build/stamp-project build/download \
109+
build/crosstool-ng/stamp \
110+
build/x-tools/*/stamp \
111+
build/x-tools/*/build/.config \
112+
-type f -exec touch {} +
113+
114+
- name: Build cross toolchain
115+
run: |
116+
docker run --rm --privileged \
117+
-v "${PWD}:/onie" \
118+
onie-build-env \
119+
bash -lc 'cd build-config && make -j"$(nproc)" \
120+
MACHINE=kvm_x86_64 \
121+
xtools'
122+
123+
# Save only on a cache miss, and only after the toolchain build above
124+
# succeeded (default if: success()), so a broken toolchain is never
125+
# cached. Running before the full build means a later-stage failure
126+
# still preserves the toolchain for the next run.
127+
- name: Save cross-toolchain cache
128+
if: steps.xtools-cache.outputs.cache-hit != 'true'
129+
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
130+
with:
131+
path: |
132+
build/stamp-project
133+
build/download
134+
build/crosstool-ng/stamp
135+
build/x-tools/*/stamp
136+
build/x-tools/*/install
137+
build/x-tools/*/build/.config
138+
key: ${{ steps.xtools-cache.outputs.cache-primary-key }}
139+
140+
- name: Build ONIE
141+
run: |
142+
docker run --rm --privileged \
143+
-v "${PWD}:/onie" \
144+
onie-build-env \
145+
bash -lc 'cd build-config && \
146+
make MACHINE=kvm_x86_64 signing-keys-generate && \
147+
make MACHINE=kvm_x86_64 shim-self-sign && \
148+
make -j"$(nproc)" MACHINE=kvm_x86_64 all recovery-iso'
149+
150+
# Scan the SBOM (produced by `make all`) for known vulnerabilities and
151+
# publish the table to the job log and the run summary. This is a
152+
# report, not a gate: sbom-vuln-scan.py always exits 0 (CVEs already
153+
# fixed by ONIE patches are suppressed via OpenVEX), so it never fails
154+
# the build. The SBOM tools (incl. grype) were provisioned by the SBOM
155+
# step of `make all`.
156+
- name: SBOM vulnerability scan
157+
run: |
158+
docker run --rm \
159+
-v "${PWD}:/onie" \
160+
onie-build-env \
161+
bash -lc 'cd build-config && make MACHINE=kvm_x86_64 sbom-vuln-scan'
162+
for f in build/images/*.sbom.vulns.md; do
163+
[ -f "$f" ] || continue
164+
cat "$f" >> "$GITHUB_STEP_SUMMARY"
165+
done
166+
- name: Upload kvm recovery image
167+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
168+
with:
169+
name: onie-kvm-recovery-iso
170+
path: build/images/onie-recovery-x86_64-kvm_x86_64-r0.iso
171+
retention-days: 7
172+
173+
# The demonstration PK/KEK/db that signed this build's shim/grub/kernel.
174+
# The boot-test job enrolls them into an OVMF varstore to validate the
175+
# secure-boot signature chain. These are the SAME keys this run signed
176+
# with, so the enrolled db matches the shipped image (regenerating would
177+
# not). Demo keys only -- non-sensitive (see machine-security.make).
178+
- name: Upload secure-boot demo keys
179+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
180+
with:
181+
name: onie-kvm-sb-keys
182+
path: encryption/machines/kvm_x86_64/keys
183+
retention-days: 7
184+
185+
# Boot the built recovery ISO headlessly under QEMU+OVMF and assert ONIE gets
186+
# past GRUB into the OS (serial-console milestones, no kernel panic). ONIE is
187+
# serial end-to-end (GRUB+kernel+userspace on ttyS0) so a serial capture
188+
# suffices -- no screen scraping/OCR. See emulation/ci-boot-test.sh.
189+
boot-test:
190+
name: Boot test kvm_x86_64
191+
needs: build
192+
runs-on: ubuntu-latest
193+
steps:
194+
- name: Checkout
195+
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
196+
- name: Enable KVM (grant /dev/kvm access)
197+
run: |
198+
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' \
199+
| sudo tee /etc/udev/rules.d/99-kvm4all.rules
200+
sudo udevadm control --reload-rules
201+
sudo udevadm trigger --name-match=kvm
202+
- name: Install QEMU + OVMF
203+
run: |
204+
sudo apt-get update
205+
sudo apt-get install -y --no-install-recommends \
206+
qemu-system-x86 qemu-utils ovmf python3-virt-firmware
207+
- name: Download kvm recovery image
208+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
209+
with:
210+
name: onie-kvm-recovery-iso
211+
path: build/images
212+
- name: Download secure-boot demo keys
213+
uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4
214+
with:
215+
name: onie-kvm-sb-keys
216+
path: encryption/machines/kvm_x86_64/keys
217+
# SB-relaxed smoke: plain OVMF on the default 'pc' machine -- proves the
218+
# image boots past GRUB into the OS independent of the SB signature chain.
219+
- name: Boot ONIE (SB-relaxed) and assert it reaches the OS
220+
run: |
221+
SERIAL_LOG="$PWD/onie-boot-serial.log" BOOT_MODE=relaxed \
222+
emulation/ci-boot-test.sh \
223+
build/images/onie-recovery-x86_64-kvm_x86_64-r0.iso 300
224+
# SB-enforced: enroll the demo PK/KEK/db, boot the secboot OVMF on
225+
# q35,smm=on, and assert the shim/grub/kernel chain verifies (plus a
226+
# negative control with db omitted that MUST be rejected). This is the
227+
# signal that catches a broken signing chain in the grub/shim/kernel
228+
# modernization PRs even when the image otherwise builds and boots.
229+
- name: Boot ONIE (SB-enforced) and assert the signing chain verifies
230+
run: |
231+
SERIAL_LOG="$PWD/onie-boot-serial-secureboot.log" BOOT_MODE=secureboot \
232+
KEYS_DIR="$PWD/encryption/machines/kvm_x86_64/keys" \
233+
emulation/ci-boot-test.sh \
234+
build/images/onie-recovery-x86_64-kvm_x86_64-r0.iso 300
235+
- name: Upload serial logs
236+
if: always()
237+
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
238+
with:
239+
name: onie-boot-serial-log
240+
path: onie-boot-serial*.log
241+
retention-days: 7

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,5 @@
44
/cscope.out.po
55
build
66
local.make
7-
onie-installer
7+
onie-installer
8+
encryption/machines/

README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,13 @@ Building ONIE
1515
The recommended way to set up an ONIE build environment is to use a Docker image, as described
1616
in the ONIE Documentation under `Preparing An ONIE Build Environment <https://opencomputeproject.github.io/onie/developers/building.html#preparing-an-onie-build-environment>`_.
1717

18+
Software Bill of Materials
19+
==========================
20+
21+
Every build emits a Software Bill of Materials (CycloneDX 1.6 and SPDX 2.3)
22+
describing the third-party software shipped in the image. See `README.sbom
23+
<README.sbom>`_ for details.
24+
1825
******************************
1926
Mailing List and Collaboration
2027
******************************

0 commit comments

Comments
 (0)