예제 #1
0
def get_lso_channel():
    """
    Get the channel to use for installing the local storage operator

    Returns:
        str: local storage operator channel

    """
    ocp_version = get_ocp_version()
    # If OCP version is not GA, we will be using the Optional Operators CatalogSource
    # This means there are two PackageManifests with the name local-storage-operator
    # so we need to also use a selector to ensure we retrieve the correct one
    ocp_ga_version = get_ocp_ga_version(ocp_version)
    selector = constants.OPTIONAL_OPERATORS_SELECTOR if not ocp_ga_version else None
    # Retrieve available channels for LSO
    package_manifest = PackageManifest(
        resource_name=constants.LOCAL_STORAGE_CSV_PREFIX, selector=selector)
    channels = package_manifest.get_channels()
    channel_names = [channel["name"] for channel in channels]

    # Ensure channel_names is sorted
    versions = [
        LooseVersion(name) for name in channel_names if name != "stable"
    ]
    versions.sort()
    sorted_versions = [v.vstring for v in versions]

    if ocp_version in channel_names:
        # Use channel corresponding to OCP version
        return ocp_version
    else:
        # Use latest channel
        return sorted_versions[-1]
예제 #2
0
    def install_local_storage_operator(self):
        """
        Install local storage operator

        """
        if config.DEPLOYMENT.get("local_storage"):
            self.navigate_operatorhub_page()
            logger.info(f"Search {self.operator_name} Operator")
            self.do_send_keys(self.dep_loc["search_operators"],
                              text="Local Storage")
            logger.info("Choose Local Storage Version")
            ocp_ga_version = get_ocp_ga_version(self.ocp_version_full)
            if ocp_ga_version:
                self.do_click(self.dep_loc["choose_local_storage_version"],
                              enable_screenshot=True)
            else:
                self.do_click(
                    self.dep_loc["choose_local_storage_version_non_ga"],
                    enable_screenshot=True,
                )

            logger.info("Click Install LSO")
            self.do_click(self.dep_loc["click_install_lso"],
                          enable_screenshot=True)
            self.do_click(self.dep_loc["click_install_lso_page"],
                          enable_screenshot=True)
            self.verify_operator_succeeded(operator="Local Storage")
예제 #3
0
def create_optional_operators_catalogsource_non_ga(force=False):
    """
    Creating optional operators CatalogSource and ImageContentSourcePolicy
    for non-ga OCP.

    Args:
        force (bool): enable/disable lso catalog setup

    """
    ocp_version = version.get_semantic_ocp_version_from_config()
    ocp_ga_version = get_ocp_ga_version(ocp_version)
    if ocp_ga_version and not force:
        return
    optional_operators_data = list(
        templating.load_yaml(constants.LOCAL_STORAGE_OPTIONAL_OPERATORS,
                             multi_document=True))
    optional_operators_yaml = tempfile.NamedTemporaryFile(
        mode="w+", prefix="optional_operators", delete=False)
    if config.DEPLOYMENT.get("optional_operators_image"):
        for _dict in optional_operators_data:
            if _dict.get("kind").lower() == "catalogsource":
                _dict["spec"]["image"] = config.DEPLOYMENT.get(
                    "optional_operators_image")
    if config.DEPLOYMENT.get("disconnected"):
        # in case of disconnected environment, we have to mirror all the
        # optional_operators images
        icsp = None
        for _dict in optional_operators_data:
            if _dict.get("kind").lower() == "catalogsource":
                index_image = _dict["spec"]["image"]
            if _dict.get("kind").lower() == "imagecontentsourcepolicy":
                icsp = _dict
        mirrored_index_image = (f"{config.DEPLOYMENT['mirror_registry']}/"
                                f"{index_image.split('/', 1)[-1]}")
        prune_and_mirror_index_image(
            index_image,
            mirrored_index_image,
            constants.DISCON_CL_REQUIRED_PACKAGES,
            icsp,
        )
        _dict["spec"]["image"] = mirrored_index_image
    templating.dump_data_to_temp_yaml(optional_operators_data,
                                      optional_operators_yaml.name)
    with open(optional_operators_yaml.name, "r") as f:
        logger.info(f.read())
    logger.info(
        "Creating optional operators CatalogSource and ImageContentSourcePolicy"
    )
    run_cmd(f"oc create -f {optional_operators_yaml.name}")
    wait_for_machineconfigpool_status("all")
