Пример #1
0
 def deploy_ocs_via_operator(self):
     """
     Method for deploy OCS via OCS operator
     """
     logger.info("Deployment of OCS via OCS operator")
     olm_manifest = self.get_olm_manifest()
     self.label_and_taint_nodes()
     run_cmd(f"oc create -f {olm_manifest}")
     # wait for package manifest
     package_manifest = PackageManifest(
         resource_name=defaults.OCS_OPERATOR_NAME)
     # Wait for package manifest is ready
     package_manifest.wait_for_resource()
     channel = config.DEPLOYMENT.get('ocs_csv_channel')
     csv_name = package_manifest.get_current_csv(channel=channel)
     csv = CSV(resource_name=csv_name, kind="csv", namespace=self.namespace)
     csv.wait_for_phase("Succeeded")
     ocs_operator_storage_cluster_cr = config.DEPLOYMENT.get(
         'ocs_operator_storage_cluster_cr')
     cluster_data = templating.load_yaml(ocs_operator_storage_cluster_cr)
     cluster_data['metadata']['name'] = config.ENV_DATA[
         'storage_cluster_name']
     deviceset_data = templating.load_yaml(constants.DEVICESET_YAML)
     device_size = int(
         config.ENV_DATA.get('device_size', defaults.DEVICE_SIZE))
     deviceset_data['dataPVCTemplate']['spec']['resources']['requests'][
         'storage'] = f"{device_size}Gi"
     cluster_data['spec']['storageDeviceSets'] = [deviceset_data]
     cluster_data_yaml = tempfile.NamedTemporaryFile(
         mode='w+', prefix='cluster_storage', delete=False)
     templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
     run_cmd(f"oc create -f {cluster_data_yaml.name}")
Пример #2
0
    def subscribe_ocs(self):
        """
        This method subscription manifest and subscribe to OCS operator.

        """
        subscription_yaml_data = templating.load_yaml(
            constants.SUBSCRIPTION_YAML)
        subscription_plan_approval = config.DEPLOYMENT.get(
            'subscription_plan_approval')
        if subscription_plan_approval:
            subscription_yaml_data['spec']['installPlanApproval'] = (
                subscription_plan_approval)
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        if channel:
            subscription_yaml_data['spec']['channel'] = channel
        subscription_manifest = tempfile.NamedTemporaryFile(
            mode='w+', prefix='subscription_manifest', delete=False)
        templating.dump_data_to_temp_yaml(subscription_yaml_data,
                                          subscription_manifest.name)
        run_cmd(f"oc create -f {subscription_manifest.name}")
        # wait for package manifest
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME)
        # Wait for package manifest is ready
        package_manifest.wait_for_resource(timeout=300)
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        subscription_plan_approval = config.DEPLOYMENT.get(
            'subscription_plan_approval')
        if subscription_plan_approval == 'Manual':
            wait_for_install_plan_and_approve(self.namespace)
Пример #3
0
def test_upgrade():
    ceph_cluster = CephCluster()
    ceph_cluster.enable_health_monitor()
    namespace = config.ENV_DATA['cluster_namespace']
    ocs_catalog = CatalogSource(
        resource_name=constants.OPERATOR_CATALOG_SOURCE_NAME,
        namespace="openshift-marketplace",
    )
    image_url = ocs_catalog.get_image_url()
    image_tag = ocs_catalog.get_image_name()
    if config.DEPLOYMENT.get('upgrade_to_latest', True):
        new_image_tag = get_latest_ds_olm_tag()
    else:
        new_image_tag = get_next_version_available_for_upgrade(image_tag)
    cs_data = deepcopy(ocs_catalog.data)
    cs_data['spec']['image'] = ':'.join([image_url, new_image_tag])
    package_manifest = PackageManifest(resource_name=OCS_OPERATOR_NAME)
    csv_name_pre_upgrade = package_manifest.get_current_csv()
    log.info(f"CSV name before upgrade is: {csv_name_pre_upgrade}")
    csv_pre_upgrade = CSV(resource_name=csv_name_pre_upgrade,
                          namespace=namespace)
    pre_upgrade_images = get_images(csv_pre_upgrade.get())

    with NamedTemporaryFile() as cs_yaml:
        dump_data_to_temp_yaml(cs_data, cs_yaml.name)
        ocs_catalog.apply(cs_yaml.name)
    # Wait for package manifest is ready
    package_manifest.wait_for_resource()
    subscription_plan_approval = config.DEPLOYMENT.get(
        'subscription_plan_approval')
    if subscription_plan_approval == 'Manual':
        wait_for_install_plan_and_approve(namespace)
    attempts = 145
    for attempt in range(1, attempts):
        if attempts == attempt:
            raise TimeoutException("No new CSV found after upgrade!")
        log.info(f"Attempt {attempt}/{attempts} to check CSV upgraded.")
        package_manifest.reload_data()
        csv_name_post_upgrade = package_manifest.get_current_csv()
        if csv_name_post_upgrade == csv_name_pre_upgrade:
            log.info(f"CSV is still: {csv_name_post_upgrade}")
            sleep(5)
        else:
            log.info(f"CSV now upgraded to: {csv_name_post_upgrade}")
            break
    csv_post_upgrade = CSV(resource_name=csv_name_post_upgrade,
                           namespace=namespace)
    log.info(
        f"Waiting for CSV {csv_name_post_upgrade} to be in succeeded state")
    csv_post_upgrade.wait_for_phase("Succeeded", timeout=600)
    post_upgrade_images = get_images(csv_post_upgrade.get())
    old_images, _, _ = get_upgrade_image_info(pre_upgrade_images,
                                              post_upgrade_images)
    verify_image_versions(old_images)
    ocs_install_verification(timeout=600, skip_osd_distribution_check=True)
    ceph_cluster.disable_health_monitor()
    if ceph_cluster.health_error_status:
        CephHealthException(f"During upgrade hit Ceph HEALTH_ERROR: "
                            f"{ceph_cluster.health_error_status}")
Пример #4
0
    def subscribe_ocs(self):
        """
        This method subscription manifest and subscribe to OCS operator.

        """
        live_deployment = config.DEPLOYMENT.get("live_deployment")
        if (
            config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM
            and not live_deployment
        ):
            link_all_sa_and_secret_and_delete_pods(constants.OCS_SECRET, self.namespace)
        operator_selector = get_selector_for_ocs_operator()
        # wait for package manifest
        # For OCS version >= 4.9, we have odf-operator
        ocs_version = version.get_semantic_ocs_version_from_config()
        if ocs_version >= version.VERSION_4_9:
            ocs_operator_name = defaults.ODF_OPERATOR_NAME
            subscription_file = constants.SUBSCRIPTION_ODF_YAML
        else:
            ocs_operator_name = defaults.OCS_OPERATOR_NAME
            subscription_file = constants.SUBSCRIPTION_YAML

        package_manifest = PackageManifest(
            resource_name=ocs_operator_name,
            selector=operator_selector,
        )
        # Wait for package manifest is ready
        package_manifest.wait_for_resource(timeout=300)
        default_channel = package_manifest.get_default_channel()
        subscription_yaml_data = templating.load_yaml(subscription_file)
        subscription_plan_approval = config.DEPLOYMENT.get("subscription_plan_approval")
        if subscription_plan_approval:
            subscription_yaml_data["spec"][
                "installPlanApproval"
            ] = subscription_plan_approval
        custom_channel = config.DEPLOYMENT.get("ocs_csv_channel")
        if custom_channel:
            logger.info(f"Custom channel will be used: {custom_channel}")
            subscription_yaml_data["spec"]["channel"] = custom_channel
        else:
            logger.info(f"Default channel will be used: {default_channel}")
            subscription_yaml_data["spec"]["channel"] = default_channel
        if config.DEPLOYMENT.get("stage"):
            subscription_yaml_data["spec"]["source"] = constants.OPERATOR_SOURCE_NAME
        if config.DEPLOYMENT.get("live_deployment"):
            subscription_yaml_data["spec"]["source"] = config.DEPLOYMENT.get(
                "live_content_source", defaults.LIVE_CONTENT_SOURCE
            )
        subscription_manifest = tempfile.NamedTemporaryFile(
            mode="w+", prefix="subscription_manifest", delete=False
        )
        templating.dump_data_to_temp_yaml(
            subscription_yaml_data, subscription_manifest.name
        )
        run_cmd(f"oc create -f {subscription_manifest.name}")
        logger.info("Sleeping for 15 seconds after subscribing OCS")
        if subscription_plan_approval == "Manual":
            wait_for_install_plan_and_approve(self.namespace)
