Add api function to fully delete a repository.

This commit is contained in:
yackob03 2013-10-01 12:13:25 -04:00
parent 891f992bf2
commit 4b9c6d9aae
5 changed files with 37 additions and 22 deletions

View file

@ -348,3 +348,8 @@ def delete_user_permission(username, namespace_name, repository_name):
raise DataModelException('User does not have permission for repo.') raise DataModelException('User does not have permission for repo.')
fetched[0].delete_instance() fetched[0].delete_instance()
def purge_repository(namespace_name, repository_name):
fetched = Repository.get(Repository.name == repository_name,
Repository.namespace == namespace_name)
fetched.delete_instance(recursive=True, delete_nullable=True)

View file

@ -11,6 +11,7 @@ from util.gravatar import compute_hash
from auth.permissions import (ReadRepositoryPermission, from auth.permissions import (ReadRepositoryPermission,
ModifyRepositoryPermission, ModifyRepositoryPermission,
AdministerRepositoryPermission) AdministerRepositoryPermission)
from endpoints.registry import delete_registry_storage
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@ -138,6 +139,19 @@ def change_repo_visibility_api(namespace, repository):
abort(404) abort(404)
@app.route('/api/repository/<path:repository>', methods=['DELETE'])
@api_login_required
@parse_repository_name
def delete_repository(namespace, repository):
permission = AdministerRepositoryPermission(namespace, repository)
if permission.can():
model.purge_repository(namespace, repository)
delete_registry_storage(namespace, repository)
return make_response('Deleted', 204)
abort(404)
def image_view(image): def image_view(image):
return { return {
'id': image.image_id, 'id': image.image_id,

View file

@ -302,3 +302,11 @@ def put_image_json(namespace, repository, image_id):
store.put_content(json_path, request.data) store.put_content(json_path, request.data)
generate_ancestry(namespace, repository, image_id, parent_id) generate_ancestry(namespace, repository, image_id, parent_id)
return make_response('true', 200) return make_response('true', 200)
def delete_registry_storage(namespace, repository):
""" Caller should have already verified proper permissions. """
repository_path = store.repository_namespace_path(namespace, repository)
logger.debug('Recursively deleting path: %s' % repository_path)
store.remove(repository_path)

View file

@ -82,7 +82,7 @@ def delete_tag(namespace, repository, tag):
methods=['DELETE']) methods=['DELETE'])
@process_auth @process_auth
@parse_repository_name @parse_repository_name
def delete_repository(namespace, repository): def delete_repository_tags(namespace, repository):
permission = ModifyRepositoryPermission(namespace, repository) permission = ModifyRepositoryPermission(namespace, repository)
if permission.can(): if permission.can():

View file

@ -51,20 +51,8 @@ class Storage(object):
return '{0}/{1}/{2}/{3}/ancestry'.format(self.images, namespace, return '{0}/{1}/{2}/{3}/ancestry'.format(self.images, namespace,
repository, image_id) repository, image_id)
def tag_path(self, namespace, repository, tagname=None): def repository_namespace_path(self, namespace, repository):
if not tagname: return '{0}/{1}/{2}/'.format(self.images, namespace, repository)
return '{0}/{1}/{2}'.format(self.repositories,
namespace,
repository)
return '{0}/{1}/{2}/tag_{3}'.format(self.repositories,
namespace,
repository,
tagname)
def index_images_path(self, namespace, repository):
return '{0}/{1}/{2}/_index_images'.format(self.repositories,
namespace,
repository)
def get_content(self, path): def get_content(self, path):
raise NotImplementedError raise NotImplementedError