Skip to content
Open
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
66 changes: 37 additions & 29 deletions tests/install_upgrade_operators/product_upgrade/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@

import pytest
from ocp_resources.cluster_version import ClusterVersion
from ocp_resources.image_digest_mirror_set import ImageDigestMirrorSet
from ocp_resources.resource import ResourceEditor
from ocp_utilities.monitoring import Prometheus
from packaging.version import Version
from pytest_testconfig import py_config

from tests.install_upgrade_operators.constants import WORKLOAD_UPDATE_STRATEGY_KEY_NAME, WORKLOADUPDATEMETHODS
from tests.install_upgrade_operators.product_upgrade.utils import (
KONFLUX_IDMS_NAME,
KONFLUX_MIRROR_BASE_URL,
apply_konflux_idms,
approve_cnv_upgrade_install_plan,
extract_ocp_version_from_ocp_image,
get_alerts_fired_during_upgrade,
Expand All @@ -19,6 +23,7 @@
get_nodes_labels,
get_nodes_taints,
get_shortest_upgrade_path,
idms_has_all_mirrors,
perform_cnv_upgrade,
run_ocp_upgrade_command,
set_workload_update_methods_hco,
Expand All @@ -31,7 +36,12 @@
)
from tests.install_upgrade_operators.utils import wait_for_operator_condition
from tests.upgrade_params import EUS
from utilities.constants import HCO_CATALOG_SOURCE, HOTFIX_STR, TIMEOUT_10MIN, NamespacesNames
from utilities.constants import (
HCO_CATALOG_SOURCE,
HOTFIX_STR,
TIMEOUT_10MIN,
NamespacesNames,
)
from utilities.data_collector import (
get_data_collector_base_directory,
)
Expand Down Expand Up @@ -85,47 +95,45 @@ def nodes_labels_before_upgrade(nodes, cnv_upgrade):
return get_nodes_labels(nodes=nodes, cnv_upgrade=cnv_upgrade)


@pytest.fixture(scope="session")
def required_konflux_mirrors(cnv_target_version, cnv_current_version):
target = Version(version=cnv_target_version)
current = Version(version=cnv_current_version)
return [
f"{KONFLUX_MIRROR_BASE_URL}/v{target.major}-{minor}" for minor in range(target.minor, current.minor - 1, -1)
]


