Fix conversion of schema 2 manifests to schema 1 manifests

Also adds a number of conversion tests and clarify the interfaces a bit more
This commit is contained in:
Joseph Schorr 2018-11-21 17:23:52 +02:00
parent bd79eaa38f
commit c233760007
11 changed files with 457 additions and 183 deletions

View file

@ -38,24 +38,24 @@ class ManifestInterface(object):
does not support layers. """
pass
@abstractproperty
def leaf_layer_v1_image_id(self):
""" Returns the Docker V1 image ID for the leaf (top) layer, if any, or None if
not applicable. """
pass
@abstractproperty
def legacy_image_ids(self):
""" Returns the Docker V1 image IDs for the layers of this manifest or None if not applicable.
"""
pass
@abstractproperty
def layers_compressed_size(self):
""" Returns the total compressed size of all the layers in this manifest. Returns None if this
cannot be computed locally.
"""
@abstractmethod
def get_leaf_layer_v1_image_id(self, content_retriever):
""" Returns the Docker V1 image ID for the leaf (top) layer, if any, or None if
not applicable. """
pass
@abstractmethod
def get_legacy_image_ids(self, content_retriever):
""" Returns the Docker V1 image IDs for the layers of this manifest or None if not applicable.
"""
pass
@abstractproperty
def blob_digests(self):
""" Returns an iterator over all the blob digests referenced by this manifest,
@ -86,10 +86,15 @@ class ManifestInterface(object):
def unsigned(self):
""" Returns an unsigned version of this manifest. """
@abstractproperty
def has_legacy_image(self):
""" Returns True if this manifest has a legacy V1 image, or False if not. """
@abstractmethod
def generate_legacy_layers(self, images_map, content_retriever):
"""
Rewrites Docker v1 image IDs and returns a generator of DockerV1Metadata.
Rewrites Docker v1 image IDs and returns a generator of DockerV1Metadata, starting
at the base layer and working towards the leaf.
If Docker gives us a layer with a v1 image ID that already points to existing
content, but the checksums don't match, then we need to rewrite the image ID
@ -99,15 +104,16 @@ class ManifestInterface(object):
"""
@abstractmethod
def get_v1_compatible_manifest(self, namespace_name, repo_name, tag_name, content_retriever):
""" Returns the manifest that is compatible with V1, by virtue of being `amd64` and `linux`.
def get_schema1_manifest(self, namespace_name, repo_name, tag_name, content_retriever):
""" Returns a schema1 version of the manifest. If this is a mainfest list, should return the
manifest that is compatible with V1, by virtue of being `amd64` and `linux`.
If none, returns None.
"""
@add_metaclass(ABCMeta)
class ContentRetriever(object):
""" Defines the interface for retrieval of various content referneced by a manifest. """
""" Defines the interface for retrieval of various content referenced by a manifest. """
@abstractmethod
def get_manifest_bytes_with_digest(self, digest):
""" Returns the bytes of the manifest with the given digest or None if none found. """