diff --git a/conf/README.md b/conf/README.md index 604a69f7e53..874e2a1d7b1 100644 --- a/conf/README.md +++ b/conf/README.md @@ -326,7 +326,10 @@ higher priority). * `node_network_configuration_policy_destination_route` - The destination route of NodeNetworkConfigurationPolicy CR * `hcp_version` - version of HCP client to be deployed on machine running the tests * `metallb_version` - MetalLB operator version to install -* `install_hypershift_upstream` - Install hypershift from upstream or not (Default: false). Necessary for unreleased OCP/CNV versions +* `deploy_acm_hub_cluster` - Deploy ACM hub cluster or not (Default: false) +* `cnv_deployment` - Deploy CNV or not (Default: false) necessary for Converged clusters with hosted clients +* `mce_deployment` - Deploy MCE or not (Default: false) +* `deploy_hyperconverged` - Deploy hyperconverged operator or not (Default: false). Necessary for Converged clusters with hosted clients with unreleased OCP version * `clusters` - section for hosted clusters * `` - name of the cluster * `hosted_cluster_path` - path to the cluster directory to store auth_path, credentials files or cluster related files diff --git a/conf/examples/provider_mode_ibm_cloud_baremetal_kubevirt_clients.yaml b/conf/examples/provider_mode_ibm_cloud_baremetal_kubevirt_clients.yaml index 251a016015b..8965b74956c 100644 --- a/conf/examples/provider_mode_ibm_cloud_baremetal_kubevirt_clients.yaml +++ b/conf/examples/provider_mode_ibm_cloud_baremetal_kubevirt_clients.yaml @@ -11,6 +11,8 @@ DEPLOYMENT: metallb_operator: true cnv_latest_stable: true local_storage: true + mce_deployment: false # use when unreleased version on Clients is needed + deploy_hyperconverged: false # use when unreleased version on Clients is needed ENV_DATA: platform: "hci_baremetal" cluster_type: "provider" # it is necessary to run the Hosted clusters deployment on the Provider cluster diff --git a/ocs_ci/deployment/hosted_cluster.py b/ocs_ci/deployment/hosted_cluster.py index 2c84e5c1d71..442f5f84c94 100644 --- a/ocs_ci/deployment/hosted_cluster.py +++ b/ocs_ci/deployment/hosted_cluster.py @@ -5,6 +5,7 @@ import time from concurrent.futures import ThreadPoolExecutor from ocs_ci.deployment.cnv import CNVInstaller +from ocs_ci.deployment.hyperconverged import HyperConverged from ocs_ci.deployment.mce import MCEInstaller from ocs_ci.deployment.deployment import Deployment from ocs_ci.deployment.helpers.hypershift_base import ( @@ -22,6 +23,7 @@ CommandFailed, TimeoutExpiredError, ResourceWrongStatusException, + UnexpectedDeploymentConfiguration, ) from ocs_ci.ocs.ocp import OCP from ocs_ci.ocs.resources.catalog_source import CatalogSource @@ -36,8 +38,6 @@ from ocs_ci.utility.utils import ( exec_cmd, TimeoutSampler, - get_ocp_version, - get_latest_release_version, ) from ocs_ci.utility.version import get_semantic_version from ocs_ci.ocs.resources.storage_client import StorageClient @@ -260,12 +260,50 @@ def deploy_hosted_ocp_clusters(self, cluster_names_list=None): # operators and finish the rest preparation steps. For the rest of the clusters we will only deploy OCP # with hcp command. first_ocp_deployment = index == 0 - cluster_name = hosted_ocp_cluster.deploy_ocp( - deploy_cnv=first_ocp_deployment, - deploy_acm_hub=first_ocp_deployment, + + # Put logic on checking and deploying dependencies here + if first_ocp_deployment: + # ACM installation is a default for Provider/Converged deployments + deploy_acm_hub = config.ENV_DATA.get("deploy_acm_hub_cluster", True) + # CNV installation is a default for Provider/Converged deployments + deploy_cnv = config.DEPLOYMENT.get("cnv_deployment", True) + deploy_mce = config.DEPLOYMENT.get("mce_deployment", False) + deploy_hyperconverged = config.ENV_DATA.get( + "deploy_hyperconverged", False + ) + + # Validate conflicting deployments + if deploy_acm_hub and deploy_mce: + raise UnexpectedDeploymentConfiguration( + "Conflict: Both 'deploy_acm_hub_cluster' and 'mce_deployment' are enabled. Choose one." + ) + if deploy_cnv and deploy_hyperconverged: + raise UnexpectedDeploymentConfiguration( + "Conflict: Both 'cnv_deployment' and 'deploy_hyperconverged' are enabled. Choose one." + ) + + else: + deploy_acm_hub = False + deploy_cnv = False + deploy_hyperconverged = False + deploy_mce = False + + if not config.ENV_DATA["platform"].lower() in HCI_PROVIDER_CLIENT_PLATFORMS: + raise ProviderModeNotFoundException() + + if not config.ENV_DATA.get("deploy_acm_hub_cluster", True): + deploy_acm_hub = False + + hosted_ocp_cluster.deploy_dependencies( + deploy_acm_hub=deploy_acm_hub, + deploy_cnv=deploy_cnv, deploy_metallb=first_ocp_deployment, download_hcp_binary=first_ocp_deployment, + deploy_hyperconverged=deploy_hyperconverged, + deploy_mce=deploy_mce, ) + + cluster_name = hosted_ocp_cluster.deploy_ocp() if cluster_name: cluster_names.append(cluster_name) @@ -361,7 +399,12 @@ def deploy_multiple_odf_clients(self): class HypershiftHostedOCP( - HyperShiftBase, MetalLBInstaller, CNVInstaller, Deployment, MCEInstaller + HyperShiftBase, + MetalLBInstaller, + CNVInstaller, + Deployment, + MCEInstaller, + HyperConverged, ): def __init__(self, name): Deployment.__init__(self) @@ -369,6 +412,7 @@ def __init__(self, name): MetalLBInstaller.__init__(self) CNVInstaller.__init__(self) MCEInstaller.__init__(self) + HyperConverged.__init__(self) self.name = name if config.ENV_DATA.get("clusters", {}).get(self.name): cluster_path = ( @@ -384,36 +428,16 @@ def __init__(self, name): f"Cluster path for desired cluster with name '{self.name}' was not found in ENV_DATA.clusters" ) - def deploy_ocp( - self, - deploy_cnv=True, - deploy_acm_hub=True, - deploy_metallb=True, - download_hcp_binary=True, - deploy_mce=True, - ): + def deploy_ocp(self, **kwargs) -> str: """ Deploy hosted OCP cluster on provisioned Provider platform Args: - deploy_cnv: (bool) Deploy CNV - deploy_acm_hub: (bool) Deploy ACM Hub - deploy_metallb: (bool) Deploy MetalLB - download_hcp_binary: (bool) Download HCP binary + **kwargs: Additional arguments for create_kubevirt_ocp_cluster (currently not in use) Returns: str: Name of the hosted cluster """ - if not config.ENV_DATA["platform"].lower() in HCI_PROVIDER_CLIENT_PLATFORMS: - raise ProviderModeNotFoundException() - - if not config.ENV_DATA.get("deploy_acm_hub_cluster", True): - deploy_acm_hub = False - - self.deploy_dependencies( - deploy_acm_hub, deploy_cnv, deploy_metallb, download_hcp_binary, deploy_mce - ) - ocp_version = str(config.ENV_DATA["clusters"][self.name].get("ocp_version")) if ocp_version and len(ocp_version.split(".")) == 2: # if ocp_version is provided in form x.y, we need to get the full form x.y.z @@ -461,6 +485,7 @@ def deploy_dependencies( deploy_metallb, download_hcp_binary, deploy_mce, + deploy_hyperconverged, ): """ Deploy dependencies for hosted OCP cluster @@ -470,8 +495,17 @@ def deploy_dependencies( deploy_metallb: bool Deploy MetalLB download_hcp_binary: bool Download HCP binary deploy_mce: bool Deploy mce + deploy_hyperconverged: bool Deploy Hyperconverged """ + + # log out all args in one log.info + logger.info( + f"Deploying dependencies for hosted OCP cluster '{self.name}': " + f"deploy_acm_hub={deploy_acm_hub}, deploy_cnv={deploy_cnv}, " + f"deploy_metallb={deploy_metallb}, download_hcp_binary={download_hcp_binary}, " + f"deploy_mce={deploy_mce}, deploy_hyperconverged={deploy_hyperconverged}" + ) initial_default_sc = helpers.get_default_storage_class() logger.info(f"Initial default StorageClass: {initial_default_sc}") if not initial_default_sc == constants.CEPHBLOCKPOOL_SC: @@ -483,8 +517,15 @@ def deploy_dependencies( except CommandFailed as e: logger.error(f"Failed to change default StorageClass: {e}") - if deploy_cnv: + if deploy_cnv and not deploy_hyperconverged: self.deploy_cnv(check_cnv_ready=True) + elif deploy_hyperconverged and not deploy_cnv: + self.deploy_hyperconverged() + elif deploy_cnv and deploy_hyperconverged: + raise UnexpectedDeploymentConfiguration( + "Both deploy_cnv and deploy_hyperconverged are set to True. " + "Please choose only one of them." + ) if deploy_acm_hub: self.deploy_acm_hub() if deploy_metallb: @@ -495,30 +536,6 @@ def deploy_dependencies( self.deploy_mce() self.validate_mce_deployment() - provider_ocp_version = str( - get_semantic_version(get_ocp_version(), only_major_minor=True) - ) - latest_released_ocp_version = str( - get_semantic_version(get_latest_release_version(), only_major_minor=True) - ) - - if provider_ocp_version > latest_released_ocp_version: - logger.info("running on unreleased OCP version") - if config.ENV_DATA.get("install_hypershift_upstream"): - try: - self.disable_multicluster_engine() - # avoid timelapse error " - # Error: [serviceaccounts "operator" is forbidden: unable to create new content" - logger.info( - "Sleeping for 5 minutes after disable_multicluster_engine()" - ) - time.sleep(5 * 60) - self.install_hypershift_upstream_on_cluster() - except CommandFailed as e: - raise AssertionError( - f"Failed to install Hypershift on the cluster: {e}" - ) - # Enable central infrastructure management service for agent if config.DEPLOYMENT.get("hosted_cluster_platform") == "agent": provisioning_obj = OCP(**OCP(kind=constants.PROVISIONING).get()[0]) diff --git a/ocs_ci/deployment/hyperconverged.py b/ocs_ci/deployment/hyperconverged.py new file mode 100644 index 00000000000..6273db7e555 --- /dev/null +++ b/ocs_ci/deployment/hyperconverged.py @@ -0,0 +1,217 @@ +import logging +import semantic_version + +from ocs_ci.ocs.ocp import OCP +from ocs_ci.ocs import constants +from ocs_ci.ocs.resources.deployment import Deployment +from ocs_ci.ocs.resources.ocs import OCS +from ocs_ci.ocs.resources.pod import wait_for_pods_to_be_running +from ocs_ci.ocs.utils import get_pod_name_by_pattern +from ocs_ci.ocs.version import get_ocp_version +from ocs_ci.utility import templating +from ocs_ci.ocs.resources.catalog_source import CatalogSource + +logger = logging.getLogger(__name__) + + +class HyperConverged: + """ + This class represent HyperConverged and contains all related methods we need to do with it. + Hyperconverged Operator is used instead of unreleased CNV, to overcome catalogsource limitations on Client clusters + """ + + def __init__(self): + self.namespace = constants.HYPERCONVERGED_NAMESPACE + self.ns_obj = OCP(kind=constants.NAMESPACES) + self.operator_group = OCP( + kind=constants.OPERATOR_GROUP, namespace=self.namespace + ) + self.catsrc = OCP( + kind=constants.CATSRC, namespace=constants.MARKETPLACE_NAMESPACE + ) + self.subs = OCP(kind=constants.PROVIDER_SUBSCRIPTION, namespace=self.namespace) + # type of hyperconverged becomes available after the Hyperconverged operator is deployed + self.hyperconverged = None + self.ocp_version = get_ocp_version() + + def create_hyperconverged_namespace(self): + """ + Creates the namespace for hyperconverged resources + + """ + if not self.ns_obj.is_exist( + resource_name=self.namespace, + ): + logger.info( + f"Creating namespace {self.namespace} for hyperconverged resources" + ) + namespace_yaml_file = templating.load_yaml( + constants.HYPERCONVERGED_NAMESPACE_YAML + ) + namespace_yaml = OCS(**namespace_yaml_file) + namespace_yaml.create() + else: + logger.info(f"{self.namespace} already exists") + return self.ns_obj.check_resource_existence( + should_exist=True, resource_name=self.namespace + ) + + def create_operator_group(self): + """ + Creates operator group for hyperconverged resources + + """ + logger.info("Creating operator group for hyperconverged resources") + + if not self.operator_group.is_exist( + resource_name=constants.HYPERCONVERGED_OPERATOR_GROUP_NAME + ): + operator_group_yaml_file = templating.load_yaml( + constants.HYPERCONVERGED_OPERATOR_GROUP_YAML + ) + operator_group_yaml = OCS(**operator_group_yaml_file) + operator_group_yaml.create() + return self.operator_group.check_resource_existence( + should_exist=True, + resource_name=constants.HYPERCONVERGED_OPERATOR_GROUP_NAME, + ) + + def create_catalog_source(self): + """ + Creates catalog source for hyperconverged resources + ! No customization by purpose. Will always align with branch default image that is set in the default config. + """ + logger.info("Check if catalog source already exist") + if not self.catsrc.is_exist( + resource_name=constants.HYPERCONVERGED_CATALOGSOURCE + ): + catalog_source_yaml_file = templating.load_yaml( + constants.HYPERVERGED_CATALOGSOURCE_YAML + ) + hyperconverged_version = get_hyperconverged_corresponding_version( + self.ocp_version + ) + catalog_source_yaml_file["spec"]["image"] = catalog_source_yaml_file[ + "spec" + ]["image"].format(hyperconverged_version=hyperconverged_version) + catalog_source_yaml = OCS(**catalog_source_yaml_file) + catalog_source_yaml.create() + self.catsrc.check_resource_existence( + should_exist=True, resource_name=constants.HYPERCONVERGED_CATALOGSOURCE + ) + catalog_source_yaml = CatalogSource( + constants.HYPERCONVERGED_CATALOGSOURCE, constants.MARKETPLACE_NAMESPACE + ) + catalog_source_yaml.wait_for_state("READY") + + def create_subscription(self): + """ + Creates subscription for hyperconverged operator + + """ + logger.info("Check if subscription already exist") + if not self.subs.is_exist(resource_name=constants.HYPERCONVERGED_SUBSCRIPTION): + subscription_yaml_data = templating.load_yaml( + constants.HYPERCONVERGED_SUBSCRIPTION_YAML + ) + hyperconverged_version = get_hyperconverged_corresponding_version( + self.ocp_version + ) + subscription_yaml_data["spec"]["channel"] = subscription_yaml_data["spec"][ + "channel" + ].format(hyperconverged_version=hyperconverged_version) + subscription_obj = OCS(**subscription_yaml_data) + subscription_obj.create() + self.subs.check_resource_existence( + should_exist=True, resource_name=constants.HYPERCONVERGED_SUBSCRIPTION + ) + + pod_names = get_pod_name_by_pattern( + "hco-operator", self.namespace + ) + get_pod_name_by_pattern("virt-operator", self.namespace) + wait_for_pods_to_be_running(namespace=self.namespace, pod_names=pod_names) + + def create_hyperconverged_instance(self): + """ + Create Hyperconverged instance + """ + self.hyperconverged = OCP( + kind=constants.HYPERCONVERGED_KIND, namespace=self.namespace + ) + if not self.hyperconverged.is_exist( + resource_name=constants.HYPERCONVERGED_NAME + ): + hyperconverged_instance_yaml_file = templating.load_yaml( + constants.HYPERCONVERGED_YAML + ) + hyperconverged_instance_yaml = OCS(**hyperconverged_instance_yaml_file) + hyperconverged_instance_yaml.create() + self.hyperconverged.check_resource_existence( + should_exist=True, resource_name=constants.HYPERCONVERGED_NAME + ) + # wait for pods to be up and running + deployments = ["virt-api", "virt-controller", "virt-exporterproxy"] + + for resource_name in deployments: + depl_ocp_obj = OCP( + kind=constants.DEPLOYMENT, + namespace=self.namespace, + resource_name=resource_name, + ) + deployment_obj = Deployment( + **depl_ocp_obj.get(retry=60, wait=10, dont_raise=True) + ) + deployment_obj.wait_for_available_replicas(timeout=600) + + def deploy_hyperconverged(self): + """ + Deploy Hyperconverged Operator and resources + """ + # avoid mix in MRO calling explicitly the method of own class + HyperConverged.create_hyperconverged_namespace(self) + HyperConverged.create_operator_group(self) + HyperConverged.create_catalog_source(self) + HyperConverged.create_subscription(self) + HyperConverged.create_hyperconverged_instance(self) + + +def get_hyperconverged_corresponding_version(ocp_version: str) -> str: + """ + Given an OCP version, return the corresponding Hyperconverged version. + + Rule: + - Hyperconverged Major = OCP Major - 3 + - Hyperconverged Minor = OCP Minor - 4 + + Args: + ocp_version: OCP version as a string (e.g., "4.18") + Returns: + Corresponding Hyperconverged version as a string (e.g., "1.14") + """ + ocp_semver = semantic_version.Version( + ocp_version + ".0" + ) # Ensure valid semantic versioning + hyperconverged_major = ocp_semver.major - 3 + hyperconverged_minor = ocp_semver.minor - 4 + + return f"{hyperconverged_major}.{hyperconverged_minor}" + + +def get_ocp_corresponding_version(hyperconverged_version: str) -> str: + """ + Given a Hyperconverged version, return the corresponding OCP version. + + Rule: + - OCP Major = Hyperconverged Major + 3 + - OCP Minor = Hyperconverged Minor + 4 + + Args: + hyperconverged_version: Hyperconverged version as a string (e.g., "1.14") + Returns: + Corresponding OCP version as a string (e.g., "4.18") + """ + hyperconverged_semver = semantic_version.Version(hyperconverged_version + ".0") + ocp_major = hyperconverged_semver.major + 3 + ocp_minor = hyperconverged_semver.minor + 4 + + return f"{ocp_major}.{ocp_minor}" diff --git a/ocs_ci/framework/conf/default_config.yaml b/ocs_ci/framework/conf/default_config.yaml index e70cb614579..ec3c8af95ba 100644 --- a/ocs_ci/framework/conf/default_config.yaml +++ b/ocs_ci/framework/conf/default_config.yaml @@ -236,6 +236,10 @@ ENV_DATA: rhel8_template: 'rhel87_ocs4qe' # ACM HUB deployment deploy_acm_hub_cluster: false + # HyperConverged deployment + deploy_hyperconverged: false + # mce deployment + deploy_mce: false # Managed service git stat default configurations # Managed StorageCluster size in TiB diff --git a/ocs_ci/ocs/constants.py b/ocs_ci/ocs/constants.py index c342be0a28b..abcd85788b4 100644 --- a/ocs_ci/ocs/constants.py +++ b/ocs_ci/ocs/constants.py @@ -506,6 +506,34 @@ DEFAULT_VOLUMESNAPSHOTCLASS_CEPHFS_MS_PC = f"{DEFAULT_CLUSTERNAME}-cephfs" DEFAULT_VOLUMESNAPSHOTCLASS_RBD_MS_PC = f"{DEFAULT_CLUSTERNAME}-ceph-rbd" +# hyperconverged defaults +HYPERCONVERGED_NAMESPACE = "kubevirt-hyperconverged" +# MCE_NAMESPACE_YAML = os.path.join(TEMPLATE_DEPLOYMENT_DIR_MCE, "mce_namespace.yaml") +TEMPLATE_DEPLOYMENT_DIR_HYPERCONVERGED = os.path.join( + TEMPLATE_DIR, "hyperconverged-deployment" +) +HYPERCONVERGED_NAMESPACE_YAML = os.path.join( + TEMPLATE_DEPLOYMENT_DIR_HYPERCONVERGED, "hyperconverged_namespace.yaml" +) +HYPERCONVERGED_OPERATOR_GROUP_YAML = os.path.join( + TEMPLATE_DEPLOYMENT_DIR_HYPERCONVERGED, "hyperconverged_operator_group.yaml" +) +HYPERCONVERGED_OPERATOR_GROUP_NAME = "hyperconverged-operator-group" +HYPERCONVERGED_CATALOGSOURCE = "hyperconverged-catalogsource" +HYPERVERGED_CATALOGSOURCE_YAML = os.path.join( + TEMPLATE_DEPLOYMENT_DIR_HYPERCONVERGED, "hyperconverged-catsrc.yaml" +) +HYPERCONVERGED_SUBSCRIPTION = "community-kubevirt-hyperconverged" +HYPERCONVERGED_SUBSCRIPTION_YAML = os.path.join( + TEMPLATE_DEPLOYMENT_DIR_HYPERCONVERGED, "hyperconverged_subscription.yaml" +) +HYPERCONVERGED_KIND = "HyperConverged" +HYPERCONVERGED_NAME = "kubevirt-hyperconverged" +HYPERCONVERGED_YAML = os.path.join( + TEMPLATE_DEPLOYMENT_DIR_HYPERCONVERGED, "hyperconverged.yaml" +) + + # CNV deployment constants CNV_NAMESPACE = "openshift-cnv" CNV_QUAY_NIGHTLY_IMAGE = "quay.io/openshift-cnv/nightly-catalog" diff --git a/ocs_ci/ocs/resources/deployment.py b/ocs_ci/ocs/resources/deployment.py index 370513a8b72..3c501f22db3 100644 --- a/ocs_ci/ocs/resources/deployment.py +++ b/ocs_ci/ocs/resources/deployment.py @@ -105,7 +105,7 @@ def set_revision(self, revision, resource_name=None): cmd = f"rollout undo {self.kind}/{resource_name} --to-revision={revision}" self.ocp.exec_oc_cmd(cmd) - def wait_for_available_replicas(self, timeout=15, sleep=3): + def wait_for_available_replicas(self, timeout=360, sleep=3): """ Wait for number of available replicas reach number of desired replicas. @@ -133,7 +133,9 @@ def _get_available_replicas(): ) return available_replicas - for available_replicas in TimeoutSampler(360, 2, func=_get_available_replicas): + for available_replicas in TimeoutSampler( + timeout, sleep, func=_get_available_replicas + ): if available_replicas == desired_replicas: logger.info( f"Deployment {self.name} reached " diff --git a/ocs_ci/templates/hyperconverged-deployment/hyperconverged-catsrc.yaml b/ocs_ci/templates/hyperconverged-deployment/hyperconverged-catsrc.yaml new file mode 100644 index 00000000000..a35cec24b33 --- /dev/null +++ b/ocs_ci/templates/hyperconverged-deployment/hyperconverged-catsrc.yaml @@ -0,0 +1,8 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: CatalogSource +metadata: + name: hyperconverged-catalogsource + namespace: openshift-marketplace +spec: + image: 'quay.io/kubevirt/hyperconverged-cluster-index:{hyperconverged_version}.0-unstable' + sourceType: grpc diff --git a/ocs_ci/templates/hyperconverged-deployment/hyperconverged.yaml b/ocs_ci/templates/hyperconverged-deployment/hyperconverged.yaml new file mode 100644 index 00000000000..345d4849c47 --- /dev/null +++ b/ocs_ci/templates/hyperconverged-deployment/hyperconverged.yaml @@ -0,0 +1,5 @@ +kind: HyperConverged +apiVersion: hco.kubevirt.io/v1beta1 +metadata: + name: kubevirt-hyperconverged + namespace: kubevirt-hyperconverged diff --git a/ocs_ci/templates/hyperconverged-deployment/hyperconverged_namespace.yaml b/ocs_ci/templates/hyperconverged-deployment/hyperconverged_namespace.yaml new file mode 100644 index 00000000000..7702ddcb468 --- /dev/null +++ b/ocs_ci/templates/hyperconverged-deployment/hyperconverged_namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: kubevirt-hyperconverged + labels: + openshift.io/cluster-monitoring: "true" diff --git a/ocs_ci/templates/hyperconverged-deployment/hyperconverged_operator_group.yaml b/ocs_ci/templates/hyperconverged-deployment/hyperconverged_operator_group.yaml new file mode 100644 index 00000000000..44d764776f7 --- /dev/null +++ b/ocs_ci/templates/hyperconverged-deployment/hyperconverged_operator_group.yaml @@ -0,0 +1,5 @@ +apiVersion: operators.coreos.com/v1 +kind: OperatorGroup +metadata: + name: hyperconverged-operator-group + namespace: kubevirt-hyperconverged diff --git a/ocs_ci/templates/hyperconverged-deployment/hyperconverged_subscription.yaml b/ocs_ci/templates/hyperconverged-deployment/hyperconverged_subscription.yaml new file mode 100644 index 00000000000..5220299d948 --- /dev/null +++ b/ocs_ci/templates/hyperconverged-deployment/hyperconverged_subscription.yaml @@ -0,0 +1,14 @@ +apiVersion: operators.coreos.com/v1alpha1 +kind: Subscription +metadata: + name: community-kubevirt-hyperconverged + namespace: kubevirt-hyperconverged +spec: + # candidate-v1.14 is the latest version of the kubevirt-hyperconverged operator that supports OCP 4.18, + # 1.15 is the latest version that supports OCP 4.19 + # rule is OCP version - 3.4 + channel: candidate-v{hyperconverged_version} + installPlanApproval: Automatic + name: community-kubevirt-hyperconverged + source: hyperconverged-catalogsource + sourceNamespace: openshift-marketplace diff --git a/tests/libtest/test_provider_create_hosted_cluster.py b/tests/libtest/test_provider_create_hosted_cluster.py index 14dd367db78..c682882f7bb 100644 --- a/tests/libtest/test_provider_create_hosted_cluster.py +++ b/tests/libtest/test_provider_create_hosted_cluster.py @@ -56,7 +56,16 @@ def test_provider_deploy_OCP_hosted(self): logger.info("Test deploy hosted OCP on provider platform") cluster_name = list(config.ENV_DATA["clusters"].keys())[-1] - HypershiftHostedOCP(cluster_name).deploy_ocp() + hypershift_hosted = HypershiftHostedOCP(cluster_name) + hypershift_hosted.deploy_dependencies( + deploy_acm_hub=True, + deploy_cnv=True, + deploy_metallb=True, + download_hcp_binary=True, + deploy_hyperconverged=False, + deploy_mce=False, + ) + hypershift_hosted.deploy_ocp() @hci_provider_required def test_provider_deploy_OCP_hosted_skip_cnv_and_lb(self): @@ -67,10 +76,16 @@ def test_provider_deploy_OCP_hosted_skip_cnv_and_lb(self): "Test deploy hosted OCP on provider platform with metallb and cnv ready" ) cluster_name = list(config.ENV_DATA["clusters"].keys())[-1] - - HypershiftHostedOCP(cluster_name).deploy_ocp( - deploy_cnv=False, deploy_metallb=False, download_hcp_binary=True + hypershift_hosted = HypershiftHostedOCP(cluster_name) + hypershift_hosted.deploy_dependencies( + deploy_acm_hub=True, + deploy_cnv=False, + deploy_metallb=False, + download_hcp_binary=True, + deploy_hyperconverged=False, + deploy_mce=False, ) + hypershift_hosted.deploy_ocp() @hci_provider_required def test_provider_deploy_OCP_hosted_skip_cnv(self): @@ -80,7 +95,16 @@ def test_provider_deploy_OCP_hosted_skip_cnv(self): logger.info("Test deploy hosted OCP on provider platform with cnv ready") cluster_name = list(config.ENV_DATA["clusters"].keys())[-1] - HypershiftHostedOCP(cluster_name).deploy_ocp(deploy_cnv=False) + hypershift_hosted = HypershiftHostedOCP(cluster_name) + hypershift_hosted.deploy_dependencies( + deploy_acm_hub=True, + deploy_cnv=False, + deploy_metallb=True, + download_hcp_binary=True, + deploy_hyperconverged=False, + deploy_mce=False, + ) + HypershiftHostedOCP(cluster_name).deploy_ocp() @hci_provider_required def test_provider_deploy_OCP_hosted_multiple(self): @@ -113,6 +137,7 @@ def test_deploy_OCP_and_setup_ODF_client_on_hosted_clusters(self): Test install ODF on hosted cluster """ logger.info("Deploy hosted OCP on provider platform multiple times") + HostedClients().do_deploy() @runs_on_provider @@ -224,6 +249,8 @@ def test_deploy_acm(self): deploy_cnv=False, deploy_metallb=False, download_hcp_binary=False, + deploy_hyperconverged=False, + deploy_mce=False, ) assert validate_acm_hub_install(), "ACM not installed or MCE not configured" @@ -240,6 +267,8 @@ def test_deploy_cnv(self): deploy_cnv=True, deploy_metallb=False, download_hcp_binary=False, + deploy_hyperconverged=False, + deploy_mce=False, ) assert hypershift_hosted.cnv_hyperconverged_installed(), "CNV not installed" @@ -256,6 +285,8 @@ def test_deploy_metallb(self): deploy_cnv=False, deploy_metallb=True, download_hcp_binary=False, + deploy_hyperconverged=False, + deploy_mce=False, ) assert hypershift_hosted.metallb_instance_created(), "Metallb not installed" @@ -272,6 +303,8 @@ def test_download_hcp(self): deploy_cnv=False, deploy_metallb=False, download_hcp_binary=True, + deploy_hyperconverged=False, + deploy_mce=False, ) assert hypershift_hosted.hcp_binary_exists(), "HCP binary not downloaded" @@ -327,14 +360,42 @@ def test_deploy_mce(self): deploy_metallb=False, download_hcp_binary=False, deploy_mce=True, + deploy_hyperconverged=False, ) @hci_provider_required - def test_provider_deploy_OCP_hosted_skip_acm(self): + def test_provider_deploy_ocp_hosted_skip_acm(self): """ Test deploy hosted OCP on provider platform with cnv ready beforehand + ! Suitable for released version of OCP only (no mce and hyperconverged) """ logger.info("Test deploy hosted OCP on provider platform with cnv ready") cluster_name = list(config.ENV_DATA["clusters"].keys())[-1] + hypershift_hosted = HypershiftHostedOCP(cluster_name) + + hypershift_hosted.deploy_dependencies( + deploy_acm_hub=False, + deploy_cnv=True, + deploy_metallb=True, + download_hcp_binary=True, + deploy_mce=False, + deploy_hyperconverged=False, + ) + + HypershiftHostedOCP(cluster_name).deploy_ocp() - HypershiftHostedOCP(cluster_name).deploy_ocp(deploy_acm_hub=False) + def test_deploy_hyperconverged(self): + """ + Test deploy hyperconverged operator + ! Hyperconverged is used instead of unreleased CNV, to overcome catalogsource limitations on client clusters + """ + logger.info("Test deploy hyperconverged operator") + hypershift_hosted = HypershiftHostedOCP("dummy") + hypershift_hosted.deploy_dependencies( + deploy_acm_hub=False, + deploy_cnv=False, + deploy_metallb=False, + download_hcp_binary=False, + deploy_mce=False, + deploy_hyperconverged=True, + )