Example #1
0
    def clone_and_unlock_ocs_private_conf(self):
        """
        Clone ocs_private_conf (flexy env and config) repo into
        flexy_host_dir

        """
        clone_repo(
            self.flexy_private_conf_url,
            self.flexy_host_private_conf_dir_path,
            self.flexy_private_conf_branch,
        )
        # prepare flexy private repo keyfile (if it is base64 encoded)
        keyfile = os.path.expanduser(constants.FLEXY_GIT_CRYPT_KEYFILE)
        try:
            with open(keyfile, "rb") as fd:
                keyfile_content = base64.b64decode(fd.read())
            logger.info(
                "Private flexy repository git crypt keyfile is base64 encoded. "
                f"Decoding it and saving to the same place ({keyfile})")
            with open(keyfile, "wb") as fd:
                fd.write(keyfile_content)
        except binascii.Error:
            logger.info(
                f"Private flexy repository git crypt keyfile is already prepared ({keyfile})."
            )
        # git-crypt unlock /path/to/keyfile
        cmd = f"git-crypt unlock {keyfile}"
        exec_cmd(cmd, cwd=self.flexy_host_private_conf_dir_path)
        logger.info("Unlocked the git repo")
Example #2
0
def clone_openshift_installer():
    """
    Clone the openshift installer repo
    """
    # git clone repo from openshift installer
    # installer ( https://github.com/openshift/installer ) master and
    # other branches (greater than release-4.3) structure has been
    # changed. Use appropriate branch when ocs-ci is ready
    # with the changes.
    # Note: Currently use release-4.3 branch for the ocp versions
    # which is greater than 4.3
    upi_repo_path = os.path.join(
        constants.EXTERNAL_DIR,
        'installer'
    )
    ocp_version = get_ocp_version()
    if Version.coerce(ocp_version) >= Version.coerce('4.4'):
        clone_repo(
            constants.VSPHERE_INSTALLER_REPO, upi_repo_path,
            constants.VSPHERE_INSTALLER_BRANCH
        )
    else:
        clone_repo(
            constants.VSPHERE_INSTALLER_REPO, upi_repo_path,
            f'release-{ocp_version}'
        )
Example #3
0
    def destroy_cluster(self, log_level="DEBUG"):
        """
        Destroy OCP cluster specific to vSphere UPI

        Args:
            log_level (str): log level openshift-installer (default: DEBUG)

        """
        previous_dir = os.getcwd()
        terraform_data_dir = os.path.join(self.cluster_path, constants.TERRAFORM_DATA_DIR)
        upi_repo_path = os.path.join(
            constants.EXTERNAL_DIR, 'installer',
        )
        tfvars = os.path.join(
            config.ENV_DATA.get('cluster_path'),
            constants.TERRAFORM_DATA_DIR,
            constants.TERRAFORM_VARS
        )
        clone_repo(
            constants.VSPHERE_INSTALLER_REPO, upi_repo_path
        )
        if (
            os.path.exists(f"{constants.VSPHERE_MAIN}.backup")
            and os.path.exists(f"{constants.VSPHERE_MAIN}.json")
        ):
            os.rename(f"{constants.VSPHERE_MAIN}.json", f"{constants.VSPHERE_MAIN}.json.backup")
        terraform = Terraform(os.path.join(upi_repo_path, "upi/vsphere/"))
        os.chdir(terraform_data_dir)
        terraform.initialize(upgrade=True)
        terraform.destroy(tfvars)
        os.chdir(previous_dir)
Example #4
0
    def _deploy_prereqs(self):
        """
        Perform prerequisites

        """
        # Clone workload repo
        clone_repo(self.workload_repo_url, self.target_clone_dir)
Example #5
0
    def destroy_scaleup_nodes(self, scale_up_terraform_data_dir, scale_up_terraform_var):
        """
        Destroy the scale-up nodes

        Args:
            scale_up_terraform_data_dir (str): Path to scale-up terraform
                data directory
            scale_up_terraform_var (str): Path to scale-up
                terraform.tfvars file

        """
        clone_repo(
            constants.VSPHERE_SCALEUP_REPO, self.upi_scale_up_repo_path
        )
        # modify scale-up repo
        self.modify_scaleup_repo()

        terraform_scale_up = Terraform(
            os.path.join(
                self.upi_scale_up_repo_path,
                "v4-testing-misc/v4-scaleup/vsphere/"
            )
        )
        os.chdir(scale_up_terraform_data_dir)
        terraform_scale_up.initialize(upgrade=True)
        terraform_scale_up.destroy(scale_up_terraform_var)
Example #6
0
    def destroy_scaleup_nodes(self, scale_up_terraform_data_dir,
                              scale_up_terraform_var):
        """
        Destroy the scale-up nodes

        Args:
            scale_up_terraform_data_dir (str): Path to scale-up terraform
                data directory
            scale_up_terraform_var (str): Path to scale-up
                terraform.tfvars file

        """
        clone_repo(constants.VSPHERE_SCALEUP_REPO, self.upi_scale_up_repo_path)
        # git clone repo from cluster-launcher
        clone_repo(constants.VSPHERE_CLUSTER_LAUNCHER,
                   self.cluster_launcer_repo_path)

        # modify scale-up repo
        helpers = VSPHEREHELPERS()
        helpers.modify_scaleup_repo()

        vsphere_dir = constants.SCALEUP_VSPHERE_DIR
        if Version.coerce(self.ocp_version) >= Version.coerce("4.5"):
            vsphere_dir = os.path.join(
                constants.CLUSTER_LAUNCHER_VSPHERE_DIR,
                f"aos-{get_ocp_version('_')}",
                "vsphere",
            )

        terraform_scale_up = Terraform(vsphere_dir)
        os.chdir(scale_up_terraform_data_dir)
        terraform_scale_up.initialize(upgrade=True)
        terraform_scale_up.destroy(scale_up_terraform_var)
