def test_get_manifest(archive_changeset: ArchiveChangeset,
                      image_name: ImageName):
    """Test manifest retrieval."""
    manifest = archive_changeset.get_manifest(image_name)
    if image_name.resolve_digest():
        assert manifest.get_config_digest() == image_name.resolve_digest()
    if image_name.tag:
        assert ArchiveChangeset.get_repository_tag(
            image_name) in manifest.get_tags()
    async def sign_image(
        self,
        signer: Signer,
        src_image_name: ImageName,
        dest_image_source: ImageSource,
        dest_image_name: ImageName,
        signature_type: SignatureTypes = SignatureTypes.SIGN,
        **kwargs,
    ) -> ImageSourceSignImage:
        LOGGER.debug(
            "%s: %s ...",
            "Endorsing"
            if signature_type == SignatureTypes.ENDORSE else "Signing"
            if signature_type == SignatureTypes.SIGN else "Resigning",
            src_image_name.resolve_name(),
        )

        dest_image_name = dest_image_name.clone()
        if dest_image_name.resolve_digest():
            dest_image_name.digest = None
            LOGGER.warning(
                "It is not possible to store a signed image to a predetermined digest! Adjusted destination: %s",
                dest_image_name.resolve_name(),
            )

        # Generate a signed image configuration ...
        data = await self._sign_image_config(signer, src_image_name,
                                             signature_type, **kwargs)
        LOGGER.debug("    Signature:\n%s", data.signature_value)
        image_config = data.image_config
        config_digest = image_config.get_digest()
        LOGGER.debug("    config digest (signed): %s", config_digest)

        # Generate a new registry manifest ...
        manifest = data.verify_image_data.manifest.clone()
        manifest.set_config_digest(config_digest,
                                   len(image_config.get_bytes()))
        data = ImageSourceSignImage(
            image_config=data.image_config,
            manifest_signed=manifest,
            signature_value=data.signature_value,
            verify_image_data=data.verify_image_data,
        )

        await dest_image_source.put_image(
            self,
            dest_image_name,
            manifest,
            image_config,
            data.verify_image_data.compressed_layer_files,
            **kwargs,
        )

        dest_image_name.digest = manifest.get_digest()

        if not self.dry_run:
            LOGGER.debug("Created new image: %s",
                         dest_image_name.resolve_name())

        return data
Example #3
0
async def replicate_manifest_lists(
        docker_registry_secure: DockerRegistrySecure):
    """Replicates manifests lists to the secure docker registry for testing."""
    # pylint: disable=protected-access
    LOGGER.debug("Replicating manifest lists into %s ...",
                 docker_registry_secure.service_name)
    async with DockerRegistryClientAsync() as docker_registry_client_async:
        for image in get_test_data_registryv2():
            if "tag_resolves_to_manifest_list" not in image:
                continue

            digest = image["digests"][
                DockerMediaTypes.DISTRIBUTION_MANIFEST_LIST_V2]
            image_name = ImageName(image["image"],
                                   digest=digest,
                                   tag=image["tag"])
            LOGGER.debug("- %s", image_name)

            scope = DockerAuthentication.SCOPE_REPOSITORY_PULL_PATTERN.format(
                image_name.image)
            auth_header_src = await docker_registry_client_async._get_request_headers(
                image_name, scope=scope)
            if not auth_header_src:
                LOGGER.warning(
                    "Unable to retrieve authentication headers for: %s",
                    image_name)

            pdrf_image_name = PDRFImageName(
                image_name.resolve_image(),
                digest=image_name.resolve_digest(),
                endpoint=image_name.resolve_endpoint(),
                tag=image_name.resolve_tag(),
            )
            try:
                replicate_manifest_list(
                    pdrf_image_name,
                    docker_registry_secure.endpoint,
                    auth_header_dest=docker_registry_secure.auth_header,
                    auth_header_src=auth_header_src,
                    ssl_context_dest=docker_registry_secure.ssl_context,
                )
            except Exception as exception:  # pylint: disable=broad-except
                LOGGER.warning(
                    "Unable to replicate manifest list '%s': %s",
                    image_name,
                    exception,
                    exc_info=True,
                )
    async def put_image_config(self, image_name: ImageName,
                               image_config: ImageConfig, **kwargs):
        image_name = image_name.clone()
        if image_name.resolve_digest():
            image_name.digest = None
            LOGGER.debug(
                "It is not possible to store an image configuration to a non-deterministic digest!"
                " Adjusted destination: %s",
                image_name.resolve_name(),
            )

        image_config_digest = image_config.get_digest()
        name = f"{image_config_digest.sha256}.json"
        if not await self._file_exists(name):
            with open(self.archive, "rb+") as file_out:
                tar_add_file(file_out, name, image_config.get_bytes())
