Skip to content
Draft
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
25 changes: 19 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ jobs:
- name: Fetch external dependencies (with retry)
run: just build-fetch

- name: Integration tests
- name: Build images and test binaries
run: |
set -xeu
# Build images as regular user, then copy to root's podman storage
Expand All @@ -168,13 +168,19 @@ jobs:

# Build test binaries before any sudo commands to avoid cargo permission issues
cargo build --release -p tests-integration
cargo build --release -p system-reinstall-bootc

sudo podman build -t localhost/bootc-fsverity -f ci/Containerfile.install-fsverity

df -h /
sudo install -m 0755 target/release/tests-integration /usr/bin/bootc-integration-tests
sudo install -m 0755 target/release/system-reinstall-bootc /usr/bin/system-reinstall-bootc
sudo rm target -rf
df -h /

- name: Integration tests
run: |
set -xeu
# The ostree-container tests
sudo podman run --privileged --pid=host -v /:/run/host -v $(pwd):/src:ro -v /var/tmp:/var/tmp \
--tmpfs /var/lib/containers \
Expand All @@ -187,14 +193,10 @@ jobs:
# inspect system state after the install tests.
sudo lsblk
sudo mount

# system-reinstall-bootc tests
cargo build --release -p system-reinstall-bootc

# not sure why this is missing in the ubuntu image but just creating this directory allows the tests to pass
sudo mkdir -p /run/sshd

sudo install -m 0755 target/release/system-reinstall-bootc /usr/bin/system-reinstall-bootc
# These tests may mutate the system live so we can't run in parallel
sudo bootc-integration-tests system-reinstall localhost/bootc --test-threads=1

Expand Down Expand Up @@ -499,6 +501,9 @@ jobs:
name: packages-${{ matrix.test_os }}
path: target/packages/

- name: Fetch external dependencies (with retry)
run: BOOTC_SKIP_PACKAGE=1 just build-fetch

- name: Build container with baseconfig
run: BOOTC_SKIP_PACKAGE=1 just build

Expand Down Expand Up @@ -602,7 +607,15 @@ jobs:
name: packages-centos-10
path: target/packages/

- name: Build and run container export test
- name: Fetch external dependencies (with retry)
run: BOOTC_SKIP_PACKAGE=1 just build-fetch

- name: Build container and fetch Anaconda ISO
run: |
BOOTC_SKIP_PACKAGE=1 just build
BOOTC_SKIP_PACKAGE=1 just fetch-anaconda-iso

- name: Run container export test
run: |
BOOTC_SKIP_PACKAGE=1 just test-container-export

Expand Down
50 changes: 45 additions & 5 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,13 @@ nocache := env("BOOTC_nocache", "")
_nocache_arg := if nocache != "" { "--no-cache" } else { "" }
_baseconfigs_env := if baseconfigs != "" { "--env=BOOTC_baseconfigs=" + baseconfigs } else { "" }
testimage_label := "bootc.testimage=1"
lbi_images := "quay.io/curl/curl:latest quay.io/curl/curl-base:latest registry.access.redhat.com/ubi9/podman:latest"
lbi_images := "quay.io/curl/curl:latest quay.io/curl/curl-base:latest docker.io/library/alpine:latest"
# Extra images pre-pulled on the GHA host so they are available via --bind-storage-ro
# inside test VMs without hitting the registry mid-test:
# bib_image: used by test-33-bib-build (needs --bind-storage-ro on plan-33)
# lbi_switch_images: additional bound images used by test-21-logically-bound-switch
bib_image := "quay.io/centos-bootc/bootc-image-builder:latest"
lbi_switch_images := "docker.io/library/alpine:3.19 docker.io/library/alpine:3.18 docker.io/library/alpine:latest"
fedora-coreos := "quay.io/fedora/fedora-coreos:testing-devel"
generic_buildargs := ""
_extra_src_args := if extra_src != "" { "-v " + extra_src + ":/run/extra-src:ro --security-opt=label=disable" } else { "" }
Expand Down Expand Up @@ -134,6 +140,15 @@ build-fetch: _keygen package
for img in {{lbi_images}}; do
retry podman pull -q "$img"
done
# Pull images that are needed at runtime inside test VMs via --bind-storage-ro.
# These are NOT baked into the test container image; instead they are made
# available to the VM through the virtiofs host-storage mount that bcvk
# sets up when a plan requests try_bind_storage.
# bib_image: bootc-image-builder, used by plan-33-bib-build
# lbi_switch_images: bound images used by plan-21-logically-bound-switch
for img in {{bib_image}} {{lbi_switch_images}}; do
retry podman pull -q "$img"
done