def get_new_device_paths(device_sets_required, osd_size_capacity_requested):
    """
    Get new device paths to add capacity over Baremetal cluster

    Args:
        device_sets_required (int) : Count of device sets to be added
        osd_size_capacity_requested (int) : Requested OSD size capacity

    Returns:
        cur_device_list (list) : List containing added device paths

    """
    ocp_obj = OCP()
    workers = get_typed_nodes(node_type="worker")
    worker_names = [worker.name for worker in workers]
    output = ocp_obj.exec_oc_cmd("get localvolume local-block -n local-storage -o yaml")
    cur_device_list = output["spec"]["storageClassDevices"][0]["devicePaths"]
    path = os.path.join(constants.EXTERNAL_DIR, "device-by-id-ocp")
    utils.clone_repo(constants.OCP_QE_DEVICEPATH_REPO, path)
    os.chdir(path)
    utils.run_cmd("ansible-playbook devices_by_id.yml")
    with open("local-storage-block.yaml", "r") as cloned_file:
        with open("local-block.yaml", "w") as our_file:
            device_from_worker1 = device_sets_required
            device_from_worker2 = device_sets_required
            device_from_worker3 = device_sets_required
            cur_line = cloned_file.readline()
            while "devicePaths:" not in cur_line:
                our_file.write(cur_line)
                cur_line = cloned_file.readline()
            our_file.write(cur_line)
            cur_line = cloned_file.readline()
            # Add required number of device path from each node
            while cur_line:
                if str(osd_size_capacity_requested) in cur_line:
                    if device_from_worker1 and (str(worker_names[0]) in cur_line):
                        if not any(s in cur_line for s in cur_device_list):
                            our_file.write(cur_line)
                            device_from_worker1 = device_from_worker1 - 1
                    if device_from_worker2 and (str(worker_names[1]) in cur_line):
                        if not any(s in cur_line for s in cur_device_list):
                            our_file.write(cur_line)
                            device_from_worker2 = device_from_worker2 - 1
                    if device_from_worker3 and (str(worker_names[2]) in cur_line):
                        if not any(s in cur_line for s in cur_device_list):
                            our_file.write(cur_line)
                            device_from_worker3 = device_from_worker3 - 1
                cur_line = cloned_file.readline()
    local_block_yaml = open("local-block.yaml")
    lvcr = yaml.load(local_block_yaml, Loader=yaml.FullLoader)
    new_dev_paths = lvcr["spec"]["storageClassDevices"][0]["devicePaths"]
    log.info(f"Newly added devices are: {new_dev_paths}")
    assert len(new_dev_paths) == (len(worker_names) * device_sets_required), (
        f"Current devices available = {len(new_dev_paths)}"
    )
    os.chdir(constants.TOP_DIR)
    shutil.rmtree(path)
    cur_device_list.extend(new_dev_paths)
    return cur_device_list
Example #8
0
def get_new_device_paths(device_sets_required, osd_size_capacity_requested):
    """
    Get new device paths to add capacity over Baremetal cluster

    Args:
        device_sets_required (int) : Count of device sets to be added
        osd_size_capacity_requested (int) : Requested OSD size capacity

    Returns:
        list : List containing added device paths

    """
    ocp_obj = OCP(kind="localvolume",
                  namespace=config.ENV_DATA["local_storage_namespace"])
    workers = get_nodes(node_type="worker")
    worker_names = [worker.name for worker in workers]
    config.ENV_DATA["worker_replicas"] = len(worker_names)
    output = ocp_obj.get(resource_name="local-block")
    # Fetch device paths present in the current LVCR
    cur_device_list = output["spec"]["storageClassDevices"][0]["devicePaths"]
    # Clone repo and run playbook to fetch all device paths from each node
    path = os.path.join(constants.EXTERNAL_DIR, "device-by-id-ocp")
    clone_repo(constants.OCP_QE_DEVICEPATH_REPO, path)
    os.chdir(path)
    run_cmd("ansible-playbook devices_by_id.yml")
    # Filter unused/unallocated device paths
    with open("local-storage-block.yaml", "r") as cloned_file:
        with open("local-block.yaml", "w") as our_file:
            device_from_worker = [1] * config.ENV_DATA["worker_replicas"]
            cur_line = cloned_file.readline()
            while "devicePaths:" not in cur_line:
                our_file.write(cur_line)
                cur_line = cloned_file.readline()
            our_file.write(cur_line)
            cur_line = cloned_file.readline()
            # Add required number of device path from each worker node
            while cur_line:
                if str(osd_size_capacity_requested) in cur_line:
                    for i in range(len(worker_names)):
                        if device_from_worker[i] and (str(worker_names[i])
                                                      in cur_line):
                            if not any(s in cur_line for s in cur_device_list):
                                our_file.write(cur_line)
                                device_from_worker[
                                    i] = device_from_worker[i] - 1
                cur_line = cloned_file.readline()
    local_block_yaml = open("local-block.yaml")
    lvcr = yaml.load(local_block_yaml, Loader=yaml.FullLoader)
    new_dev_paths = lvcr["spec"]["storageClassDevices"][0]["devicePaths"]
    logger.info(f"Newly added devices are: {new_dev_paths}")
    if new_dev_paths:
        assert len(new_dev_paths) == (
            len(worker_names) * device_sets_required
        ), f"Current devices available = {len(new_dev_paths)}"
        os.chdir(constants.TOP_DIR)
        shutil.rmtree(path)
        # Return list of old device paths and newly added device paths
        cur_device_list.extend(new_dev_paths)
    return cur_device_list