Пример #5
0
    def deploy_with_external_mode(self):
        """
        This function handles the deployment of OCS on
        external/indpendent RHCS cluster

        """
        live_deployment = config.DEPLOYMENT.get("live_deployment")
        logger.info("Deploying OCS with external mode RHCS")
        ui_deployment = config.DEPLOYMENT.get("ui_deployment")
        if not ui_deployment:
            logger.info("Creating namespace and operator group.")
            run_cmd(f"oc create -f {constants.OLM_YAML}")
        if not live_deployment:
            self.create_ocs_operator_source()
        self.subscribe_ocs()
        operator_selector = get_selector_for_ocs_operator()
        subscription_plan_approval = config.DEPLOYMENT.get(
            "subscription_plan_approval")
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME,
            selector=operator_selector,
            subscription_plan_approval=subscription_plan_approval,
        )
        package_manifest.wait_for_resource(timeout=300)
        channel = config.DEPLOYMENT.get("ocs_csv_channel")
        csv_name = package_manifest.get_current_csv(channel=channel)
        csv = CSV(resource_name=csv_name, namespace=self.namespace)
        csv.wait_for_phase("Succeeded", timeout=720)

        # Create secret for external cluster
        secret_data = templating.load_yaml(
            constants.EXTERNAL_CLUSTER_SECRET_YAML)
        external_cluster_details = config.EXTERNAL_MODE.get(
            "external_cluster_details", "")
        if not external_cluster_details:
            raise ExternalClusterDetailsException(
                "No external cluster data found")
        secret_data["data"][
            "external_cluster_details"] = external_cluster_details
        secret_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="external_cluster_secret", delete=False)
        templating.dump_data_to_temp_yaml(secret_data, secret_data_yaml.name)
        logger.info("Creating external cluster secret")
        run_cmd(f"oc create -f {secret_data_yaml.name}")

        cluster_data = templating.load_yaml(
            constants.EXTERNAL_STORAGE_CLUSTER_YAML)
        cluster_data["metadata"]["name"] = config.ENV_DATA[
            "storage_cluster_name"]
        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="external_cluster_storage", delete=False)
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}", timeout=2400)
        self.external_post_deploy_validation()
        setup_ceph_toolbox()
Пример #6
0
    def deploy_ocs_via_operator(self):
        """
        Method for deploy OCS via OCS operator
        """
        logger.info("Deployment of OCS via OCS operator")
        olm_manifest, subscription_manifest = (
            self.get_olm_and_subscription_manifest())
        self.label_and_taint_nodes()
        run_cmd(f"oc create -f {olm_manifest}")
        catalog_source = CatalogSource(
            resource_name='ocs-catalogsource',
            namespace='openshift-marketplace',
        )
        # Wait for catalog source is ready
        catalog_source.wait_for_state("READY")
        run_cmd(f"oc create -f {subscription_manifest}")
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME)
        # Wait for package manifest is ready
        package_manifest.wait_for_resource()
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        csv_name = package_manifest.get_current_csv(channel=channel)
        csv = CSV(resource_name=csv_name, kind="csv", namespace=self.namespace)
        csv.wait_for_phase("Succeeded", timeout=400)
        ocs_operator_storage_cluster_cr = config.DEPLOYMENT.get(
            'ocs_operator_storage_cluster_cr')
        cluster_data = templating.load_yaml(ocs_operator_storage_cluster_cr)
        cluster_data['metadata']['name'] = config.ENV_DATA[
            'storage_cluster_name']
        deviceset_data = templating.load_yaml(constants.DEVICESET_YAML)
        device_size = int(
            config.ENV_DATA.get('device_size', defaults.DEVICE_SIZE))
        deviceset_data['dataPVCTemplate']['spec']['resources']['requests'][
            'storage'] = f"{device_size}Gi"

        # Allow lower instance requests and limits for OCS deployment
        if config.DEPLOYMENT.get('allow_lower_instance_requirements'):
            none_resources = {'Requests': None, 'Limits': None}
            deviceset_data["resources"] = deepcopy(none_resources)
            cluster_data['spec']['resources'] = {
                resource: deepcopy(none_resources)
                for resource in ['mon', 'mds', 'rgw', 'mgr', 'noobaa']
            }

        if self.platform.lower() == constants.VSPHERE_PLATFORM:
            cluster_data['spec']['monPVCTemplate']['spec'][
                'storageClassName'] = constants.DEFAULT_SC_VSPHERE
            deviceset_data['dataPVCTemplate']['spec'][
                'storageClassName'] = constants.DEFAULT_SC_VSPHERE

        cluster_data['spec']['storageDeviceSets'] = [deviceset_data]
        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode='w+', prefix='cluster_storage', delete=False)
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}")
Пример #7
0
    def subscribe_ocs(self):
        """
        This method subscription manifest and subscribe to OCS operator.

        """
        operator_selector = get_selector_for_ocs_operator()
        # wait for package manifest
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME,
            selector=operator_selector,
        )
        # Wait for package manifest is ready
        package_manifest.wait_for_resource(timeout=300)
        default_channel = package_manifest.get_default_channel()
        subscription_yaml_data = templating.load_yaml(
            constants.SUBSCRIPTION_YAML
        )
        subscription_plan_approval = config.DEPLOYMENT.get(
            'subscription_plan_approval'
        )
        if subscription_plan_approval:
            subscription_yaml_data['spec']['installPlanApproval'] = (
                subscription_plan_approval
            )
        custom_channel = config.DEPLOYMENT.get('ocs_csv_channel')
        if custom_channel:
            logger.info(f"Custom channel will be used: {custom_channel}")
            subscription_yaml_data['spec']['channel'] = custom_channel
        else:
            logger.info(f"Default channel will be used: {default_channel}")
            subscription_yaml_data['spec']['channel'] = default_channel
        if config.DEPLOYMENT.get('stage'):
            subscription_yaml_data['spec']['source'] = (
                constants.OPERATOR_SOURCE_NAME
            )
        if config.DEPLOYMENT.get('live_deployment'):
            subscription_yaml_data['spec']['source'] = (
                config.DEPLOYMENT.get(
                    'live_content_source', defaults.LIVE_CONTENT_SOURCE
                )
            )
        subscription_manifest = tempfile.NamedTemporaryFile(
            mode='w+', prefix='subscription_manifest', delete=False
        )
        templating.dump_data_to_temp_yaml(
            subscription_yaml_data, subscription_manifest.name
        )
        run_cmd(f"oc create -f {subscription_manifest.name}")
        subscription_plan_approval = config.DEPLOYMENT.get(
            'subscription_plan_approval'
        )
        if subscription_plan_approval == 'Manual':
            wait_for_install_plan_and_approve(self.namespace)
