Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions .github/actions/bootc-ubuntu-setup/action.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
name: 'Bootc Ubuntu Setup'
description: 'Default host setup'
inputs:
libvirt:
description: 'Install libvirt and virtualization stack'
required: false
default: 'false'
runs:
using: 'composite'
steps:
Expand Down Expand Up @@ -45,3 +50,10 @@ runs:
id: set_arch
shell: bash
run: echo "ARCH=$(arch)" >> $GITHUB_ENV
# Install libvirt stack if requested
- name: Install libvirt and virtualization stack
if: ${{ inputs.libvirt == 'true' }}
shell: bash
run: |
set -eux
sudo apt install -y libkrb5-dev pkg-config libvirt-dev genisoimage qemu-utils qemu-kvm qemu-utils libvirt-daemon-system
40 changes: 32 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -131,8 +131,8 @@ jobs:
- uses: actions/checkout@v4
- name: Bootc Ubuntu Setup
uses: ./.github/actions/bootc-ubuntu-setup
- name: Install qemu-utils
run: sudo apt install -y qemu-utils
with:
libvirt: true

- name: Build container and disk image
run: |
Expand Down Expand Up @@ -163,12 +163,10 @@ jobs:
- uses: actions/checkout@v4
- name: Bootc Ubuntu Setup
uses: ./.github/actions/bootc-ubuntu-setup
- name: Install deps
run: |
sudo apt-get update
# see https://tmt.readthedocs.io/en/stable/overview.html#install
sudo apt install -y libkrb5-dev pkg-config libvirt-dev genisoimage qemu-kvm qemu-utils libvirt-daemon-system just
pip install --user "tmt[provision-virtual]"
with:
libvirt: true
- name: Install tmt
run: pip install --user "tmt[provision-virtual]"

- name: Create folder to save disk image
run: mkdir -p target
Expand All @@ -192,3 +190,29 @@ jobs:
with:
name: tmt-log-PR-${{ github.event.number }}-${{ matrix.test_os }}-${{ env.ARCH }}-${{ matrix.tmt_plan }}
path: /var/tmp/tmt
# This variant does composefs testing
test-integration-cfs:
strategy:
fail-fast: false
matrix:
test_os: [centos-10]

runs-on: ubuntu-24.04

steps:
- uses: actions/checkout@v4
- name: Bootc Ubuntu Setup
uses: ./.github/actions/bootc-ubuntu-setup
with:
libvirt: true

- name: Build container and disk image
run: |
just build-sealed-integration-test-disk

- name: Archive disk image
uses: actions/upload-artifact@v4
with:
name: PR-${{ github.event.number }}-${{ matrix.test_os }}-${{ env.ARCH }}-sealed-disk
path: target/bootc-integration-test.qcow2
retention-days: 1
4 changes: 0 additions & 4 deletions .packit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,6 @@ jobs:
owner: rhcontainerbot
project: bootc
enable_net: true
# TODO
notifications:
failure_comment:
message: "bootc Copr build failed for {commit_sha}. @admin check logs {logs_url} and packit dashboard {packit_dashboard_url}"

- job: tests
trigger: pull_request
Expand Down
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 9 additions & 5 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
# Build this project from source and drop the updated content on to
# a bootc container image. By default we use CentOS Stream 9 as a base;
# use e.g. --build-arg=base=quay.io/fedora/fedora-bootc:41 to target
# Build this project from source and write the updated content
# (i.e. /usr/bin/bootc and systemd units) to a new derived container
# image. See the `Justfile` for an example
#
# Use e.g. --build-arg=base=quay.io/fedora/fedora-bootc:42 to target
# Fedora instead.

ARG base=quay.io/centos-bootc/centos-bootc:stream9
ARG base=quay.io/centos-bootc/centos-bootc:stream10

# This first image captures a snapshot of the source code,
# note all the exclusions in .dockerignore.
FROM scratch as src
COPY . /src

Expand Down Expand Up @@ -37,7 +41,7 @@ EORUN

