diff --git a/endpoints/v1/tag.py b/endpoints/v1/tag.py index acad5e303..33e02a367 100644 --- a/endpoints/v1/tag.py +++ b/endpoints/v1/tag.py @@ -98,6 +98,9 @@ def delete_tag(namespace_name, repo_name, tag): if permission.can(): repo = model.get_repository(namespace_name, repo_name) + if repo is None: + abort(403) + if repo.kind != 'image': msg = 'This repository is for managing %s resources and not container images.' % repo.kind abort(405, message=msg, namespace=namespace_name) diff --git a/test/registry/protocol_v1.py b/test/registry/protocol_v1.py index e1eb9a411..53532200b 100644 --- a/test/registry/protocol_v1.py +++ b/test/registry/protocol_v1.py @@ -14,6 +14,7 @@ class V1ProtocolSteps(Enum): GET_IMAGES = 'get-images' PUT_TAG = 'put-tag' PUT_IMAGE_JSON = 'put-image-json' + DELETE_TAG = 'delete-tag' class V1Protocol(RegistryProtocol): @@ -192,3 +193,18 @@ class V1Protocol(RegistryProtocol): expected_status=204, headers=headers) return PushResult(checksums=None, manifests=None, headers=headers) + + def delete(self, session, namespace, repo_name, tag_names, credentials=None, + expected_failure=None, options=None): + auth = self._auth_for_credentials(credentials) + tag_names = [tag_names] if isinstance(tag_names, str) else tag_names + + # Ping! + self.ping(session) + + for tag_name in tag_names: + # DELETE /v1/repositories/{namespace}/{repository}/tags/{tag} + self.conduct(session, 'DELETE', + '/v1/repositories/%s/tags/%s' % (self.repo_name(namespace, repo_name), tag_name), + auth=auth, + expected_status=(200, expected_failure, V1ProtocolSteps.DELETE_TAG)) diff --git a/test/registry/registry_tests.py b/test/registry/registry_tests.py index 270f1b44e..d6fdd8017 100644 --- a/test/registry/registry_tests.py +++ b/test/registry/registry_tests.py @@ -601,19 +601,19 @@ def test_invalid_blob_reference(manifest_protocol, basic_images, liveserver_sess expected_failure=Failures.INVALID_BLOB) -def test_delete_tag(manifest_protocol, puller, basic_images, liveserver_session, +def test_delete_tag(pusher, puller, basic_images, liveserver_session, app_reloader): """ Test: Push a repository, delete a tag, and attempt to pull. """ credentials = ('devtable', 'password') # Push the tags. - result = manifest_protocol.push(liveserver_session, 'devtable', 'newrepo', ['one', 'two'], - basic_images, credentials=credentials) + result = pusher.push(liveserver_session, 'devtable', 'newrepo', ['one', 'two'], + basic_images, credentials=credentials) - # Delete tag `one` by digest. - manifest_protocol.delete(liveserver_session, 'devtable', 'newrepo', - result.manifests['one'].digest, - credentials=credentials) + # Delete tag `one` by digest or tag. + pusher.delete(liveserver_session, 'devtable', 'newrepo', + result.manifests['one'].digest if result.manifests else 'one', + credentials=credentials) # Attempt to pull tag `one` and ensure it doesn't work. puller.pull(liveserver_session, 'devtable', 'newrepo', 'one', basic_images,