def get_manifests(self, *, architecture: str = None, os: str = None) -> List[FormattedSHA256]: """ Retrieves the listing of manifest layer identifiers. Args: architecture: The name of the CPU architecture. os: The name of the operating system. Returns: list: Manifest identifiers in the form: <hash type>:<digest value>. """ if self.get_media_type() not in [ DockerMediaTypes.DISTRIBUTION_MANIFEST_LIST_V2, OCIMediaTypes.IMAGE_INDEX_V1, ]: raise NotImplementedError( f"Unsupported media type: {self.get_media_type()}") result = [] for manifest in self.get_json()["manifests"]: if (architecture and manifest.get("platform", "").get( "architecture", "") != architecture): continue if os and manifest.get("platform", "").get("os", "") != os: continue result.append(FormattedSHA256.parse(manifest["digest"])) return result
async def test_chunk_file(client_session: ClientSession, tmp_path: Path): """Tests that remote files can be chunked to disk.""" url = "https://tools.ietf.org/rfc/rfc2616.txt" # Hat tip digest_expected = FormattedSHA256.parse( "sha256:10211d2885196b97b1c78e1672f3f68ae97c294596ef2b7fd890cbd30a3427bf" ) size = 422279 async with client_session.get(url=url, allow_redirects=True) as client_response: path_async = tmp_path.joinpath("test_async") async with aiofiles.open(path_async, mode="w+b") as file: result = await chunk_to_file(client_response, file) assert result["client_response"] == client_response assert result["digest"] == digest_expected assert result["size"] == size digest_actual = await hash_file(path_async) assert digest_actual == digest_expected path_sync = tmp_path.joinpath("test_sync") async with client_session.get(url=url, allow_redirects=True) as client_response: with path_sync.open("w+b") as file: result = await chunk_to_file(client_response, file, file_is_async=False) assert result["client_response"] == client_response assert result["digest"] == digest_expected assert result["size"] == size digest_actual = await hash_file(path_async) assert digest_actual == digest_expected
def get_config_digest(self, image_name: ImageName = None) -> FormattedSHA256: if self.get_media_type() not in [ DockerMediaTypes.DISTRIBUTION_MANIFEST_V2, OCIMediaTypes.IMAGE_MANIFEST_V1, ]: raise NotImplementedError("Unsupported media type: {0}".format( self.get_media_type())) return FormattedSHA256.parse(self.get_json()["config"]["digest"])
def get_layers(self, image_name: ImageName = None) -> List[FormattedSHA256]: if self.get_media_type() not in [ DockerMediaTypes.DISTRIBUTION_MANIFEST_V2, OCIMediaTypes.IMAGE_MANIFEST_V1, ]: raise NotImplementedError("Unsupported media type: {0}".format( self.get_media_type())) return [ FormattedSHA256.parse(layer["digest"]) for layer in self.get_json()["layers"] ]
def get_image_layers(self) -> List[FormattedSHA256]: """ Retrieves the listing of image layer identifiers. Returns: The listing of image layer identifiers. """ # Note: We need to handle both key cases, as Microsoft does not conform to the standard. try: rootfs = self.get_json()["rootfs"] except KeyError: rootfs = self.get_json()["rootfS"] if rootfs is None: raise MalformedConfigurationError( "Unable to locate rootf[Ss] key within image configuration!", config=self, ) diff_ids = rootfs["diff_ids"] return [FormattedSHA256.parse(x) for x in diff_ids]
def get_config_digest(self, image_name: ImageName = None) -> FormattedSHA256: key = DeviceMapperRepositoryManifest._get_repository_key(image_name) image = self.get_json()["Repositories"].get(key, {}) return FormattedSHA256.parse(image.get(str(image_name), None))
def config_digest_signed_canonical(request) -> FormattedSHA256: """Provides the digest value of the canonical form of the signed sample image configuration.""" return FormattedSHA256.parse( get_test_data(request, __name__, "config_signed_canonical.json.digest", "r") )
def config_digest(request) -> FormattedSHA256: """Provides the digest value of the sample image configuration.""" return FormattedSHA256.parse( get_test_data(request, __name__, "config.json.digest", "r") )
def test_parse(): """Test that a formatted SHA256 can be parsed.""" digest = "0123456789012345678901234567890123456789012345678901234567890123" with pytest.raises(ValueError) as exc_info: FormattedSHA256.parse(digest) assert digest in str(exc_info.value) digest = "sha256:0123456789012345678901234567890123456789012345678901234567890123" formattedsha256 = FormattedSHA256.parse(digest) assert formattedsha256 assert formattedsha256.sha256 == digest[7:] # pylint: disable=no-member assert str(formattedsha256) == digest with pytest.raises(ValueError) as exc_info: FormattedSHA256.parse(None) assert "None" in str(exc_info.value) digest = "012345678901234567890123456789012345678901234567890123456789012" with pytest.raises(ValueError) as exc_info: FormattedSHA256.parse(digest) assert digest in str(exc_info.value) digest = "sha256:012345678901234567890123456789012345678901234567890123456789012" with pytest.raises(ValueError) as exc_info: FormattedSHA256.parse(digest) assert digest in str(exc_info.value) digest = "sha1:0123456789012345678901234567890123456789012345678901234567890123" with pytest.raises(ValueError) as exc_info: FormattedSHA256.parse(digest) assert digest in str(exc_info.value)