Skip to content

Auto-verify artifact packages against require/recommend#4726

Draft
vaibhavdaren wants to merge 1 commit intomainfrom
vaibhav-verify-artifact-plugin
Draft

Auto-verify artifact packages against require/recommend#4726
vaibhavdaren wants to merge 1 commit intomainfrom
vaibhav-verify-artifact-plugin

Conversation

@vaibhavdaren
Copy link
Contributor

@vaibhavdaren vaibhavdaren commented Mar 20, 2026

When the artifact plugin is present with verify=True (default), a verify-installation phase is automatically injected at order=79. It intersects require/recommend packages for the current guest with packages listed in artifacts.yaml, and verifies that the overlapping packages were installed from the tmt-artifact-shared repository.

Related to #4646

When the artifact plugin is present with verify=True (default), a
verify-installation phase is automatically injected at order=79. It
intersects require/recommend packages for the current guest with
packages listed in artifacts.yaml, and verifies that the overlapping
packages were installed from the tmt-artifact-shared repository.
@vaibhavdaren vaibhavdaren self-assigned this Mar 20, 2026
@vaibhavdaren vaibhavdaren added step | prepare Stuff related to the prepare step ci | full test Pull request is ready for the full test execution plugin | artifact Related to the `prepare/artifact` plugin. labels Mar 20, 2026
@github-project-automation github-project-automation bot moved this to backlog in planning Mar 20, 2026
@vaibhavdaren vaibhavdaren linked an issue Mar 20, 2026 that may be closed by this pull request
Copy link
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

The pull request introduces an automatic verification phase for artifact packages, ensuring that packages listed in require/recommend are installed from the tmt-artifact-shared repository when the artifact plugin is enabled with verify=True. This is a valuable addition for ensuring test environment integrity. The implementation correctly handles the intersection of artifact metadata and test requirements, and prioritizes explicit verify-installation configurations over auto-detected ones. The use of Final for constants in tmt/steps/prepare/artifact/__init__.py is a good practice.

{dest for phase in artifact_phases_with_verify for dest in phase.data.where}
)
verify_data = PrepareVerifyInstallationData(
name='verify-artifact-packages',
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Define name as a constant. This improves maintainability by centralizing the string literal, making it easier to update and ensuring consistency if referenced elsewhere.

verify_data = PrepareVerifyInstallationData(
name='verify-artifact-packages',
how='verify-installation',
summary='Verify packages were installed from artifact repositories',
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

Define summary as a constant. This improves maintainability by centralizing the string literal, making it easier to update and ensuring consistency if referenced elsewhere.

Comment on lines +391 to +409
if artifact_phases_with_verify and not has_verify_phase:
# Mirror the where= scope of the artifact phases: if any artifact
# phase runs on all guests (empty where), verify should too;
# otherwise restrict to the union of their guest/role targets.
if any(not phase.data.where for phase in artifact_phases_with_verify):
verify_where: list[str] = []
else:
verify_where = list(
{dest for phase in artifact_phases_with_verify for dest in phase.data.where}
)
verify_data = PrepareVerifyInstallationData(
name='verify-artifact-packages',
how='verify-installation',
summary='Verify packages were installed from artifact repositories',
order=tmt.steps.PHASE_ORDER_PREPARE_VERIFY_INSTALLATION,
auto=True,
where=verify_where,
)
self._phases.append(PreparePlugin.delegate(self, data=verify_data))
Copy link
Member

Choose a reason for hiding this comment

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

Uph, please not like this. Would rather it be created inside the artifact plugin instead, where we would also control how it is created. The questionable thing is if can be created while in the prepare.go phase, but that needs to be solved regardless because we do not know the packages and their origins until PrepareArtifact (probably all of them) complete.

Copy link
Member

Choose a reason for hiding this comment

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

For reference, see Discover dist-git in how it inserts the phase dynamically

Copy link
Contributor

Choose a reason for hiding this comment

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

It does, but it's a discover phase adding to prepare step that haven't started yet. prepare phase adding to prepare step, after the queue has been established and started is not supported. Right now, I would do it in the prepare step, just as test requirements are sorted out there. It's not ideal, but it's available today, and can be improved independently later.

Copy link
Member

Choose a reason for hiding this comment

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

Uph. At the minimum, encapsulate it in a function, and document to get rid of it as soon as possible.

Copy link
Member

Choose a reason for hiding this comment

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

On second thought, I still don't like it. What does it take to inject the phase in the queue properly and improperly?

Copy link
Contributor

Choose a reason for hiding this comment

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

Changing how queues are populated in steps, adding API to support dynamic additions while the queue is already running, which most likely requires reordering of the queued tasks as tasks were enqueued according to phases' order keys. I don't mind working on that, already some needed work landed, it just won't be ready today.

Copy link
Contributor

Choose a reason for hiding this comment

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

And a unit test, to make sure it works because this would be rather a rare use case. If there's a bug in how queue works, we'd see tmt explode everywhere; if there's a bug in how tasks are enqueued from another tasks of the same step, only a handful of tests would fail, so this calls for having a test as well.

Copy link
Member

Choose a reason for hiding this comment

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

We did create the interface in preparation for it at least

tmt/tmt/steps/__init__.py

Lines 1322 to 1330 in b32fa85

def add_phase(self, phase: Phase) -> None:
"""
Add a phase dynamically to the current step.
:param phase: The phase to add.
"""
if not isinstance(phase, self._plugin_base_class):
raise GeneralError(f"The phase '{phase}' is not part of step '{self}'.")
self._phases.append(phase)

Comment on lines +74 to +83
def _build_auto_verify(self, guest: Guest) -> dict[str, str]:
"""
Build a verify mapping from artifact metadata and test requirements.

Reads ``artifacts.yaml`` from the plan workdir, collects all
package names provided by artifact providers, and intersects them
with packages listed in ``require``/``recommend`` of tests enabled
on this guest. Returns a mapping of intersecting package names to
the artifact shared repository name.
"""
Copy link
Member

Choose a reason for hiding this comment

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

Well, the second issue with not being able to inject the phase is having this magic method. Didn't like the branching in discover, and this just adds another flavor of it. This wouldn't even work if you have one artifact provider with verify and another without since it cannot discriminate between them, unless there is even more introspection between these phases

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci | full test Pull request is ready for the full test execution plugin | artifact Related to the `prepare/artifact` plugin. step | prepare Stuff related to the prepare step

Projects

Status: backlog

Development

Successfully merging this pull request may close these issues.

Link the verify install plugin to the artifact plugin

3 participants