Пример #8
0
    def deploy_with_external_mode(self):
        """
        This function handles the deployment of OCS on
        external/indpendent RHCS cluster

        """
        live_deployment = config.DEPLOYMENT.get("live_deployment")
        logger.info("Deploying OCS with external mode RHCS")
        ui_deployment = config.DEPLOYMENT.get("ui_deployment")
        if not ui_deployment:
            logger.info("Creating namespace and operator group.")
            run_cmd(f"oc create -f {constants.OLM_YAML}")
        if not live_deployment:
            create_catalog_source()
        self.subscribe_ocs()
        operator_selector = get_selector_for_ocs_operator()
        subscription_plan_approval = config.DEPLOYMENT.get("subscription_plan_approval")
        ocs_version = version.get_semantic_ocs_version_from_config()
        if ocs_version >= version.VERSION_4_9:
            ocs_operator_names = [
                defaults.ODF_OPERATOR_NAME,
                defaults.OCS_OPERATOR_NAME,
            ]
        else:
            ocs_operator_names = [defaults.OCS_OPERATOR_NAME]
        channel = config.DEPLOYMENT.get("ocs_csv_channel")
        for ocs_operator_name in ocs_operator_names:
            package_manifest = PackageManifest(
                resource_name=ocs_operator_name,
                selector=operator_selector,
                subscription_plan_approval=subscription_plan_approval,
            )
            package_manifest.wait_for_resource(timeout=300)
            csv_name = package_manifest.get_current_csv(channel=channel)
            csv = CSV(resource_name=csv_name, namespace=self.namespace)
            csv.wait_for_phase("Succeeded", timeout=720)

        # Set rook log level
        self.set_rook_log_level()

        # Create secret for external cluster
        create_external_secret()

        cluster_data = templating.load_yaml(constants.EXTERNAL_STORAGE_CLUSTER_YAML)
        cluster_data["metadata"]["name"] = config.ENV_DATA["storage_cluster_name"]
        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="external_cluster_storage", delete=False
        )
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}", timeout=2400)
        self.external_post_deploy_validation()
        setup_ceph_toolbox()
Пример #9
0
def test_upgrade():
    namespace = config.ENV_DATA['cluster_namespace']
    ocs_catalog = CatalogSource(
        resource_name=OPERATOR_CATALOG_SOURCE_NAME,
        namespace="openshift-marketplace",
    )
    image_url = ocs_catalog.get_image_url()
    image_tag = ocs_catalog.get_image_name()
    if config.DEPLOYMENT.get('upgrade_to_latest', True):
        new_image_tag = get_latest_ds_olm_tag()
    else:
        new_image_tag = get_next_version_available_for_upgrade(image_tag)
    cs_data = deepcopy(ocs_catalog.data)
    cs_data['spec']['image'] = ':'.join([image_url, new_image_tag])
    package_manifest = PackageManifest(resource_name=OCS_OPERATOR_NAME)
    csv_name_pre_upgrade = package_manifest.get_current_csv()
    log.info(f"CSV name before upgrade is: {csv_name_pre_upgrade}")
    with NamedTemporaryFile() as cs_yaml:
        dump_data_to_temp_yaml(cs_data, cs_yaml.name)
        ocs_catalog.apply(cs_yaml.name)
    # Wait for package manifest is ready
    package_manifest.wait_for_resource()
    attempts = 145
    for attempt in range(1, attempts):
        if attempts == attempt:
            raise TimeoutException("No new CSV found after upgrade!")
        log.info(f"Attempt {attempt}/{attempts} to check CSV upgraded.")
        package_manifest.reload_data()
        csv_name_post_upgrade = package_manifest.get_current_csv()
        if csv_name_post_upgrade == csv_name_pre_upgrade:
            log.info(f"CSV is still: {csv_name_post_upgrade}")
            sleep(5)
        else:
            log.info(f"CSV now upgraded to: {csv_name_post_upgrade}")
            break

    csv = CSV(
        resource_name=csv_name_post_upgrade,
        namespace=namespace
    )
    log.info(
        f"Waiting for CSV {csv_name_post_upgrade} to be in succeeded state"
    )
    csv.wait_for_phase("Succeeded", timeout=400)
    ocs_install_verification(timeout=600)
Пример #10
0
    def set_upgrade_channel(self):
        """
        Wait for the new package manifest for upgrade.

        Returns:
            str: OCS subscription channel

        """
        operator_selector = get_selector_for_ocs_operator()
        package_manifest = PackageManifest(
            resource_name=OCS_OPERATOR_NAME, selector=operator_selector,
        )
        package_manifest.wait_for_resource()
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        if not channel:
            channel = package_manifest.get_default_channel()

        return channel
