Skip to content

Commit 3067f33

Browse files
committed
test: Add integration test running on github runner
Signed-off-by: Xiaofeng Wang <[email protected]>
1 parent 735a0b0 commit 3067f33

File tree

5 files changed

+323
-0
lines changed

5 files changed

+323
-0
lines changed

.github/workflows/integration.yml

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
name: bootc integration test
2+
on:
3+
pull_request:
4+
branches: [main]
5+
6+
jobs:
7+
build:
8+
strategy:
9+
matrix:
10+
test_os: [fedora-42]
11+
12+
runs-on: ubuntu-latest
13+
14+
steps:
15+
- name: Install podman for heredoc support
16+
run: |
17+
set -eux
18+
echo 'deb [trusted=yes] https://ftp.debian.org/debian/ testing main' | sudo tee /etc/apt/sources.list.d/testing.list
19+
sudo apt update
20+
sudo apt install -y crun/testing podman/testing
21+
22+
- uses: actions/checkout@v4
23+
24+
- name: Build bootc and bootc image
25+
env:
26+
TEST_OS: ${{ matrix.test_os }}
27+
run: tests/build.sh
28+
29+
- name: Archive bootc disk image - disk.raw
30+
uses: actions/upload-artifact@v4
31+
with:
32+
name: PR-${{ github.event.number }}-${{ matrix.test_os }}-disk
33+
path: /tmp/tmp-bootc-build/disk.raw
34+
retention-days: 1
35+
36+
- name: Archive SSH private key - id_rsa
37+
uses: actions/upload-artifact@v4
38+
with:
39+
name: PR-${{ github.event.number }}-${{ matrix.test_os }}-id_rsa
40+
path: /tmp/tmp-bootc-build/id_rsa
41+
retention-days: 1
42+
43+
test:
44+
needs: build
45+
strategy:
46+
matrix:
47+
test_os: [fedora-42]
48+
tmt_plan: [test-01-readonly, test-20-local-upgrade, test-21-logically-bound-switch, test-22-logically-bound-install, test-23-install-outside-container, test-24-local-upgrade-reboot]
49+
50+
runs-on: ubuntu-latest
51+
52+
steps:
53+
- uses: actions/checkout@v4
54+
55+
- name: Install dependence
56+
run: |
57+
sudo apt-get update
58+
sudo apt install -y qemu-kvm qemu-system
59+
pip install --user tmt
60+
61+
- name: Create folder to save disk image
62+
run: mkdir -p /tmp/tmp-bootc-build
63+
64+
- name: Download disk.raw
65+
uses: actions/download-artifact@v4
66+
with:
67+
name: PR-${{ github.event.number }}-${{ matrix.test_os }}-disk
68+
path: /tmp/tmp-bootc-build
69+
70+
- name: Download id_rsa
71+
uses: actions/download-artifact@v4
72+
with:
73+
name: PR-${{ github.event.number }}-${{ matrix.test_os }}-id_rsa
74+
path: /tmp/tmp-bootc-build
75+
76+
- name: Run test
77+
env:
78+
TMT_PLAN_NAME: ${{ matrix.tmt_plan }}
79+
run: chmod 600 /tmp/tmp-bootc-build/id_rsa && tests/test.sh
80+
81+
- name: Archive TMT logs
82+
if: always()
83+
uses: actions/upload-artifact@v4
84+
with:
85+
name: tmt-log-PR-${{ github.event.number }}-${{ matrix.test_os }}-${{ matrix.tmt_plan }}
86+
path: /var/tmp/tmt

Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,9 @@ test-bin-archive: all
6666
test-tmt:
6767
cargo xtask test-tmt
6868

69+
test:
70+
tests/build.sh && tests/test.sh
71+
6972
# This gates CI by default. Note that for clippy, we gate on
7073
# only the clippy correctness and suspicious lints, plus a select
7174
# set of default rustc warnings.

