diff --git a/ocs_ci/deployment/helpers/hypershift_base.py b/ocs_ci/deployment/helpers/hypershift_base.py index df042be1f448..cbd179880d5b 100644 --- a/ocs_ci/deployment/helpers/hypershift_base.py +++ b/ocs_ci/deployment/helpers/hypershift_base.py @@ -18,6 +18,7 @@ from ocs_ci.ocs.exceptions import ( CommandFailed, TimeoutExpiredError, + ClusterNotFoundException, ) from ocs_ci.ocs.ocp import OCP from ocs_ci.ocs.resources.pod import wait_for_pods_to_be_in_statuses_concurrently @@ -242,7 +243,10 @@ def is_hosted_cluster(cluster_name=None): cluster_name = cluster_name or config.ENV_DATA["cluster_name"] config.switch_ctx(config.get_cluster_index_by_name(cluster_name)) - config.switch_to_provider() + try: + config.switch_to_provider() + except ClusterNotFoundException: + return False ocp_obj = OCP( kind=constants.HOSTED_CLUSTERS, namespace=constants.CLUSTERS_NAMESPACE ) @@ -1141,8 +1145,9 @@ def apply_idms_to_hosted_cluster(self, name, idms_json_dict=None, replace=False) Args: name (str): HostedCluster name (namespace is clusters- but resource lives in clusters namespace) - idms_json_dict (dict|None): If provided, use this pre-fetched dict - (output of 'oc get imagedigestmirrorsets -o json'). + idms_json_dict (dict|None): If provided, use this pre-fetched dict. Can be either: + - Output of 'oc get imagedigestmirrorsets -o json' (list with "items") + - A single ImageDigestMirrorSet resource dict (without "items" wrapper) If None, it will be fetched automatically. replace (bool): If True, replace any existing spec.imageContentSources with the new list. If False, merge (append new unique entries after existing ones). diff --git a/ocs_ci/deployment/helpers/idms_parser.py b/ocs_ci/deployment/helpers/idms_parser.py index c58d2d574775..0588bf830356 100644 --- a/ocs_ci/deployment/helpers/idms_parser.py +++ b/ocs_ci/deployment/helpers/idms_parser.py @@ -146,13 +146,24 @@ def extract_image_content_sources(idms_json_dict): Extract imageContentSources list (for HostedCluster spec) from ImageDigestMirrorSet JSON. Args: - idms_json_dict (dict): Output of 'oc get imagedigestmirrorsets -o json' parsed as dict + idms_json_dict (dict): Either: + - Output of 'oc get imagedigestmirrorsets -o json' parsed as dict (with "items" list) + - A single ImageDigestMirrorSet resource dict (without "items" wrapper) Returns: list[dict]: imageContentSources entries (possibly empty) """ - if not idms_json_dict or not idms_json_dict.get("items"): + if not idms_json_dict: return [] + + # Check if this is a single IDMS resource or a list with "items" + if idms_json_dict.get("kind") == "ImageDigestMirrorSet": + # Single IDMS resource - wrap it in the expected format + idms_json_dict = {"apiVersion": "v1", "kind": "List", "items": [idms_json_dict]} + elif not idms_json_dict.get("items"): + # No items and not a single IDMS resource + return [] + idms_obj = parse_image_digest_mirror_set(idms_json_dict) image_content_sources = [] for item in idms_obj.items: diff --git a/ocs_ci/utility/operators.py b/ocs_ci/utility/operators.py index 35bdd44fce6e..e5c0350c8110 100644 --- a/ocs_ci/utility/operators.py +++ b/ocs_ci/utility/operators.py @@ -171,7 +171,6 @@ def _create_catalog(self, image: str, name: str): with open(catalog_data_yaml.name, "w") as fd: fd.write(yaml.dump(catalog_data)) run_cmd(f"oc apply -f {catalog_data_yaml.name}") - wait_for_machineconfigpool_status("all", force_delete_pods=False) def create_unreleased_catalog(self): """ @@ -181,10 +180,30 @@ def create_unreleased_catalog(self): raise ValueError( "Child class must define attribute `unreleased_catalog_image`" ) - self.create_idms_for_unreleased_catalog() + cluster_name = config.ENV_DATA.get("cluster_name") + # Import here to avoid circular import + from ocs_ci.deployment.helpers.hypershift_base import ( + HyperShiftBase, + is_hosted_cluster, + ) + + is_hosted = is_hosted_cluster(cluster_name) + if is_hosted: + with config.RunWithProviderConfigContextIfAvailable(): + idms_data = self.get_idms_data() + hypershift_base = HyperShiftBase() + + # Apply IDMS mirrors to the hosted cluster's imageContentSources + hypershift_base.apply_idms_to_hosted_cluster( + name=cluster_name, idms_json_dict=idms_data, replace=False + ) + else: + self.create_idms_for_unreleased_catalog() self._create_catalog( self.unreleased_catalog_full_image, self.unreleased_catalog_name ) + if not is_hosted: + wait_for_machineconfigpool_status("all", force_delete_pods=False) def create_disconnected_catalog(self): # in case of disconnected environment, we have to mirror all the @@ -201,6 +220,11 @@ def create_disconnected_catalog(self): idms=idms, ) self._create_catalog(mirrored_index_image, self.unreleased_catalog_name) + # Import here to avoid circular import + from ocs_ci.deployment.helpers.hypershift_base import is_hosted_cluster + + if not is_hosted_cluster(config.ENV_DATA.get("cluster_name")): + wait_for_machineconfigpool_status("all", force_delete_pods=False) @retry(CommandFailed, tries=5, delay=30, backoff=1) def is_available(self):