Пример #11
0
    def deploy_ocs_via_operator(self):
        """
        Method for deploy OCS via OCS operator
        """
        ui_deployment = config.DEPLOYMENT.get('ui_deployment')
        live_deployment = config.DEPLOYMENT.get('live_deployment')

        if config.DEPLOYMENT.get('local_storage'):
            setup_local_storage()

        if ui_deployment:
            if not live_deployment:
                self.create_ocs_operator_source()
            self.deployment_with_ui()
            # Skip the rest of the deployment when deploy via UI
            return
        else:
            logger.info("Deployment of OCS via OCS operator")
            self.label_and_taint_nodes()
        logger.info("Creating namespace and operator group.")
        run_cmd(f"oc create -f {constants.OLM_YAML}")
        if not live_deployment:
            self.create_ocs_operator_source()
        self.subscribe_ocs()
        operator_selector = get_selector_for_ocs_operator()
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME,
            selector=operator_selector,
        )
        package_manifest.wait_for_resource(timeout=300)
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        csv_name = package_manifest.get_current_csv(channel=channel)
        csv = CSV(resource_name=csv_name, namespace=self.namespace)
        csv.wait_for_phase("Succeeded", timeout=720)

        # Modify the CSV with custom values if required
        if all(key in config.DEPLOYMENT
               for key in ('csv_change_from', 'csv_change_to')):
            modify_csv(csv=csv_name,
                       replace_from=config.DEPLOYMENT['csv_change_from'],
                       replace_to=config.DEPLOYMENT['csv_change_to'])
        cluster_data = templating.load_yaml(constants.STORAGE_CLUSTER_YAML)
        cluster_data['metadata']['name'] = config.ENV_DATA[
            'storage_cluster_name']
        deviceset_data = cluster_data['spec']['storageDeviceSets'][0]
        device_size = int(
            config.ENV_DATA.get('device_size', defaults.DEVICE_SIZE))
        if self.platform.lower() == constants.BAREMETAL_PLATFORM:
            pv_size_list = helpers.get_pv_size(
                storageclass=constants.DEFAULT_STORAGECLASS_LSO)
            pv_size_list.sort()
            deviceset_data['dataPVCTemplate']['spec']['resources']['requests'][
                'storage'] = f"{pv_size_list[0]}"
        else:
            deviceset_data['dataPVCTemplate']['spec']['resources']['requests'][
                'storage'] = f"{device_size}Gi"

        if self.platform.lower() == constants.VSPHERE_PLATFORM:
            deviceset_data['dataPVCTemplate']['spec'][
                'storageClassName'] = constants.DEFAULT_SC_VSPHERE

        if config.DEPLOYMENT.get('local_storage'):
            cluster_data['spec']['manageNodes'] = False
            cluster_data['spec']['monDataDirHostPath'] = '/var/lib/rook'
            deviceset_data['portable'] = False
            deviceset_data['dataPVCTemplate']['spec'][
                'storageClassName'] = 'localblock'
            if self.platform.lower() == constants.AWS_PLATFORM:
                deviceset_data['count'] = 2

        ocs_version = float(config.ENV_DATA['ocs_version'])
        # Allow lower instance requests and limits for OCS deployment
        # The resources we need to change can be found here:
        # https://github.com/openshift/ocs-operator/blob/release-4.5/pkg/deploy-manager/storagecluster.go#L88-L116
        if config.DEPLOYMENT.get('allow_lower_instance_requirements'):
            none_resources = {'Requests': None, 'Limits': None}
            deviceset_data["resources"] = deepcopy(none_resources)
            resources = [
                'mon',
                'mds',
                'rgw',
                'mgr',
                'noobaa-core',
                'noobaa-db',
            ]
            if ocs_version >= 4.5:
                resources.append('noobaa-endpoint')
            cluster_data['spec']['resources'] = {
                resource: deepcopy(none_resources)
                for resource in resources
            }
        else:
            local_storage = config.DEPLOYMENT.get('local_storage')
            platform = config.ENV_DATA.get('platform', '').lower()
            if local_storage and platform == 'aws':
                resources = {
                    'mds': {
                        'limits': {
                            'cpu': 3
                        },
                        'requests': {
                            'cpu': 1
                        }
                    },
                    'noobaa-core': {
                        'limits': {
                            'cpu': 2,
                            'memory': '8Gi'
                        },
                        'requests': {
                            'cpu': 1,
                            'memory': '8Gi'
                        }
                    },
                    'noobaa-db': {
                        'limits': {
                            'cpu': 2,
                            'memory': '8Gi'
                        },
                        'requests': {
                            'cpu': 1,
                            'memory': '8Gi'
                        }
                    }
                }
                if ocs_version >= 4.5:
                    resources['noobaa-endpoint'] = {
                        'limits': {
                            'cpu': 2,
                            'memory': '8Gi'
                        },
                        'requests': {
                            'cpu': 1,
                            'memory': '8Gi'
                        }
                    }
                cluster_data['spec']['resources'] = resources

        # Enable host network if enabled in config (this require all the
        # rules to be enabled on underlaying platform).
        if config.DEPLOYMENT.get('host_network'):
            cluster_data['spec']['hostNetwork'] = True

        cluster_data['spec']['storageDeviceSets'] = [deviceset_data]
        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode='w+', prefix='cluster_storage', delete=False)
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}", timeout=2400)
Пример #12
0
    def deploy_ocs_via_operator(self):
        """
        Method for deploy OCS via OCS operator
        """
        ui_deployment = config.DEPLOYMENT.get('ui_deployment')
        live_deployment = config.DEPLOYMENT.get('live_deployment')

        if config.DEPLOYMENT.get('local_storage'):
            setup_local_storage()

        if ui_deployment:
            if not live_deployment:
                self.create_ocs_operator_source()
            self.deployment_with_ui()
            # Skip the rest of the deployment when deploy via UI
            return
        else:
            logger.info("Deployment of OCS via OCS operator")
            self.label_and_taint_nodes()
        logger.info("Creating namespace and operator group.")
        run_cmd(f"oc create -f {constants.OLM_YAML}")
        if not live_deployment:
            self.create_ocs_operator_source()
        self.subscribe_ocs()
        operator_selector = get_selector_for_ocs_operator()
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME,
            selector=operator_selector,
        )
        package_manifest.wait_for_resource(timeout=300)
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        csv_name = package_manifest.get_current_csv(channel=channel)
        csv = CSV(resource_name=csv_name, namespace=self.namespace)
        csv.wait_for_phase("Succeeded", timeout=720)
        cluster_data = templating.load_yaml(constants.STORAGE_CLUSTER_YAML)
        cluster_data['metadata']['name'] = config.ENV_DATA[
            'storage_cluster_name']
        deviceset_data = cluster_data['spec']['storageDeviceSets'][0]
        device_size = int(
            config.ENV_DATA.get('device_size', defaults.DEVICE_SIZE))
        deviceset_data['dataPVCTemplate']['spec']['resources']['requests'][
            'storage'] = f"{device_size}Gi"

        if self.platform.lower() == constants.VSPHERE_PLATFORM:
            deviceset_data['dataPVCTemplate']['spec'][
                'storageClassName'] = constants.DEFAULT_SC_VSPHERE

        if config.DEPLOYMENT.get('local_storage'):
            cluster_data['spec']['manageNodes'] = False
            cluster_data['spec']['monDataDirHostPath'] = '/var/lib/rook'
            deviceset_data['portable'] = False
            deviceset_data['dataPVCTemplate']['spec'][
                'storageClassName'] = 'localblock'
            if self.platform.lower() == constants.AWS_PLATFORM:
                deviceset_data['count'] = 2

        # Allow lower instance requests and limits for OCS deployment
        if config.DEPLOYMENT.get('allow_lower_instance_requirements'):
            none_resources = {'Requests': None, 'Limits': None}
            deviceset_data["resources"] = deepcopy(none_resources)
            cluster_data['spec']['resources'] = {
                resource: deepcopy(none_resources)
                for resource in [
                    'mon',
                    'mds',
                    'rgw',
                    'mgr',
                    'noobaa-core',
                    'noobaa-db',
                ]
            }

        # Enable host network if enabled in config (this require all the
        # rules to be enabled on underlaying platform).
        if config.DEPLOYMENT.get('host_network'):
            cluster_data['spec']['hostNetwork'] = True

        cluster_data['spec']['storageDeviceSets'] = [deviceset_data]
        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode='w+', prefix='cluster_storage', delete=False)
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}", timeout=2400)
Пример #13
0
    def deploy_ocs_via_operator(self):
        """
        Method for deploy OCS via OCS operator
        """
        ui_deployment = config.DEPLOYMENT.get("ui_deployment")
        live_deployment = config.DEPLOYMENT.get("live_deployment")

        if ui_deployment:
            if not live_deployment:
                self.create_ocs_operator_source()
            self.deployment_with_ui()
            # Skip the rest of the deployment when deploy via UI
            return
        else:
            logger.info("Deployment of OCS via OCS operator")
            self.label_and_taint_nodes()

        if config.DEPLOYMENT.get("local_storage"):
            setup_local_storage(storageclass=self.DEFAULT_STORAGECLASS_LSO)

        logger.info("Creating namespace and operator group.")
        run_cmd(f"oc create -f {constants.OLM_YAML}")
        if config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM:
            ibmcloud.add_deployment_dependencies()
            if not live_deployment:
                create_ocs_secret(self.namespace)
                create_ocs_secret(constants.MARKETPLACE_NAMESPACE)
        if not live_deployment:
            self.create_ocs_operator_source()
        self.subscribe_ocs()
        operator_selector = get_selector_for_ocs_operator()
        subscription_plan_approval = config.DEPLOYMENT.get(
            "subscription_plan_approval")
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME,
            selector=operator_selector,
            subscription_plan_approval=subscription_plan_approval,
        )
        package_manifest.wait_for_resource(timeout=300)
        channel = config.DEPLOYMENT.get("ocs_csv_channel")
        csv_name = package_manifest.get_current_csv(channel=channel)
        csv = CSV(resource_name=csv_name, namespace=self.namespace)
        if (config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM
                and not live_deployment):
            csv.wait_for_phase("Installing", timeout=720)
            logger.info("Sleeping for 30 seconds before applying SA")
            time.sleep(30)
            link_all_sa_and_secret(constants.OCS_SECRET, self.namespace)
            logger.info("Deleting all pods in openshift-storage namespace")
            exec_cmd(f"oc delete pod --all -n {self.namespace}")
        csv.wait_for_phase("Succeeded", timeout=720)

        # Modify the CSV with custom values if required
        if all(key in config.DEPLOYMENT
               for key in ("csv_change_from", "csv_change_to")):
            modify_csv(
                csv=csv_name,
                replace_from=config.DEPLOYMENT["csv_change_from"],
                replace_to=config.DEPLOYMENT["csv_change_to"],
            )

        # create custom storage class for StorageCluster CR if necessary
        if self.CUSTOM_STORAGE_CLASS_PATH is not None:
            with open(self.CUSTOM_STORAGE_CLASS_PATH, "r") as custom_sc_fo:
                custom_sc = yaml.load(custom_sc_fo, Loader=yaml.SafeLoader)
            # set value of DEFAULT_STORAGECLASS to mach the custom storage cls
            self.DEFAULT_STORAGECLASS = custom_sc["metadata"]["name"]
            run_cmd(f"oc create -f {self.CUSTOM_STORAGE_CLASS_PATH}")

        # creating StorageCluster
        if self.platform == constants.IBM_POWER_PLATFORM:
            cluster_data = templating.load_yaml(
                constants.IBM_STORAGE_CLUSTER_YAML)
        else:
            cluster_data = templating.load_yaml(constants.STORAGE_CLUSTER_YAML)

        cluster_data["metadata"]["name"] = config.ENV_DATA[
            "storage_cluster_name"]

        if self.platform == constants.IBM_POWER_PLATFORM:
            numberofstoragenodes = config.ENV_DATA["number_of_storage_nodes"]
            deviceset = [None] * numberofstoragenodes

            for i in range(numberofstoragenodes):
                deviceset_data = cluster_data["spec"]["storageDeviceSets"][i]
                device_size = int(
                    config.ENV_DATA.get("device_size", defaults.DEVICE_SIZE))

                # set size of request for storage
                if self.platform.lower() == "powervs":
                    pv_size_list = helpers.get_pv_size(
                        storageclass=self.DEFAULT_STORAGECLASS_LSO)
                    pv_size_list.sort()
                    deviceset_data["dataPVCTemplate"]["spec"]["resources"][
                        "requests"]["storage"] = f"{pv_size_list[0]}"
                else:
                    deviceset_data["dataPVCTemplate"]["spec"]["resources"][
                        "requests"]["storage"] = f"{device_size}Gi"

                # set storage class to OCS default on current platform
                if self.DEFAULT_STORAGECLASS_LSO:
                    deviceset_data["dataPVCTemplate"]["spec"][
                        "storageClassName"] = self.DEFAULT_STORAGECLASS_LSO

                # StorageCluster tweaks for LSO
                if config.DEPLOYMENT.get("local_storage"):
                    cluster_data["spec"]["manageNodes"] = False
                    cluster_data["spec"][
                        "monDataDirHostPath"] = "/var/lib/rook"
                    deviceset_data["portable"] = False
                    deviceset_data["dataPVCTemplate"]["spec"][
                        "storageClassName"] = self.DEFAULT_STORAGECLASS_LSO

                deviceset[i] = deviceset_data
        else:
            deviceset_data = cluster_data["spec"]["storageDeviceSets"][0]
            device_size = int(
                config.ENV_DATA.get("device_size", defaults.DEVICE_SIZE))

            # set size of request for storage
            if self.platform.lower() == constants.BAREMETAL_PLATFORM:
                pv_size_list = helpers.get_pv_size(
                    storageclass=self.DEFAULT_STORAGECLASS_LSO)
                pv_size_list.sort()
                deviceset_data["dataPVCTemplate"]["spec"]["resources"][
                    "requests"]["storage"] = f"{pv_size_list[0]}"
            else:
                deviceset_data["dataPVCTemplate"]["spec"]["resources"][
                    "requests"]["storage"] = f"{device_size}Gi"

            # set storage class to OCS default on current platform
            if self.DEFAULT_STORAGECLASS:
                deviceset_data["dataPVCTemplate"]["spec"][
                    "storageClassName"] = self.DEFAULT_STORAGECLASS

            ocs_version = float(config.ENV_DATA["ocs_version"])
            ocp_version = float(get_ocp_version())

            # StorageCluster tweaks for LSO
            if config.DEPLOYMENT.get("local_storage"):
                cluster_data["spec"]["manageNodes"] = False
                cluster_data["spec"]["monDataDirHostPath"] = "/var/lib/rook"
                deviceset_data["portable"] = False
                deviceset_data["dataPVCTemplate"]["spec"][
                    "storageClassName"] = self.DEFAULT_STORAGECLASS_LSO
                if self.platform.lower() == constants.AWS_PLATFORM:
                    deviceset_data["count"] = 2
                if ocs_version >= 4.5:
                    deviceset_data["resources"] = {
                        "limits": {
                            "cpu": 2,
                            "memory": "5Gi"
                        },
                        "requests": {
                            "cpu": 1,
                            "memory": "5Gi"
                        },
                    }
                if (ocp_version >= 4.6) and (ocs_version >= 4.6):
                    cluster_data["metadata"]["annotations"] = {
                        "cluster.ocs.openshift.io/local-devices": "true"
                    }

            # Allow lower instance requests and limits for OCS deployment
            # The resources we need to change can be found here:
            # https://github.com/openshift/ocs-operator/blob/release-4.5/pkg/deploy-manager/storagecluster.go#L88-L116
            if config.DEPLOYMENT.get("allow_lower_instance_requirements"):
                none_resources = {"Requests": None, "Limits": None}
                deviceset_data["resources"] = deepcopy(none_resources)
                resources = [
                    "mon",
                    "mds",
                    "rgw",
                    "mgr",
                    "noobaa-core",
                    "noobaa-db",
                ]
                if ocs_version >= 4.5:
                    resources.append("noobaa-endpoint")
                cluster_data["spec"]["resources"] = {
                    resource: deepcopy(none_resources)
                    for resource in resources
                }
                if ocs_version >= 4.5:
                    cluster_data["spec"]["resources"]["noobaa-endpoint"] = {
                        "limits": {
                            "cpu": 1,
                            "memory": "500Mi"
                        },
                        "requests": {
                            "cpu": 1,
                            "memory": "500Mi"
                        },
                    }
            else:
                local_storage = config.DEPLOYMENT.get("local_storage")
                platform = config.ENV_DATA.get("platform", "").lower()
                if local_storage and platform == "aws":
                    resources = {
                        "mds": {
                            "limits": {
                                "cpu": 3,
                                "memory": "8Gi"
                            },
                            "requests": {
                                "cpu": 1,
                                "memory": "8Gi"
                            },
                        }
                    }
                    if ocs_version < 4.5:
                        resources["noobaa-core"] = {
                            "limits": {
                                "cpu": 2,
                                "memory": "8Gi"
                            },
                            "requests": {
                                "cpu": 1,
                                "memory": "8Gi"
                            },
                        }
                        resources["noobaa-db"] = {
                            "limits": {
                                "cpu": 2,
                                "memory": "8Gi"
                            },
                            "requests": {
                                "cpu": 1,
                                "memory": "8Gi"
                            },
                        }
                    cluster_data["spec"]["resources"] = resources
        # Enable host network if enabled in config (this require all the
        # rules to be enabled on underlaying platform).
        if config.DEPLOYMENT.get("host_network"):
            cluster_data["spec"]["hostNetwork"] = True

        if self.platform == constants.IBM_POWER_PLATFORM:
            cluster_data["spec"]["storageDeviceSets"] = deviceset
        else:
            cluster_data["spec"]["storageDeviceSets"] = [deviceset_data]

        if self.platform == constants.IBMCLOUD_PLATFORM:
            mon_pvc_template = {
                "spec": {
                    "accessModes": ["ReadWriteOnce"],
                    "resources": {
                        "requests": {
                            "storage": "20Gi"
                        }
                    },
                    "storageClassName": self.DEFAULT_STORAGECLASS,
                    "volumeMode": "Filesystem",
                }
            }
            cluster_data["spec"]["monPVCTemplate"] = mon_pvc_template
            # Need to check if it's needed for ibm cloud to set manageNodes
            cluster_data["spec"]["manageNodes"] = False

        if config.ENV_DATA.get("encryption_at_rest"):
            if ocs_version < 4.6:
                error_message = "Encryption at REST can be enabled only on OCS >= 4.6!"
                logger.error(error_message)
                raise UnsupportedFeatureError(error_message)
            logger.info("Enabling encryption at REST!")
            cluster_data["spec"]["encryption"] = {
                "enable": True,
            }

        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="cluster_storage", delete=False)
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}", timeout=1200)
        if config.DEPLOYMENT["infra_nodes"]:
            _ocp = ocp.OCP(kind="node")
            _ocp.exec_oc_cmd(
                command=f"annotate namespace {defaults.ROOK_CLUSTER_NAMESPACE} "
                f"{constants.NODE_SELECTOR_ANNOTATION}")