pkg_path=$(realpath target/packages)

Expand Down Expand Up @@ -186,6 +201,7 @@ build-sealed:
[group('core')]
test-tmt *ARGS: build
@just _build-upgrade-image
@just _build-selinux-policy-image
@just test-tmt-nobuild {{ARGS}}

# Split out from `test-container` because, unlike the container integration tests,
Expand Down Expand Up @@ -261,9 +277,11 @@ validate:
cargo xtask update-generated direct --check
podman build {{base_buildargs}} --target validate-post-build .

# Test container export via Anaconda liveimg install in a QEMU VM
# Fetch the Anaconda boot ISO needed for the container export test.
# Run this as an explicit init step (with retry) before test-container-export
# so that transient network failures are isolated from the actual test run.
[group('testing')]
test-container-export: build
fetch-anaconda-iso: build
#!/bin/bash
set -xeuo pipefail
iso=target/anaconda-test/boot.iso
Expand All @@ -279,7 +297,20 @@ test-container-export: build
echo "Unsupported OS: ${ID}-${VERSION_ID}" >&2; exit 1 ;;
esac
mkdir -p target/anaconda-test
curl -L --retry 3 --progress-bar -o "$iso" "$url"
curl -L --retry 5 --retry-delay 30 --progress-bar -o "$iso" "$url"
fi

# Test container export via Anaconda liveimg install in a QEMU VM.
# Requires the ISO to already be present; run `just fetch-anaconda-iso` first
# (or let the CI "Fetch Anaconda boot ISO" step handle it).
[group('testing')]
test-container-export: build
#!/bin/bash
set -xeuo pipefail
iso=target/anaconda-test/boot.iso
if [ ! -f "$iso" ]; then
echo "ERROR: $iso not found. Run 'just fetch-anaconda-iso' first." >&2
exit 1
fi
cargo run -p tests-integration -- anaconda-test --iso "$iso" {{base_img}}

Expand Down Expand Up @@ -519,6 +550,15 @@ _build-upgrade-image:
_build-upgrade-source-image:
podman build --build-arg=base={{base}} --build-arg=variant={{variant}} -t {{upgrade_source_img}} -f tmt/tests/Dockerfile.upgrade-source .

# Build the pre-baked SELinux policy derived image used by test-29.
# Extends localhost/bootc with selinux-policy-devel + a custom policy module already
# installed, so the test VM does not need network access to dnf-install those tools.
# The resulting image is exposed to the test VM via --bind-storage-ro.
selinux_policy_img := base_img + "-selinux-tools"

_build-selinux-policy-image:
podman build -t {{selinux_policy_img}} -f hack/Containerfile.selinux-policy .

# Copy an image from user podman storage to root's podman storage
# This allows building as regular user then running privileged tests
[group('testing')]
Expand Down Expand Up @@ -559,6 +599,6 @@ copy-to-rootful $image:
copy-lbi-to-rootful:
#!/bin/bash
set -euxo pipefail
for img in {{lbi_images}}; do
for img in {{lbi_images}} {{bib_image}} {{lbi_switch_images}} {{selinux_policy_img}}; do
just copy-to-rootful "$img"
done
5 changes: 5 additions & 0 deletions crates/xtask/src/tmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ const FIELD_FIXME_SKIP_IF_UKI: &str = "fixme_skip_if_uki";

// bcvk options
const BCVK_OPT_BIND_STORAGE_RO: &str = "--bind-storage-ro";
const BCVK_OPT_RESTRICT_NETWORK: &str = "--restrict-network";
const ENV_BOOTC_UPGRADE_IMAGE: &str = "BOOTC_upgrade_image";

