def get_treeinfo_serialized(self):
        """
        Create a Pulp 3 Distribution content for saving later in a bulk operation.

        Returns:
            dict: a serialized treeinfo data, or None if no treeinfo can be found.

        """
        namespaces = [".treeinfo", "treeinfo"]
        for namespace in namespaces:
            treeinfo = PulpTreeInfo()
            try:
                treeinfo.load(f=os.path.join(
                    self.pulp2content.pulp2_storage_path, namespace))
            except FileNotFoundError:
                continue
            self.filename = namespace
            treeinfo_parsed = treeinfo.parsed_sections()
            treeinfo_serialized = TreeinfoData(treeinfo_parsed).to_dict(
                filename=namespace)
            # Pulp 2 only knows about the top level kickstart repository
            treeinfo_serialized["repositories"] = {'.': None}
            # Pulp 2 did not support addon repositories, so we should not list them here either
            treeinfo_serialized['addons'] = {}
            # Pulp 2 only supported variants that are in the root of the repository
            variants = {}
            for name, variant in treeinfo_serialized['variants'].items():
                if variant['repository'] == '.':
                    variants[name] = variant
            treeinfo_serialized['variants'] = variants
            # Reset build_timestamp so Pulp will fetch all the addons during the next sync
            treeinfo_serialized['distribution_tree']['build_timestamp'] = 0
            return treeinfo_serialized

        return None
예제 #2
0
    def get_treeinfo_serialized(self):
        """
        Create a Pulp 3 Distribution content for saving later in a bulk operation.

        Returns:
            dict: a serialized treeinfo data, or None if no treeinfo can be found.

        """
        namespaces = [".treeinfo", "treeinfo"]
        for namespace in namespaces:
            treeinfo = PulpTreeInfo()
            treeinfo_path = os.path.join(
                self.pulp2content.pulp2_storage_path, namespace
            )
            try:
                treeinfo.load(f=treeinfo_path)
            except FileNotFoundError:
                continue

            with open(treeinfo_path, "rb") as treeinfo_fd:
                treeinfo_digest = hashlib.sha256(treeinfo_fd.read()).hexdigest()
            self.filename = namespace
            treeinfo_parsed = treeinfo.parsed_sections()
            treeinfo_serialized = TreeinfoData(treeinfo_parsed).to_dict(
                filename=namespace
            )
            # Pulp 2 only knows about the top level kickstart repository
            treeinfo_serialized["repositories"] = {".": None}
            # Pulp 2 did not support addon repositories, so we should not list them here either
            treeinfo_serialized["addons"] = {}
            # Pulp 2 only supported variants that are in the root of the repository
            variants = {}
            for name, variant in treeinfo_serialized["variants"].items():
                if variant["repository"] == ".":
                    variants[name] = variant
            treeinfo_serialized["variants"] = variants
            # Set older timestamp so Pulp will fetch all the addons during the next sync
            # We can't reset it to 0, some creative repository providers use the same
            # name/release in many distribution trees and the only way to distinguish tem is by
            # the build timestamp. e.g. CentOS 8 BaseOs, Appstream, PowerTools, HighAvailability.
            orig_build_timestamp = int(
                float(treeinfo_serialized["distribution_tree"]["build_timestamp"])
            )
            treeinfo_serialized["distribution_tree"]["build_timestamp"] = (
                orig_build_timestamp - 1
            )
            treeinfo_serialized["distribution_tree"]["digest"] = treeinfo_digest
            return treeinfo_serialized

        return None
예제 #3
0
    def handle_sub_repos(self, distribution_tree):
        """
        Get sub-repo content and publish them.

        Args:
            distribution_tree (pulp_rpm.models.DistributionTree): A distribution_tree object.

        """
        original_treeinfo_content_artifact = distribution_tree.contentartifact_set.get(
            relative_path__in=[".treeinfo", "treeinfo"]
        )
        artifact_file = storage.open(original_treeinfo_content_artifact.artifact.file.name)
        with tempfile.NamedTemporaryFile("wb", dir=".") as temp_file:
            shutil.copyfileobj(artifact_file, temp_file)
            temp_file.flush()
            treeinfo = PulpTreeInfo()
            treeinfo.load(f=temp_file.name)
            treeinfo_data = TreeinfoData(treeinfo.parsed_sections())

            # rewrite the treeinfo file such that the variant repository and package location
            # is a relative subtree
            treeinfo.rewrite_subrepo_paths(treeinfo_data)

            # TODO: better way to do this?
            main_variant = treeinfo.original_parser._sections.get("general", {}).get(
                "variant", None
            )
            treeinfo_file = tempfile.NamedTemporaryFile(dir=".")
            treeinfo.dump(treeinfo_file.name, main_variant=main_variant)
            with open(treeinfo_file.name, "rb") as treeinfo_fd:
                PublishedMetadata.create_from_file(
                    relative_path=original_treeinfo_content_artifact.relative_path,
                    publication=self.publication,
                    file=File(treeinfo_fd),
                )
        artifact_file.close()
        relations = ["addon", "variant"]
        for relation in relations:
            addons_or_variants = getattr(distribution_tree, f"{relation}s").all()
            for addon_or_variant in addons_or_variants:
                if not addon_or_variant.repository:
                    # a variant of the main repo
                    continue
                repository = addon_or_variant.repository.cast()
                repository_version = repository.latest_version()

                if repository_version and repository.user_hidden:
                    addon_or_variant_id = getattr(addon_or_variant, f"{relation}_id")
                    self.sub_repos.append(
                        (
                            addon_or_variant_id,
                            repository_version.content,
                            repository.original_checksum_types,
                        )
                    )
예제 #4
0
    def handle_sub_repos(self, distribution_tree):
        """
        Get sub-repo content and publish them.

        Args:
            distribution_tree (pulp_rpm.models.DistributionTree): A distribution_tree object.

        """
        original_treeinfo_content_artifact = distribution_tree.contentartifact_set.get(
            relative_path__in=[".treeinfo", "treeinfo"])
        artifact_file = storage.open(
            original_treeinfo_content_artifact.artifact.file.name)
        with NamedTemporaryFile("wb") as temp_file:
            shutil.copyfileobj(artifact_file, temp_file)
            temp_file.flush()
            treeinfo = PulpTreeInfo()
            treeinfo.load(f=temp_file.name)
            treeinfo_parsed = treeinfo.parsed_sections()
            treeinfodata = TreeinfoData(treeinfo_parsed)
            for variant in treeinfo.variants.get_variants():
                variant.paths.repository = treeinfodata.variants[
                    variant.id]["repository"]
                variant.paths.packages = treeinfodata.variants[
                    variant.id]["packages"]
            treeinfo_file = NamedTemporaryFile()
            treeinfo.dump(treeinfo_file.name)
            PublishedMetadata.create_from_file(
                relative_path=original_treeinfo_content_artifact.relative_path,
                publication=self.publication,
                file=File(open(treeinfo_file.name, "rb")),
            )
        relations = ["addon", "variant"]
        for relation in relations:
            addons_or_variants = getattr(distribution_tree,
                                         f"{relation}s").all()
            for addon_or_variant in addons_or_variants:
                if not addon_or_variant.repository:
                    # a variant of the main repo
                    continue
                repository = addon_or_variant.repository.cast()
                repository_version = repository.latest_version()

                if repository_version and repository.sub_repo:
                    addon_or_variant_id = getattr(addon_or_variant,
                                                  f"{relation}_id")
                    self.sub_repos.append((
                        addon_or_variant_id,
                        repository_version.content,
                        repository.original_checksum_types,
                    ))