Пример #14
0
    def deploy_ocs_via_operator(self, image=None):
        """
        Method for deploy OCS via OCS operator

        Args:
            image (str): Image of ocs registry.

        """
        ui_deployment = config.DEPLOYMENT.get("ui_deployment")
        live_deployment = config.DEPLOYMENT.get("live_deployment")
        arbiter_deployment = config.DEPLOYMENT.get("arbiter_deployment")

        if ui_deployment:
            self.deployment_with_ui()
            # Skip the rest of the deployment when deploy via UI
            return
        else:
            logger.info("Deployment of OCS via OCS operator")
            self.label_and_taint_nodes()

        if config.DEPLOYMENT.get("local_storage"):
            setup_local_storage(storageclass=self.DEFAULT_STORAGECLASS_LSO)

        logger.info("Creating namespace and operator group.")
        run_cmd(f"oc create -f {constants.OLM_YAML}")
        if config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM:
            ibmcloud.add_deployment_dependencies()
            if not live_deployment:
                create_ocs_secret(self.namespace)
        if not live_deployment:
            create_catalog_source(image)
        self.subscribe_ocs()
        operator_selector = get_selector_for_ocs_operator()
        subscription_plan_approval = config.DEPLOYMENT.get(
            "subscription_plan_approval")
        package_manifest = PackageManifest(
            resource_name=defaults.OCS_OPERATOR_NAME,
            selector=operator_selector,
            subscription_plan_approval=subscription_plan_approval,
        )
        package_manifest.wait_for_resource(timeout=300)
        channel = config.DEPLOYMENT.get("ocs_csv_channel")
        csv_name = package_manifest.get_current_csv(channel=channel)
        csv = CSV(resource_name=csv_name, namespace=self.namespace)
        if (config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM
                and not live_deployment):
            csv.wait_for_phase("Installing", timeout=720)
            logger.info("Sleeping for 30 seconds before applying SA")
            time.sleep(30)
            link_all_sa_and_secret(constants.OCS_SECRET, self.namespace)
            logger.info("Deleting all pods in openshift-storage namespace")
            exec_cmd(f"oc delete pod --all -n {self.namespace}")
        csv.wait_for_phase("Succeeded", timeout=720)
        ocp_version = float(get_ocp_version())
        if config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM:
            config_map = ocp.OCP(
                kind="configmap",
                namespace=self.namespace,
                resource_name=constants.ROOK_OPERATOR_CONFIGMAP,
            )
            config_map.get(retry=10, wait=5)
            config_map_patch = (
                '\'{"data": {"ROOK_CSI_KUBELET_DIR_PATH": "/var/data/kubelet"}}\''
            )
            logger.info("Patching config map to change KUBLET DIR PATH")
            exec_cmd(
                f"oc patch configmap -n {self.namespace} "
                f"{constants.ROOK_OPERATOR_CONFIGMAP} -p {config_map_patch}")
            if config.DEPLOYMENT.get("create_ibm_cos_secret", True):
                logger.info("Creating secret for IBM Cloud Object Storage")
                with open(constants.IBM_COS_SECRET_YAML, "r") as cos_secret_fd:
                    cos_secret_data = yaml.load(cos_secret_fd,
                                                Loader=yaml.SafeLoader)
                key_id = config.AUTH["ibmcloud"]["ibm_cos_access_key_id"]
                key_secret = config.AUTH["ibmcloud"][
                    "ibm_cos_secret_access_key"]
                cos_secret_data["data"]["IBM_COS_ACCESS_KEY_ID"] = key_id
                cos_secret_data["data"][
                    "IBM_COS_SECRET_ACCESS_KEY"] = key_secret
                cos_secret_data_yaml = tempfile.NamedTemporaryFile(
                    mode="w+", prefix="cos_secret", delete=False)
                templating.dump_data_to_temp_yaml(cos_secret_data,
                                                  cos_secret_data_yaml.name)
                exec_cmd(f"oc create -f {cos_secret_data_yaml.name}")

        # Modify the CSV with custom values if required
        if all(key in config.DEPLOYMENT
               for key in ("csv_change_from", "csv_change_to")):
            modify_csv(
                csv=csv_name,
                replace_from=config.DEPLOYMENT["csv_change_from"],
                replace_to=config.DEPLOYMENT["csv_change_to"],
            )

        # create custom storage class for StorageCluster CR if necessary
        if self.CUSTOM_STORAGE_CLASS_PATH is not None:
            with open(self.CUSTOM_STORAGE_CLASS_PATH, "r") as custom_sc_fo:
                custom_sc = yaml.load(custom_sc_fo, Loader=yaml.SafeLoader)
            # set value of DEFAULT_STORAGECLASS to mach the custom storage cls
            self.DEFAULT_STORAGECLASS = custom_sc["metadata"]["name"]
            run_cmd(f"oc create -f {self.CUSTOM_STORAGE_CLASS_PATH}")

        # creating StorageCluster
        if config.DEPLOYMENT.get("kms_deployment"):
            kms = KMS.get_kms_deployment()
            kms.deploy()
        cluster_data = templating.load_yaml(constants.STORAGE_CLUSTER_YAML)

        # Figure out all the OCS modules enabled/disabled
        # CLI parameter --disable-components takes the precedence over
        # anything which comes from config file
        if config.ENV_DATA.get("disable_components"):
            for component in config.ENV_DATA["disable_components"]:
                config.COMPONENTS[f"disable_{component}"] = True
                logger.warning(f"disabling: {component}")

        # Update cluster_data with respective component enable/disable
        for key in config.COMPONENTS.keys():
            comp_name = constants.OCS_COMPONENTS_MAP[key.split("_")[1]]
            if config.COMPONENTS[key]:
                if "noobaa" in key:
                    merge_dict(
                        cluster_data,
                        {
                            "spec": {
                                "multiCloudGateway": {
                                    "reconcileStrategy": "ignore"
                                }
                            }
                        },
                    )
                else:
                    merge_dict(
                        cluster_data,
                        {
                            "spec": {
                                "managedResources": {
                                    f"{comp_name}": {
                                        "reconcileStrategy": "ignore"
                                    }
                                }
                            }
                        },
                    )

        if arbiter_deployment:
            cluster_data["spec"]["arbiter"] = {}
            cluster_data["spec"]["nodeTopologies"] = {}
            cluster_data["spec"]["arbiter"]["enable"] = True
            cluster_data["spec"]["nodeTopologies"][
                "arbiterLocation"] = self.get_arbiter_location()
            cluster_data["spec"]["storageDeviceSets"][0][
                "replica"] = config.DEPLOYMENT.get(
                    "ocs_operator_nodes_to_label", 4)

        cluster_data["metadata"]["name"] = config.ENV_DATA[
            "storage_cluster_name"]

        deviceset_data = cluster_data["spec"]["storageDeviceSets"][0]
        device_size = int(
            config.ENV_DATA.get("device_size", defaults.DEVICE_SIZE))

        logger.info(
            "Flexible scaling is available from version 4.7 on LSO cluster with less than 3 zones"
        )
        ocs_version = config.ENV_DATA["ocs_version"]
        zone_num = get_az_count()
        if (config.DEPLOYMENT.get("local_storage")
                and Version.coerce(ocs_version) >= Version.coerce("4.7")
                and zone_num < 3):
            cluster_data["spec"]["flexibleScaling"] = True
            # https://bugzilla.redhat.com/show_bug.cgi?id=1921023
            cluster_data["spec"]["storageDeviceSets"][0]["count"] = 3
            cluster_data["spec"]["storageDeviceSets"][0]["replica"] = 1

        # set size of request for storage
        if self.platform.lower() == constants.BAREMETAL_PLATFORM:
            pv_size_list = helpers.get_pv_size(
                storageclass=self.DEFAULT_STORAGECLASS_LSO)
            pv_size_list.sort()
            deviceset_data["dataPVCTemplate"]["spec"]["resources"]["requests"][
                "storage"] = f"{pv_size_list[0]}"
        else:
            deviceset_data["dataPVCTemplate"]["spec"]["resources"]["requests"][
                "storage"] = f"{device_size}Gi"

        # set storage class to OCS default on current platform
        if self.DEFAULT_STORAGECLASS:
            deviceset_data["dataPVCTemplate"]["spec"][
                "storageClassName"] = self.DEFAULT_STORAGECLASS

        ocs_version = float(config.ENV_DATA["ocs_version"])

        # StorageCluster tweaks for LSO
        if config.DEPLOYMENT.get("local_storage"):
            cluster_data["spec"]["manageNodes"] = False
            cluster_data["spec"]["monDataDirHostPath"] = "/var/lib/rook"
            deviceset_data["name"] = constants.DEFAULT_DEVICESET_LSO_PVC_NAME
            deviceset_data["portable"] = False
            deviceset_data["dataPVCTemplate"]["spec"][
                "storageClassName"] = self.DEFAULT_STORAGECLASS_LSO
            lso_type = config.DEPLOYMENT.get("type")
            if (self.platform.lower() == constants.AWS_PLATFORM
                    and not lso_type == constants.AWS_EBS):
                deviceset_data["count"] = 2
            if (ocp_version >= 4.6) and (ocs_version >= 4.6):
                cluster_data["metadata"]["annotations"] = {
                    "cluster.ocs.openshift.io/local-devices": "true"
                }

        # Allow lower instance requests and limits for OCS deployment
        # The resources we need to change can be found here:
        # https://github.com/openshift/ocs-operator/blob/release-4.5/pkg/deploy-manager/storagecluster.go#L88-L116
        if config.DEPLOYMENT.get("allow_lower_instance_requirements"):
            none_resources = {"Requests": None, "Limits": None}
            deviceset_data["resources"] = deepcopy(none_resources)
            resources = [
                "mon",
                "mds",
                "rgw",
                "mgr",
                "noobaa-core",
                "noobaa-db",
            ]
            if ocs_version >= 4.5:
                resources.append("noobaa-endpoint")
            cluster_data["spec"]["resources"] = {
                resource: deepcopy(none_resources)
                for resource in resources
            }
            if ocs_version >= 4.5:
                cluster_data["spec"]["resources"]["noobaa-endpoint"] = {
                    "limits": {
                        "cpu": 1,
                        "memory": "500Mi"
                    },
                    "requests": {
                        "cpu": 1,
                        "memory": "500Mi"
                    },
                }
        else:
            local_storage = config.DEPLOYMENT.get("local_storage")
            platform = config.ENV_DATA.get("platform", "").lower()
            if local_storage and platform == "aws":
                resources = {
                    "mds": {
                        "limits": {
                            "cpu": 3,
                            "memory": "8Gi"
                        },
                        "requests": {
                            "cpu": 1,
                            "memory": "8Gi"
                        },
                    }
                }
                if ocs_version < 4.5:
                    resources["noobaa-core"] = {
                        "limits": {
                            "cpu": 2,
                            "memory": "8Gi"
                        },
                        "requests": {
                            "cpu": 1,
                            "memory": "8Gi"
                        },
                    }
                    resources["noobaa-db"] = {
                        "limits": {
                            "cpu": 2,
                            "memory": "8Gi"
                        },
                        "requests": {
                            "cpu": 1,
                            "memory": "8Gi"
                        },
                    }
                cluster_data["spec"]["resources"] = resources

        # Enable host network if enabled in config (this require all the
        # rules to be enabled on underlaying platform).
        if config.DEPLOYMENT.get("host_network"):
            cluster_data["spec"]["hostNetwork"] = True

        cluster_data["spec"]["storageDeviceSets"] = [deviceset_data]

        if self.platform == constants.IBMCLOUD_PLATFORM:
            mon_pvc_template = {
                "spec": {
                    "accessModes": ["ReadWriteOnce"],
                    "resources": {
                        "requests": {
                            "storage": "20Gi"
                        }
                    },
                    "storageClassName": self.DEFAULT_STORAGECLASS,
                    "volumeMode": "Filesystem",
                }
            }
            cluster_data["spec"]["monPVCTemplate"] = mon_pvc_template
            # Need to check if it's needed for ibm cloud to set manageNodes
            cluster_data["spec"]["manageNodes"] = False

        if config.ENV_DATA.get("encryption_at_rest"):
            if ocs_version < 4.6:
                error_message = "Encryption at REST can be enabled only on OCS >= 4.6!"
                logger.error(error_message)
                raise UnsupportedFeatureError(error_message)
            logger.info("Enabling encryption at REST!")
            cluster_data["spec"]["encryption"] = {
                "enable": True,
            }
            if config.DEPLOYMENT.get("kms_deployment"):
                cluster_data["spec"]["encryption"]["kms"] = {
                    "enable": True,
                }

        if config.DEPLOYMENT.get("ceph_debug"):
            setup_ceph_debug()
            cluster_data["spec"]["managedResources"] = {
                "cephConfig": {
                    "reconcileStrategy": "ignore"
                }
            }

        cluster_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="cluster_storage", delete=False)
        templating.dump_data_to_temp_yaml(cluster_data, cluster_data_yaml.name)
        run_cmd(f"oc create -f {cluster_data_yaml.name}", timeout=1200)
        if config.DEPLOYMENT["infra_nodes"]:
            _ocp = ocp.OCP(kind="node")
            _ocp.exec_oc_cmd(
                command=f"annotate namespace {defaults.ROOK_CLUSTER_NAMESPACE} "
                f"{constants.NODE_SELECTOR_ANNOTATION}")