Example #9
0
        def deploy_prereq(self):
            """
            Overriding deploy_prereq from parent. Perform all necessary
            prerequisites for AWSUPI here.
            """
            super(AWSUPI.OCPDeployment, self).deploy_prereq()

            # setup necessary env variables
            upi_env_vars = {
                'INSTANCE_NAME_PREFIX': config.ENV_DATA['cluster_name'],
                'AWS_REGION': config.ENV_DATA['region'],
                'rhcos_ami': config.ENV_DATA.get('rhcos_ami'),
                'route53_domain_name': config.ENV_DATA['base_domain'],
                'vm_type_masters': config.ENV_DATA['master_instance_type'],
                'vm_type_workers': config.ENV_DATA['worker_instance_type'],
                'num_workers': str(config.ENV_DATA['worker_replicas']),
                'AVAILABILITY_ZONE_COUNT': str(config.ENV_DATA.get(
                    'availability_zone_count', ''
                )),
                'BASE_DOMAIN': config.ENV_DATA['base_domain'],
                'remove_bootstrap': 'yes'
            }
            if config.DEPLOYMENT['preserve_bootstrap_node']:
                logger.info("Setting ENV VAR to preserve bootstrap node")
                upi_env_vars['remove_bootstrap'] = 'No'

            for key, value in upi_env_vars.items():
                if value:
                    os.environ[key] = value

            # ensure environment variables have been set correctly
            for key, value in upi_env_vars.items():
                if value:
                    assert os.getenv(key) == value

            # git clone repo from openshift-qe repo
            clone_repo(
                constants.OCP_QE_MISC_REPO, self.upi_repo_path
            )

            # Sym link install-dir to cluster_path
            install_dir = os.path.join(self.upi_script_path, "install-dir")
            absolute_cluster_path = os.path.abspath(self.cluster_path)
            logger.info(
                "Sym linking %s to %s", install_dir, absolute_cluster_path
            )
            os.symlink(absolute_cluster_path, install_dir)

            # NOT A CLEAN APPROACH: copy openshift-install and oc binary to
            # script path because upi script expects it to be present in
            # script dir
            bindir = os.path.abspath(os.path.expanduser(config.RUN['bin_dir']))
            shutil.copy2(
                os.path.join(bindir, 'openshift-install'),
                self.upi_script_path,
            )
            shutil.copy2(
                os.path.join(bindir, 'oc'), self.upi_script_path
            )
Example #10
0
    def destroy_cluster(self, log_level="DEBUG"):
        """
        Destroy OCP cluster specific to vSphere UPI

        Args:
            log_level (str): log level openshift-installer (default: DEBUG)

        """
        previous_dir = os.getcwd()

        # delete the extra disks
        self.delete_disks()

        # check whether cluster has scale-up nodes
        scale_up_terraform_data_dir = os.path.join(
            self.cluster_path,
            constants.TERRAFORM_DATA_DIR,
            constants.SCALEUP_TERRAFORM_DATA_DIR
        )
        scale_up_terraform_var = os.path.join(
            scale_up_terraform_data_dir,
            "scale_up_terraform.tfvars"
        )
        if os.path.exists(scale_up_terraform_var):
            os.chdir(scale_up_terraform_data_dir)
            self.destroy_scaleup_nodes(
                scale_up_terraform_data_dir,
                scale_up_terraform_var
            )
            os.chdir(previous_dir)

        terraform_data_dir = os.path.join(self.cluster_path, constants.TERRAFORM_DATA_DIR)
        upi_repo_path = os.path.join(
            constants.EXTERNAL_DIR, 'installer',
        )
        tfvars = os.path.join(
            config.ENV_DATA.get('cluster_path'),
            constants.TERRAFORM_DATA_DIR,
            constants.TERRAFORM_VARS
        )
        clone_repo(
            constants.VSPHERE_INSTALLER_REPO, upi_repo_path,
            f'release-{get_ocp_version()}'
        )
        if (
            os.path.exists(f"{constants.VSPHERE_MAIN}.backup")
            and os.path.exists(f"{constants.VSPHERE_MAIN}.json")
        ):
            os.rename(f"{constants.VSPHERE_MAIN}.json", f"{constants.VSPHERE_MAIN}.json.backup")

        terraform = Terraform(os.path.join(upi_repo_path, "upi/vsphere/"))
        os.chdir(terraform_data_dir)
        terraform.initialize(upgrade=True)
        terraform.destroy(tfvars)
        os.chdir(previous_dir)

        # post destroy checks
        self.post_destroy_checks()
Example #11
0
 def factory(destination_dir, git_url):
     """
     Args:
         destination_dir (str): Destination directory for cloned project.
         git_url (str): Project's URL.
     """
     bdi_dir.append(destination_dir)
     log.info(f"Cloning chart from github into {destination_dir}")
     clone_repo(url=git_url, location=destination_dir)