예제 #4
0
def setup_local_storage(storageclass):
    """
    Setup the necessary resources for enabling local storage.

    Args:
        storageclass (string): storageClassName value to be used in
            LocalVolume CR based on LOCAL_VOLUME_YAML

    """
    # Get the worker nodes
    workers = get_nodes(node_type="worker")
    worker_names = [worker.name for worker in workers]
    logger.debug("Workers: %s", worker_names)

    ocp_version = version.get_semantic_ocp_version_from_config()
    ocs_version = version.get_semantic_ocs_version_from_config()
    ocp_ga_version = get_ocp_ga_version(ocp_version)
    if not ocp_ga_version:
        optional_operators_data = list(
            templating.load_yaml(constants.LOCAL_STORAGE_OPTIONAL_OPERATORS,
                                 multi_document=True))
        optional_operators_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="optional_operators", delete=False)
        if config.DEPLOYMENT.get("optional_operators_image"):
            for _dict in optional_operators_data:
                if _dict.get("kind").lower() == "catalogsource":
                    _dict["spec"]["image"] = config.DEPLOYMENT.get(
                        "optional_operators_image")
        if config.DEPLOYMENT.get("disconnected"):
            # in case of disconnected environment, we have to mirror all the
            # optional_operators images
            icsp = None
            for _dict in optional_operators_data:
                if _dict.get("kind").lower() == "catalogsource":
                    index_image = _dict["spec"]["image"]
                if _dict.get("kind").lower() == "imagecontentsourcepolicy":
                    icsp = _dict
            mirrored_index_image = (f"{config.DEPLOYMENT['mirror_registry']}/"
                                    f"{index_image.split('/', 1)[-1]}")
            prune_and_mirror_index_image(
                index_image,
                mirrored_index_image,
                constants.DISCON_CL_REQUIRED_PACKAGES,
                icsp,
            )
            _dict["spec"]["image"] = mirrored_index_image
        templating.dump_data_to_temp_yaml(optional_operators_data,
                                          optional_operators_yaml.name)
        with open(optional_operators_yaml.name, "r") as f:
            logger.info(f.read())
        logger.info(
            "Creating optional operators CatalogSource and ImageContentSourcePolicy"
        )
        run_cmd(f"oc create -f {optional_operators_yaml.name}")
        logger.info(
            "Sleeping for 60 sec to start update machineconfigpool status")
        # sleep here to start update machineconfigpool status
        time.sleep(60)
        wait_for_machineconfigpool_status("all")

    logger.info("Retrieving local-storage-operator data from yaml")
    lso_data = list(
        templating.load_yaml(constants.LOCAL_STORAGE_OPERATOR,
                             multi_document=True))

    # ensure namespace is correct
    lso_namespace = config.ENV_DATA["local_storage_namespace"]
    for data in lso_data:
        if data["kind"] == "Namespace":
            data["metadata"]["name"] = lso_namespace
        else:
            data["metadata"]["namespace"] = lso_namespace
        if data["kind"] == "OperatorGroup":
            data["spec"]["targetNamespaces"] = [lso_namespace]

    # Update local-storage-operator subscription data with channel
    for data in lso_data:
        if data["kind"] == "Subscription":
            data["spec"]["channel"] = get_lso_channel()
        if not ocp_ga_version:
            if data["kind"] == "Subscription":
                data["spec"]["source"] = "optional-operators"

    # Create temp yaml file and create local storage operator
    logger.info(
        "Creating temp yaml file with local-storage-operator data:\n %s",
        lso_data)
    lso_data_yaml = tempfile.NamedTemporaryFile(
        mode="w+", prefix="local_storage_operator", delete=False)
    templating.dump_data_to_temp_yaml(lso_data, lso_data_yaml.name)
    with open(lso_data_yaml.name, "r") as f:
        logger.info(f.read())
    logger.info("Creating local-storage-operator")
    run_cmd(f"oc create -f {lso_data_yaml.name}")

    local_storage_operator = ocp.OCP(kind=constants.POD,
                                     namespace=lso_namespace)
    assert local_storage_operator.wait_for_resource(
        condition=constants.STATUS_RUNNING,
        selector=constants.LOCAL_STORAGE_OPERATOR_LABEL,
        timeout=600,
    ), "Local storage operator did not reach running phase"

    # Add disks for vSphere/RHV platform
    platform = config.ENV_DATA.get("platform").lower()
    lso_type = config.DEPLOYMENT.get("type")

    if platform == constants.VSPHERE_PLATFORM:
        add_disk_for_vsphere_platform()

    if platform == constants.RHV_PLATFORM:
        add_disk_for_rhv_platform()

    if (ocp_version >= version.VERSION_4_6) and (ocs_version >=
                                                 version.VERSION_4_6):
        # Pull local volume discovery yaml data
        logger.info("Pulling LocalVolumeDiscovery CR data from yaml")
        lvd_data = templating.load_yaml(constants.LOCAL_VOLUME_DISCOVERY_YAML)
        # Set local-volume-discovery namespace
        lvd_data["metadata"]["namespace"] = lso_namespace

        worker_nodes = get_compute_node_names(no_replace=True)

        # Update local volume discovery data with Worker node Names
        logger.info(
            "Updating LocalVolumeDiscovery CR data with worker nodes Name: %s",
            worker_nodes,
        )
        lvd_data["spec"]["nodeSelector"]["nodeSelectorTerms"][0][
            "matchExpressions"][0]["values"] = worker_nodes
        lvd_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="local_volume_discovery", delete=False)
        templating.dump_data_to_temp_yaml(lvd_data, lvd_data_yaml.name)

        logger.info("Creating LocalVolumeDiscovery CR")
        run_cmd(f"oc create -f {lvd_data_yaml.name}")

        # Pull local volume set yaml data
        logger.info("Pulling LocalVolumeSet CR data from yaml")
        lvs_data = templating.load_yaml(constants.LOCAL_VOLUME_SET_YAML)

        # Since we don't have datastore with SSD on our current VMware machines, localvolumeset doesn't detect
        # NonRotational disk. As a workaround we are setting Rotational to device MechanicalProperties to detect
        # HDD disk
        if platform == constants.VSPHERE_PLATFORM or config.ENV_DATA.get(
                "local_storage_allow_rotational_disks"):
            logger.info("Adding Rotational for deviceMechanicalProperties spec"
                        " to detect HDD disk")
            lvs_data["spec"]["deviceInclusionSpec"][
                "deviceMechanicalProperties"].append("Rotational")

        # Update local volume set data with Worker node Names
        logger.info(
            "Updating LocalVolumeSet CR data with worker nodes Name: %s",
            worker_nodes)
        lvs_data["spec"]["nodeSelector"]["nodeSelectorTerms"][0][
            "matchExpressions"][0]["values"] = worker_nodes

        # Set storage class
        logger.info(
            "Updating LocalVolumeSet CR data with LSO storageclass: %s",
            storageclass)
        lvs_data["spec"]["storageClassName"] = storageclass

        # set volumeMode to Filesystem for MCG only deployment
        if config.ENV_DATA["mcg_only_deployment"]:
            lvs_data["spec"]["volumeMode"] = constants.VOLUME_MODE_FILESYSTEM

        lvs_data_yaml = tempfile.NamedTemporaryFile(mode="w+",
                                                    prefix="local_volume_set",
                                                    delete=False)
        templating.dump_data_to_temp_yaml(lvs_data, lvs_data_yaml.name)
        logger.info("Creating LocalVolumeSet CR")
        run_cmd(f"oc create -f {lvs_data_yaml.name}")
    else:
        # Retrieve NVME device path ID for each worker node
        device_paths = get_device_paths(worker_names)

        # Pull local volume yaml data
        logger.info("Pulling LocalVolume CR data from yaml")
        lv_data = templating.load_yaml(constants.LOCAL_VOLUME_YAML)

        # Set local-volume namespace
        lv_data["metadata"]["namespace"] = lso_namespace

        # Set storage class
        logger.info("Updating LocalVolume CR data with LSO storageclass: %s",
                    storageclass)
        for scd in lv_data["spec"]["storageClassDevices"]:
            scd["storageClassName"] = storageclass

        # Update local volume data with NVME IDs
        logger.info("Updating LocalVolume CR data with device paths: %s",
                    device_paths)
        lv_data["spec"]["storageClassDevices"][0]["devicePaths"] = device_paths

        # Create temp yaml file and create local volume
        lv_data_yaml = tempfile.NamedTemporaryFile(mode="w+",
                                                   prefix="local_volume",
                                                   delete=False)
        templating.dump_data_to_temp_yaml(lv_data, lv_data_yaml.name)
        logger.info("Creating LocalVolume CR")
        run_cmd(f"oc create -f {lv_data_yaml.name}")
    logger.info("Waiting 30 seconds for PVs to create")
    storage_class_device_count = 1
    if platform == constants.AWS_PLATFORM and not lso_type == constants.AWS_EBS:
        storage_class_device_count = 2
    elif platform == constants.IBM_POWER_PLATFORM:
        numberofstoragedisks = config.ENV_DATA.get("number_of_storage_disks",
                                                   1)
        storage_class_device_count = numberofstoragedisks
    elif platform == constants.VSPHERE_PLATFORM:
        # extra_disks is used in vSphere attach_disk() method
        storage_class_device_count = config.ENV_DATA.get("extra_disks", 1)
    expected_pvs = len(worker_names) * storage_class_device_count
    verify_pvs_created(expected_pvs, storageclass)
