Merge pull request #3249 from quay/fix-aci
Fix ACI conversion and add a registry test for it
This commit is contained in:
commit
6d5489b254
4 changed files with 74 additions and 7 deletions
|
@ -1,5 +1,6 @@
|
|||
import logging
|
||||
import hashlib
|
||||
import json
|
||||
import logging
|
||||
|
||||
from flask import redirect, Blueprint, abort, send_file, make_response, request
|
||||
|
||||
|
@ -350,7 +351,14 @@ def _repo_verb(namespace, repository, tag_name, verb, formatter, sign=False, che
|
|||
|
||||
def os_arch_checker(os, arch):
|
||||
def checker(tag, manifest):
|
||||
image_json = manifest.leaf_layer.v1_metadata
|
||||
try:
|
||||
image_json = json.loads(manifest.get_parsed_manifest().leaf_layer.raw_v1_metadata)
|
||||
except ValueError:
|
||||
logger.exception('Could not parse leaf layer JSON for manifest %s', manifest)
|
||||
return False
|
||||
except TypeError:
|
||||
logger.exception('Could not parse leaf layer JSON for manifest %s', manifest)
|
||||
return False
|
||||
|
||||
# Verify the architecture and os.
|
||||
operating_system = image_json.get('os', 'linux')
|
||||
|
|
|
@ -21,7 +21,8 @@ class AppCImageFormatter(TarImageFormatter):
|
|||
def stream_generator(self, tag, manifest, synthetic_image_id, layer_iterator,
|
||||
tar_stream_getter_iterator, reporter=None):
|
||||
image_mtime = 0
|
||||
created = manifest.get_parsed_manifest().created_datetime
|
||||
parsed_manifest = manifest.get_parsed_manifest()
|
||||
created = parsed_manifest.created_datetime
|
||||
if created is not None:
|
||||
image_mtime = calendar.timegm(created.utctimetuple())
|
||||
|
||||
|
@ -32,7 +33,7 @@ class AppCImageFormatter(TarImageFormatter):
|
|||
# Yield the manifest.
|
||||
aci_manifest = json.dumps(DockerV1ToACIManifestTranslator.build_manifest(
|
||||
tag,
|
||||
manifest,
|
||||
parsed_manifest,
|
||||
synthetic_image_id
|
||||
))
|
||||
yield self.tar_file('manifest', aci_manifest, mtime=image_mtime)
|
||||
|
@ -172,7 +173,7 @@ class DockerV1ToACIManifestTranslator(object):
|
|||
@staticmethod
|
||||
def build_manifest(tag, manifest, synthetic_image_id):
|
||||
""" Builds an ACI manifest of an existing repository image. """
|
||||
docker_layer_data = JSONPathDict(manifest.leaf_layer.v1_metadata)
|
||||
docker_layer_data = JSONPathDict(json.loads(manifest.leaf_layer.raw_v1_metadata))
|
||||
config = docker_layer_data['config'] or JSONPathDict({})
|
||||
|
||||
namespace = tag.repository.namespace_name
|
||||
|
@ -209,7 +210,7 @@ class DockerV1ToACIManifestTranslator(object):
|
|||
"labels": [
|
||||
{
|
||||
"name": "version",
|
||||
"value": tag,
|
||||
"value": tag.name,
|
||||
},
|
||||
{
|
||||
"name": "arch",
|
||||
|
|
|
@ -33,7 +33,7 @@ def sized_images():
|
|||
Image(id='parentid', bytes=parent_bytes, parent_id=None, size=len(parent_bytes),
|
||||
config={'foo': 'bar'}),
|
||||
Image(id='someid', bytes=image_bytes, parent_id='parentid', size=len(image_bytes),
|
||||
config={'foo': 'childbar'}),
|
||||
config={'foo': 'childbar', 'Entrypoint': ['hello']}),
|
||||
]
|
||||
|
||||
|
||||
|
|
|
@ -950,6 +950,8 @@ def test_multilayer_squashed_images(use_estimates, pusher, multi_layer_images, l
|
|||
|
||||
# Pull the squashed version.
|
||||
response = liveserver_session.get('/c1/squash/devtable/newrepo/latest', auth=credentials)
|
||||
assert response.status_code == 200
|
||||
|
||||
tar = tarfile.open(fileobj=StringIO(response.content))
|
||||
|
||||
# Verify the squashed image.
|
||||
|
@ -1002,6 +1004,8 @@ def test_squashed_images(use_estimates, pusher, sized_images, liveserver_session
|
|||
|
||||
# Pull the squashed version.
|
||||
response = liveserver_session.get('/c1/squash/devtable/newrepo/latest', auth=credentials)
|
||||
assert response.status_code == 200
|
||||
|
||||
tar = tarfile.open(fileobj=StringIO(response.content))
|
||||
|
||||
# Verify the squashed image.
|
||||
|
@ -1030,6 +1034,60 @@ def test_squashed_images(use_estimates, pusher, sized_images, liveserver_session
|
|||
assert tar.extractfile('contents').read() == 'some contents'
|
||||
|
||||
|
||||
EXPECTED_ACI_MANIFEST = {
|
||||
"acKind": "ImageManifest",
|
||||
"app": {
|
||||
"environment": [],
|
||||
"mountPoints": [],
|
||||
"group": "root",
|
||||
"user": "root",
|
||||
"workingDirectory": "/",
|
||||
"exec": [u'/bin/sh', u'-c', u'""hello""'],
|
||||
"isolators": [],
|
||||
"eventHandlers": [],
|
||||
"ports": [],
|
||||
"annotations": [
|
||||
{"name": "created", "value": ""},
|
||||
{"name": "homepage", "value": "http://localhost:5000/devtable/newrepo:latest"},
|
||||
{"name": "quay.io/derived-image",
|
||||
"value": "035333848582cdb72d2bac4a0809bc7eed9d88004cfb3463562013fce53c2499"},
|
||||
]
|
||||
},
|
||||
"labels": [
|
||||
{"name": "version", "value": "latest"},
|
||||
{"name": "arch", "value": "amd64"},
|
||||
{"name": "os", "value": "linux"}
|
||||
],
|
||||
"acVersion": "0.6.1",
|
||||
"name": "localhost/devtable/newrepo",
|
||||
}
|
||||
|
||||
|
||||
def test_aci_conversion(pusher, sized_images, liveserver_session,
|
||||
liveserver, registry_server_executor, app_reloader):
|
||||
""" Test: Pulling of ACI converted images. """
|
||||
credentials = ('devtable', 'password')
|
||||
|
||||
# Push an image to download.
|
||||
pusher.push(liveserver_session, 'devtable', 'newrepo', 'latest', sized_images,
|
||||
credentials=credentials)
|
||||
|
||||
# Pull the ACI version.
|
||||
response = liveserver_session.get('/c1/aci/server_name/devtable/newrepo/latest/aci/linux/amd64',
|
||||
auth=credentials)
|
||||
assert response.status_code == 200
|
||||
tar = tarfile.open(fileobj=StringIO(response.content))
|
||||
assert set(tar.getnames()) == {'manifest', 'rootfs', 'rootfs/contents'}
|
||||
|
||||
assert tar.extractfile('rootfs/contents').read() == 'some contents'
|
||||
assert json.loads(tar.extractfile('manifest').read()) == EXPECTED_ACI_MANIFEST
|
||||
|
||||
# Pull the ACI signature.
|
||||
response = liveserver_session.get('/c1/aci/server_name/devtable/newrepo/latest/aci.asc/linux/amd64',
|
||||
auth=credentials)
|
||||
assert response.status_code == 200
|
||||
|
||||
|
||||
@pytest.mark.parametrize('push_user, push_namespace, push_repo, mount_repo_name, expected_failure', [
|
||||
# Successful mount, same namespace.
|
||||
('devtable', 'devtable', 'baserepo', 'devtable/baserepo', None),
|
||||
|
|
Reference in a new issue