Example #12
0
    def add_nodes(self):
        """
        Add new nodes to the cluster
        """
        # create separate directory for scale-up terraform data
        scaleup_terraform_data_dir = os.path.join(
            self.cluster_path, constants.TERRAFORM_DATA_DIR,
            constants.SCALEUP_TERRAFORM_DATA_DIR)
        create_directory_path(scaleup_terraform_data_dir)
        logger.info(
            f"scale-up terraform data directory: {scaleup_terraform_data_dir}")

        # git clone repo from openshift-misc
        clone_repo(constants.VSPHERE_SCALEUP_REPO, self.upi_scale_up_repo_path)

        # modify scale-up repo
        self.modify_scaleup_repo()

        config.ENV_DATA['vsphere_resource_pool'] = config.ENV_DATA.get(
            "cluster_name")

        # sync guest time with host
        if config.ENV_DATA.get('sync_time_with_host'):
            sync_time_with_host(constants.SCALEUP_VSPHERE_MACHINE_CONF, True)

        # get the RHCOS worker list
        self.rhcos_ips = get_node_ips()
        logger.info(f"RHCOS IP's: {json.dumps(self.rhcos_ips)}")

        # generate terraform variable for scaling nodes
        self.generate_terraform_vars_for_scaleup()

        # Add nodes using terraform
        scaleup_terraform = Terraform(constants.SCALEUP_VSPHERE_DIR)
        previous_dir = os.getcwd()
        os.chdir(scaleup_terraform_data_dir)
        scaleup_terraform.initialize()
        scaleup_terraform.apply(self.scale_up_terraform_var)
        scaleup_terraform_tfstate = os.path.join(scaleup_terraform_data_dir,
                                                 "terraform.tfstate")
        out = scaleup_terraform.output(scaleup_terraform_tfstate,
                                       "rhel_worker")
        rhel_worker_nodes = json.loads(out)['value']
        logger.info(f"RHEL worker nodes: {rhel_worker_nodes}")
        os.chdir(previous_dir)

        # Install OCP on rhel nodes
        rhel_install = OCPINSTALLRHEL(rhel_worker_nodes)
        rhel_install.prepare_rhel_nodes()
        rhel_install.execute_ansible_playbook()

        # Giving some time to settle down the new nodes
        time.sleep(self.wait_time)

        # wait for nodes to be in READY state
        wait_for_nodes_status(timeout=300)
Example #13
0
    def clone_and_unlock_ocs_private_conf(self):
        """
        Clone ocs_private_conf (flexy env and config) repo into
        flexy_host_dir

        """
        clone_repo(self.flexy_private_conf_url,
                   self.flexy_host_private_conf_dir_path,
                   self.flexy_private_conf_branch)
        # git-crypt unlock /path/to/keyfile
        cmd = (f'git-crypt unlock '
               f'{os.path.expanduser(constants.FLEXY_GIT_CRYPT_KEYFILE)}')
        run_cmd(cmd, cwd=self.flexy_host_private_conf_dir_path)
        logger.info("Unlocked the git repo")
Example #14
0
        def deploy_prereq(self):
            """
            Overriding deploy_prereq from parent. Perform all necessary
            prerequisites for AWSUPI here.
            """
            super(AWSUPI.OCPDeployment, self).deploy_prereq()

            # setup necessary env variables
            upi_env_vars = {
                'INSTANCE_NAME_PREFIX': config.ENV_DATA['cluster_name'],
                'AWS_REGION': config.ENV_DATA['region'],
                'rhcos_ami': config.ENV_DATA['rhcos_ami'],
                'route53_domain_name': config.ENV_DATA['base_domain'],
                'vm_type_masters': config.ENV_DATA['master_instance_type'],
                'vm_type_workers': config.ENV_DATA['worker_instance_type'],
                'num_workers': str(config.ENV_DATA['worker_replicas'])
            }
            for key, value in upi_env_vars.items():
                os.environ[key] = value

            # ensure environment variables have been set correctly
            for key, value in upi_env_vars.items():
                assert os.getenv(key) == value, f"{os.getenv(key)} != {value}"

            # git clone repo from openshift-qe repo
            clone_repo(
                constants.OCP_QE_MISC_REPO, self.upi_repo_path
            )

            # Sym link install-dir to cluster_path
            install_dir = os.path.join(self.upi_script_path, "install-dir")
            absolute_cluster_path = os.path.abspath(self.cluster_path)
            logger.info(
                "Sym linking %s to %s", install_dir, absolute_cluster_path
            )
            os.symlink(absolute_cluster_path, install_dir)

            # NOT A CLEAN APPROACH: copy openshift-install and oc binary to
            # script path because upi script expects it to be present in
            # script dir
            bindir = os.path.abspath(os.path.expanduser(config.RUN['bin_dir']))
            shutil.copy2(
                os.path.join(bindir, 'openshift-install'),
                self.upi_script_path,
            )
            shutil.copy2(
                os.path.join(bindir, 'oc'), self.upi_script_path
            )