// Distro identifiers
Expand Down Expand Up @@ -517,6 +518,10 @@ pub(crate) fn run_tmt(sh: &Shell, args: &RunTmtArgs) -> Result<()> {

let mut opts = Vec::new();

// Block outbound internet from the VM during test execution.
// Inbound SSH port-forward still works so tmt can reach the VM.
opts.push(BCVK_OPT_RESTRICT_NETWORK.to_string());

// If test wants bind storage and distro supports it, add --bind-storage-ro
if try_bind_storage && supports_bind_storage_ro {
opts.push(BCVK_OPT_BIND_STORAGE_RO.to_string());
Expand Down
45 changes: 45 additions & 0 deletions hack/Containerfile.selinux-policy
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Pre-built derived image used by test-29 (soft-reboot-selinux-policy).
#
# Building this in the CI build phase (network-allowed) avoids a live dnf
# install inside the test VM, which would be a network access mid-test.
#
# What this does:
# 1. Installs SELinux policy build tools into localhost/bootc
# 2. Compiles and installs a minimal custom policy module, which changes
# the compiled policy checksum relative to the base image
# 3. Cleans up build artifacts so the image passes standard lint checks
#
# The resulting image is exposed to the test VM via --bind-storage-ro and
# pulled into bootc storage before the switch/soft-reboot attempt.
FROM localhost/bootc

# Install tools needed to build and install SELinux policy modules.
# The packages are available from the base image's own repos (no extra
# repo file needed: localhost/bootc is derived from a centos/fedora/rhel
# base that ships these in standard repositories).
RUN dnf install -y selinux-policy-devel checkpolicy policycoreutils \
&& dnf clean all \
&& rm -rf /var/log/dnf* /var/log/hawkey.log /var/log/rhsm \
/var/cache/dnf /var/lib/dnf /var/lib/rhsm

# Create a minimal SELinux policy module and install it.
# Installing a module changes the compiled policy checksum, which is exactly
# what test-29 needs to verify that soft-reboot is blocked when policies differ.
RUN <<EORUN
set -eux
mkdir -p /tmp/bootc-test-policy
cd /tmp/bootc-test-policy
cat > bootc_test_policy.te <<'EOF'
module bootc_test_policy 1.0;
require {
type unconfined_t;
class file { read write };
}
type bootc_test_t;
EOF
checkmodule -M -m -o bootc_test_policy.mod bootc_test_policy.te
semodule_package -o bootc_test_policy.pp -m bootc_test_policy.mod
semodule -i bootc_test_policy.pp
rm -rf /tmp/bootc-test-policy
rm -rf /var/lib/sepolgen /var/cache/ldconfig
EORUN
2 changes: 1 addition & 1 deletion hack/lbi/podman.image
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
[Image]
Image=registry.access.redhat.com/ubi9/podman:latest
Image=docker.io/library/alpine:latest

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But this isn't podman anymore...

2 changes: 2 additions & 0 deletions hack/packages.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,5 @@ dosfstools
e2fsprogs
# Required by bib-build test
qemu-img
# Required by 030-test-composefs.nu (pre-fetches busybox OCI image during build)
skopeo
10 changes: 10 additions & 0 deletions hack/provision-fetch.sh
Original file line number Diff line number Diff line change
Expand Up @@ -89,3 +89,13 @@ fi
dnf clean all
# Clean logs and caches
rm /var/log/* /var/cache /var/lib/{dnf,rpm-state,rhsm} -rf

# Pre-fetch the busybox OCI image for the composefs cfs pull test
# (030-test-composefs.nu). We save it as an OCI layout so the test can
# use "oci:" transport instead of "docker://" and avoid a live registry
# pull inside the test VM. This runs after dnf clean so it doesn't affect
# the dnf cache, but still within the network-allowed fetch stage.
mkdir -p /usr/share/bootc-test/busybox-oci
skopeo copy --retry-times 5 \
docker://docker.io/library/busybox:latest \
oci:/usr/share/bootc-test/busybox-oci
8 changes: 7 additions & 1 deletion tmt/plans/integration.fmf
Original file line number Diff line number Diff line change
Expand Up @@ -31,13 +31,14 @@ prepare:
# Work around https://github.com/bootc-dev/bootc/issues/1896
- cd bootc && rpm2cpio *.src.rpm > pkg.cpio && cpio -idmv < pkg.cpio && rm pkg.cpio && rm -f *-vendor.tar.zstd && zstd -d *.tar.zstd && tar -xvf *.tar -C . --strip-components=1 && ls -al
- pwd && ls -al && cd bootc/hack && ./provision-packit.sh
- cp bootc/hack/packit-reboot.yml /tmp/packit-reboot.yml
when: running_env != image_mode
# tmt-reboot and reboot do not work in this case
# reboot in ansible is the only way to reboot in tmt prepare
- how: ansible
order: 99
playbook:
- https://github.com/bootc-dev/bootc/raw/refs/heads/main/hack/packit-reboot.yml
- /tmp/packit-reboot.yml
when: running_env != image_mode
execute:
how: tmt
Expand All @@ -64,6 +65,7 @@ execute:
how: fmf
test:
- /tmt/tests/tests/test-21-logically-bound-switch
extra-try_bind_storage: true
extra-fixme_skip_if_composefs: true

/plan-22-logically-bound-install:
Expand Down Expand Up @@ -136,6 +138,7 @@ execute:
how: fmf
test:
- /tmt/tests/tests/test-29-soft-reboot-selinux-policy
extra-try_bind_storage: true
extra-fixme_skip_if_uki: true

/plan-30-install-unified-flag:
Expand All @@ -144,6 +147,7 @@ execute:
how: fmf
test:
- /tmt/tests/tests/test-30-install-unified-flag
extra-try_bind_storage: true
extra-fixme_skip_if_composefs: true

/plan-31-switch-mutate-in-place:
Expand Down Expand Up @@ -182,6 +186,7 @@ execute:
how: fmf
test:
- /tmt/tests/tests/test-33-bib-build
extra-try_bind_storage: true
extra-fixme_skip_if_composefs: true

/plan-34-user-agent:
Expand Down Expand Up @@ -249,6 +254,7 @@ execute:
how: fmf
test:
- /tmt/tests/tests/test-40-install-karg-delete
extra-try_bind_storage: true
extra-fixme_skip_if_composefs: true

/plan-41-composefs-gc-uki:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ if not $has_storage {
# And verify this works
bootc image cmd list -q o>/dev/null

bootc image cmd pull busybox
bootc image cmd pull oci:/usr/share/bootc-test/busybox-oci
podman --storage-opt=additionalimagestore=/usr/lib/bootc/storage image exists busybox

# Images in bootc storage should be listed with type "unified"
Expand Down
2 changes: 1 addition & 1 deletion tmt/tests/booted/readonly/030-test-composefs.nu
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ if $is_composefs {
# we can't get from `bootc internals cfs ...`
mkdir /var/tmp/sysroot/composefs
bootc internals cfs --insecure --repo /var/tmp/sysroot/composefs init
bootc internals cfs --insecure --repo /var/tmp/sysroot/composefs oci pull docker://busybox busybox
bootc internals cfs --insecure --repo /var/tmp/sysroot/composefs oci pull oci:/usr/share/bootc-test/busybox-oci busybox
test -L /var/tmp/sysroot/composefs/streams/refs/oci/busybox
}

Expand Down
6 changes: 3 additions & 3 deletions tmt/tests/booted/tap.nu
Original file line number Diff line number Diff line change
Expand Up @@ -39,17 +39,17 @@ export def get_target_image [] {

# If map not found, use default centos-9 image
if not ($map_path | path exists) {
return "docker://quay.io/centos-bootc/centos-bootc:stream9"
return "containers-storage:quay.io/centos-bootc/centos-bootc:stream9"
}

let image_map = (open $map_path)

let image = $image_map.base | get -i $key
if ($image | is-empty) {
# Fallback to centos-9 if key not found
$"docker://($image_map.base.centos-9)"
$"containers-storage:($image_map.base.centos-9)"
} else {
$"docker://($image)"
$"containers-storage:($image)"
}
}

Expand Down
1 change: 1 addition & 0 deletions tmt/tests/booted/test-bib-build.nu
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
# - qemu-img
# extra:
# fixme_skip_if_composefs: true
# try_bind_storage: true
#
# This test validates that bootc-image-builder (bib) can successfully
# create disk images from the current booted image. This is a critical
Expand Down
1 change: 1 addition & 0 deletions tmt/tests/booted/test-install-karg-delete.nu
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
# summary: Test bootc install --karg-delete
# duration: 30m
# extra:
# try_bind_storage: true
# fixme_skip_if_composefs: true
#
use std assert
Expand Down
1 change: 1 addition & 0 deletions tmt/tests/booted/test-install-unified-flag.nu
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# number: 30
# extra:
# try_bind_storage: true
# fixme_skip_if_composefs: true
# tmt:
# summary: Test bootc install with experimental unified storage flag
Expand Down
2 changes: 1 addition & 1 deletion tmt/tests/booted/test-logically-bound-install.nu
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use tap.nu
let expected_images = [
"quay.io/curl/curl:latest",
"quay.io/curl/curl-base:latest",
"registry.access.redhat.com/ubi9/podman:latest" # this image is signed
"docker.io/library/alpine:latest"
]

def validate_images [images: list<string>] {
Expand Down
Loading
Loading