first steps undertaken to fix spulec/moto#1684 and spulec/moto#1685
This commit is contained in:
parent
e118a678a6
commit
3a355f126c
@ -4,12 +4,12 @@ import hashlib
|
|||||||
from copy import copy
|
from copy import copy
|
||||||
from random import random
|
from random import random
|
||||||
|
|
||||||
|
from botocore.exceptions import ParamValidationError
|
||||||
|
|
||||||
from moto.core import BaseBackend, BaseModel
|
from moto.core import BaseBackend, BaseModel
|
||||||
from moto.ec2 import ec2_backends
|
from moto.ec2 import ec2_backends
|
||||||
from moto.ecr.exceptions import ImageNotFoundException, RepositoryNotFoundException
|
from moto.ecr.exceptions import ImageNotFoundException, RepositoryNotFoundException
|
||||||
|
|
||||||
from botocore.exceptions import ParamValidationError
|
|
||||||
|
|
||||||
DEFAULT_REGISTRY_ID = '012345678910'
|
DEFAULT_REGISTRY_ID = '012345678910'
|
||||||
|
|
||||||
|
|
||||||
@ -97,13 +97,13 @@ class Repository(BaseObject):
|
|||||||
|
|
||||||
class Image(BaseObject):
|
class Image(BaseObject):
|
||||||
|
|
||||||
def __init__(self, tag, manifest, repository, registry_id=DEFAULT_REGISTRY_ID):
|
def __init__(self, tag, manifest, repository, digest=None, registry_id=DEFAULT_REGISTRY_ID):
|
||||||
self.image_tag = tag
|
self.image_tag = tag
|
||||||
self.image_manifest = manifest
|
self.image_manifest = manifest
|
||||||
self.image_size_in_bytes = 50 * 1024 * 1024
|
self.image_size_in_bytes = 50 * 1024 * 1024
|
||||||
self.repository = repository
|
self.repository = repository
|
||||||
self.registry_id = registry_id
|
self.registry_id = registry_id
|
||||||
self.image_digest = None
|
self.image_digest = digest
|
||||||
self.image_pushed_at = None
|
self.image_pushed_at = None
|
||||||
|
|
||||||
def _create_digest(self):
|
def _create_digest(self):
|
||||||
@ -115,6 +115,9 @@ class Image(BaseObject):
|
|||||||
self._create_digest()
|
self._create_digest()
|
||||||
return self.image_digest
|
return self.image_digest
|
||||||
|
|
||||||
|
def get_image_manifest(self):
|
||||||
|
return self.image_manifest
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def response_object(self):
|
def response_object(self):
|
||||||
response_object = self.gen_response_object()
|
response_object = self.gen_response_object()
|
||||||
@ -124,14 +127,14 @@ class Image(BaseObject):
|
|||||||
response_object['imageManifest'] = self.image_manifest
|
response_object['imageManifest'] = self.image_manifest
|
||||||
response_object['repositoryName'] = self.repository
|
response_object['repositoryName'] = self.repository
|
||||||
response_object['registryId'] = self.registry_id
|
response_object['registryId'] = self.registry_id
|
||||||
return response_object
|
return {k: v for k, v in response_object.items() if v is not None and v != [None]}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def response_list_object(self):
|
def response_list_object(self):
|
||||||
response_object = self.gen_response_object()
|
response_object = self.gen_response_object()
|
||||||
response_object['imageTag'] = self.image_tag
|
response_object['imageTag'] = self.image_tag
|
||||||
response_object['imageDigest'] = "i don't know"
|
response_object['imageDigest'] = "i don't know"
|
||||||
return response_object
|
return {k: v for k, v in response_object.items() if v is not None and v != [None]}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def response_describe_object(self):
|
def response_describe_object(self):
|
||||||
@ -143,7 +146,7 @@ class Image(BaseObject):
|
|||||||
response_object['registryId'] = self.registry_id
|
response_object['registryId'] = self.registry_id
|
||||||
response_object['imageSizeInBytes'] = self.image_size_in_bytes
|
response_object['imageSizeInBytes'] = self.image_size_in_bytes
|
||||||
response_object['imagePushedAt'] = '2017-05-09'
|
response_object['imagePushedAt'] = '2017-05-09'
|
||||||
return response_object
|
return {k: v for k, v in response_object.items() if v is not None and v != [None]}
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def response_batch_get_image(self):
|
def response_batch_get_image(self):
|
||||||
@ -154,7 +157,7 @@ class Image(BaseObject):
|
|||||||
response_object['imageManifest'] = self.image_manifest
|
response_object['imageManifest'] = self.image_manifest
|
||||||
response_object['repositoryName'] = self.repository
|
response_object['repositoryName'] = self.repository
|
||||||
response_object['registryId'] = self.registry_id
|
response_object['registryId'] = self.registry_id
|
||||||
return response_object
|
return {k: v for k, v in response_object.items() if v is not None and v != [None]}
|
||||||
|
|
||||||
|
|
||||||
class ECRBackend(BaseBackend):
|
class ECRBackend(BaseBackend):
|
||||||
@ -252,8 +255,14 @@ class ECRBackend(BaseBackend):
|
|||||||
else:
|
else:
|
||||||
raise Exception("{0} is not a repository".format(repository_name))
|
raise Exception("{0} is not a repository".format(repository_name))
|
||||||
|
|
||||||
image = Image(image_tag, image_manifest, repository_name)
|
existing_image = list(filter(lambda x: x.response_object['imageManifest'] == image_manifest, repository.images))
|
||||||
repository.images.append(image)
|
if not existing_image:
|
||||||
|
image = Image(image_tag, image_manifest, repository_name)
|
||||||
|
repository.images.append(image)
|
||||||
|
else:
|
||||||
|
image = Image(image_tag, image_manifest, repository_name, existing_image[0].get_image_digest())
|
||||||
|
repository.images.append(image)
|
||||||
|
|
||||||
return image
|
return image
|
||||||
|
|
||||||
def batch_get_image(self, repository_name, registry_id=None, image_ids=None, accepted_media_types=None):
|
def batch_get_image(self, repository_name, registry_id=None, image_ids=None, accepted_media_types=None):
|
||||||
|
@ -197,6 +197,54 @@ def test_put_image():
|
|||||||
response['image']['repositoryName'].should.equal('test_repository')
|
response['image']['repositoryName'].should.equal('test_repository')
|
||||||
response['image']['registryId'].should.equal('012345678910')
|
response['image']['registryId'].should.equal('012345678910')
|
||||||
|
|
||||||
|
@mock_ecr
|
||||||
|
def test_put_image_with_multiple_tags():
|
||||||
|
client = boto3.client('ecr', region_name='us-east-1')
|
||||||
|
_ = client.create_repository(
|
||||||
|
repositoryName='test_repository'
|
||||||
|
)
|
||||||
|
manifest = _create_image_manifest()
|
||||||
|
response = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(manifest),
|
||||||
|
imageTag='v1'
|
||||||
|
)
|
||||||
|
|
||||||
|
response['image']['imageId']['imageTag'].should.equal('v1')
|
||||||
|
response['image']['imageId']['imageDigest'].should.contain("sha")
|
||||||
|
response['image']['repositoryName'].should.equal('test_repository')
|
||||||
|
response['image']['registryId'].should.equal('012345678910')
|
||||||
|
|
||||||
|
response1 = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(manifest),
|
||||||
|
imageTag='latest'
|
||||||
|
)
|
||||||
|
|
||||||
|
response1['image']['imageId']['imageTag'].should.equal('latest')
|
||||||
|
response1['image']['imageId']['imageDigest'].should.contain("sha")
|
||||||
|
response1['image']['repositoryName'].should.equal('test_repository')
|
||||||
|
response1['image']['registryId'].should.equal('012345678910')
|
||||||
|
|
||||||
|
response2 = client.describe_images(repositoryName='test_repository')
|
||||||
|
type(response2['imageDetails']).should.be(list)
|
||||||
|
len(response2['imageDetails']).should.be(1)
|
||||||
|
|
||||||
|
response['imageDetails'][0]['imageDigest'].should.contain("sha")
|
||||||
|
|
||||||
|
# response['imageDetails'][0]['registryId'].should.equal("012345678910")
|
||||||
|
# response['imageDetails'][1]['registryId'].should.equal("012345678910")
|
||||||
|
# response['imageDetails'][2]['registryId'].should.equal("012345678910")
|
||||||
|
# response['imageDetails'][3]['registryId'].should.equal("012345678910")
|
||||||
|
#
|
||||||
|
# response['imageDetails'][0]['repositoryName'].should.equal("test_repository")
|
||||||
|
# response['imageDetails'][1]['repositoryName'].should.equal("test_repository")
|
||||||
|
# response['imageDetails'][2]['repositoryName'].should.equal("test_repository")
|
||||||
|
# response['imageDetails'][3]['repositoryName'].should.equal("test_repository")
|
||||||
|
#
|
||||||
|
# response['imageDetails'][0].should_not.have.key('imageTags')
|
||||||
|
# len(response['imageDetails'][1]['imageTags']).should.be(1)
|
||||||
|
|
||||||
|
|
||||||
@mock_ecr
|
@mock_ecr
|
||||||
def test_list_images():
|
def test_list_images():
|
||||||
@ -259,6 +307,11 @@ def test_describe_images():
|
|||||||
repositoryName='test_repository'
|
repositoryName='test_repository'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_ = client.put_image(
|
||||||
|
repositoryName='test_repository',
|
||||||
|
imageManifest=json.dumps(_create_image_manifest())
|
||||||
|
)
|
||||||
|
|
||||||
_ = client.put_image(
|
_ = client.put_image(
|
||||||
repositoryName='test_repository',
|
repositoryName='test_repository',
|
||||||
imageManifest=json.dumps(_create_image_manifest()),
|
imageManifest=json.dumps(_create_image_manifest()),
|
||||||
@ -279,32 +332,37 @@ def test_describe_images():
|
|||||||
|
|
||||||
response = client.describe_images(repositoryName='test_repository')
|
response = client.describe_images(repositoryName='test_repository')
|
||||||
type(response['imageDetails']).should.be(list)
|
type(response['imageDetails']).should.be(list)
|
||||||
len(response['imageDetails']).should.be(3)
|
len(response['imageDetails']).should.be(4)
|
||||||
|
|
||||||
response['imageDetails'][0]['imageDigest'].should.contain("sha")
|
response['imageDetails'][0]['imageDigest'].should.contain("sha")
|
||||||
response['imageDetails'][1]['imageDigest'].should.contain("sha")
|
response['imageDetails'][1]['imageDigest'].should.contain("sha")
|
||||||
response['imageDetails'][2]['imageDigest'].should.contain("sha")
|
response['imageDetails'][2]['imageDigest'].should.contain("sha")
|
||||||
|
response['imageDetails'][3]['imageDigest'].should.contain("sha")
|
||||||
|
|
||||||
response['imageDetails'][0]['registryId'].should.equal("012345678910")
|
response['imageDetails'][0]['registryId'].should.equal("012345678910")
|
||||||
response['imageDetails'][1]['registryId'].should.equal("012345678910")
|
response['imageDetails'][1]['registryId'].should.equal("012345678910")
|
||||||
response['imageDetails'][2]['registryId'].should.equal("012345678910")
|
response['imageDetails'][2]['registryId'].should.equal("012345678910")
|
||||||
|
response['imageDetails'][3]['registryId'].should.equal("012345678910")
|
||||||
|
|
||||||
response['imageDetails'][0]['repositoryName'].should.equal("test_repository")
|
response['imageDetails'][0]['repositoryName'].should.equal("test_repository")
|
||||||
response['imageDetails'][1]['repositoryName'].should.equal("test_repository")
|
response['imageDetails'][1]['repositoryName'].should.equal("test_repository")
|
||||||
response['imageDetails'][2]['repositoryName'].should.equal("test_repository")
|
response['imageDetails'][2]['repositoryName'].should.equal("test_repository")
|
||||||
|
response['imageDetails'][3]['repositoryName'].should.equal("test_repository")
|
||||||
|
|
||||||
len(response['imageDetails'][0]['imageTags']).should.be(1)
|
response['imageDetails'][0].should_not.have.key('imageTags')
|
||||||
len(response['imageDetails'][1]['imageTags']).should.be(1)
|
len(response['imageDetails'][1]['imageTags']).should.be(1)
|
||||||
len(response['imageDetails'][2]['imageTags']).should.be(1)
|
len(response['imageDetails'][2]['imageTags']).should.be(1)
|
||||||
|
len(response['imageDetails'][3]['imageTags']).should.be(1)
|
||||||
|
|
||||||
image_tags = ['latest', 'v1', 'v2']
|
image_tags = ['latest', 'v1', 'v2']
|
||||||
set([response['imageDetails'][0]['imageTags'][0],
|
set([response['imageDetails'][1]['imageTags'][0],
|
||||||
response['imageDetails'][1]['imageTags'][0],
|
response['imageDetails'][2]['imageTags'][0],
|
||||||
response['imageDetails'][2]['imageTags'][0]]).should.equal(set(image_tags))
|
response['imageDetails'][3]['imageTags'][0]]).should.equal(set(image_tags))
|
||||||
|
|
||||||
response['imageDetails'][0]['imageSizeInBytes'].should.equal(52428800)
|
response['imageDetails'][0]['imageSizeInBytes'].should.equal(52428800)
|
||||||
response['imageDetails'][1]['imageSizeInBytes'].should.equal(52428800)
|
response['imageDetails'][1]['imageSizeInBytes'].should.equal(52428800)
|
||||||
response['imageDetails'][2]['imageSizeInBytes'].should.equal(52428800)
|
response['imageDetails'][2]['imageSizeInBytes'].should.equal(52428800)
|
||||||
|
response['imageDetails'][3]['imageSizeInBytes'].should.equal(52428800)
|
||||||
|
|
||||||
|
|
||||||
@mock_ecr
|
@mock_ecr
|
||||||
|
Loading…
Reference in New Issue
Block a user