Example #15
0
def test_ocs_monkey():
    ocs_monkety_dir = "/tmp/ocs-monkey"
    # ocs-monkey run time in seconds
    run_time = 3200
    clone_repo(constants.OCS_MONKEY_REPOSITORY, ocs_monkety_dir)
    run_cmd(
        f"pip install -r {os.path.join(ocs_monkety_dir, 'requirements.txt')}")
    workload_run_cmd = f"python workload_runner.py -t {run_time}"

    start_time = time.time()
    log.info("Starting ocs-monkey")
    popen_obj = subprocess.Popen(
        shlex.split(workload_run_cmd),
        stderr=subprocess.STDOUT,
        stdout=subprocess.PIPE,
        encoding="utf-8",
        cwd=ocs_monkety_dir,
    )

    while True:
        output = popen_obj.stdout.readline()
        # Check whether the process is completed
        ret = popen_obj.poll()
        if len(output) == 0 and ret is not None:
            log.info("ocs-monkey run completed.")
            assert ret == 0, (f"ocs-monkey exited with return value {ret}. "
                              f"Check logs for details.")
            break
        # Stream the output in console
        if output:
            log.info(output.strip())
        # Terminate the process if it is not completed within the specified
        # time. Give grace period of 600 seconds considering the time
        # taken for setup
        if time.time() - start_time > run_time + 600:
            log.error(
                f"ocs-monkey did not complete with in the specified run time"
                f" {run_time} seconds. Killing the process now.")
            popen_obj.terminate()
            raise TimeoutError(
                f"ocs-monkey did not complete with in the specified run time "
                f"{run_time} seconds. Killed the process after providing "
                f"grace period of 600 seconds.")
Example #16
0
def fetch_all_device_paths():
    """
    Return all device paths inside worker nodes

    Returns:
        list : List containing all device paths

    """
    path = os.path.join(constants.EXTERNAL_DIR, "device-by-id-ocp")
    clone_repo(constants.OCP_QE_DEVICEPATH_REPO, path)
    os.chdir(path)
    logger.info("Running script to fetch device paths...")
    run_cmd("ansible-playbook devices_by_id.yml")
    with open("local-storage-block.yaml") as local_storage_block:
        local_block = yaml.load(local_storage_block, Loader=yaml.FullLoader)
        dev_paths = local_block["spec"]["storageClassDevices"][0]["devicePaths"]
    logger.info(f"All devices are {dev_paths}")
    os.chdir(constants.TOP_DIR)
    shutil.rmtree(path)
    return dev_paths
Example #17
0
def test_ocs_monkey():
    ocs_monkety_dir = "/tmp/ocs-monkey"
    # ocs-monkey run time in seconds
    run_time = 3600
    clone_repo(constants.OCS_MONKEY_REPOSITORY, ocs_monkety_dir)
    run_cmd(
        f"pip install -r {os.path.join(ocs_monkety_dir, 'requirements.txt')}")
    workload_run_cmd = f"python workload_runner.py -t {run_time}"
    chaos_runner_cmd = "python chaos_runner.py"

    start_time = time.time()
    log.info("Starting workload runner")
    popen_workload = subprocess.Popen(
        shlex.split(workload_run_cmd),
        stderr=subprocess.STDOUT,
        stdout=subprocess.PIPE,
        encoding="utf-8",
        cwd=ocs_monkety_dir,
    )

    log.info("Starting chaos runner")
    popen_chaos = subprocess.Popen(
        shlex.split(chaos_runner_cmd),
        stderr=subprocess.STDOUT,
        stdout=subprocess.PIPE,
        encoding="utf-8",
        cwd=ocs_monkety_dir,
    )

    while True:
        output_workload = popen_workload.stdout.readline()

        # Get the status of workload runner process
        ret_workload = popen_workload.poll()

        # Stream the workload runner output in console
        if output_workload:
            log.info(output_workload.strip())

        if ret_workload is not None:
            log.info("Workload runner completed.")
            log.debug(popen_workload.stdout.read())
            # Terminate chaos_runner if workload_runner is completed
            log.info("Terminating chaos runner")
            popen_chaos.terminate()
            # Check return value of workload runner process
            assert ret_workload == 0, (
                f"Workload runner exited with return value {ret_workload}. "
                f"Check logs for details.")
            log.info("ocs-monkey run completed")
            break

        output_chaos = popen_chaos.stdout.readline()
        # Get the status of chaos runner process
        ret_chaos = popen_chaos.poll()

        # Stream the chaos runner output in console
        if output_chaos:
            log.info(output_chaos.strip())

        if ret_chaos is not None:
            log.info("Chaos runner completed.")
            log.debug(popen_chaos.stdout.read())
            # Terminate workload_runner if chaos_runner is completed
            log.info("Terminating workload runner")
            popen_workload.terminate()
            assert ret_chaos == 0, (
                f"Chaos runner exited with return value {ret_chaos}. "
                f"Check logs for details.")
            log.info("ocs-monkey run completed")
            break

        # Terminate the process if it is not completed within the specified
        # time. Give grace period of 900 seconds considering the time
        # taken for setup
        if time.time() - start_time > run_time + 900:
            log.error(
                f"ocs-monkey did not complete with in the specified run time"
                f" {run_time} seconds. Killing the process now.")
            popen_workload.terminate()
            popen_chaos.terminate()
            raise TimeoutError(
                f"ocs-monkey did not complete with in the specified run time "
                f"{run_time} seconds. Killed the process after providing "
                f"grace period of 900 seconds.")

    assert ceph_health_check(tries=40,
                             delay=30), "Ceph cluster health is not OK"
