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
43 changes: 43 additions & 0 deletions .packit.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,27 @@ jobs:
context:
running_env: "packit"

# This plan uses an image-mode harness plus a separate package-mode target.
- job: tests
trigger: pull_request
identifier: package-mode-tier-1
require:
label:
present:
- ci/tier-1
targets:
- centos-stream-10-x86_64
- centos-stream-10-aarch64
- fedora-latest-stable-x86_64
- fedora-latest-stable-aarch64
tmt_plan: /tmt/plans/package-mode
tf_extra_params:
environments:
- tmt:
context:
running_env: "packit"
package_source: "artifacts"

# ci/merge: full target set
- job: tests
trigger: pull_request
Expand All @@ -124,6 +145,28 @@ jobs:
context:
running_env: "packit"

- job: tests
trigger: pull_request
identifier: package-mode-full
require:
label:
present:
- ci/merge
targets:
- centos-stream-9-x86_64
- centos-stream-9-aarch64
- centos-stream-10-x86_64
- centos-stream-10-aarch64
- fedora-all-x86_64
- fedora-all-aarch64
tmt_plan: /tmt/plans/package-mode
tf_extra_params:
environments:
- tmt:
context:
running_env: "packit"
package_source: "artifacts"

- job: propose_downstream
trigger: release
dist_git_branches:
Expand Down
67 changes: 67 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,73 @@ To run a specific test:
just test-tmt readonly
```

The package-mode tests use a separate TMT plan with two disposable VMs. By
default, `just test-tmt-package-mode` builds `localhost/bootc` from the latest
Fedora bootc base and uses TMT's `fedora` image alias (the latest released
Fedora image). This performs a full local image build, so it takes longer and
uses more disk/network than simply launching the VM test. The build archive is
stored under the ignored `target/` directory and copied to the harness VM.
For local Just runs, TMT uses a temporary metadata root containing only
`.fmf/` and `tmt/`, so ignored build output is not synchronized to either VM;
the OCI archive stays in `target/` and is synchronized separately.
TMT's run workdir defaults to
`${XDG_CACHE_HOME:-$HOME/.cache}/bootc/tmt-package-mode-runs`. It must be outside
the checkout and temporary metadata root, and visible at the same absolute path
to both the TMT container and the host session-libvirt process so libvirt can
access seed images created by TMT. Set `TMT_WORKDIR_ROOT` to use a different
shared directory that meets these requirements:

```bash
TMT_WORKDIR_ROOT=/shared/tmt-package-mode-runs just test-tmt-package-mode
```

The target creates the directory if needed and passes its absolute path to TMT.
To use a different guest image, set `test_disk_image`:

```bash
# Uses the latest released Fedora image.
just test-tmt-package-mode

