Fix for hard merge
This commit is contained in:
parent
a8b340feb6
commit
9679ec91ec
6 changed files with 54 additions and 29 deletions
|
@ -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)
|
||||
|
||||
|
|
|
@ -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.
|
||||
"""
|
||||
|
|
|
@ -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())
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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__)
|
||||
|
|
|
@ -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
|
||||
|
|
Reference in a new issue