Example #18
0
        def deploy_prereq(self):
            """
            Pre-Requisites for vSphere UPI Deployment
            """
            super(VSPHEREUPI.OCPDeployment, self).deploy_prereq()
            # create ignitions
            self.create_ignitions()
            self.kubeconfig = os.path.join(
                self.cluster_path, config.RUN.get('kubeconfig_location'))

            # git clone repo from openshift installer
            clone_repo(constants.VSPHERE_INSTALLER_REPO, self.upi_repo_path)

            # upload bootstrap ignition to public access server
            bootstrap_path = os.path.join(config.ENV_DATA.get('cluster_path'),
                                          constants.BOOTSTRAP_IGN)
            remote_path = os.path.join(
                config.ENV_DATA.get('path_to_upload'),
                f"{config.RUN.get('run_id')}_{constants.BOOTSTRAP_IGN}")
            upload_file(config.ENV_DATA.get('httpd_server'), bootstrap_path,
                        remote_path, config.ENV_DATA.get('httpd_server_user'),
                        config.ENV_DATA.get('httpd_server_password'))

            # generate bootstrap ignition url
            path_to_bootstrap_on_remote = remote_path.replace(
                "/var/www/html/", "")
            bootstrap_ignition_url = (
                f"http://{config.ENV_DATA.get('httpd_server')}/"
                f"{path_to_bootstrap_on_remote}")
            logger.info(f"bootstrap_ignition_url: {bootstrap_ignition_url}")
            config.ENV_DATA['bootstrap_ignition_url'] = bootstrap_ignition_url

            # load master and worker ignitions to variables
            master_ignition_path = os.path.join(
                config.ENV_DATA.get('cluster_path'), constants.MASTER_IGN)
            master_ignition = read_file_as_str(f"{master_ignition_path}")
            config.ENV_DATA['control_plane_ignition'] = master_ignition

            worker_ignition_path = os.path.join(
                config.ENV_DATA.get('cluster_path'), constants.WORKER_IGN)
            worker_ignition = read_file_as_str(f"{worker_ignition_path}")
            config.ENV_DATA['compute_ignition'] = worker_ignition

            cluster_domain = (f"{config.ENV_DATA.get('cluster_name')}."
                              f"{config.ENV_DATA.get('base_domain')}")
            config.ENV_DATA['cluster_domain'] = cluster_domain

            # generate terraform variables from template
            logger.info("Generating terraform variables")
            _templating = Templating()
            terraform_var_template = "terraform.tfvars.j2"
            terraform_var_template_path = os.path.join("ocp-deployment",
                                                       terraform_var_template)
            terraform_config_str = _templating.render_template(
                terraform_var_template_path, config.ENV_DATA)

            terraform_var_yaml = os.path.join(self.cluster_path,
                                              constants.TERRAFORM_DATA_DIR,
                                              "terraform.tfvars.yaml")
            with open(terraform_var_yaml, "w") as f:
                f.write(terraform_config_str)
            self.terraform_var = convert_yaml2tfvars(terraform_var_yaml)

            # update gateway and DNS
            if config.ENV_DATA.get('gateway'):
                replace_content_in_file(constants.INSTALLER_IGNITION,
                                        '${cidrhost(var.machine_cidr,1)}',
                                        f"{config.ENV_DATA.get('gateway')}")

            if config.ENV_DATA.get('dns'):
                replace_content_in_file(constants.INSTALLER_IGNITION,
                                        constants.INSTALLER_DEFAULT_DNS,
                                        f"{config.ENV_DATA.get('dns')}")

            # update the zone in route
            if config.ENV_DATA.get('region'):
                def_zone = 'provider "aws" { region = "%s" } \n' % config.ENV_DATA.get(
                    'region')
                replace_content_in_file(constants.INSTALLER_ROUTE53, "xyz",
                                        def_zone)

            # increase memory
            if config.ENV_DATA.get('memory'):
                replace_content_in_file(constants.INSTALLER_MACHINE_CONF,
                                        '${var.memory}',
                                        config.ENV_DATA.get('memory'))

            # increase CPUs
            worker_num_cpus = config.ENV_DATA.get('worker_num_cpus')
            master_num_cpus = config.ENV_DATA.get('master_num_cpus')
            if worker_num_cpus or master_num_cpus:
                with open(constants.VSPHERE_MAIN, 'r') as fd:
                    obj = hcl.load(fd)
                    if worker_num_cpus:
                        obj['module']['compute']['num_cpu'] = worker_num_cpus
                    if master_num_cpus:
                        obj['module']['control_plane'][
                            'num_cpu'] = master_num_cpus
                # Dump data to json file since hcl module
                # doesn't support dumping of data in HCL format
                dump_data_to_json(obj, f"{constants.VSPHERE_MAIN}.json")
                os.rename(constants.VSPHERE_MAIN,
                          f"{constants.VSPHERE_MAIN}.backup")
Example #19
0
def svt_project_clone():
    """
    This function clones the SVT project.
    """
    clone_repo("https://github.com/openshift/svt.git", "/tmp/svt")