Example #5
0
def test_get_layers(archive_manifest: ArchiveManifest, image_name: ImageName):
    """Test manifest layer retrieval."""
    if (image_name.resolve_digest(
    ) == "sha256:a51f3f9281a1a3d89dce25fec8acffbe9f59ddb67d98e04245c4c886e32d3782"
        ):
        assert archive_manifest.get_layers(image_name) == [
            "sha256:137120c8596a15ab42c39c0c5cf83ef864b6b65b5516887c895915e87292bd07",
            "sha256:755520f73bc74ae73b12f53229e401e8d4c584b74f5704d2d36ba7c45e2657cf",
            "sha256:13fb089903a5e0e9b00d78ba48496da528ce8d81e08a1042ebeced8c35d714cb",
            "sha256:f86d68f70ca006025a7f7013f69898f78d1d9272c4d3909e3ec4c7f9958da20e",
            "sha256:7b4a4edd704242cec1710679a088be8aabff25c3a79f4eecbe8d11d57c53a20b",
            "sha256:ef4724d42630f3022ef67c3f6749e85a13e81b8efcf98fbd517476499f10e5ab",
        ]
    else:
        assert archive_manifest.get_layers(image_name) == [
            "sha256:2c2e149ae9a88ae6bee1583459b2d3e5e317877b795c08781fab36eab4b4329f",
            "sha256:83419ef1d0ad0520c9fc44da4345637e5c05e34fa564ddf2fb6d6f94a6b2d205",
            "sha256:c2d494c64683fb7edac60aaffc570c514c1c80c797aafcf25b8a9438690da4df",
            "sha256:d3b1a8ce509767258045f6cc050dfc8cff27f66f9fa8c61c9dc46733e492e0af",
            "sha256:0a0084e273d71f3b39100a5c209a3208fafdb90e3dd038cded5e2a54265d23fa",
        ]
    def get_manifest(self, image_name: ImageName) -> "ArchiveManifest":
        """
        Retrieves the archive manifest for a given image name from the archive changeset.

        Args:
            image_name: The image name.

        Returns:
            The corresponding archive manifest.
        """
        if image_name.digest:
            for manifest in self.get_manifests():
                if manifest.get_config_digest() == image_name.resolve_digest():
                    return manifest
        else:
            tag = ArchiveChangeset.get_repository_tag(image_name)
            for manifest in self.get_manifests():
                tags = manifest.get_tags()
                if tags and tag in manifest.get_tags():
                    return manifest
        raise RuntimeError(
            f"Unable to locate configuration in archive manifest for: {image_name.resolve_name()}"
        )
Example #7
0
async def test_get_manifest_list(
    docker_registry_secure: DockerRegistrySecure,
    image: TypingGetTestData,
    registry_v2_image_source: RegistryV2ImageSource,
    **kwargs,
):
    """Test manifest retrieval."""
    if "tag_resolves_to_manifest_list" not in image:
        pytest.skip(
            f"Image {image['image']} does not reference a manifest list.")

    image_name = ImageName(
        image["image"],
        digest=image["digests"][
            DockerMediaTypes.DISTRIBUTION_MANIFEST_LIST_V2],
        endpoint=docker_registry_secure.endpoint,
        tag=image["tag"],
    )

    LOGGER.debug("Retrieving manifest list for: %s ...", image_name)
    manifest = await registry_v2_image_source.get_manifest(
        image_name, **kwargs)
    assert isinstance(manifest, RegistryV2Manifest)
    assert manifest.get_digest() == image_name.resolve_digest()
def test_get_config_digest(archive_manifest: ArchiveManifest,
                           image_name: ImageName):
    """Test configuration digest retrieval."""
    assert archive_manifest.get_config_digest(
        image_name) == image_name.resolve_digest()
def test_remove_manifest(archive_changeset: ArchiveChangeset,
                         image_name: ImageName):
    """Test manifest removal."""
    assert len(archive_changeset.get_manifests()) == 2
    archive_changeset.remove_manifest(image_name.resolve_digest())
    assert len(archive_changeset.get_manifests()) == 1