Add support for pushing and pulling schema 2 manifests with remote layers
This is required for windows image support
This commit is contained in:
parent
d97055e2ba
commit
37b20010aa
19 changed files with 339 additions and 29 deletions
|
|
@ -136,6 +136,10 @@ class DockerSchema2Manifest(ManifestInterface):
|
|||
except ValidationError as ve:
|
||||
raise MalformedSchema2Manifest('manifest data does not match schema: %s' % ve)
|
||||
|
||||
for layer in self.layers:
|
||||
if layer.is_remote and not layer.urls:
|
||||
raise MalformedSchema2Manifest('missing `urls` for remote layer')
|
||||
|
||||
@property
|
||||
def schema_version(self):
|
||||
return 2
|
||||
|
|
@ -169,18 +173,39 @@ class DockerSchema2Manifest(ManifestInterface):
|
|||
def leaf_layer(self):
|
||||
return self.layers[-1]
|
||||
|
||||
@property
|
||||
def has_remote_layer(self):
|
||||
for layer in self.layers:
|
||||
if layer.is_remote:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
@property
|
||||
def leaf_layer_v1_image_id(self):
|
||||
# NOTE: If there exists a layer with remote content, then we consider this manifest
|
||||
# to not support legacy images.
|
||||
if self.has_remote_layer:
|
||||
return None
|
||||
|
||||
return list(self.layers_with_v1_ids)[-1].v1_id
|
||||
|
||||
@property
|
||||
def legacy_image_ids(self):
|
||||
if self.has_remote_layer:
|
||||
return None
|
||||
|
||||
return [l.v1_id for l in self.layers_with_v1_ids]
|
||||
|
||||
@property
|
||||
def blob_digests(self):
|
||||
return [str(layer.digest) for layer in self.layers] + [str(self.config.digest)]
|
||||
|
||||
@property
|
||||
def local_blob_digests(self):
|
||||
return ([str(layer.digest) for layer in self.layers if not layer.urls] +
|
||||
[str(self.config.digest)])
|
||||
|
||||
def get_manifest_labels(self, lookup_config_fn):
|
||||
return self._get_built_config(lookup_config_fn).labels
|
||||
|
||||
|
|
@ -218,6 +243,7 @@ class DockerSchema2Manifest(ManifestInterface):
|
|||
|
||||
@property
|
||||
def layers_with_v1_ids(self):
|
||||
assert not self.has_remote_layer
|
||||
digest_history = hashlib.sha256()
|
||||
v1_layer_parent_id = None
|
||||
v1_layer_id = None
|
||||
|
|
@ -240,6 +266,7 @@ class DockerSchema2Manifest(ManifestInterface):
|
|||
this schema. The `lookup_config_fn` is a function that, when given the config
|
||||
digest SHA, returns the associated configuration JSON bytes for this schema.
|
||||
"""
|
||||
assert not self.has_remote_layer
|
||||
schema2_config = self._get_built_config(lookup_config_fn)
|
||||
|
||||
# Build the V1 IDs for the layers.
|
||||
|
|
@ -253,6 +280,8 @@ class DockerSchema2Manifest(ManifestInterface):
|
|||
return v1_builder
|
||||
|
||||
def generate_legacy_layers(self, images_map, lookup_config_fn):
|
||||
assert not self.has_remote_layer
|
||||
|
||||
# NOTE: We use the DockerSchema1ManifestBuilder here because it already contains
|
||||
# the logic for generating the DockerV1Metadata. All of this will go away once we get
|
||||
# rid of legacy images in the database, so this is a temporary solution.
|
||||
|
|
@ -261,6 +290,9 @@ class DockerSchema2Manifest(ManifestInterface):
|
|||
return v1_builder.build().generate_legacy_layers(images_map, lookup_config_fn)
|
||||
|
||||
def get_v1_compatible_manifest(self, namespace_name, repo_name, tag_name, lookup_fn):
|
||||
if self.has_remote_layer:
|
||||
return None
|
||||
|
||||
v1_builder = DockerSchema1ManifestBuilder(namespace_name, repo_name, tag_name)
|
||||
self.populate_schema1_builder(v1_builder, lookup_fn)
|
||||
return v1_builder.build()
|
||||
|
|
|
|||
Reference in a new issue