Example #20
0
        def deploy_prereq(self):
            """
            Overriding deploy_prereq from parent. Perform all necessary
            prerequisites for AWSUPI here.
            """
            super(AWSUPI.OCPDeployment, self).deploy_prereq()

            # setup necessary env variables
            upi_env_vars = {
                "INSTANCE_NAME_PREFIX":
                config.ENV_DATA["cluster_name"],
                "CLUSTER_NAME":
                config.ENV_DATA["cluster_name"],
                "AWS_REGION":
                config.ENV_DATA["region"],
                "rhcos_ami":
                config.ENV_DATA.get("rhcos_ami"),
                "route53_domain_name":
                config.ENV_DATA["base_domain"],
                "vm_type_masters":
                config.ENV_DATA["master_instance_type"],
                "vm_type_workers":
                config.ENV_DATA["worker_instance_type"],
                "num_workers":
                str(config.ENV_DATA["worker_replicas"]),
                "AVAILABILITY_ZONE_COUNT":
                str(config.ENV_DATA.get("availability_zone_count", "")),
                "BASE_DOMAIN":
                config.ENV_DATA["base_domain"],
                "remove_bootstrap":
                "yes",
                "IAAS_PLATFORM":
                "aws",
                "HOSTS_SCRIPT_DIR":
                self.upi_script_path,
                "OCP_INSTALL_DIR":
                os.path.join(self.upi_script_path, "install-dir"),
                "DISABLE_MASTER_MACHINESET":
                "yes",
            }
            if config.DEPLOYMENT["preserve_bootstrap_node"]:
                logger.info("Setting ENV VAR to preserve bootstrap node")
                upi_env_vars["remove_bootstrap"] = "No"

            logger.info(f"UPI ENV VARS = {upi_env_vars}")

            for key, value in upi_env_vars.items():
                if value:
                    os.environ[key] = value

            # ensure environment variables have been set correctly
            for key, value in upi_env_vars.items():
                if value:
                    assert os.getenv(key) == value

            # git clone repo from openshift-qe repo
            clone_repo(constants.OCP_QE_MISC_REPO, self.upi_repo_path)

            # Sym link install-dir to cluster_path
            install_dir = os.path.join(self.upi_script_path, "install-dir")
            absolute_cluster_path = os.path.abspath(self.cluster_path)
            logger.info("Sym linking %s to %s", install_dir,
                        absolute_cluster_path)
            os.symlink(absolute_cluster_path, install_dir)

            # NOT A CLEAN APPROACH: copy openshift-install and oc binary to
            # script path because upi script expects it to be present in
            # script dir
            bindir = os.path.abspath(os.path.expanduser(config.RUN["bin_dir"]))
            shutil.copy2(
                os.path.join(bindir, "openshift-install"),
                self.upi_script_path,
            )
            shutil.copy2(os.path.join(bindir, "oc"), self.upi_script_path)
            # and another UGLY WORKAROUND: copy openshift-install also to the
            # absolute_cluster_path (for more details, see
            # https://github.com/red-hat-storage/ocs-ci/pull/4650)
            shutil.copy2(
                os.path.join(bindir, "openshift-install"),
                os.path.abspath(os.path.join(self.cluster_path, "..")),
            )
Example #21
0
    def add_nodes(self):
        """
        Add new nodes to the cluster
        """
        # create separate directory for scale-up terraform data
        scaleup_terraform_data_dir = os.path.join(
            self.cluster_path,
            constants.TERRAFORM_DATA_DIR,
            constants.SCALEUP_TERRAFORM_DATA_DIR,
        )
        create_directory_path(scaleup_terraform_data_dir)
        logger.info(
            f"scale-up terraform data directory: {scaleup_terraform_data_dir}")

        # git clone repo from openshift-misc
        clone_repo(constants.VSPHERE_SCALEUP_REPO, self.upi_scale_up_repo_path)

        # git clone repo from cluster-launcher
        clone_repo(constants.VSPHERE_CLUSTER_LAUNCHER,
                   self.cluster_launcer_repo_path)

        helpers = VSPHEREHELPERS()
        helpers.modify_scaleup_repo()

        config.ENV_DATA["vsphere_resource_pool"] = config.ENV_DATA.get(
            "cluster_name")

        # sync guest time with host
        sync_time_with_host_file = constants.SCALEUP_VSPHERE_MACHINE_CONF
        if config.ENV_DATA["folder_structure"]:
            sync_time_with_host_file = os.path.join(
                constants.CLUSTER_LAUNCHER_VSPHERE_DIR,
                f"aos-{get_ocp_version(seperator='_')}",
                constants.CLUSTER_LAUNCHER_MACHINE_CONF,
            )
        if config.ENV_DATA.get("sync_time_with_host"):
            sync_time_with_host(sync_time_with_host_file, True)

        # get the RHCOS worker list
        rhcos_ips = get_node_ips()
        logger.info(f"RHCOS IP's: {json.dumps(rhcos_ips)}")

        # generate terraform variable for scaling nodes
        self.scale_up_terraform_var = helpers.generate_terraform_vars_for_scaleup(
            rhcos_ips)

        # choose the vsphere_dir based on OCP version
        # generate cluster_info and config yaml files
        # for OCP version greater than 4.4
        vsphere_dir = constants.SCALEUP_VSPHERE_DIR
        rhel_module = "rhel-worker"
        if Version.coerce(self.ocp_version) >= Version.coerce("4.5"):
            vsphere_dir = os.path.join(
                constants.CLUSTER_LAUNCHER_VSPHERE_DIR,
                f"aos-{get_ocp_version('_')}",
                "vsphere",
            )
            helpers.generate_cluster_info()
            helpers.generate_config_yaml()
            rhel_module = "RHEL_WORKER_LIST"

        # Add nodes using terraform
        scaleup_terraform = Terraform(vsphere_dir)
        previous_dir = os.getcwd()
        os.chdir(scaleup_terraform_data_dir)
        scaleup_terraform.initialize()
        scaleup_terraform.apply(self.scale_up_terraform_var)
        scaleup_terraform_tfstate = os.path.join(scaleup_terraform_data_dir,
                                                 "terraform.tfstate")
        out = scaleup_terraform.output(scaleup_terraform_tfstate, rhel_module)
        if config.ENV_DATA["folder_structure"]:
            rhel_worker_nodes = out.strip().replace('"', "").split(",")
        else:
            rhel_worker_nodes = json.loads(out)["value"]

        logger.info(f"RHEL worker nodes: {rhel_worker_nodes}")
        os.chdir(previous_dir)

        # Install OCP on rhel nodes
        rhel_install = OCPINSTALLRHEL(rhel_worker_nodes)
        rhel_install.prepare_rhel_nodes()
        rhel_install.execute_ansible_playbook()

        # Giving some time to settle down the new nodes
        time.sleep(self.wait_time)

        # wait for nodes to be in READY state
        wait_for_nodes_status(timeout=300)
