Skip to content

Support Ansible prepare step in image mode#4636

Closed
thrix wants to merge 1 commit intomainfrom
ansible-prepare-image-mode
Closed

Support Ansible prepare step in image mode#4636
thrix wants to merge 1 commit intomainfrom
ansible-prepare-image-mode

Conversation

@thrix
Copy link
Copy Markdown
Contributor

@thrix thrix commented Mar 3, 2026

Summary

  • Add image mode (bootc) support for the ansible prepare plugin
  • When running on a bootc guest, starts a container, runs ansible-playbook with containers.podman.podman connection plugin, commits the result, switches via bootc switch, and reboots
  • Includes integration test following the tests/prepare/bootc/ pattern

Details

On image mode guests, /usr is read-only and system changes must be baked into the container image. The existing shell and install prepare plugins handle this via Containerfile directives, but the ansible plugin had no image mode support.

The implementation:

  1. Flushes any pending containerfile directives from prior shell/install phases
  2. Ensures ansible-playbook is available on the guest (installs ansible-core if needed)
  3. Gets the current bootc image and ensures it's in podman storage
  4. Starts a container from the image
  5. Runs each playbook with ansible-playbook -c containers.podman.podman
  6. Commits the container to a new image
  7. Switches via bootc switch --transport containers-storage and reboots

Test plan

  • Run existing prepare tests for regressions
  • Run new tests/prepare/bootc-ansible/ test with an image mode guest
  • Verify log output shows: container start, ansible-playbook with podman connection, commit, switch, reboot

Closes #4624

Add image mode support for the ansible prepare plugin. When running
on a bootc guest, the plugin:

1. Flushes any pending containerfile directives from prior phases
2. Ensures ansible-playbook is available on the guest
3. Starts a container from the current bootc image
4. Runs ansible-playbook with the containers.podman.podman connection
   plugin targeting the container
5. Commits the container to a new image
6. Switches via bootc switch and reboots

This enables running Ansible playbooks (e.g. system roles) against
image mode guests where /usr is read-only and changes must be baked
into the container image.

Closes #4511

Assisted-by Claude Code
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request adds support for the Ansible prepare step in image mode (bootc), including a new integration test. However, a high-severity Path Traversal vulnerability and several instances of potential Command Injection were identified due to improper handling of user-supplied paths and command arguments, which could allow an attacker to read arbitrary files or execute unintended commands. It is recommended to use existing path sanitization helpers and switch from shell-based command execution to structured command objects.

Comment on lines +273 to +278
if lowercased.startswith('file://'):
rel_path = Path(raw_playbook[7:])
else:
rel_path = Path(raw_playbook)

local_path = self.step.plan.anchor_path / rel_path
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-high high

A high-severity Path Traversal vulnerability exists in the _resolve_playbook_for_guest method. It resolves local playbook paths by concatenating the plan's anchor path with a user-supplied path without proper validation, potentially allowing an attacker to read arbitrary files. The method fails to use the unrooted() helper or verify that the resulting path is within the anchor path. Additionally, consider refactoring the duplicated playbook resolution logic to improve maintainability.

Suggested change
if lowercased.startswith('file://'):
rel_path = Path(raw_playbook[7:])
else:
rel_path = Path(raw_playbook)
local_path = self.step.plan.anchor_path / rel_path
if lowercased.startswith('file://'):
rel_path = Path(raw_playbook[7:])
else:
rel_path = Path(raw_playbook)
local_path = self.step.plan.anchor_path / rel_path.unrooted()
if not local_path.is_relative_to(self.step.plan.anchor_path):
raise PrepareError(f"Playbook path '{raw_playbook}' is outside the plan directory.")

Comment on lines +346 to +352
f'{guest.facts.sudo_prefix} podman run -d'
f' --name {container_name}'
f' -v {guest.run_workdir}:{guest.run_workdir}:Z'
f' {current_image}'
f' sleep infinity'
)
)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The podman run command is constructed using an f-string and executed via ShellScript. Variables such as guest.run_workdir and current_image are included without proper shell quoting. While paths internally generated and controlled by the application, like guest.run_workdir, do not strictly require quoting for security against command injection, lack of quoting can still cause the command to fail if paths contain spaces. For current_image, if it's user-provided, this poses a command injection risk. Using the Command class is preferred as it handles argument quoting safely for all variables and improves robustness.

            # Start a container from the current bootc image
            logger.info('ansible', f'starting container {container_name}', 'green')
            podman_run_cmd = Command('podman', 'run', '-d')
            if guest.facts.sudo_prefix:
                podman_run_cmd = Command(guest.facts.sudo_prefix) + podman_run_cmd
            podman_run_cmd += Command('--name', container_name)
            podman_run_cmd += Command('-v', f'{guest.run_workdir}:{guest.run_workdir}:Z')
            podman_run_cmd += Command(current_image, 'sleep', 'infinity')
            guest.execute(podman_run_cmd)
