Ejemplo n.º 1
0
def get_flattened_files_info(source_dir: str) -> [(str, str)]:
    """
    :param source_dir: Path of the directory containing different versions
    of operator bundles (CRD, CSV, package) in separate version directories
    :return: A list of tuples where in each tuple, the first element is
    the source file path to be copied to the flattened directory, and the second is
    the new file name to be used in the file copy.
    """

    # get package content and check if CSV exists in source_dir root, and
    # process all subdirectories and filter those that do not contain valid manifest files
    root_path, dir_names, root_dir_files = next(os.walk(source_dir))
    csvs_path_and_content, pkg_path_and_content \
        = get_csvs_pkg_info_from_root(source_dir)

    dir_paths = [os.path.join(source_dir, dir_name) for dir_name in dir_names]
    manifest_paths = list(filter(lambda x: is_manifest_folder(x), dir_paths))

    # nested layout
    if manifest_paths:
        file_paths_to_copy = []  # [ (SRC_FILE_PATH, NEW_FILE_NAME) ]

        crd_dict = {}  # { CRD_NAME => (VERSION, CRD_PATH) }
        csv_paths = []

        for manifest_path in manifest_paths:
            folder_semver = get_folder_semver(manifest_path)
            if not folder_semver:
                continue
            parse_manifest_folder(manifest_path, folder_semver, csv_paths,
                                  crd_dict)

        # add package in source_dir
        package_path = pkg_path_and_content[0]
        file_paths_to_copy.append(
            (package_path, os.path.basename(package_path)))

        # add all CRDs with the latest version
        for _, crd_path in crd_dict.values():
            file_paths_to_copy.append((crd_path, os.path.basename(crd_path)))

        # add all CSVs
        for csv_file_name, csv_entries in create_csv_dict(csv_paths).items():
            for (version, csv_path) in csv_entries:
                basename, ext = os.path.splitext(csv_file_name)
                file_paths_to_copy.append(
                    (csv_path, f'{basename}-v{version}{ext}'))

        return file_paths_to_copy
    # flat layout
    elif pkg_path_and_content and csvs_path_and_content:
        logger.info('The source directory is already flat.')
        # just return files from dir as they are already flat
        return [(os.path.join(source_dir, name), name)
                for name in root_dir_files]

    msg = 'The source directory structure is not in valid flat or nested format,' \
          'because no valid CSV file is found in root or manifest directories.'
    logger.error(msg)
    raise OpCourierBadBundle(msg, {})
Ejemplo n.º 2
0
    def get_manifests_info(self, source_dir):
        """
        Given a source directory, this method returns a dict containing all
        operator manifest file information, grouped by subfolder name if the
        manifest directory structure is nested.

        :param source_dir: Path to local directory of operator manifests, which can be
                           in either flat or nested format
        :return: A dictionary object where the key is the folder name of the operator
                 manifest, and the value is a list of yaml strings of manifest files

                 FLAT_KEY is used as key if the directory structure is flat
        """
        # MANIFEST_DIR_NAME => manifest_files_content
        # FLAT_KEY is used as key to indicate the flat directory structure
        manifests = {}

        root_path, dir_names, root_dir_files = next(os.walk(source_dir))
        csvs_path_and_content, pkg_path_and_content \
            = get_csvs_pkg_info_from_root(source_dir)

        dir_paths = [
            os.path.join(source_dir, dir_name) for dir_name in dir_names
        ]
        manifest_paths = list(
            filter(lambda x: is_manifest_folder(x), dir_paths))

        # if there is at least 1 valid manifest folder, we treat the directory layout as
        # nested, and add all manifest files from each version folder to manifests dict

        # nested layout: add package to each manifest dict entry
        if manifest_paths:
            logger.info('The source directory is in nested structure.')
            self.nested = True
            for manifest_path in manifest_paths:
                manifest_dir_name = os.path.basename(manifest_path)

                crd_files_info, csv_files_info = get_crd_csv_files_info(
                    manifest_path)
                manifests[manifest_dir_name] = crd_files_info + csv_files_info
            for manifest_dir_name in manifests:
                manifests[manifest_dir_name].append(pkg_path_and_content)
        # flat layout: collect all valid manifest files and add to FLAT_KEY entry
        elif pkg_path_and_content and csvs_path_and_content:
            logger.info('The source directory is in flat structure.')
            crd_files_info, csv_files_info = get_crd_csv_files_info(root_path)
            files_info = [pkg_path_and_content]
            files_info.extend(crd_files_info + csv_files_info)

            manifests[FLAT_KEY] = files_info
        else:
            msg = 'The source directory structure is not in valid flat or nested format,'\
                  'because no valid CSV file is found in root or manifest directories.'
            logger.error(msg)
            raise OpCourierBadBundle(msg, {})

        return manifests
Ejemplo n.º 3
0
def nest_bundles(source_dir, output_dir):
    root_path, dir_names, root_dir_files = next(os.walk(source_dir))
    csvs_info, pkg_info = get_csvs_pkg_info_from_root(source_dir)

    dir_paths = [os.path.join(source_dir, dir_name) for dir_name in dir_names]
    manifest_paths = list(filter(lambda x: is_manifest_folder(x), dir_paths))

    # nested layout
    if manifest_paths:
        logger.warning('The source directory is already nested.')

        # extract paths of package file in root dir and
        # valid CRD/CSV files from subdirectories, and ignore irrelevant ones
        manifest_files_path = [pkg_info[0]]

        for manifest_path in manifest_paths:
            crds_info, csvs_info = get_crd_csv_files_info(manifest_path)
            crd_csv_file_paths = [
                file_info[0] for file_info in (crds_info + csvs_info)
            ]
            manifest_files_path.extend(crd_csv_file_paths)

        # copy all manifest files to output_dir with folder structure preserved
        os.makedirs(output_dir, exist_ok=True)
        for file_path in manifest_files_path:
            file_path_relative = os.path.relpath(file_path, source_dir)
            output_file_path = os.path.join(output_dir, file_path_relative)
            os.makedirs(os.path.dirname(output_file_path), exist_ok=True)
            copyfile(file_path, output_file_path)

    # flat layout
    elif csvs_info and pkg_info:
        # extract all valid manifest (CRD, CSV, PKG) files from root
        # and make nested bundles
        crds_info, csvs_info = get_crd_csv_files_info(source_dir)
        with TemporaryDirectory() as temp_dir:
            manifest_files_content = [pkg_info[1]]
            manifest_files_content.extend([
                file_content for (_, file_content) in (crds_info + csvs_info)
            ])

            nest_flat_bundles(manifest_files_content, output_dir, temp_dir)
    else:
        msg = 'The source directory structure is not in valid flat or nested format,' \
              'because no valid CSV file is found in root or manifest directories.'
        logger.error(msg)
        raise OpCourierBadBundle(msg, {})