Skip to content

Commit

Permalink
Implement the bootc provision plugin (#3161)
Browse files Browse the repository at this point in the history
This creates a new provision plugin that is built on top of the
existing TestCloud (virtual) plugin. It adds new parameters to
pass a Containerfile or container image. The plugin will then
build a container image (if necessary) then build a bootc disk
image from the container image using bootc image builder.

Currently, bootc requires podman to be run as root when building a
disk image. This is typically handled by running a podman machine
as root.  When the podman connection is rootless=True, this will
automatically start a new rootful podman-machine to be used for
the bootc disk creation.

An additional parameter "add-tmt-dependencies" toggles building a
derived container image with the tmt test requirements.

Signed-off-by: Chris Kyrouac <[email protected]>
Co-authored-by: Petr Šplíchal <[email protected]>
  • Loading branch information
ckyrouac and psss authored Nov 21, 2024
1 parent 880c133 commit e8edeeb
Show file tree
Hide file tree
Showing 14 changed files with 595 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .packit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ jobs:
tf_extra_params:
test:
tmt:
name: /plans/provision/virtual
name: /plans/provision/(bootc|virtual)
environments:
- tmt:
context:
Expand Down
6 changes: 6 additions & 0 deletions docs/releases.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ environment files are found.
The ``tmt try`` command now supports the new
:ref:`/stories/cli/try/option/arch` option.

As a tech preview, a new :ref:`/plugins/provision/bootc` provision
plugin has been implemented. It takes a container image as input,
builds a bootc disk image from the container image, then uses the
:ref:`/plugins/provision/virtual.testcloud` plugin to create a
virtual machine using the bootc disk image.


tmt-1.38.0
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Expand Down
34 changes: 34 additions & 0 deletions plans/provision/bootc.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
summary: Bootc virtual machine via testcloud

description: |
Verify functionality of the bootc provision plugin.

discover:
how: fmf
filter: 'tag:provision-bootc'

prepare+:
- name: start-libvirtd
script: |
systemctl start libvirtd
systemctl status libvirtd

adjust+:
- enabled: true
when: how == provision

- provision:
hardware:
virtualization:
is-supported: true
memory: ">= 4 GB"
when: trigger == commit

- prepare+:
- name: Disable IPv6
how: shell
script:
- sysctl -w net.ipv6.conf.all.disable_ipv6=1
- sysctl -w net.ipv6.conf.default.disable_ipv6=1
because: Disable IPv6 in CI to avoid IPv6 connections that are disabled in CI
when: trigger == commit
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ provision-virtual = [
"testcloud>=0.11.3",
]
provision-container = []
provision-bootc = []
report-junit = [
# Required to support XML parsing and checking the XSD schemas.
"lxml>=4.6.5",
Expand All @@ -75,6 +76,7 @@ all = [
"tmt[test-convert]",
"tmt[export-polarion]",
"tmt[provision-container]",
"tmt[provision-bootc]",
"tmt[provision-virtual]",
"tmt[provision-beaker]",
"tmt[report-junit]",
Expand Down
1 change: 1 addition & 0 deletions tests/provision/bootc/data/.fmf/version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1
6 changes: 6 additions & 0 deletions tests/provision/bootc/data/includes-deps.containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
FROM quay.io/centos-bootc/centos-bootc:stream9

RUN dnf -y install cloud-init rsync && \
ln -s ../cloud-init.target /usr/lib/systemd/system/default.target.wants && \
rm /usr/local -rf && ln -sr /var/usrlocal /usr/local && mkdir -p /var/usrlocal/bin && \
dnf clean all
1 change: 1 addition & 0 deletions tests/provision/bootc/data/needs-deps.containerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FROM quay.io/centos-bootc/centos-bootc:stream9
45 changes: 45 additions & 0 deletions tests/provision/bootc/data/plans.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
discover:
how: fmf
provision:
how: bootc
disk: 20
execute:
how: tmt


/image:

/needs-deps:
summary: "Image that needs dependencies"
provision+:
add-tmt-dependencies: true
container-image: localhost/tmt-bootc-needs-deps
environment:
PATTERN: localhost/tmtmodified

/includes-deps:
summary: "Image that already includes dependencies"
provision+:
add-tmt-dependencies: false
container-image: localhost/tmt-bootc-includes-deps
environment:
PATTERN: localhost/tmt-bootc-includes-deps

/containerfile:

/needs-deps:
summary: "Containerfile that needs dependencies"
provision+:
add-tmt-dependencies: true
container-file: needs-deps.containerfile
environment:
PATTERN: localhost/tmtmodified

/includes-deps:
summary: "Containerfile that already includes dependencies"
provision:
how: bootc
add-tmt-dependencies: false
container-file: includes-deps.containerfile
environment:
PATTERN: localhost/tmtbase
2 changes: 2 additions & 0 deletions tests/provision/bootc/data/test.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
summary: Check that booted image matches expected pattern
test: "bootc status && bootc status | grep $PATTERN"
13 changes: 13 additions & 0 deletions tests/provision/bootc/main.fmf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
summary: Make sure that bootc provision method works
tag+:
- provision-only
- provision-bootc
require:
- tmt+provision-virtual
duration: 40m

# As for now there is an expected AVC failure:
# https://github.com/osbuild/bootc-image-builder/issues/645
check:
- how: avc
result: xfail
47 changes: 47 additions & 0 deletions tests/provision/bootc/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/bash
. /usr/share/beakerlib/beakerlib.sh || exit 1

IMAGE_NEEDS_DEPS="localhost/tmt-bootc-needs-deps"
IMAGE_INCLUDES_DEPS="localhost/tmt-bootc-includes-deps"

TESTCLOUD_IMAGE="/var/tmp/tmt/testcloud/images/disk.qcow2"


rlJournalStart
rlPhaseStartSetup
# Use /var/tmp/tmt so the temp directories are accessible
# in the podman machine mount
rlRun "mkdir -p /var/tmp/tmt"
rlRun "run=\$(mktemp -d --tmpdir=/var/tmp/tmt)" 0 "Create run directory"
rlRun "pushd data"
rlPhaseEnd

rlPhaseStartTest "Image that needs dependencies"
rlRun "podman build . -f needs-deps.containerfile -t $IMAGE_NEEDS_DEPS"
rlRun "tmt -vvv run --scratch -i $run plan --name /plans/image/needs-deps"
rlRun "rm -rf $TESTCLOUD_IMAGE"
rlPhaseEnd

rlPhaseStartTest "Image that already includes dependencies"
rlRun "podman build . -f includes-deps.containerfile -t $IMAGE_INCLUDES_DEPS"
rlRun "tmt -vvv run --scratch -i $run plan --name /plans/image/includes-deps"
rlRun "rm -rf $TESTCLOUD_IMAGE"
rlPhaseEnd

rlPhaseStartTest "Containerfile that needs dependencies"
rlRun "tmt -vvv run --scratch -i $run plan --name /plans/containerfile/needs-deps"
rlRun "rm -rf $TESTCLOUD_IMAGE"
rlPhaseEnd

rlPhaseStartTest "Containerfile that already includes dependencies"
rlRun "tmt -vvv run --scratch -i $run plan --name /plans/containerfile/includes-deps"
rlRun "rm -rf $TESTCLOUD_IMAGE"
rlPhaseEnd

rlPhaseStartCleanup
rlRun "popd"
rlRun "rm -r $run" 0 "Remove run directory"
rlRun "podman rmi $IMAGE_INCLUDES_DEPS" 0,1
rlRun "podman rmi $IMAGE_NEEDS_DEPS" 0,1
rlPhaseEnd
rlJournalEnd
11 changes: 11 additions & 0 deletions tmt.spec
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ Recommends: qemu-system-x86-core

%description -n tmt+provision-virtual %_metapackage_description

%package -n tmt+provision-bootc
Summary: Dependencies required for tmt bootc machine provisioner
Provides: tmt-provision-bootc == %{version}-%{release}
Requires: tmt == %{version}-%{release}
Requires: tmt+provision-virtual == %{version}-%{release}
Requires: podman
Recommends: podman-machine

%description -n tmt+provision-bootc %_metapackage_description

%package -n tmt+provision-beaker
Summary: Dependencies required for tmt beaker provisioner
Provides: tmt-provision-beaker == %{version}-%{release}
Expand Down Expand Up @@ -152,6 +162,7 @@ install -pm 644 %{name}/steps/provision/mrack/mrack* %{buildroot}/etc/%{name}/

%files -n tmt+provision-container -f %{_pyproject_ghost_distinfo}
%files -n tmt+provision-virtual -f %{_pyproject_ghost_distinfo}
%files -n tmt+provision-bootc -f %{_pyproject_ghost_distinfo}
%files -n tmt+test-convert -f %{_pyproject_ghost_distinfo}
%files -n tmt+provision-beaker -f %{_pyproject_ghost_distinfo}
%config(noreplace) %{_sysconfdir}/%{name}/mrack*
Expand Down
71 changes: 71 additions & 0 deletions tmt/schemas/provision/bootc.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
---

#
# JSON Schema definition for `bootc` provision plugin
#
# https://tmt.readthedocs.io/en/stable/spec/plans.html#bootc
#

$id: /schemas/provision/bootc
$schema: https://json-schema.org/draft-07/schema

type: object
additionalProperties: false

properties:

how:
type: string
enum:
- bootc

name:
type: string

image:
type: string

user:
type: string

become:
type: boolean

key:
$ref: "/schemas/common#/definitions/one_or_more_strings"

memory:
type: integer

disk:
type: integer

connection:
type: string
enum:
- session
- system

arch:
$ref: "/schemas/common#/definitions/arch"

role:
$ref: "/schemas/common#/definitions/role"

container-file:
type: string

container-file-workdir:
type: string

container-image:
type: string

add-tmt-dependencies:
type: boolean

image-builder:
type: string

required:
- how
Loading

0 comments on commit e8edeeb

Please sign in to comment.