def parse_manifest_from_bytes(manifest_bytes, media_type, validate=True): """ Parses and returns a manifest from the given bytes, for the given media type. Raises a ManifestException if the parse fails for some reason. """ assert isinstance(manifest_bytes, Bytes) if media_type == DOCKER_SCHEMA2_MANIFEST_CONTENT_TYPE: return DockerSchema2Manifest(manifest_bytes) if media_type == DOCKER_SCHEMA2_MANIFESTLIST_CONTENT_TYPE: return DockerSchema2ManifestList(manifest_bytes) if media_type == OCI_IMAGE_MANIFEST_CONTENT_TYPE: return OCIManifest(manifest_bytes) if media_type == OCI_IMAGE_INDEX_CONTENT_TYPE: return OCIIndex(manifest_bytes) if media_type in DOCKER_SCHEMA1_CONTENT_TYPES: return DockerSchema1Manifest(manifest_bytes, validate=validate) raise ManifestException("Unknown or unsupported manifest media type `%s`" % media_type)
def __init__(self, manifest_bytes: Bytes, validate=False): assert isinstance(manifest_bytes, Bytes) self._payload = manifest_bytes try: self._parsed = json.loads(self._payload.as_unicode()) except ValueError as e: raise ManifestException(f"malformed manifest data: {e}")
def get_schema1_parsed_manifest(self, manifest, namespace_name, repo_name, tag_name, storage, raise_on_error=False): if raise_on_error: raise ManifestException("manifest is not acceptable by the client") return None
def _load_manifest(self): digest = self._manifest_data[self._digest_key] size = self._manifest_data[self._size_key] manifest_bytes = self._content_retriever.get_manifest_bytes_with_digest( digest) if manifest_bytes is None: raise ManifestException( "Could not find child manifest with digest `%s`" % digest) if len(manifest_bytes) != size: raise ManifestException( "Size of manifest does not match that retrieved: %s vs %s", len(manifest_bytes), size, ) content_type = self._manifest_data[self._media_type_key] if content_type not in self._supported_types: raise ManifestException( "Unknown or unsupported manifest media type `%s`" % content_type) return self._supported_types[content_type]( Bytes.for_string_or_unicode(manifest_bytes), validate=False)
def validate(self, content_retriever): """ Performs validation of required assertions about the manifest. Raises a ManifestException on failure. """ # Validate the parent image IDs. encountered_ids = set() for layer in self.layers: if layer.v1_metadata.parent_image_id: if layer.v1_metadata.parent_image_id not in encountered_ids: raise ManifestException("Unknown parent image %s" % layer.v1_metadata.parent_image_id) if layer.v1_metadata.image_id: encountered_ids.add(layer.v1_metadata.image_id)