Add missing size to image configs
This is related to an incompatibility between docker and podman. "docker build" produces image manifests that look like this: {'config': {'digest': 'sha256:abc', 'mediaType': 'application/vnd.docker.container.image.v1+json'}, 'layers': [{'digest': 'sha256:def', 'mediaType': 'application/vnd.docker.image.rootfs.diff.tar.gzip', 'size': 5678}, ... "podman build" manifests look like this: {'config': {'digest': 'sha256:abc', 'mediaType': 'application/vnd.docker.container.image.v1+json', 'size': 1234}, 'layers': [{'digest': 'sha256:def', 'mediaType': 'application/vnd.docker.image.rootfs.diff.tar.gzip', 'size': 5678}, ... Podman includes the size attribute for the image config, but Docker does not. If you "docker build" and "docker push" to a zuul-registry, and then "podman pull" from it, it will fail because of the missing size. One solution to this would be to simply "podman build" instead of "docker build". That's probably best. But somehow, when the result of "docker build" is pushed to Docker Hub, and then that is used with "podman pull", it works. We can surmise that Docker Hub is correcting the manifest with the missing data in that case. To maintain compatability, let's do the same. Also, add a missing content-type header on blob GETs. This doesn't seem to be important, but it's more correct. Change-Id: I0db0dbf9775b02438880624bcf98d2b8f4d2575c
This commit is contained in:
parent
0d97c0738e
commit
8f2629ed85
@ -224,6 +224,7 @@ class RegistryAPI:
|
||||
return self.not_found()
|
||||
res = cherrypy.response
|
||||
res.headers['Docker-Content-Digest'] = digest
|
||||
res.headers['Content-Type'] = 'application/octet-stream'
|
||||
if size is not None:
|
||||
res.headers['Content-Length'] = str(size)
|
||||
return data_iter
|
||||
@ -294,11 +295,31 @@ class RegistryAPI:
|
||||
res.headers['Content-Length'] = '0'
|
||||
res.status = '201 Created'
|
||||
|
||||
def _fix_manifest(self, namespace, content_type, body):
|
||||
# The "docker build" commande can produce a manifest with a
|
||||
# config that lacks a size attribute. It appears that Docker
|
||||
# Hub will silently add the size, so any image fetched from
|
||||
# there will have it. Podman build produces image configs
|
||||
# with the size attribute. The podman family of tools fails
|
||||
# to pull images without a config size. To avoid this error,
|
||||
# we emulate the Docker Hub behavior.
|
||||
if (content_type ==
|
||||
'application/vnd.docker.distribution.manifest.v2+json'):
|
||||
data = json.loads(body)
|
||||
if 'size' not in data['config']:
|
||||
digest = data['config']['digest']
|
||||
size = self.storage.blob_size(namespace, digest)
|
||||
data['config']['size'] = size
|
||||
body = json.dumps(data).encode('utf8')
|
||||
return body
|
||||
|
||||
@cherrypy.expose
|
||||
@cherrypy.config(**{'tools.check_auth.level': Authorization.WRITE})
|
||||
def put_manifest(self, repository, ref):
|
||||
namespace, repository = self.get_namespace(repository)
|
||||
body = cherrypy.request.body.read()
|
||||
content_type = cherrypy.request.headers['Content-Type']
|
||||
body = self._fix_manifest(namespace, content_type, body)
|
||||
hasher = hashlib.sha256()
|
||||
hasher.update(body)
|
||||
digest = 'sha256:' + hasher.hexdigest()
|
||||
|
Loading…
x
Reference in New Issue
Block a user