Do not allow incorrect sized layers
This is a partial revert of I70a7bb5f73d1dddc540e96529784bb8c9bb0b9e3 The off-by-one error turned out to come from our range response (I1fb1abf3c76ea8db7820caa90c97ddbf92997842). There are no clients we know of that send an incorrect size in the manifest; we should error if we see that. Revert the adding of layer sizes done with Id5b1c5726fbe046b2f9f2994bf34f5fd7ecd90de and replace it with a hard error. I have tested both docker and podman pushes against this change and both correctly set a size for each layer in the manifest per [1]. Although I can not replicate it, the missing sizes might have already been fixed upstream, or related to the aforementioned off-by-one response we were giving. [1] https://docs.docker.com/registry/spec/manifest-v2-2/#manifest-list-field-descriptions Change-Id: Ibe061171bfd8ab6043b491bbab933bf277f8e12b
This commit is contained in:
parent
ce2fb31a72
commit
b88539964d
@ -21,8 +21,3 @@ registry:
|
||||
storage:
|
||||
driver: filesystem
|
||||
root: /tmp/storage
|
||||
# Check the size of layers matches the size specified in the
|
||||
# container manifest. Some versions of docker can push invalid
|
||||
# manifests (and *also* don't care about a size mismatch when
|
||||
# pulling); set this to false to ignore layer-size mismatches.
|
||||
strict: true
|
||||
|
@ -323,38 +323,23 @@ class RegistryAPI:
|
||||
data['config']['size'] = size
|
||||
changed = True
|
||||
|
||||
# Validate layer sizes
|
||||
for layer in data['layers']:
|
||||
digest = layer['digest']
|
||||
actual_size = self.storage.blob_size(namespace, digest)
|
||||
|
||||
# As above, we may or may not have a size for layers. If
|
||||
# this layer doesn't have a size, add it.
|
||||
if 'size' not in layer:
|
||||
layer['size'] = actual_size
|
||||
changed = True
|
||||
continue
|
||||
|
||||
# However, if we got a size, we validate it
|
||||
msg = ('Client push error: layer %s missing size ' % digest)
|
||||
raise cherrypy.HTTPError(400, msg)
|
||||
size = layer['size']
|
||||
if size == actual_size:
|
||||
continue
|
||||
|
||||
msg = ("Manifest has invalid size for layer %s "
|
||||
"(size:%d actual:%d)" % (digest, size, actual_size))
|
||||
self.log.error(msg)
|
||||
# Docker pushes a manifest with sizes one byte larger
|
||||
# than it actaully sends. We choose to ignore this.
|
||||
# https://github.com/docker/for-linux/issues/1296
|
||||
if ('docker/' in request.headers.get('User-Agent', '')
|
||||
and (actual_size + 1 == size)):
|
||||
self.log.info("Fix docker layer size for %s" % digest)
|
||||
layer['size'] = actual_size
|
||||
changed = True
|
||||
elif self.conf.get('strict', True):
|
||||
# We don't delete layers here as they may be used by
|
||||
# different images with valid manifests. Return an error to
|
||||
# the client so it can try again.
|
||||
raise cherrypy.HTTPError(400, msg)
|
||||
# We don't delete layers here as they may be used by
|
||||
# different images with valid manifests. Return an error to
|
||||
# the client so it can try again.
|
||||
raise cherrypy.HTTPError(400, msg)
|
||||
|
||||
if changed:
|
||||
body = json.dumps(data).encode('utf8')
|
||||
|
Loading…
Reference in New Issue
Block a user