示例#1
0
 async def _handle_distribution(self, distribution):
     log.info(
         _('Downloading Release file for distribution: "{}"').format(
             distribution))
     # Create release_file
     if distribution[-1] == "/":
         release_file_dir = distribution.strip("/")
     else:
         release_file_dir = os.path.join("dists", distribution)
     release_file_dc = DeclarativeContent(
         content=ReleaseFile(distribution=distribution),
         d_artifacts=[
             self._to_d_artifact(os.path.join(release_file_dir, filename))
             for filename in ["Release", "InRelease", "Release.gpg"]
         ],
     )
     release_file = await self._create_unit(release_file_dc)
     if release_file is None:
         return
     # Create release object
     release_unit = Release(codename=release_file.codename,
                            suite=release_file.suite,
                            distribution=distribution)
     release_dc = DeclarativeContent(content=release_unit)
     release = await self._create_unit(release_dc)
     # Create release architectures
     architectures = _filter_split_architectures(release_file.architectures,
                                                 self.remote.architectures,
                                                 distribution)
     for architecture in architectures:
         release_architecture_dc = DeclarativeContent(
             content=ReleaseArchitecture(architecture=architecture,
                                         release=release))
         await self.put(release_architecture_dc)
     # Parse release file
     log.info(
         _('Parsing Release file at distribution="{}"').format(
             distribution))
     release_artifact = await _get_main_artifact_blocking(release_file)
     release_file_dict = deb822.Release(release_artifact.file)
     # collect file references in new dict
     file_references = defaultdict(deb822.Deb822Dict)
     for digest_name in ["SHA512", "SHA256", "SHA1", "MD5sum"]:
         if digest_name in release_file_dict:
             for unit in release_file_dict[digest_name]:
                 file_references[unit["Name"]].update(unit)
     await asyncio.gather(*[
         self._handle_component(component, release, release_file,
                                file_references, architectures)
         for component in _filter_split_components(
             release_file.components, self.remote.components, distribution)
     ])
示例#2
0
    async def run(self):
        """
        Build and emit `DeclarativeContent` from the Release data.
        """
        # TODO Merge into one list of futures
        future_releases = []
        future_package_indices = []
        future_installer_file_indices = []
        with ProgressReport(
                message="Creating download requests for Release files",
                code="download.release",
                total=self.num_distributions,
        ) as pb:
            for distribution in self.distributions:
                log.info(
                    'Downloading Release file for distribution: "{}"'.format(
                        distribution))
                release_relpath = os.path.join("dists", distribution,
                                               "Release")
                release_path = os.path.join(self.parsed_url.path,
                                            release_relpath)
                release_da = DeclarativeArtifact(
                    Artifact(),
                    urlunparse(self.parsed_url._replace(path=release_path)),
                    release_relpath,
                    self.remote,
                    deferred_download=False,
                )
                release_gpg_relpath = os.path.join("dists", distribution,
                                                   "Release.gpg")
                release_gpg_path = os.path.join(self.parsed_url.path,
                                                release_gpg_relpath)
                release_gpg_da = DeclarativeFailsafeArtifact(
                    Artifact(),
                    urlunparse(
                        self.parsed_url._replace(path=release_gpg_path)),
                    release_gpg_relpath,
                    self.remote,
                    deferred_download=False,
                )
                inrelease_relpath = os.path.join("dists", distribution,
                                                 "InRelease")
                inrelease_path = os.path.join(self.parsed_url.path,
                                              inrelease_relpath)
                inrelease_da = DeclarativeFailsafeArtifact(
                    Artifact(),
                    urlunparse(self.parsed_url._replace(path=inrelease_path)),
                    inrelease_relpath,
                    self.remote,
                    deferred_download=False,
                )
                release_unit = Release(distribution=distribution,
                                       relative_path=release_relpath)
                release_dc = DeclarativeContent(
                    content=release_unit,
                    d_artifacts=[release_da, release_gpg_da, inrelease_da],
                    does_batch=False,
                )
                future_releases.append(release_dc.get_or_create_future())
                await self.put(release_dc)
                pb.increment()

        with ProgressReport(message="Parsing Release files",
                            code="parsing.release",
                            total=self.num_distributions) as pb:
            for release_future in asyncio.as_completed(future_releases):
                release = await release_future
                if release is None:
                    continue
                log.info('Parsing Release file for release: "{}"'.format(
                    release.codename))
                release_artifact = release._artifacts.get(
                    sha256=release.sha256)
                release_dict = deb822.Release(release_artifact.file)
                async for d_content in self._read_release_file(
                        release, release_dict):
                    if isinstance(d_content.content, PackageIndex):
                        future_package_indices.append(
                            d_content.get_or_create_future())
                    if isinstance(d_content.content, InstallerFileIndex):
                        future_installer_file_indices.append(
                            d_content.get_or_create_future())
                    await self.put(d_content)
                pb.increment()

        with ProgressReport(message="Parsing package index files",
                            code="parsing.packageindex") as pb:
            for package_index_future in asyncio.as_completed(
                    future_package_indices):
                package_index = await package_index_future
                if package_index is None:
                    continue
                package_index_artifact = package_index.main_artifact
                log.debug("Parsing package index for {}:{}.".format(
                    package_index.component, package_index.architecture))
                async for package_dc in self._read_package_index(
                        package_index_artifact.file):
                    await self.put(package_dc)
                pb.increment()

        with ProgressReport(message="Parsing installer file index files",
                            code="parsing.installer") as pb:
            for installer_file_index_future in asyncio.as_completed(
                    future_installer_file_indices):
                installer_file_index = await installer_file_index_future
                if installer_file_index is None:
                    continue
                log.debug("Parsing installer file index for {}:{}.".format(
                    installer_file_index.component,
                    installer_file_index.architecture))
                async for d_content in self._read_installer_file_index(
                        installer_file_index):
                    await self.put(d_content)
                pb.increment()