# This image installs build deps, pulls in our source code, and installs updated
# bootc binaries in /out. The intention is that the target rootfs is extracted from /out
# back into a final stae (without the build deps etc) below.
# back into a final stage (without the build deps etc) below.
FROM base as build
# Flip this off to disable initramfs code
ARG initramfs=1
Expand Down
65 changes: 65 additions & 0 deletions Dockerfile.cfsuki
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# Override via --build-arg=base=<image> to use a different base
ARG base=localhost/bootc
# This is where we get the tools to build the UKI
ARG buildroot=quay.io/fedora/fedora:42
FROM $base AS base

FROM $buildroot as buildroot-base
RUN <<EORUN
set -xeuo pipefail
dnf install -y systemd-ukify sbsigntools systemd-boot-unsigned
dnf clean all
EORUN

FROM buildroot-base as kernel
# Must be passed
ARG COMPOSEFS_FSVERITY
RUN --mount=type=secret,id=key \
--mount=type=secret,id=cert \
--mount=type=bind,from=base,target=/target \
<<EOF
set -eux

# Should be generated externally
test -n "${COMPOSEFS_FSVERITY}"

# Inject the composefs kernel argument and specify a root with the x86_64 DPS UUID.
# TODO: Discoverable partition fleshed out, or drop root UUID as systemd-stub extension
# TODO: https://github.com/containers/composefs-rs/issues/183
cmdline="composefs=${COMPOSEFS_FSVERITY} root=UUID=4f68bce3-e8cd-4db1-96e7-fbcaf984b709 console=ttyS0,114800n8 enforcing=0 rw"

kver=$(cd /target/usr/lib/modules && echo *)
ukify build \
--linux "/target/usr/lib/modules/$kver/vmlinuz" \
--initrd "/target/usr/lib/modules/$kver/initramfs.img" \
--uname="${kver}" \
--cmdline "${cmdline}" \
--os-release "@/target/usr/lib/os-release" \
--signtool sbsign \
--secureboot-private-key "/run/secrets/key" \
--secureboot-certificate "/run/secrets/cert" \
--measure \
--json pretty \
--output "/boot/$kver.efi"
sbsign \
--key "/run/secrets/key" \
--cert "/run/secrets/cert" \
"/usr/lib/systemd/boot/efi/systemd-bootx64.efi" \
--output "/boot/systemd-bootx64.efi"
EOF

FROM base as final

RUN --mount=type=bind,from=kernel,target=/run/kernel <<EOF
kver=$(cd /usr/lib/modules && echo *)
mkdir -p /boot/EFI/Linux
# We put the UKI in /boot for now due to composefs verity not being the
# same due to mtime of /usr/lib/modules being changed
cp /run/kernel/boot/$kver.efi /boot/EFI/Linux/$kver.efi
bootc container lint --fatal-warnings
EOF

FROM base as final-final
COPY --from=final /boot /boot
# Override the default
LABEL containers.bootc=sealed
48 changes: 48 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,64 @@
build *ARGS:
podman build --jobs=4 -t localhost/bootc {{ARGS}} .

build-sealed *ARGS:
podman build --jobs=4 -t localhost/bootc-unsealed {{ARGS}} .
cargo xtask build-sealed localhost/bootc-unsealed localhost/bootc

# This container image has additional testing content and utilities
build-integration-test-image *ARGS:
cd hack && podman build --jobs=4 -t localhost/bootc-integration -f Containerfile {{ARGS}} .
# Keep these in sync with what's used in hack/lbi
podman pull -q --retry 5 --retry-delay 5s quay.io/curl/curl:latest quay.io/curl/curl-base:latest registry.access.redhat.com/ubi9/podman:latest

# Like build-integration-test-image but sealed
build-sealed-integration-test-image *ARGS:
just build {{ARGS}}
just build-integration-test-image
cargo xtask build-sealed localhost/bootc-integration localhost/bootc-integration-sealed