@pytest.fixture()
def updated_image_content_source_policy(
admin_client,
nodes,
tmpdir_factory,
active_machine_config_pools,
machine_config_pools_conditions,
cnv_image_url,
def updated_konflux_idms(
cnv_image_name,
nodes,
cnv_source,
cnv_target_version,
cnv_registry_source,
pull_secret_directory,
generated_pulled_secret,
required_konflux_mirrors,
is_disconnected_cluster,
is_idms_cluster,
active_machine_config_pools,
machine_config_pools_conditions,
):
"""
Creates a new ImageContentSourcePolicy file with a given CNV image and applies it to the cluster.
"""
"""Ensures the Konflux IDMS contains the required mirror entries for the CNV upgrade target version."""
if is_disconnected_cluster:
LOGGER.warning("Skip applying ICSP/IDMS in a disconnected setup.")
LOGGER.warning("Skip applying IDMS in a disconnected setup.")
return

if cnv_source == HOTFIX_STR:
LOGGER.info("ICSP updates skipped as upgrading using production source/upgrade to hotfix")
LOGGER.info("IDMS updates skipped as upgrading using production source/upgrade to hotfix")
return
file_path = get_generated_icsp_idms(
image_url=cnv_image_url,
registry_source=cnv_registry_source["source_map"],
generated_pulled_secret=generated_pulled_secret,
pull_secret_directory=pull_secret_directory,
is_idms_cluster=is_idms_cluster,
)
apply_icsp_idms(
file_paths=[file_path],

idms = ImageDigestMirrorSet(name=KONFLUX_IDMS_NAME)
if idms.exists and idms_has_all_mirrors(idms=idms, required_mirrors=required_konflux_mirrors):
LOGGER.info(f"IDMS {KONFLUX_IDMS_NAME} already contains all required mirrors.")
return

apply_konflux_idms(
idms=idms,
required_mirrors=required_konflux_mirrors,
machine_config_pools=active_machine_config_pools,
mcp_conditions=machine_config_pools_conditions,
nodes=nodes,
is_idms_file=is_idms_cluster,
delete_file=True,
)


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def test_cnv_upgrade_process(
cnv_upgrade_stream,
fired_alerts_before_upgrade,
disabled_default_sources_in_operatorhub,
updated_image_content_source_policy,
updated_konflux_idms,
updated_custom_hco_catalog_source_image,
updated_cnv_subscription_source,
approved_cnv_upgrade_install_plan,
Expand Down
56 changes: 56 additions & 0 deletions tests/install_upgrade_operators/product_upgrade/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,11 @@
from ocp_resources.cluster_service_version import ClusterServiceVersion
from ocp_resources.cluster_version import ClusterVersion
from ocp_resources.hyperconverged import HyperConverged
from ocp_resources.image_digest_mirror_set import ImageDigestMirrorSet
from ocp_resources.kubevirt import KubeVirt
from ocp_resources.machine_config_pool import MachineConfigPool
from ocp_resources.namespace import Namespace
from ocp_resources.node import Node
from ocp_resources.resource import Resource, ResourceEditor
from packaging.version import Version
from pyhelper_utils.shell import run_command
Expand Down Expand Up @@ -59,6 +61,9 @@

LOGGER = logging.getLogger(__name__)
TIER_2_PODS_TYPE = "tier-2"
KONFLUX_IDMS_NAME = "zz-cnv-icsp-fallback"
KONFLUX_MIRROR_BASE_URL = "quay.io/openshift-virtualization/konflux-builds"
KONFLUX_IDMS_SOURCE = "registry.redhat.io/container-native-virtualization"

# list of whitelisted alerts
WHITELIST_ALERTS_UPGRADE_LIST = ["OutdatedVirtualMachineInstanceWorkloads"]
Expand Down Expand Up @@ -713,3 +718,54 @@ def _get_updated_odf_csv(_target_version: str, _admin_client: DynamicClient) ->
if not sample:
return
LOGGER.info(f"Following odf csvs are not updated: {','.join(sample)}")


def apply_konflux_idms(
idms: ImageDigestMirrorSet,
required_mirrors: list[str],
machine_config_pools: list[MachineConfigPool],
mcp_conditions: dict[str, list[dict[str, str]]],
nodes: list[Node],
) -> None:
"""Creates or patches the Konflux IDMS with the required mirror entries.

Args:
idms: The Konflux IDMS resource to create or patch.
required_mirrors: Konflux mirror URLs to set on the IDMS.
machine_config_pools: Active machine config pools to pause/wait.
mcp_conditions: Initial MCP conditions for tracking update progress.
nodes: Cluster nodes to verify readiness after MCP update.
"""
image_digest_mirrors = [{"source": KONFLUX_IDMS_SOURCE, "mirrors": required_mirrors}]

LOGGER.info("Pausing MCP updates while modifying IDMS.")
with ResourceEditor(patches={mcp: {"spec": {"paused": True}} for mcp in machine_config_pools}):
if idms.exists:
LOGGER.info(f"Patching IDMS {KONFLUX_IDMS_NAME} with mirrors: {required_mirrors}")
ResourceEditor(patches={idms: {"spec": {"imageDigestMirrors": image_digest_mirrors}}}).update()
else:
LOGGER.info(f"Creating IDMS {KONFLUX_IDMS_NAME} with mirrors: {required_mirrors}")
ImageDigestMirrorSet(
name=KONFLUX_IDMS_NAME,
image_digest_mirrors=image_digest_mirrors,
teardown=False,
).deploy(wait=True)

LOGGER.info("Wait for MCP update after IDMS modification.")
wait_for_mcp_update_completion(
machine_config_pools_list=machine_config_pools,
initial_mcp_conditions=mcp_conditions,
nodes=nodes,
)


def idms_has_all_mirrors(idms: ImageDigestMirrorSet, required_mirrors: list[str]) -> bool:
"""Returns True if the IDMS already contains all required Konflux mirror entries."""
source_entry = next(
(entry for entry in idms.instance.spec.imageDigestMirrors if entry["source"] == KONFLUX_IDMS_SOURCE),
None,
)
if not source_entry:
return False
existing_urls = {str(mirror) for mirror in source_entry["mirrors"]}
return all(mirror in existing_urls for mirror in required_mirrors)