Properly handle the empty layer when pushing schema 2 manifests

Docker doesn't send us the contents of this layer, so we are forced to synthesize it ourselves
This commit is contained in:
Joseph Schorr 2018-11-25 16:16:59 +02:00
parent 947c029afa
commit 4985040d31
13 changed files with 173 additions and 25 deletions

View file

@ -249,7 +249,21 @@ class V2Protocol(RegistryProtocol):
if options.manifest_invalid_blob_references:
checksum = 'sha256:' + hashlib.sha256('notarealthing').hexdigest()
builder.add_layer(checksum, len(image.bytes), urls=image.urls)
if not image.is_empty:
builder.add_layer(checksum, len(image.bytes), urls=image.urls)
def history_for_image(image):
history = {
'created': '2018-04-03T18:37:09.284840891Z',
'created_by': (('/bin/sh -c #(nop) ENTRYPOINT %s' % image.config['Entrypoint'])
if image.config and image.config.get('Entrypoint')
else '/bin/sh -c #(nop) %s' % image.id),
}
if image.is_empty:
history['empty_layer'] = True
return history
config = {
"os": "linux",
@ -257,12 +271,7 @@ class V2Protocol(RegistryProtocol):
"type": "layers",
"diff_ids": []
},
"history": [{
'created': '2018-04-03T18:37:09.284840891Z',
'created_by': (('/bin/sh -c #(nop) ENTRYPOINT %s' % image.config['Entrypoint'])
if image.config and image.config.get('Entrypoint')
else '/bin/sh -c #(nop) %s' % image.id),
} for image in images],
"history": [history_for_image(image) for image in images],
}
if images[-1].config:
@ -535,17 +544,28 @@ class V2Protocol(RegistryProtocol):
image_ids[tag_name] = manifest.leaf_layer_v1_image_id
# Verify the layers.
for index, layer in enumerate(manifest.layers):
layer_index = 0
empty_count = 0
for image in images:
if manifest.schema_version == 2 and image.is_empty:
empty_count += 1
continue
# If the layer is remote, then we expect the blob to *not* exist in the system.
expected_status = 404 if images[index].urls else 200
layer = manifest.layers[layer_index]
expected_status = 404 if image.urls else 200
result = self.conduct(session, 'GET',
'/v2/%s/blobs/%s' % (self.repo_name(namespace, repo_name),
layer.digest),
expected_status=expected_status,
headers=headers)
if expected_status == 200:
assert result.content == images[index].bytes
assert result.content == image.bytes
layer_index += 1
assert (len(manifest.layers) + empty_count) == len(images)
return PullResult(manifests=manifests, image_ids=image_ids)