# Optional: use another TMT-compatible image.
test_disk_image=/path/to/package-mode-test-image.qcow2 just test-tmt-package-mode
```

The local build base can be overridden with `BOOTC_base`; when changing the
guest image, choose a matching bootc base (for example, Fedora guests should use
the corresponding `quay.io/fedora/fedora-bootc` release). The package-mode test
performs a destructive migration inside its target VM, so use only a disposable
image/environment. TMT and its virtual provisioning backend must be installed
and configured locally.

Packit runs the same plan with `package_source=artifacts`: the TMT controller
must provide `/var/share/test-artifacts/` with exactly one top-level `.src.rpm`
and `/etc/yum.repos.d/test-artifacts.repo`. `/var/ARTIFACTS/` is forwarded to
the harness when present, but is an optional Testing Farm pass-through, not a
test prerequisite. Local `just test-tmt-package-mode` runs use
`package_source=local` and need none of those controller artifact paths; they
skip Packit provisioning and the harness reboot while retaining the shared
migration test and archive transfer. Local mode tests migration behavior using
the image built from the checkout; it does not validate the SRPM, repository, or
Packit provisioning path.

In both package-source modes, the target preloads the test's bound container
images because the installer resolves those references from target-side storage.

Package-mode OCI archives and artifact directories are transferred from the
harness with `ansible.posix.synchronize` (rsync over TMT's forwarded SSH
connection). This avoids Ansible `fetch`/`copy` falling back to a piped SSH
transfer that can buffer a 1 GB+ archive in controller memory; the original
SFTP/SCP errors were not recorded. The TMT controller must have `rsync` and the
`ansible.posix` collection installed. TMT 1.79 or newer is required on both the
local and Testing Farm controllers. The plan installs `rsync` on both guests
from their configured base repositories before synchronizing any payloads.
The verified archive and its SHA256 sidecar are staged under the run-specific
controller `TMT_PLAN_DATA/package-mode-transfer` directory. TMT 1.79 pushes
controller plan data to the selected test guest before execute, where the test
checks the sidecar and loads the archive. A finish playbook removes controller
staging after test success or failure; the fetch playbook still cleans up if
staging or checksum verification fails during prepare.

### Faster iteration cycles

The test cycle currently builds a disk image and creates a new ephemeral
Expand Down
48 changes: 47 additions & 1 deletion Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,17 @@ erofs_version := env("BOOTC_erofs_version", "v1")
# Baseconfigs to inject into the image for testing (e.g. "etc-transient" or "root-transient")
baseconfigs := env("BOOTC_baseconfigs", "")
# Base container image to build from
base := env("BOOTC_base", "quay.io/centos-bootc/centos-bootc:stream10")
default_base := "quay.io/centos-bootc/centos-bootc:stream10"
base := env("BOOTC_base", default_base)
# Package-mode tests default to Fedora to match test_disk_image=fedora.
# Honor BOOTC_base or a Justfile `base=` override when explicitly provided.
package_mode_base := if base != default_base {
base
} else if env("BOOTC_base", "") != "" {
base
} else {
"quay.io/fedora/fedora-bootc:latest"
}
# Buildroot base image
buildroot_base := env("BOOTC_buildroot_base", "quay.io/centos/centos:stream10")
# Optional: path to extra source (e.g. composefs-rs) for local development
Expand Down Expand Up @@ -192,6 +202,42 @@ test-tmt *ARGS: build
@just _build-upgrade-image
@just test-tmt-nobuild {{ARGS}}

# Run the package-mode TMT plan using its two TMT-provisioned guests.
[group('core')]
test-tmt-package-mode:
#!/bin/bash
set -euo pipefail
repo_root="$(git rev-parse --show-toplevel)"
repo_root="$(realpath -- "$repo_root")"
metadata_root="$(realpath -- "$(mktemp -d "${TMPDIR:-/tmp}/bootc-tmt-package-mode.XXXXXXXX")")"
trap 'rm -rf -- "$metadata_root"' EXIT
cp -a -- "$repo_root/.fmf" "$metadata_root/"
cp -a -- "$repo_root/tmt" "$metadata_root/"
workdir_root="${TMT_WORKDIR_ROOT:-${XDG_CACHE_HOME:-$HOME/.cache}/bootc/tmt-package-mode-runs}"
workdir_root="$(realpath -m -- "$workdir_root")"
if [[ "$workdir_root" == "$repo_root" || "$workdir_root" == "$repo_root/"* ]]; then
echo "TMT workdir root must be outside the checkout (fmf root): $workdir_root" >&2
exit 1
fi
if [[ "$workdir_root" == "$metadata_root" || "$workdir_root" == "$metadata_root/"* ]]; then
echo "TMT workdir root must be outside the temporary metadata root: $workdir_root" >&2
exit 1
fi
mkdir -p -- "$workdir_root"
just base={{package_mode_base}} build
if [[ "{{base_img}}" != localhost/bootc ]]; then
podman tag {{base_img}} localhost/bootc
fi
podman save --format oci-archive \
--output target/package-mode-local.oci localhost/bootc
archive_path="$(realpath -- target/package-mode-local.oci)"
PACKAGE_MODE_IMAGE_ARCHIVE="$archive_path" tmt \
--root "$metadata_root" \
--context=running_env=packit \
--context=package_source=local \
--context="test_disk_image=${test_disk_image:-fedora}" \
run --workdir-root "$workdir_root" plans --name '^/tmt/plans/package-mode$'

# Split out from `test-container` because, unlike the container integration tests,
# unit tests don't depend on variant/filesystem/bootloader/boot_type/seal_state, so
# CI runs this once per OS (in the `package` job) instead of once per test-integration
Expand Down
Loading
Loading