References
  1. Paths that are internally generated and controlled by the application do not need to be quoted in shell commands, as they are not considered user-provided input.

Comment on lines +377 to +387
ansible_cmd = (
f'{guest.facts.sudo_prefix} ansible-playbook'
f' -c containers.podman.podman'
f" -i '{container_name},'"
f' {guest_playbook}'
)

if self.data.extra_args:
ansible_cmd += f' {self.data.extra_args}'

return guest.execute(ShellScript(ansible_cmd))
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

security-medium medium

The ansible-playbook command is constructed using an f-string and executed via ShellScript. Variables such as container_name, guest_playbook, and self.data.extra_args are included without proper shell quoting. While paths internally generated and controlled by the application, like container_name, do not strictly require quoting for security against command injection, lack of quoting can still cause the command to fail if paths contain spaces. For guest_playbook and especially self.data.extra_args (which is user-provided), this poses a significant command injection risk. Structured Command objects should be used instead of raw shell strings to handle argument quoting safely.

                    # Build the ansible-playbook command to run on the guest
                    ansible_cmd = Command('ansible-playbook')
                    if guest.facts.sudo_prefix:
                        ansible_cmd = Command(guest.facts.sudo_prefix) + ansible_cmd
                    ansible_cmd += Command('-c', 'containers.podman.podman', '-i', f'{container_name},', guest_playbook)

                    if self.data.extra_args:
                        import shlex
                        ansible_cmd += Command(*shlex.split(self.data.extra_args))

                    return guest.execute(ansible_cmd)
References
  1. Paths that are internally generated and controlled by the application do not need to be quoted in shell commands, as they are not considered user-provided input.

@thrix thrix added this to planning Mar 4, 2026
@github-project-automation github-project-automation bot moved this to backlog in planning Mar 4, 2026
@thrix thrix moved this from backlog to implement in planning Mar 4, 2026
thrix added a commit that referenced this pull request Mar 19, 2026
Fixes #4606

Get rid of the standalone `tests/prepare/bootc/` and user rather
the existing per-plugin prepare step test suites (`prepare/install`, `prepare/shell`,
`prepare/recommend`). Extend them with image mode coverage on
both CentOS Stream 10 and Fedora 44 bootc qcow2 images.

All image mode tests verify that prepared state (installed packages,
enabled repos, excluded packages) persists after a reboot, which is
critical for image mode where changes are applied via Containerfile
rebuild + `bootc switch` + reboot.

Implements three missing methods in `Bootc` package manager
(`tmt/package_managers/bootc.py`) that enable `prepare/install`
with COPR and `prepare/artifact` on image mode guests:

- `enable_copr()` — delegates to the underlying `Dnf`/`Dnf5`
  package manager via `bootc_builder`. The copr plugin install
  and `dnf copr enable` write to `/etc` which persists in image
  mode.

- `create_repository()` — delegates to `aux_engine` to run
  `createrepo` on the live system.

- `install_repository()` — delegates to `aux_engine` to write
  `.repo` file to `/etc/yum.repos.d/` and refresh the package
  cache on the live system without triggering a container rebuild.

`create_repository()` and `install_repository()` are not directly
tested — they are trivial one-line delegations to `aux_engine` and
will be exercised once the `prepare/artifact` tests are extended
for image mode in a follow-up PR.

- Adds `TEST_IMAGE_MODE_IMAGES` variable and `is_image_mode*`
  helper functions to `tests/images.sh`

- Creates `/plans/provision/virtual-image-mode` CI plan with
  `PROVISION_HOW=virtual-image-mode` environment. Tests can be
  marked to run in this plan using the tag `provision-virtual-image-mode`.

- Adds corresponding Packit job `provision-virtual-image-mode` to run
  the tests separately

The following existing tests are extended with image mode coverage
(reboot persistence verification via `tmt-reboot`):

| Test | Scenarios on image mode |
|------|------------------------|
| `prepare/install` | existing packages, downloaded packages, COPR, debuginfo, exclude, escape |
| `prepare/shell` | custom script with Containerfile assertions |
| `prepare/recommend` | recommended packages with missing package handling |

Inner test plans gain `adjust: when: package_manager == bootc`
blocks that override the execute step to verify packages/repos
and reboot.

