From 279fe3f578b9f6067bdf1721348200e67d5db918 Mon Sep 17 00:00:00 2001 From: Evan Goode Date: Thu, 31 Oct 2024 12:29:31 -0400 Subject: [PATCH] Build bootc VM image for dnf4 bootc tests --- bootc/Containerfile | 86 ++++++++++++++++++++++++++ container-test | 79 ++++++++++++++++++++++- plans/integration/bootc-behave-dnf.fmf | 13 ++++ 3 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 bootc/Containerfile create mode 100644 plans/integration/bootc-behave-dnf.fmf diff --git a/bootc/Containerfile b/bootc/Containerfile new file mode 100644 index 000000000..62612a1b8 --- /dev/null +++ b/bootc/Containerfile @@ -0,0 +1,86 @@ +# Example Usage: +# $ podman build --build-arg TYPE=distro -t ci-dnf-stack -f Dockerfile +# $ podman run --net none -it ci-dnf-stack behave dnf + +ARG BASE=quay.io/fedora/fedora-bootc:40 +FROM $BASE + +ENV LANG C.UTF-8 +ARG TYPE=nightly + +# disable deltas and weak deps +RUN set -x && \ + echo -e "deltarpm=0" >> /etc/dnf/dnf.conf && \ + echo -e "install_weak_deps=0" >> /etc/dnf/dnf.conf + +# Import extra CA certificates +COPY ./ca-trust/ /etc/pki/ca-trust/source/anchors/ +RUN update-ca-trust + +# Copy extra repo files +COPY ./repos.d/ /etc/yum.repos.d/ + +# enable dnf5 +RUN set -x && \ + dnf -y --refresh upgrade; \ + dnf -y install dnf5 dnf5-plugins; \ + dnf5 -y copr enable rpmsoftwaremanagement/test-utils; \ + dnf5 -y copr enable rpmsoftwaremanagement/dnf-nightly; \ + # run upgrade before distro-sync in case there is a new version in dnf-nightly that has a new dependency + dnf5 -y upgrade; \ + dnf5 -y distro-sync --repo copr:copr.fedorainfracloud.org:rpmsoftwaremanagement:dnf-nightly; + +RUN set -x && \ + if [ -n "$COPR" ] && [ -n "$COPR_RPMS" ]; then \ + dnf5 -y copr enable $COPR; \ + dnf5 -y install $COPR_RPMS; \ + fi + +# TMT +RUN <> /opt/testcloud-guest.sh +chmod +x /opt/testcloud-guest.sh +echo "[Unit]" >> /etc/systemd/system/testcloud.service +echo "Description=Testcloud guest integration" >> /etc/systemd/system/testcloud.service +echo "After=cloud-init.service" >> /etc/systemd/system/testcloud.service +echo "[Service]" >> /etc/systemd/system/testcloud.service +echo "ExecStart=/bin/bash /opt/testcloud-guest.sh" >> /etc/systemd/system/testcloud.service +echo "[Install]" >> /etc/systemd/system/testcloud.service +echo "WantedBy=multi-user.target" >> /etc/systemd/system/testcloud.service +systemctl enable testcloud.service +EOF + +# copy test suite +COPY ./dnf-behave-tests/ /opt/ci/dnf-behave-tests + +# install test suite dependencies +RUN set -x && \ + dnf5 -y builddep /opt/ci/dnf-behave-tests/requirements.spec && \ + pip3 install -r /opt/ci/dnf-behave-tests/requirements.txt + +# install local RPMs if available +COPY ./rpms/ /opt/ci/rpms/ +RUN rm /opt/ci/rpms/*-{devel,debuginfo,debugsource}*.rpm; \ + if [ -n "$(find /opt/ci/rpms/ -maxdepth 1 -name '*.rpm' -print -quit)" ]; then \ + dnf5 -y install /opt/ci/rpms/*.rpm --disableplugin=local; \ + fi + +# create directory for dbus daemon socket +RUN set -x && \ + mkdir -p /run/dbus + +RUN set -x && \ + rm -rf "/opt/ci/dnf-behave-tests/fixtures/certificates/testcerts/" && \ + rm -rf "/opt/ci/dnf-behave-tests/fixtures/gpgkeys/keys/" && \ + rm -rf "/opt/ci/dnf-behave-tests/fixtures/repos/" + +# build test repos from sources +RUN set -x && \ + cd /opt/ci/dnf-behave-tests/fixtures/specs/ && \ + ./build.sh --force-rebuild + +WORKDIR /opt/ci/dnf-behave-tests diff --git a/container-test b/container-test index d8cbfbfd8..096a39e5c 100755 --- a/container-test +++ b/container-test @@ -30,7 +30,7 @@ def command_line_parser(): help="Test suite to run (directory with *.feature files)") parser.add_argument( "-c", "--container", metavar="IMAGE", - default='dnf-bot/dnf-testing:latest', + default='localhost/dnf-bot/dnf-testing:latest', help="Specified Image ID or name if do not want to run the last built image") parser.add_argument( "-d", "--devel", action="store_true", default=False, @@ -64,6 +64,29 @@ def command_line_parser(): "--container-arg", metavar="", dest="container_args", action="append", help='Additional argument for the docker/podman build command. Can be specified multiple times.') + # bootc-build command + # TODO + bootc_build_parser = subparsers.add_parser( + 'bootc_build', help="Build a container with functional tests") + bootc_build_parser.add_argument( + "-f", "--file", metavar="FILE", dest="docker_file", + default="bootc/Containerfile", help="Path to Containerfile to use") + bootc_build_parser.add_argument( + "--usecache", action="store_true", default=False, + help="Use cache when building the image") + bootc_build_parser.add_argument( + "--type", metavar="", + help='Build type for the image, e.g. "nightly" or "distro". Needs to be supported by the Containerfile.') + bootc_build_parser.add_argument( + "--base", metavar="", + help='Base image to override the FROM clause in the Dockerfile.') + bootc_build_parser.add_argument( + "--container-arg", metavar="", dest="container_args", action="append", + help='Additional argument for the docker/podman build command. Can be specified multiple times.') + bootc_build_parser.add_argument( + "--bootc-output", metavar="DIRECTORY", dest="bootc_output", + default="./build", help="Path to a directory to store bootc image") + # run command run_parser = subparsers.add_parser( 'run', @@ -433,6 +456,60 @@ class BehaveRunner(object): if returncode > 0: error('Failed to build the container.') + def command_bootc_build(self): + ''' + Build bootc VM image for testing + ''' + command = self.docker_bin + ['build', '--force-rm'] + command += self.param_cache + + if self.command_line_args.type is not None: + command += ['--build-arg', 'TYPE={}'.format(self.command_line_args.type)] + + if self.command_line_args.base is not None: + command += ['--build-arg', 'BASE={}'.format(self.command_line_args.base)] + + command += ['-t', self.command_line_args.container] + command += ['-f', self.command_line_args.docker_file, PROGPATH] + + if self.command_line_args.container_args: + command += self.command_line_args.container_args + + if self.command_line_args.verbose: + print("Running command:", command, '\n') + + returncode = subprocess.call(command) + if returncode > 0: + error('Failed to build the container.') + + breakpoint() + + builder_image = "quay.io/centos-bootc/bootc-image-builder:latest" + command = self.docker_bin + ["pull", builder_image] + returncode = subprocess.call(command) + if returncode > 0: + error("Failed to pull builder image {}".format(builder_image)) + + output_dir = os.path.realpath(self.command_line_args.bootc_output) + os.makedirs(output_dir, exist_ok=True) + + # See https://github.com/osbuild/bootc-image-builder#-examples + command = self.docker_bin + [ + "run", "--rm", "--privileged", + "-v", "/var/lib/containers/storage:/var/lib/containers/storage", + "--security-opt", "label=type:unconfined_t", + "-v", "{}:/output".format(output_dir), + builder_image, + "--type", "qcow2", + "--rootfs", "ext4", + "--local", self.command_line_args.container] + + print(command) + + returncode = subprocess.call(command) + if returncode > 0: + error("Failed to build qcow2 image") + if __name__ == '__main__': BehaveRunner()() diff --git a/plans/integration/bootc-behave-dnf.fmf b/plans/integration/bootc-behave-dnf.fmf new file mode 100644 index 000000000..90aa83f88 --- /dev/null +++ b/plans/integration/bootc-behave-dnf.fmf @@ -0,0 +1,13 @@ +provision: + how: virtual + image: file://./build/qcow2/disk.qcow2 + connection: system + disk: 20 +summary: Run bootc behave tests +tag: dnf +execute: + how: tmt + script: | + bash -c 'echo hello from bootc behave dnf' + # $TMT_PLANS_DATA/ci-dnf-stack/container-test run_bootc +