示例#3
0
    async def _handle_distribution(self, distribution):
        log.info(
            _('Downloading Release file for distribution: "{}"').format(
                distribution))
        # Create release_file
        if distribution[-1] == "/":
            release_file_dir = distribution.strip("/")
        else:
            release_file_dir = os.path.join("dists", distribution)
        release_file_dc = DeclarativeContent(
            content=ReleaseFile(distribution=distribution),
            d_artifacts=[
                self._to_d_artifact(os.path.join(release_file_dir, filename))
                for filename in ["Release", "InRelease", "Release.gpg"]
            ],
        )
        release_file = await self._create_unit(release_file_dc)
        if release_file is None:
            return
        # Create release object
        release_unit = Release(codename=release_file.codename,
                               suite=release_file.suite,
                               distribution=distribution)
        release_dc = DeclarativeContent(content=release_unit)
        release = await self._create_unit(release_dc)
        # Create release architectures
        if release_file.architectures:
            architectures = _filter_split_architectures(
                release_file.architectures, self.remote.architectures,
                distribution)
        elif distribution[-1] == "/":
            message = (
                "The ReleaseFile content unit architecrures are unset for the flat repo with "
                "distribution '{}'. ReleaseArchitecture content creation is deferred!"
            )
            log.warning(_(message).format(distribution))
            architectures = []

        for architecture in architectures:
            release_architecture_dc = DeclarativeContent(
                content=ReleaseArchitecture(architecture=architecture,
                                            release=release))
            await self.put(release_architecture_dc)
        # Parse release file
        log.info(
            _('Parsing Release file at distribution="{}"').format(
                distribution))
        release_artifact = await _get_main_artifact_blocking(release_file)
        release_file_dict = deb822.Release(release_artifact.file)

        # Retrieve and interpret any 'No-Support-for-Architecture-all' value:
        # We will refer to the presence of 'No-Support-for-Architecture-all: Packages' in a Release
        # file as indicating "hybrid format". For more info, see:
        # https://wiki.debian.org/DebianRepository/Format#No-Support-for-Architecture-all
        no_support_for_arch_all = release_file_dict.get(
            "No-Support-for-Architecture-all", "")
        if no_support_for_arch_all.strip() == "Packages":
            hybrid_format = True
        elif not no_support_for_arch_all:
            hybrid_format = False
        else:
            raise UnknownNoSupportForArchitectureAllValue(
                release_file.relative_path, no_support_for_arch_all)

        # collect file references in new dict
        file_references = defaultdict(deb822.Deb822Dict)
        for digest_name in ["SHA512", "SHA256", "SHA1", "MD5sum"]:
            if digest_name in release_file_dict:
                for unit in release_file_dict[digest_name]:
                    file_references[unit["Name"]].update(unit)

        if distribution[-1] == "/":
            # Handle flat repo
            sub_tasks = [
                self._handle_flat_repo(file_references, release_file, release)
            ]
        else:
            # Handle components
            sub_tasks = [
                self._handle_component(
                    component,
                    release,
                    release_file,
                    file_references,
                    architectures,
                    hybrid_format,
                ) for component in _filter_split_components(
                    release_file.components, self.remote.components,
                    distribution)
            ]
        await asyncio.gather(*sub_tasks)