Example #22
0
    def destroy_cluster(self, log_level="DEBUG"):
        """
        Destroy OCP cluster specific to vSphere UPI

        Args:
            log_level (str): log level openshift-installer (default: DEBUG)

        """
        previous_dir = os.getcwd()

        # Download terraform binary based on terraform version
        # in terraform.log
        terraform_log_path = os.path.join(config.ENV_DATA.get("cluster_path"),
                                          config.ENV_DATA.get("TF_LOG_FILE"))

        # check for terraform.log, this check is for partially
        # deployed clusters
        try:
            with open(terraform_log_path, "r") as fd:
                logger.debug(
                    f"Reading terraform version from {terraform_log_path}")
                version_line = fd.readline()
                terraform_version = version_line.split()[-1]
        except FileNotFoundError:
            logger.debug(f"{terraform_log_path} file not found")
            terraform_version = config.DEPLOYMENT["terraform_version"]

        terraform_installer = get_terraform(version=terraform_version)
        config.ENV_DATA["terraform_installer"] = terraform_installer

        # getting OCP version here since we run destroy job as
        # separate job in jenkins
        ocp_version = get_ocp_version()
        self.folder_structure = False
        if Version.coerce(ocp_version) >= Version.coerce("4.5"):
            set_aws_region()
            self.folder_structure = True
            config.ENV_DATA["folder_structure"] = self.folder_structure

        # delete the extra disks
        self.delete_disks()

        # check whether cluster has scale-up nodes
        scale_up_terraform_data_dir = os.path.join(
            self.cluster_path,
            constants.TERRAFORM_DATA_DIR,
            constants.SCALEUP_TERRAFORM_DATA_DIR,
        )
        scale_up_terraform_var = os.path.join(scale_up_terraform_data_dir,
                                              "scale_up_terraform.tfvars")
        if os.path.exists(scale_up_terraform_var):
            os.chdir(scale_up_terraform_data_dir)
            self.destroy_scaleup_nodes(scale_up_terraform_data_dir,
                                       scale_up_terraform_var)
            os.chdir(previous_dir)

        terraform_data_dir = os.path.join(self.cluster_path,
                                          constants.TERRAFORM_DATA_DIR)
        upi_repo_path = os.path.join(
            constants.EXTERNAL_DIR,
            "installer",
        )
        tfvars = os.path.join(
            config.ENV_DATA.get("cluster_path"),
            constants.TERRAFORM_DATA_DIR,
            constants.TERRAFORM_VARS,
        )

        clone_openshift_installer()
        if os.path.exists(
                f"{constants.VSPHERE_MAIN}.backup") and os.path.exists(
                    f"{constants.VSPHERE_MAIN}.json"):
            os.rename(
                f"{constants.VSPHERE_MAIN}.json",
                f"{constants.VSPHERE_MAIN}.json.backup",
            )

        # terraform initialization and destroy cluster
        terraform = Terraform(os.path.join(upi_repo_path, "upi/vsphere/"))
        os.chdir(terraform_data_dir)
        if Version.coerce(ocp_version) >= Version.coerce("4.6"):
            # Download terraform ignition provider. For OCP upgrade clusters,
            # ignition provider doesn't exist, so downloading in destroy job
            # as well
            terraform_plugins_path = ".terraform/plugins/linux_amd64/"
            terraform_ignition_provider_path = os.path.join(
                terraform_data_dir,
                terraform_plugins_path,
                "terraform-provider-ignition",
            )

            # check the upgrade history of cluster and checkout to the
            # original installer release. This is due to the issue of not
            # supporting terraform state of OCP 4.5 in installer
            # release of 4.6 branch. More details in
            # https://github.com/red-hat-storage/ocs-ci/issues/2941
            is_cluster_upgraded = False
            try:
                upgrade_history = get_ocp_upgrade_history()
                if len(upgrade_history) > 1:
                    is_cluster_upgraded = True
                    original_installed_ocp_version = upgrade_history[-1]
                    installer_release_branch = (
                        f"release-{original_installed_ocp_version[0:3]}")
                    clone_repo(
                        constants.VSPHERE_INSTALLER_REPO,
                        upi_repo_path,
                        installer_release_branch,
                    )
            except Exception as ex:
                logger.error(ex)

            if not (os.path.exists(terraform_ignition_provider_path)
                    or is_cluster_upgraded):
                get_terraform_ignition_provider(terraform_data_dir)
            terraform.initialize()
        else:
            terraform.initialize(upgrade=True)
        terraform.destroy(tfvars, refresh=(not self.folder_structure))
        os.chdir(previous_dir)

        # post destroy checks
        self.post_destroy_checks()