| Plugin | Reason |
|--------|--------|
| `prepare/artifact` | Currently `provision-container` only with `distro == fedora` gate. Code fixes are in place but test infrastructure needs refactoring. |
| `prepare/ansible` | Runs ansible-playbook via SSH, cannot be deferred to Containerfile. Tracked in #4636. |
| `prepare/feature/epel`, `fips`, `profile` | Use Ansible playbooks internally. To be covered with #4636 or follow-up. |
| `prepare/distgit` | Existing test needs refactoring to support image mode provision. |
| `prepare/require` | Currently `provision-container` only. |

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code

Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Mar 22, 2026
Fixes #4606

Get rid of the standalone `tests/prepare/bootc/` and user rather
the existing per-plugin prepare step test suites (`prepare/install`, `prepare/shell`,
`prepare/recommend`). Extend them with image mode coverage on
both CentOS Stream 10 and Fedora 44 bootc qcow2 images.

All image mode tests verify that prepared state (installed packages,
enabled repos, excluded packages) persists after a reboot, which is
critical for image mode where changes are applied via Containerfile
rebuild + `bootc switch` + reboot.

Implements three missing methods in `Bootc` package manager
(`tmt/package_managers/bootc.py`) that enable `prepare/install`
with COPR and `prepare/artifact` on image mode guests:

- `enable_copr()` — delegates to the underlying `Dnf`/`Dnf5`
  package manager via `bootc_builder`. The copr plugin install
  and `dnf copr enable` write to `/etc` which persists in image
  mode.

- `create_repository()` — delegates to `aux_engine` to run
  `createrepo` on the live system.

- `install_repository()` — delegates to `aux_engine` to write
  `.repo` file to `/etc/yum.repos.d/` and refresh the package
  cache on the live system without triggering a container rebuild.

`create_repository()` and `install_repository()` are not directly
tested — they are trivial one-line delegations to `aux_engine` and
will be exercised once the `prepare/artifact` tests are extended
for image mode in a follow-up PR.

- Adds `TEST_IMAGE_MODE_IMAGES` variable and `is_image_mode*`
  helper functions to `tests/images.sh`

- Creates `/plans/provision/virtual-image-mode` CI plan with
  `PROVISION_HOW=virtual-image-mode` environment. Tests can be
  marked to run in this plan using the tag `provision-virtual-image-mode`.

- Adds corresponding Packit job `provision-virtual-image-mode` to run
  the tests separately

The following existing tests are extended with image mode coverage
(reboot persistence verification via `tmt-reboot`):

| Test | Scenarios on image mode |
|------|------------------------|
| `prepare/install` | existing packages, downloaded packages, COPR, debuginfo, exclude, escape |
| `prepare/shell` | custom script with Containerfile assertions |
| `prepare/recommend` | recommended packages with missing package handling |

Inner test plans gain `adjust: when: package_manager == bootc`
blocks that override the execute step to verify packages/repos
and reboot.

| Plugin | Reason |
|--------|--------|
| `prepare/artifact` | Currently `provision-container` only with `distro == fedora` gate. Code fixes are in place but test infrastructure needs refactoring. |
| `prepare/ansible` | Runs ansible-playbook via SSH, cannot be deferred to Containerfile. Tracked in #4636. |
| `prepare/feature/epel`, `fips`, `profile` | Use Ansible playbooks internally. To be covered with #4636 or follow-up. |
| `prepare/distgit` | Existing test needs refactoring to support image mode provision. |
| `prepare/require` | Currently `provision-container` only. |

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code

Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Mar 22, 2026
Fixes #4606

Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

Implement three methods in `Bootc` package manager:

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

Not covered (follow-up):
- `prepare/artifact`, `prepare/require` — `provision-container` only
- `prepare/ansible`, `prepare/feature` — need #4636
- `prepare/distgit` — test refactoring needed

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Mar 23, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
thrix added a commit that referenced this pull request Mar 26, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Mar 26, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Mar 26, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
@thrix thrix added this to the 1.71 milestone Mar 27, 2026
Copy link
Copy Markdown
Member

@LecrisUT LecrisUT left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not like this approach. Please elaborate why you went with this and what other alternatives have you considered.

Comment on lines +185 to +203
def _ensure_ansible_on_guest(
self,
guest: 'Guest',
logger: tmt.log.Logger,
) -> None:
"""
Ensure ansible-playbook is available on the guest.

Checks if ansible-playbook is already installed. If not, installs
ansible-core via the bootc package manager, which triggers a
container image build, bootc switch, and reboot.
"""

try:
guest.execute(Command('which', 'ansible-playbook'), silent=True)
logger.debug('ansible-playbook is already available on the guest.')
except tmt.utils.RunError:
logger.info('ansible', 'installing ansible-core on the guest', 'green')
guest.package_manager.install(Package('ansible-core'))
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is ansible required on the guest?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LecrisUT this should happen on the guest to:

  1. mitigate having an external container registry in place to share the images (or find some other crazy way how to get the base image from the guest and push it to the guest). The base container image is available only on the guest

  2. Be similar to a regular container rebuild, less suprises, easier to explain how it works

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mitigate having an external container registry