build-sealed-integration-test-disk: build-sealed-integration-test-image
mkdir -p target
just build-disk-image localhost/bootc-integration-sealed target/bootc-integration.qcow2

# Only used by ci.yml right now
build-install-test-image: build-integration-test-image
cd hack && podman build -t localhost/bootc-integration-install -f Containerfile.drop-lbis

build-disk-image container target:
#!/bin/bash
set -xeuo pipefail
SIZE=20G
bcvk=$(which bcvk 2>/dev/null || true)
if test -z "${bcvk}" && test "$(id -u)" != 0; then
echo "This task currently requires full root"; exit 1
fi
# testcloud barfs on .raw
if test -n "${bcvk}"; then
bcvk to-disk --format=qcow2 --disk-size "${SIZE}" --filesystem ext4 {{container}} {{target}}
else
TMPDISK={{target}}.raw
truncate -s "${SIZE}" "${TMPDISK}"
podman run \
--rm \
--privileged \
--pid=host \
--security-opt label=type:unconfined_t \
-v /var/lib/containers:/var/lib/containers \
-v /dev:/dev \
-v $(pwd)/target:/target \
localhost/bootc-integration \
bootc install to-disk \
--filesystem "ext4" \
--karg=console=ttyS0,115200n8 \
--generic-image \
--via-loopback \
/target/$(basename ${TMPDISK})
qemu-img convert -f raw -O qcow2 ${TMPDISK} {{target}}
rm -f "${TMPDISK}"
fi


# These tests accept the container image as input, and may spawn it.
run-container-external-tests:
./tests/container/run localhost/bootc
Expand Down
1 change: 0 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,6 @@ validate:
cargo test --no-run
(cd crates/ostree-ext && cargo check --no-default-features)
(cd crates/lib && cargo check --no-default-features)
cargo check --features=composefs-backend
cargo clippy -- $(CLIPPY_CONFIG)
env RUSTDOCFLAGS='-D warnings' cargo doc --lib
.PHONY: validate
Expand Down
6 changes: 3 additions & 3 deletions crates/initramfs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use rustix::{
use serde::Deserialize;

use composefs::{
fsverity::{FsVerityHashValue, Sha256HashValue},
fsverity::{FsVerityHashValue, Sha512HashValue},
mount::FsHandle,
mountcompat::{overlayfs_set_fd, overlayfs_set_lower_and_data_fds, prepare_mount},
repository::Repository,
Expand Down Expand Up @@ -207,7 +207,7 @@ fn open_root_fs(path: &Path) -> Result<OwnedFd> {
/// * insecure - Whether fsverity is optional or not
#[context("Mounting composefs image")]
pub fn mount_composefs_image(sysroot: &OwnedFd, name: &str, insecure: bool) -> Result<OwnedFd> {
let mut repo = Repository::<Sha256HashValue>::open_path(sysroot, "composefs")?;
let mut repo = Repository::<Sha512HashValue>::open_path(sysroot, "composefs")?;
repo.set_insecure(insecure);
repo.mount(name).context("Failed to mount composefs image")
}
Expand Down Expand Up @@ -282,7 +282,7 @@ pub fn setup_root(args: Args) -> Result<()> {
// TODO: Deduplicate this with composefs branch karg parser
None => &std::fs::read_to_string("/proc/cmdline")?,
};
let (image, insecure) = get_cmdline_composefs::<Sha256HashValue>(cmdline)?;
let (image, insecure) = get_cmdline_composefs::<Sha512HashValue>(cmdline)?;

let new_root = match args.root_fs {
Some(path) => open_root_fs(&path).context("Failed to clone specified root fs")?,
Expand Down
2 changes: 1 addition & 1 deletion crates/lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ similar-asserts = { workspace = true }
static_assertions = { workspace = true }

[features]
default = ["install-to-disk"]
default = ["install-to-disk", "composefs-backend"]
# This feature enables `bootc install to-disk`, which is considered just a "demo"
# or reference installer; we expect most nontrivial use cases to be using
# `bootc install to-filesystem`.
Expand Down
Loading
Loading