Пример #15
0
def test_upgrade():
    ceph_cluster = CephCluster()
    with CephHealthMonitor(ceph_cluster):
        namespace = config.ENV_DATA['cluster_namespace']
        version_before_upgrade = config.ENV_DATA.get("ocs_version")
        upgrade_version = config.UPGRADE.get("upgrade_ocs_version",
                                             version_before_upgrade)
        ocs_registry_image = config.UPGRADE.get('upgrade_ocs_registry_image')
        if ocs_registry_image:
            upgrade_version = get_ocs_version_from_image(ocs_registry_image)
        parsed_version_before_upgrade = parse_version(version_before_upgrade)
        parsed_upgrade_version = parse_version(upgrade_version)
        assert parsed_upgrade_version >= parsed_version_before_upgrade, (
            f"Version you would like to upgrade to: {upgrade_version} "
            f"is not higher or equal to the version you currently running: "
            f"{version_before_upgrade}")
        operator_selector = get_selector_for_ocs_operator()
        package_manifest = PackageManifest(
            resource_name=OCS_OPERATOR_NAME,
            selector=operator_selector,
        )
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        csv_name_pre_upgrade = package_manifest.get_current_csv(channel)
        log.info(f"CSV name before upgrade is: {csv_name_pre_upgrade}")
        csv_pre_upgrade = CSV(resource_name=csv_name_pre_upgrade,
                              namespace=namespace)
        pre_upgrade_images = get_images(csv_pre_upgrade.get())
        version_change = parsed_upgrade_version > parsed_version_before_upgrade
        if version_change:
            version_config_file = os.path.join(constants.CONF_DIR,
                                               'ocs_version',
                                               f'ocs-{upgrade_version}.yaml')
            load_config_file(version_config_file)
        ocs_catalog = CatalogSource(
            resource_name=constants.OPERATOR_CATALOG_SOURCE_NAME,
            namespace=constants.MARKETPLACE_NAMESPACE,
        )
        upgrade_in_current_source = config.UPGRADE.get(
            'upgrade_in_current_source', False)
        if not upgrade_in_current_source:
            if not ocs_catalog.is_exist() and not upgrade_in_current_source:
                log.info("OCS catalog source doesn't exist. Creating new one.")
                create_catalog_source(ocs_registry_image, ignore_upgrade=True)
            image_url = ocs_catalog.get_image_url()
            image_tag = ocs_catalog.get_image_name()
            log.info(f"Current image is: {image_url}, tag: {image_tag}")
            if ocs_registry_image:
                image_url, new_image_tag = ocs_registry_image.split(':')
            elif (config.UPGRADE.get('upgrade_to_latest', True)
                  or version_change):
                new_image_tag = get_latest_ds_olm_tag()
            else:
                new_image_tag = get_next_version_available_for_upgrade(
                    image_tag)
            cs_data = deepcopy(ocs_catalog.data)
            image_for_upgrade = ':'.join([image_url, new_image_tag])
            log.info(f"Image: {image_for_upgrade} will be used for upgrade.")
            cs_data['spec']['image'] = image_for_upgrade

            with NamedTemporaryFile() as cs_yaml:
                dump_data_to_temp_yaml(cs_data, cs_yaml.name)
                ocs_catalog.apply(cs_yaml.name)
        # Wait for the new package manifest for upgrade.
        operator_selector = get_selector_for_ocs_operator()
        package_manifest = PackageManifest(
            resource_name=OCS_OPERATOR_NAME,
            selector=operator_selector,
        )
        package_manifest.wait_for_resource()
        channel = config.DEPLOYMENT.get('ocs_csv_channel')
        if not channel:
            channel = package_manifest.get_default_channel()

        # update subscription
        subscription = OCP(
            resource_name=constants.OCS_SUBSCRIPTION,
            kind='subscription',
            namespace=config.ENV_DATA['cluster_namespace'],
        )
        current_ocs_source = subscription.data['spec']['source']
        log.info(f"Current OCS subscription source: {current_ocs_source}")
        ocs_source = current_ocs_source if upgrade_in_current_source else (
            constants.OPERATOR_CATALOG_SOURCE_NAME)
        patch_subscription_cmd = (
            f'oc patch subscription {constants.OCS_SUBSCRIPTION} '
            f'-n {namespace} --type merge -p \'{{"spec":{{"channel": '
            f'"{channel}", "source": "{ocs_source}"}}}}\'')
        run_cmd(patch_subscription_cmd)

        subscription_plan_approval = config.DEPLOYMENT.get(
            'subscription_plan_approval')
        if subscription_plan_approval == 'Manual':
            wait_for_install_plan_and_approve(namespace)
        attempts = 145
        for attempt in range(1, attempts + 1):
            log.info(f"Attempt {attempt}/{attempts} to check CSV upgraded.")
            csv_name_post_upgrade = package_manifest.get_current_csv(channel)
            if csv_name_post_upgrade == csv_name_pre_upgrade:
                log.info(f"CSV is still: {csv_name_post_upgrade}")
                sleep(5)
            else:
                log.info(f"CSV now upgraded to: {csv_name_post_upgrade}")
                break
            if attempts == attempt:
                raise TimeoutException("No new CSV found after upgrade!")
        csv_post_upgrade = CSV(resource_name=csv_name_post_upgrade,
                               namespace=namespace)
        log.info(
            f"Waiting for CSV {csv_name_post_upgrade} to be in succeeded state"
        )
        if version_before_upgrade == '4.2' and upgrade_version == '4.3':
            log.info("Force creating Ceph toolbox after upgrade 4.2 -> 4.3")
            setup_ceph_toolbox(force_setup=True)
        osd_count = get_osd_count()
        csv_post_upgrade.wait_for_phase("Succeeded", timeout=200 * osd_count)
        post_upgrade_images = get_images(csv_post_upgrade.get())
        old_images, _, _ = get_upgrade_image_info(pre_upgrade_images,
                                                  post_upgrade_images)
        verify_image_versions(old_images, parsed_upgrade_version)
        ocs_install_verification(
            timeout=600,
            skip_osd_distribution_check=True,
            ocs_registry_image=ocs_registry_image,
            post_upgrade_verification=True,
        )