The local container registry of the bootc runtime should be usable right?

Be similar to a regular container rebuild, less suprises

I disagree with this creating less surprises. E.g. if the package being tested is anything inside the ansible dependency stack, and this fails at the prepare step, how would one debug this? Having a minimal dependency footprint would be the best for the "less surprises"


Before anything, I would like a better breakdown of any other alternative approaches. From what I understand of bootc it is supposed to be possible to do local builds from the current state, don't know if bootc image copy-to-storage, but there seem to be many ways of interacting with bootc and would like to have a more thorough breakdown of it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The local container registry of the bootc runtime should be usable right?

it has nothing to do with bootc runtime, it is the guest local registry on the machine

I disagree with this creating less surprises. E.g. if the package being tested is anything inside the ansible dependency stack, and this fails at the prepare step, how would one debug this? Having a minimal dependency footprint would be the best for the "less surprises"

Not sure I follow, the failed preparation should be visible from the tmt logs?

Before anything, I would like a better breakdown of any other alternative approaches. From what I understand of bootc it is supposed to be possible to do local builds from the current state,

Local to what? guest or host?

don't know if bootc image copy-to-storage, but there seem to be many ways of interacting with bootc and would like to have a more thorough breakdown of it

I am not aware of any alternative approaches that would not require what I wrote

Comment on lines +333 to +339
ShellScript(
f'{guest.facts.sudo_prefix} /bin/bash -c "('
f' ( podman pull {current_image}'
f' || podman pull containers-storage:{current_image} )'
f' || bootc image copy-to-storage --target {current_image}'
')"'
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the indirect bash

Comment on lines +376 to +382
# Build the ansible-playbook command to run on the guest
ansible_cmd = (
f'{guest.facts.sudo_prefix} ansible-playbook'
f' -c containers.podman.podman'
f" -i '{container_name},'"
f' {guest_playbook}'
)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👎 to this approach. It uses both a containers connection and it also runs on the guest!?

@thrix
Copy link
Copy Markdown
Contributor Author

thrix commented Apr 1, 2026

It was decided we will not support Ansible for now, only fix the playbooks for feature plugins to be image-mode friendly.

thrix added a commit that referenced this pull request Apr 8, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
@thrix thrix modified the milestones: 1.71, 1.72 Apr 9, 2026
@thrix
Copy link
Copy Markdown
Contributor Author

thrix commented Apr 14, 2026

As discussed, closing this for now, we will go with #4625 by adjusting the playbooks to not use tasks which will not work in image mode (e.g. dnf)

@thrix thrix closed this Apr 14, 2026
@github-project-automation github-project-automation bot moved this from implement to done in planning Apr 14, 2026
thrix added a commit that referenced this pull request Apr 14, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Apr 17, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
thrix added a commit that referenced this pull request Apr 20, 2026
Remove standalone `tests/prepare/bootc/` and extend existing plugin
tests (`prepare/install`, `prepare/shell`, `prepare/recommend`) with
image mode coverage on CentOS Stream 10 and Fedora 44 bootc images.

- `enable_copr()` — installs copr plugin via Containerfile (since
  `/usr` is read-only), then runs `dnf copr enable` on the live
  system to write `.repo` to `/etc`.

- `create_repository()`, `install_repository()` — delegate to
  `aux_engine` to run on the live system. Not directly tested,
  will be exercised when `prepare/artifact` tests are extended.

Existing tests gain `IS_IMAGE_MODE` handling and run against
image mode images when triggered by the new
`/plans/provision/virtual/image-mode` sub-plan.

Reboot persistence is verified through a dedicated
`reboot-persistence` inner plan that installs packages, reboots
via `tmt-reboot`, and re-verifies. A single reboot test is
sufficient — all install variants (repo, local RPM, COPR, etc.)
go through the same bootc mechanism (Containerfile rebuild →
`bootc switch` → reboot), so if packages survive a reboot in
one case, they survive in all.

- `prepare/artifact`, `prepare/require` — currently
  `provision-container` only
- `prepare/ansible`, `prepare/feature/epel,fips,profile` —
  need Ansible support in image mode (#4636)
- `prepare/distgit` — test refactoring needed

Pull Request Checklist

* [x] implement the feature
* [x] extend the test coverage

Assisted-by: Claude Code
Signed-off-by: Miroslav Vadkerti <mvadkert@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: done

Development

Successfully merging this pull request may close these issues.

Implement ansible prepare step support in image mode

5 participants