Fix for hard merge

This commit is contained in:
Joseph Schorr 2017-07-17 16:36:05 +03:00
parent a8b340feb6
commit 9679ec91ec
6 changed files with 54 additions and 29 deletions

View file

@ -10,7 +10,7 @@ from endpoints.api import (resource, nickname, require_repo_read, require_repo_w
parse_args, query_param, truthy_bool, disallow_for_app_repositories)
from endpoints.api.tag_models_interface import Repository
from endpoints.api.tag_models_pre_oci import pre_oci_model as model
from endpoints.exception import NotFound
from endpoints.exception import NotFound, InvalidRequest
from endpoints.v2.manifest import _generate_and_store_manifest
from util.names import TAG_ERROR, TAG_REGEX
@ -53,7 +53,7 @@ class ListRepositoryTags(RepositoryParamResource):
class RepositoryTag(RepositoryParamResource):
""" Resource for managing repository tags. """
schemas = {
'MoveTag': {
'ChangeTag': {
'type': 'object',
'description': 'Makes changes to a specific tag',
'properties': {
@ -61,7 +61,7 @@ class RepositoryTag(RepositoryParamResource):
'type': ['string', 'null'],
'description': '(If specified) Image identifier to which the tag should point',
},
'image': {
'expiration': {
'type': ['number', 'null'],
'description': '(If specified) The expiration for the image',
},
@ -71,8 +71,8 @@ class RepositoryTag(RepositoryParamResource):
@require_repo_write
@disallow_for_app_repositories
@nickname('changeTagImage')
@validate_json_request('MoveTag')
@nickname('changeTag')
@validate_json_request('ChangeTag')
def put(self, namespace, repository, tag):
""" Change which image a tag points to or create a new tag."""
@ -106,12 +106,16 @@ class RepositoryTag(RepositoryParamResource):
'namespace': namespace,
'expiration_date': expiration_date,
'old_expiration_date': existing_end_ts
}, repo=repo)
}, repo_name=repository)
else:
abort(400, 'Could not update tag expiration; Tag has probably changed')
raise InvalidRequest('Could not update tag expiration; Tag has probably changed')
if 'image' in request.get_json():
image_id = request.get_json()['image']
image = model.get_repository_image(namespace, repository, image_id)
if image is None:
raise NotFound()
original_image_id = model.get_repo_tag_image(repo, tag)
model.create_or_update_tag(namespace, repository, tag, image_id)

View file