예제 #5
0
def setup_local_storage(storageclass):
    """
    Setup the necessary resources for enabling local storage.

    Args:
        storageclass (string): storageClassName value to be used in
            LocalVolume CR based on LOCAL_VOLUME_YAML

    """
    # Get the worker nodes
    workers = get_nodes(node_type="worker")
    worker_names = [worker.name for worker in workers]
    logger.debug("Workers: %s", worker_names)

    ocp_version = get_ocp_version()
    ocs_version = config.ENV_DATA.get("ocs_version")
    ocp_ga_version = get_ocp_ga_version(ocp_version)
    if not ocp_ga_version:
        optional_operators_data = templating.load_yaml(
            constants.LOCAL_STORAGE_OPTIONAL_OPERATORS, multi_document=True
        )
        logger.info(
            "Creating temp yaml file with optional operators data:\n %s",
            optional_operators_data,
        )
        optional_operators_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="optional_operators", delete=False
        )
        templating.dump_data_to_temp_yaml(
            optional_operators_data, optional_operators_yaml.name
        )
        with open(optional_operators_yaml.name, "r") as f:
            logger.info(f.read())
        logger.info(
            "Creating optional operators CatalogSource and" " ImageContentSourcePolicy"
        )
        run_cmd(f"oc create -f {optional_operators_yaml.name}")
        logger.info("Sleeping for 60 sec to start update machineconfigpool status")
        # sleep here to start update machineconfigpool status
        time.sleep(60)
        wait_for_machineconfigpool_status("all")

    logger.info("Retrieving local-storage-operator data from yaml")
    lso_data = list(
        templating.load_yaml(constants.LOCAL_STORAGE_OPERATOR, multi_document=True)
    )

    # ensure namespace is correct
    lso_namespace = config.ENV_DATA["local_storage_namespace"]
    for data in lso_data:
        if data["kind"] == "Namespace":
            data["metadata"]["name"] = lso_namespace
        else:
            data["metadata"]["namespace"] = lso_namespace
        if data["kind"] == "OperatorGroup":
            data["spec"]["targetNamespaces"] = [lso_namespace]

    # Update local-storage-operator subscription data with channel
    for data in lso_data:
        if data["kind"] == "Subscription":
            data["spec"]["channel"] = get_lso_channel()
        if not ocp_ga_version:
            if data["kind"] == "Subscription":
                data["spec"]["source"] = "optional-operators"

    # Create temp yaml file and create local storage operator
    logger.info(
        "Creating temp yaml file with local-storage-operator data:\n %s", lso_data
    )
    lso_data_yaml = tempfile.NamedTemporaryFile(
        mode="w+", prefix="local_storage_operator", delete=False
    )
    templating.dump_data_to_temp_yaml(lso_data, lso_data_yaml.name)
    with open(lso_data_yaml.name, "r") as f:
        logger.info(f.read())
    logger.info("Creating local-storage-operator")
    run_cmd(f"oc create -f {lso_data_yaml.name}")

    local_storage_operator = ocp.OCP(kind=constants.POD, namespace=lso_namespace)
    assert local_storage_operator.wait_for_resource(
        condition=constants.STATUS_RUNNING,
        selector=constants.LOCAL_STORAGE_OPERATOR_LABEL,
        timeout=600,
    ), "Local storage operator did not reach running phase"

    # Add RDM disk for vSphere platform
    platform = config.ENV_DATA.get("platform").lower()
    lso_type = config.DEPLOYMENT.get("type")
    if platform == constants.VSPHERE_PLATFORM:
        # Types of LSO Deployment
        # Importing here to avoid circular dependency
        from ocs_ci.deployment.vmware import VSPHEREBASE

        vsphere_base = VSPHEREBASE()

        if lso_type == constants.RDM:
            logger.info(f"LSO Deployment type: {constants.RDM}")
            vsphere_base.add_rdm_disks()

        if lso_type == constants.VMDK:
            logger.info(f"LSO Deployment type: {constants.VMDK}")
            vsphere_base.attach_disk(
                config.ENV_DATA.get("device_size", defaults.DEVICE_SIZE),
                config.DEPLOYMENT.get("provision_type", constants.VM_DISK_TYPE),
            )

        if lso_type == constants.DIRECTPATH:
            raise NotImplementedError(
                "LSO Deployment for VMDirectPath is not implemented"
            )
    if (ocp_version >= "4.6") and (ocs_version >= "4.6"):
        # Pull local volume discovery yaml data
        logger.info("Pulling LocalVolumeDiscovery CR data from yaml")
        lvd_data = templating.load_yaml(constants.LOCAL_VOLUME_DISCOVERY_YAML)
        # Set local-volume-discovery namespace
        lvd_data["metadata"]["namespace"] = lso_namespace

        worker_nodes = get_compute_node_names(no_replace=True)

        # Update local volume discovery data with Worker node Names
        logger.info(
            "Updating LocalVolumeDiscovery CR data with worker nodes Name: %s",
            worker_nodes,
        )
        lvd_data["spec"]["nodeSelector"]["nodeSelectorTerms"][0]["matchExpressions"][0][
            "values"
        ] = worker_nodes
        lvd_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="local_volume_discovery", delete=False
        )
        templating.dump_data_to_temp_yaml(lvd_data, lvd_data_yaml.name)

        logger.info("Creating LocalVolumeDiscovery CR")
        run_cmd(f"oc create -f {lvd_data_yaml.name}")

        # Pull local volume set yaml data
        logger.info("Pulling LocalVolumeSet CR data from yaml")
        lvs_data = templating.load_yaml(constants.LOCAL_VOLUME_SET_YAML)

        # Since we don't have datastore with SSD on our current VMware machines, localvolumeset doesn't detect
        # NonRotational disk. As a workaround we are setting Rotational to device MechanicalProperties to detect
        # HDD disk
        if platform == constants.VSPHERE_PLATFORM or config.ENV_DATA.get(
            "local_storage_allow_rotational_disks"
        ):
            logger.info(
                "Adding Rotational for deviceMechanicalProperties spec"
                " to detect HDD disk"
            )
            lvs_data["spec"]["deviceInclusionSpec"][
                "deviceMechanicalProperties"
            ].append("Rotational")

        # Update local volume set data with Worker node Names
        logger.info(
            "Updating LocalVolumeSet CR data with worker nodes Name: %s", worker_nodes
        )
        lvs_data["spec"]["nodeSelector"]["nodeSelectorTerms"][0]["matchExpressions"][0][
            "values"
        ] = worker_nodes

        # Set storage class
        logger.info(
            "Updating LocalVolumeSet CR data with LSO storageclass: %s", storageclass
        )
        lvs_data["spec"]["storageClassName"] = storageclass

        lvs_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="local_volume_set", delete=False
        )
        templating.dump_data_to_temp_yaml(lvs_data, lvs_data_yaml.name)
        logger.info("Creating LocalVolumeSet CR")
        run_cmd(f"oc create -f {lvs_data_yaml.name}")
    else:
        # Retrieve NVME device path ID for each worker node
        device_paths = get_device_paths(worker_names)

        # Pull local volume yaml data
        logger.info("Pulling LocalVolume CR data from yaml")
        lv_data = templating.load_yaml(constants.LOCAL_VOLUME_YAML)

        # Set local-volume namespace
        lv_data["metadata"]["namespace"] = lso_namespace

        # Set storage class
        logger.info(
            "Updating LocalVolume CR data with LSO storageclass: %s", storageclass
        )
        for scd in lv_data["spec"]["storageClassDevices"]:
            scd["storageClassName"] = storageclass

        # Update local volume data with NVME IDs
        logger.info("Updating LocalVolume CR data with device paths: %s", device_paths)
        lv_data["spec"]["storageClassDevices"][0]["devicePaths"] = device_paths

        # Create temp yaml file and create local volume
        lv_data_yaml = tempfile.NamedTemporaryFile(
            mode="w+", prefix="local_volume", delete=False
        )
        templating.dump_data_to_temp_yaml(lv_data, lv_data_yaml.name)
        logger.info("Creating LocalVolume CR")
        run_cmd(f"oc create -f {lv_data_yaml.name}")
    logger.info("Waiting 30 seconds for PVs to create")
    storage_class_device_count = 1
    if platform == constants.AWS_PLATFORM:
        storage_class_device_count = 2
    verify_pvs_created(len(worker_names) * storage_class_device_count)