Пример #16
0
def test_upgrade():
    ceph_cluster = CephCluster()
    with CephHealthMonitor(ceph_cluster):
        namespace = config.ENV_DATA['cluster_namespace']
        ocs_catalog = CatalogSource(
            resource_name=constants.OPERATOR_CATALOG_SOURCE_NAME,
            namespace=constants.MARKETPLACE_NAMESPACE,
        )
        version_before_upgrade = config.ENV_DATA.get("ocs_version")
        upgrade_version = config.UPGRADE.get("upgrade_ocs_version",
                                             version_before_upgrade)
        parsed_version_before_upgrade = parse_version(version_before_upgrade)
        parsed_upgrade_version = parse_version(upgrade_version)
        assert parsed_upgrade_version >= parsed_version_before_upgrade, (
            f"Version you would like to upgrade to: {upgrade_version} "
            f"is not higher or equal to the version you currently running: "
            f"{version_before_upgrade}")
        version_change = parsed_upgrade_version > parsed_version_before_upgrade
        if version_change:
            version_config_file = os.path.join(constants.CONF_DIR,
                                               'ocs_version',
                                               f'ocs-{upgrade_version}.yaml')
            assert os.path.exists(version_config_file), (
                f"OCS version config file {version_config_file} doesn't exist!"
            )
            with open(os.path.abspath(
                    os.path.expanduser(version_config_file))) as file_stream:
                custom_config_data = yaml.safe_load(file_stream)
                config.update(custom_config_data)
        image_url = ocs_catalog.get_image_url()
        image_tag = ocs_catalog.get_image_name()
        log.info(f"Current image is: {image_url}, tag: {image_tag}")
        ocs_registry_image = config.UPGRADE.get('upgrade_ocs_registry_image')
        if ocs_registry_image:
            image_url, new_image_tag = ocs_registry_image.split(':')
        elif config.UPGRADE.get('upgrade_to_latest', True) or version_change:
            new_image_tag = get_latest_ds_olm_tag()
        else:
            new_image_tag = get_next_version_available_for_upgrade(image_tag)
        cs_data = deepcopy(ocs_catalog.data)
        image_for_upgrade = ':'.join([image_url, new_image_tag])
        log.info(f"Image: {image_for_upgrade} will be used for upgrade.")
        cs_data['spec']['image'] = image_for_upgrade
        operator_selector = get_selector_for_ocs_operator()
        package_manifest = PackageManifest(
            resource_name=OCS_OPERATOR_NAME,
            selector=operator_selector,
        )
        csv_name_pre_upgrade = package_manifest.get_current_csv()
        log.info(f"CSV name before upgrade is: {csv_name_pre_upgrade}")
        csv_pre_upgrade = CSV(resource_name=csv_name_pre_upgrade,
                              namespace=namespace)
        pre_upgrade_images = get_images(csv_pre_upgrade.get())

        with NamedTemporaryFile() as cs_yaml:
            dump_data_to_temp_yaml(cs_data, cs_yaml.name)
            ocs_catalog.apply(cs_yaml.name)
        # Wait for package manifest is ready
        package_manifest.wait_for_resource()
        subscription_plan_approval = config.DEPLOYMENT.get(
            'subscription_plan_approval')
        if subscription_plan_approval == 'Manual':
            wait_for_install_plan_and_approve(namespace)
        attempts = 145
        for attempt in range(1, attempts):
            if attempts == attempt:
                raise TimeoutException("No new CSV found after upgrade!")
            log.info(f"Attempt {attempt}/{attempts} to check CSV upgraded.")
            package_manifest.reload_data()
            csv_name_post_upgrade = package_manifest.get_current_csv()
            if csv_name_post_upgrade == csv_name_pre_upgrade:
                log.info(f"CSV is still: {csv_name_post_upgrade}")
                sleep(5)
            else:
                log.info(f"CSV now upgraded to: {csv_name_post_upgrade}")
                break
        csv_post_upgrade = CSV(resource_name=csv_name_post_upgrade,
                               namespace=namespace)
        log.info(
            f"Waiting for CSV {csv_name_post_upgrade} to be in succeeded state"
        )
        if version_before_upgrade == '4.2' and upgrade_version == '4.3':
            log.info("Force creating Ceph toolbox after upgrade 4.2 -> 4.3")
            setup_ceph_toolbox(force_setup=True)
        csv_post_upgrade.wait_for_phase("Succeeded", timeout=600)
        post_upgrade_images = get_images(csv_post_upgrade.get())
        old_images, _, _ = get_upgrade_image_info(pre_upgrade_images,
                                                  post_upgrade_images)
        verify_image_versions(old_images, parsed_upgrade_version)
        ocs_install_verification(timeout=600, skip_osd_distribution_check=True)