@ -61,7 +61,7 @@ class Repository(namedtuple('Repository', ['namespace_name', 'repository_name'])
class Image(
namedtuple('Image', [
'docker_image_id', 'created', 'comment', 'command', 'storage_image_size',
'storage_uploading', 'ancestor_length', 'ancestor_id_list'
'storage_uploading', 'ancestor_id_list'
])):
"""
Image
@ -71,7 +71,6 @@ class Image(
:type command: string
:type storage_image_size: int
:type storage_uploading: boolean
:type ancestor_length: int
:type ancestor_id_list: [int]
"""
@ -91,7 +90,7 @@ class Image(
'command': json.loads(command) if command else None,
'size': self.storage_image_size,
'uploading': self.storage_uploading,
'sort_index': self.ancestor_length,
'sort_index': len(self.ancestor_id_list),
}
if include_ancestors:
@ -116,9 +115,9 @@ class TagDataInterface(object):
"""
@abstractmethod
def get_repo(self, namespace_name, repository_name, docker_image_id):
def get_repo(self, namespace_name, repository_name):
"""
Returns a repository associated with the given namespace, repository, and docker_image_id
Returns a repository associated with the given namespace and repository name.
"""
@abstractmethod
@ -157,6 +156,13 @@ class TagDataInterface(object):
Returns the repository associated with the namespace_name and repository_name
"""
@abstractmethod
def get_repository_image(self, namespace_name, repository_name, docker_image_id):
"""
Returns the repository image associated with the namespace_name, repository_name, and docker
image ID.
"""
@abstractmethod
def restore_tag_to_manifest(self, repository_name, tag_name, manifest_digest):
"""
@ -170,3 +176,11 @@ class TagDataInterface(object):
Returns the existing repo tag image if it exists or else returns None
Side effects include adding the tag with associated name to the image with the associated id in the named repo.
"""
@abstractmethod
def change_repository_tag_expiration(self, namespace_name, repository_name, tag_name,
expiration_date):
""" Sets the expiration date of the tag under the matching repository to that given. If the
expiration date is None, then the tag will not expire. Returns a tuple of the previous
expiration timestamp in seconds (if any), and whether the operation succeeded.
"""

View file

@ -27,12 +27,12 @@ class PreOCIModel(TagDataInterface):
return RepositoryTagHistory(tags=repository_tag_history, more=more)
def get_repo(self, namespace_name, repository_name, docker_image_id):
image = model.image.get_repo_image(namespace_name, repository_name, docker_image_id)
if image is None:
def get_repo(self, namespace_name, repository_name):
repo = model.repository.get_repository(namespace_name, repository_name)
if repo is None:
return None
return Repository(image.repository.namespace_user, image.repository.name)
return Repository(repo.namespace_user, repo.name)
def get_repo_tag_image(self, repository, tag_name):
repo = model.repository.get_repository(str(repository.namespace_name), str(repository.repository_name))
@ -73,6 +73,13 @@ class PreOCIModel(TagDataInterface):
new_tags.append(convert_tag(tag))
return new_tags
def get_repository_image(self, namespace_name, repository_name, docker_image_id):
image = model.image.get_repo_image(namespace_name, repository_name, docker_image_id)
if image is None:
return None
return convert_image(image)
def get_repository(self, namespace_name, repository_name):
repo = model.repository.get_repository(namespace_name, repository_name)
if repo is None:
@ -102,13 +109,17 @@ class PreOCIModel(TagDataInterface):
return convert_image(image)
def change_repository_tag_expiration(self, namespace_name, repository_name, tag_name,
expiration_date):
return model.tag.change_repository_tag_expiration(namespace_name, repository_name, tag_name,
expiration_date)
def convert_image(database_image):
return Image(docker_image_id=database_image.docker_image_id, created=database_image.created,
comment=database_image.comment, command=database_image.command,
storage_image_size=database_image.storage.image_size,
storage_uploading=database_image.storage.uploading,
ancestor_length=len(database_image.ancestors),
ancestor_id_list=database_image.ancestor_id_list())

View file

@ -106,20 +106,18 @@ def test_list_repository_tag_history(expected, namespace_name, repository_name,
specific_tag) == expected
def get_repo_image_mock(monkeypatch, return_value):
def return_return_value(namespace_name, repository_name, image_id):
def get_repo_mock(monkeypatch, return_value):
def return_return_value(namespace_name, repository_name):
return return_value
monkeypatch.setattr(model.image, 'get_repo_image', return_return_value)
monkeypatch.setattr(model.repository, 'get_repository', return_return_value)
def test_get_repo_not_exists(get_monkeypatch):
namespace_name = 'namespace_name'
repository_name = 'repository_name'
image_id = 'image_id'
get_repo_image_mock(get_monkeypatch, None)
repo = pre_oci_model.get_repo(namespace_name, repository_name, image_id)
get_repo_mock(get_monkeypatch, None)
repo = pre_oci_model.get_repo(namespace_name, repository_name)
assert repo is None
@ -127,14 +125,13 @@ def test_get_repo_not_exists(get_monkeypatch):
def test_get_repo_exists(get_monkeypatch):
namespace_name = 'namespace_name'
repository_name = 'repository_name'
image_id = 'image_id'
mock = Mock()
mock.namespace_user = namespace_name
mock.name = repository_name
mock.repository = mock
get_repo_image_mock(get_monkeypatch, mock)
get_repo_mock(get_monkeypatch, mock)
repo = pre_oci_model.get_repo(namespace_name, repository_name, image_id)
repo = pre_oci_model.get_repo(namespace_name, repository_name)
assert repo is not None
assert repo.repository_name == repository_name

View file

@ -1,7 +1,7 @@
import logging
from app import app
from endpoints.v2.models_pre_oci import pre_oci_model as model
from endpoints.v2.models_pre_oci import data_model as model
from util.timedeltastring import convert_to_timedelta
logger = logging.getLogger(__name__)

View file

@ -17,7 +17,6 @@ from endpoints.v2.models_interface import Label
from endpoints.v2.models_pre_oci import data_model as model
from endpoints.v2.errors import (BlobUnknown, ManifestInvalid, ManifestUnknown, TagInvalid,
NameInvalid, TagExpired)
>>>>>>> Change error message when trying to pull a deleted or expired tag
from endpoints.v2.labelhandlers import handle_label
from image.docker import ManifestException
from image.docker.schema1 import DockerSchema1Manifest, DockerSchema1ManifestBuilder