Skip to content

Commit 3bcac31

Browse files
committed
test: add bootc-installer image type test
Add an integration test that uses the new `bootc-installer` image type to perform a full install and validate that booting into the resulting image works.
1 parent 7a360fa commit 3bcac31

File tree

1 file changed

+122
-0
lines changed

1 file changed

+122
-0
lines changed

test/test_build_iso.py

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,17 @@
11
import os
2+
import random
3+
import json
24
import platform
5+
import string
36
import subprocess
7+
import textwrap
48
from contextlib import ExitStack
59

610
import pytest
711
# local test utils
812
import testutil
913
from containerbuild import build_container_fixture # pylint: disable=unused-import
14+
from containerbuild import make_container
1015
from testcases import gen_testcases
1116
from vm import QEMU
1217

@@ -83,3 +88,120 @@ def test_iso_install_img_is_squashfs(tmp_path, image_type):
8388
# was an intermediate ext4 image "squashfs-root/LiveOS/rootfs.img"
8489
output = subprocess.check_output(["unsquashfs", "-ls", mount_point / "images/install.img"], text=True)
8590
assert "usr/bin/bootc" in output
91+
92+
93+
@pytest.mark.skipif(platform.system() != "Linux", reason="boot test only runs on linux right now")
94+
@pytest.mark.parametrize("container_ref", [
95+
"quay.io/centos-bootc/centos-bootc:stream10",
96+
"quay.io/fedora/fedora-bootc:42",
97+
"quay.io/centos-bootc/centos-bootc:stream9",
98+
])
99+
def test_bootc_installer_iso_installs(tmp_path, build_container, container_ref):
100+
# XXX: duplicated from test_build_disk.py
101+
username = "test"
102+
password = "".join(
103+
random.choices(string.ascii_uppercase + string.digits, k=18))
104+
ssh_keyfile_private_path = tmp_path / "ssh-keyfile"
105+
ssh_keyfile_public_path = ssh_keyfile_private_path.with_suffix(".pub")
106+
if not ssh_keyfile_private_path.exists():
107+
subprocess.run([
108+
"ssh-keygen",
109+
"-N", "",
110+
# be very conservative with keys for paramiko
111+
"-b", "2048",
112+
"-t", "rsa",
113+
"-f", os.fspath(ssh_keyfile_private_path),
114+
], check=True)
115+
ssh_pubkey = ssh_keyfile_public_path.read_text(encoding="utf8").strip()
116+
cfg = {
117+
"customizations": {
118+
"user": [
119+
{
120+
"name": "root",
121+
"key": ssh_pubkey,
122+
# note that we have no "home" here for ISOs
123+
}, {
124+
"name": username,
125+
"password": password,
126+
"groups": ["wheel"],
127+
},
128+
],
129+
"kernel": {
130+
# XXX: we need https://github.com/osbuild/images/pull/1786 or no kargs are added to anaconda
131+
# XXX2: drop a bunch of the debug flags
132+
#
133+
# Use console=ttyS0 so that we see output in our debug
134+
# logs. by default anaconda prints to the last console=
135+
# from the kernel commandline
136+
"append": "systemd.debug-shell=1 rd.systemd.debug-shell=1 inst.debug console=ttyS0",
137+
},
138+
},
139+
}
140+
config_json_path = tmp_path / "config.json"
141+
config_json_path.write_text(json.dumps(cfg), encoding="utf-8")
142+
# create anaconda iso from base
143+
cntf_path = tmp_path / "Containerfile"
144+
cntf_path.write_text(textwrap.dedent(f"""\n
145+
FROM {container_ref}
146+
RUN dnf install -y \
147+
anaconda-core \
148+
anaconda-dracut \
149+
anaconda-install-img-deps \
150+
biosdevname \
151+
grub2-efi-x64-cdboot \
152+
net-tools \
153+
prefixdevname \
154+
python3-mako \
155+
lorax-templates-* \
156+
squashfs-tools \
157+
&& dnf clean all
158+
# shim-x64 is marked installed but the files are not in the expected
159+
# place for https://github.com/osbuild/osbuild/blob/v160/stages/org.osbuild.grub2.iso#L91, see
160+
# workaround via reinstall, we could add a config to the grub2.iso
161+
# stage to allow a different prefix that then would be used by
162+
# anaconda.
163+
# once https://github.com/osbuild/osbuild/pull/2202 is merged we
164+
# can update images/ to set the correct efi_src_dir and this can
165+
# be removed
166+
# see also https://bugzilla.redhat.com/show_bug.cgi?id=1750708
167+
RUN dnf reinstall -y shim-x64
168+
# lorax wants to create a symlink in /mnt which points to /var/mnt
169+
# on bootc but /var/mnt does not exist on some images.
170+
#
171+
# If https://gitlab.com/fedora/bootc/base-images/-/merge_requests/294
172+
# gets merged this will be no longer needed
173+
RUN mkdir /var/mnt
174+
"""), encoding="utf8")
175+
output_path = tmp_path / "output"
176+
output_path.mkdir()
177+
with make_container(tmp_path) as container_tag:
178+
cmd = [
179+
*testutil.podman_run_common,
180+
"-v", f"{config_json_path}:/config.json:ro",
181+
"-v", f"{output_path}:/output",
182+
"-v", "/var/tmp/osbuild-test-store:/store", # share the cache between builds
183+
"-v", "/var/lib/containers/storage:/var/lib/containers/storage",
184+
build_container,
185+
"--type", "bootc-installer",
186+
"--rootfs", "ext4",
187+
"--installer-payload-ref", container_ref,
188+
f"localhost/{container_tag}",
189+
]
190+
subprocess.check_call(cmd)
191+
installer_iso_path = output_path / "bootiso" / "install.iso"
192+
test_disk_path = installer_iso_path.with_name("test-disk.img")
193+
with open(test_disk_path, "w", encoding="utf8") as fp:
194+
fp.truncate(10_1000_1000_1000)
195+
# install to test disk
196+
with QEMU(test_disk_path, cdrom=installer_iso_path) as vm:
197+
vm.start(wait_event="qmp:RESET", snapshot=False, use_ovmf=True)
198+
vm.force_stop()
199+
# boot test disk and do extremly simple check
200+
with QEMU(test_disk_path) as vm:
201+
vm.start(use_ovmf=True)
202+
exit_status, _ = vm.run("true", user=username, password=password)
203+
assert exit_status == 0
204+
#assert_kernel_args(vm, image_type)
205+
exit_status, output = vm.run("bootc status", user="root", keyfile=ssh_keyfile_private_path)
206+
assert exit_status == 0
207+
assert f"Booted image: {container_ref}" in output

0 commit comments

Comments
 (0)