tests/build.sh

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#!/bin/bash
2+
set -exuo pipefail
3+
4+
# This script basically builds bootc from source using the provided base image,
5+
# then runs the target tests.
6+
7+
mkdir -p /tmp/tmp-bootc-build
8+
BOOTC_TEMPDIR="/tmp/tmp-bootc-build"
9+
10+
# Get OS info from TEST_OS env
11+
OS_ID=$(echo "$TEST_OS" | cut -d '-' -f 1)
12+
OS_VERSION_ID=$(echo "$TEST_OS" | cut -d '-' -f 2)
13+
14+
# Base image
15+
case "$OS_ID" in
16+
"centos")
17+
TIER1_IMAGE_URL="quay.io/centos-bootc/centos-bootc:stream${OS_VERSION_ID}"
18+
;;
19+
"fedora")
20+
TIER1_IMAGE_URL="quay.io/fedora/fedora-bootc:${OS_VERSION_ID}"
21+
;;
22+
esac
23+
24+
CONTAINERFILE="${BOOTC_TEMPDIR}/Containerfile"
25+
tee "$CONTAINERFILE" > /dev/null << CONTAINERFILEOF
26+
FROM $TIER1_IMAGE_URL as build
27+
28+
WORKDIR /code
29+
30+
RUN <<EORUN
31+
set -xeuo pipefail
32+
. /usr/lib/os-release
33+
case \$ID in
34+
centos|rhel) dnf config-manager --set-enabled crb;;
35+
fedora) dnf -y install dnf-utils 'dnf5-command(builddep)';;
36+
esac
37+
dnf -y builddep contrib/packaging/bootc.spec
38+
dnf -y install git-core
39+
EORUN
40+
41+
RUN mkdir -p /build/target/dev-rootfs
42+
# git config --global --add safe.directory /code to fix "fatal: detected dubious ownership in repository at '/code'" error
43+
RUN --mount=type=cache,target=/build/target --mount=type=cache,target=/var/roothome git config --global --add safe.directory /code && make test-bin-archive && mkdir -p /out && cp target/bootc.tar.zst /out
44+
45+
FROM $TIER1_IMAGE_URL
46+
47+
# Inject our built code
48+
COPY --from=build /out/bootc.tar.zst /tmp
49+
RUN tar -C / --zstd -xvf /tmp/bootc.tar.zst && rm -vrf /tmp/*
50+
51+
RUN <<EORUN
52+
set -xeuo pipefail
53+
54+
# Provision test requirement
55+
/code/hack/provision-derived.sh
56+
# Also copy in some default install configs we use for testing
57+
cp -a /code/hack/install-test-configs/* /usr/lib/bootc/install/
58+
# And some test kargs
59+
cp -a /code/hack/test-kargs/* /usr/lib/bootc/kargs.d/
60+
61+
# For testing farm
62+
mkdir -p -m 0700 /var/roothome
63+
64+
# Enable ttyS0 console
65+
mkdir -p /usr/lib/bootc/kargs.d/
66+
cat <<KARGEOF >> /usr/lib/bootc/kargs.d/20-console.toml
67+
kargs = ["console=ttyS0,115200n8"]
68+
KARGEOF
69+
70+
# For test-22-logically-bound-install
71+
cp -a /code/tmt/tests/lbi/usr/. /usr
72+
ln -s /usr/share/containers/systemd/curl.container /usr/lib/bootc/bound-images.d/curl.container
73+
ln -s /usr/share/containers/systemd/curl-base.image /usr/lib/bootc/bound-images.d/curl-base.image
74+
ln -s /usr/share/containers/systemd/podman.image /usr/lib/bootc/bound-images.d/podman.image
75+
76+
# Install rsync which is required by tmt
77+
dnf -y install cloud-init rsync
78+
dnf -y clean all
79+
80+
rm -rf /var/cache /var/lib/dnf
81+
EORUN
82+
CONTAINERFILEOF
83+
84+
LOCAL_IMAGE="localhost/bootc:test"
85+
sudo podman build \
86+
--retry 5 \
87+
--retry-delay 5s \
88+
-v "$(pwd)":/code:z \
89+
-t "$LOCAL_IMAGE" \
90+
-f "$CONTAINERFILE" \
91+
"$BOOTC_TEMPDIR"
92+
93+
SSH_KEY=${BOOTC_TEMPDIR}/id_rsa
94+
ssh-keygen -f "${SSH_KEY}" -N "" -q -t rsa-sha2-256 -b 2048
95+
96+
sudo truncate -s 10G "${BOOTC_TEMPDIR}/disk.raw"
97+
98+
# For test-22-logically-bound-install
99+
sudo podman pull --retry 5 --retry-delay 5s quay.io/curl/curl:latest
100+
sudo podman pull --retry 5 --retry-delay 5s quay.io/curl/curl-base:latest
101+
sudo podman pull --retry 5 --retry-delay 5s registry.access.redhat.com/ubi9/podman:latest
102+
103+
sudo podman run \
104+
--rm \
105+
--privileged \
106+
--pid=host \
107+
--security-opt label=type:unconfined_t \
108+
-v /var/lib/containers:/var/lib/containers \
109+
-v /dev:/dev \
110+
-v "$BOOTC_TEMPDIR":/output \
111+
"$LOCAL_IMAGE" \
112+
bootc install to-disk \
113+
--filesystem "xfs" \
114+
--root-ssh-authorized-keys "/output/id_rsa.pub" \
115+
--karg=console=ttyS0,115200n8 \
116+
--generic-image \
117+
--via-loopback \
118+
/output/disk.raw

tests/test.sh

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/bin/bash
2+
set -exuo pipefail
3+
4+
# This script runs disk image with qemu-system and run tmt against this vm.
5+
6+
BOOTC_TEMPDIR="/tmp/tmp-bootc-build"
7+
SSH_OPTIONS=(-o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o ConnectTimeout=5)
8+
SSH_KEY=${BOOTC_TEMPDIR}/id_rsa
9+
10+
ARCH=$(uname -m)
11+
case "$ARCH" in
12+
"aarch64")
13+
sudo qemu-system-aarch64 \
14+
-name bootc-vm \
15+
-enable-kvm \
16+
-machine virt \
17+
-cpu host \
18+
-m 2G \
19+
-bios /usr/share/AAVMF/AAVMF_CODE.fd \
20+
-drive file="${BOOTC_TEMPDIR}/disk.raw",if=virtio,format=raw \
21+
-net nic,model=virtio \
22+
-net user,hostfwd=tcp::2222-:22 \
23+
-display none \
24+
-daemonize
25+
;;
26+
"x86_64")
27+
sudo qemu-system-x86_64 \
28+
-name bootc-vm \
29+
-enable-kvm \
30+
-cpu host \
31+
-m 2G \
32+
-drive file="${BOOTC_TEMPDIR}/disk.raw",if=virtio,format=raw \
33+
-net nic,model=virtio \
34+
-net user,hostfwd=tcp::2222-:22 \
35+
-display none \
36+
-daemonize
37+
;;
38+
*)
39+
echo "Only support x86_64 and aarch64" >&2
40+
exit 1
41+
;;
42+
esac
43+
44+
wait_for_ssh_up() {
45+
SSH_STATUS=$(ssh "${SSH_OPTIONS[@]}" -i "$SSH_KEY" -p 2222 root@"${1}" '/bin/bash -c "echo -n READY"')
46+
if [[ $SSH_STATUS == READY ]]; then
47+
echo 1
48+
else
49+
echo 0
50+
fi
51+
}
52+
53+
for _ in $(seq 0 30); do
54+
RESULT=$(wait_for_ssh_up "localhost")
55+
if [[ $RESULT == 1 ]]; then
56+
echo "SSH is ready now! 🥳"
57+
break
58+
fi
59+
sleep 10
60+
done
61+
62+
# Make sure VM is ready for testing
63+
ssh "${SSH_OPTIONS[@]}" \
64+
-i "$SSH_KEY" \
65+
-p 2222 \
66+
root@localhost \
67+
"bootc status"
68+
69+
# TMT will rsync tmt-* scripts to TMT_SCRIPTS_DIR=/var/lib/tmt/scripts
70+
tmt run --all --verbose -e TMT_SCRIPTS_DIR=/var/lib/tmt/scripts provision --how connect --guest localhost --port 2222 --user root --key "$SSH_KEY" plan --name "/tmt/plans/bootc-integration/${TMT_PLAN_NAME}"

tmt/plans/bootc-integration.fmf

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
execute:
2+
how: tmt
3+
4+
/test-01-readonly:
5+
summary: Execute booted readonly/nondestructive tests
6+
discover:
7+
how: fmf
8+
test:
9+
- /tmt/tests/test-01-readonly
10+
11+
/test-20-local-upgrade:
12+
summary: Execute local upgrade tests
13+
discover:
14+
how: fmf
15+
test:
16+
- /tmt/tests/test-20-local-upgrade
17+
18+
/test-21-logically-bound-switch:
19+
summary: Execute logically bound images tests for switching images
20+
discover:
21+
how: fmf
22+
test:
23+
- /tmt/tests/test-21-logically-bound-switch
24+
25+
/test-22-logically-bound-install:
26+
summary: Execute logically bound images tests for switching images
27+
environment+:
28+
LBI: enabled
29+
discover:
30+
how: fmf
31+
test:
32+
- /tmt/tests/test-22-logically-bound-install
33+
34+
/test-23-install-outside-container:
35+
summary: Execute tests for installing outside of a container
36+
discover:
37+
how: fmf
38+
test:
39+
- /tmt/tests/test-23-install-outside-container
40+
41+
/test-24-local-upgrade-reboot:
42+
summary: Execute local upgrade tests with automated reboot
43+
discover:
44+
how: fmf
45+
test:
46+
- /tmt/tests/test-24-local-upgrade-reboot

0 commit comments

Comments
 (0)