Skip to content
Snippets Groups Projects
Commit a9e1c4cf authored by Antoine Pietri's avatar Antoine Pietri
Browse files

api: add vault views

parent 6a282145
No related branches found
No related tags found
No related merge requests found
......@@ -3,14 +3,15 @@
# License: GNU General Public License version 3, or any later version
# See top-level LICENSE file for more information
import swh.web.api.views.origin # noqa
import swh.web.api.views.content # noqa
import swh.web.api.views.directory # noqa
import swh.web.api.views.entity # noqa
import swh.web.api.views.origin # noqa
import swh.web.api.views.person # noqa
import swh.web.api.views.release # noqa
import swh.web.api.views.revision # noqa
import swh.web.api.views.directory # noqa
import swh.web.api.views.entity # noqa
import swh.web.api.views.stat # noqa
import swh.web.api.views.vault # noqa
from swh.web.api.apiurls import APIUrls
......
# Copyright (C) 2015-2017 The Software Heritage developers
# See the AUTHORS file at the top-level directory of this distribution
# License: GNU Affero General Public License version 3, or any later version
# See top-level LICENSE file for more information
from django.http import HttpResponse
from swh.web.common import service, query
from swh.web.common.utils import reverse
from swh.web.api import apidoc as api_doc
from swh.web.api.apiurls import api_route
from swh.web.api.views.utils import (
api_lookup, doc_exc_id_not_found, doc_exc_bad_id,
)
@api_route('/vault/directory/(?P<dir_id>[a-fA-F0-9]+)/',
'vault-cook-directory')
@api_doc.route('/vault/directory', tags=['hidden'])
@api_doc.arg('dir_id',
default='d4a96ba891017d0d26c15e509b4e6515e40d75ee',
argtype=api_doc.argtypes.sha1_git,
argdoc="The directory's sha1 identifier")
@api_doc.param('email', default=None,
argtype=api_doc.argtypes.int,
doc="e-mail to notify when the bundle is ready")
@api_doc.raises(exc=api_doc.excs.badinput, doc=doc_exc_bad_id)
@api_doc.raises(exc=api_doc.excs.notfound, doc=doc_exc_id_not_found)
@api_doc.returns(rettype=api_doc.rettypes.dict,
retdoc=('dictionary mapping containing the status of '
'the cooking'))
def api_vault_cook_directory(request, dir_id):
"""Requests an archive of the directoy identified by dir_id.
To import the directory in the current directory, use::
$ tar xvf path/to/directory.tar.gz
"""
email = request.GET.get('email', None)
_, obj_id = query.parse_hash_with_algorithms_or_throws(
dir_id, ['sha1'], 'Only sha1_git is supported.')
def _enrich_dir_cook(res):
res['fetch_url'] = reverse('vault-fetch-directory',
kwargs={'dir_id': dir_id})
return res
return api_lookup(
service.vault_cook, 'directory', obj_id, email,
notfound_msg="Directory with ID '{}' not found.".format(dir_id),
enrich_fn=_enrich_dir_cook)
@api_route(r'/vault/directory/(?P<dir_id>[a-fA-F0-9]+)/raw/',
'vault-fetch-directory')
@api_doc.route('/vault/directory/raw', tags=['hidden'], handle_response=True)
@api_doc.arg('dir_id',
default='d4a96ba891017d0d26c15e509b4e6515e40d75ee',
argtype=api_doc.argtypes.sha1_git,
argdoc="The directory's sha1 identifier")
@api_doc.raises(exc=api_doc.excs.badinput, doc=doc_exc_bad_id)
@api_doc.raises(exc=api_doc.excs.notfound, doc=doc_exc_id_not_found)
@api_doc.returns(rettype=api_doc.rettypes.octet_stream,
retdoc='the cooked directory tarball')
def api_vault_fetch_directory(request, dir_id):
"""Fetch the archive of the directoy identified by dir_id."""
_, obj_id = query.parse_hash_with_algorithms_or_throws(
dir_id, ['sha1'], 'Only sha1_git is supported.')
res = api_lookup(
service.vault_fetch, 'directory', obj_id,
notfound_msg="Directory with ID '{}' not found.".format(dir_id))
fname = '{}.tar.gz'.format(dir_id)
response = HttpResponse(res, content_type='application/gzip')
response['Content-disposition'] = 'attachment; filename={}'.format(fname)
return response
@api_route(r'/vault/revision_gitfast/(?P<rev_id>[a-fA-F0-9]+)/',
'vault-cook-revision_gitfast')
@api_doc.route('/vault/revision_gitfast', tags=['hidden'])
@api_doc.arg('rev_id',
default='9174026cfe69d73ef80b27890615f8b2ef5c265a',
argtype=api_doc.argtypes.sha1_git,
argdoc="The revision's sha1_git identifier")
@api_doc.param('email', default=None,
argtype=api_doc.argtypes.int,
doc="e-mail to notify when the bundle is ready")
@api_doc.raises(exc=api_doc.excs.badinput, doc=doc_exc_bad_id)
@api_doc.raises(exc=api_doc.excs.notfound, doc=doc_exc_id_not_found)
@api_doc.returns(rettype=api_doc.rettypes.dict,
retdoc='dictionary mapping containing the status of '
'the cooking')
def api_vault_cook_revision_gitfast(request, rev_id):
"""Requests an archive of the revision identified by rev_id.
To import the revision in the current directory, use::
$ git init
$ zcat path/to/revision.gitfast.gz | git fast-import
"""
email = request.GET.get('email', None)
_, obj_id = query.parse_hash_with_algorithms_or_throws(
rev_id, ['sha1'], 'Only sha1_git is supported.')
def _enrich_dir_cook(res):
res['fetch_url'] = reverse('vault-fetch-revision_gitfast',
kwargs={'rev_id': rev_id})
return res
return api_lookup(
service.vault_cook, 'revision_gitfast', obj_id, email,
notfound_msg="Revision with ID '{}' not found.".format(rev_id),
enrich_fn=_enrich_dir_cook)
@api_route('/vault/revision_gitfast/(?P<rev_id>[a-fA-F0-9]+)/raw/',
'vault-fetch-revision_gitfast')
@api_doc.route('/vault/revision_gitfast/raw', tags=['hidden'],
handle_response=True)
@api_doc.arg('rev_id',
default='9174026cfe69d73ef80b27890615f8b2ef5c265a',
argtype=api_doc.argtypes.sha1_git,
argdoc="The revision's sha1_git identifier")
@api_doc.raises(exc=api_doc.excs.badinput, doc=doc_exc_bad_id)
@api_doc.raises(exc=api_doc.excs.notfound, doc=doc_exc_id_not_found)
@api_doc.returns(rettype=api_doc.rettypes.octet_stream,
retdoc='the cooked revision git fast-export')
def api_vault_fetch_revision_gitfast(request, rev_id):
"""Fetch the archive of the revision identified by rev_id."""
_, obj_id = query.parse_hash_with_algorithms_or_throws(
rev_id, ['sha1'], 'Only sha1_git is supported.')
res = api_lookup(
service.vault_fetch, 'revision_gitfast', obj_id,
notfound_msg="Revision with ID '{}' not found.".format(rev_id))
fname = '{}.gitfast.gz'.format(rev_id)
response = HttpResponse(res, content_type='application/gzip')
response['Content-disposition'] = 'attachment; filename={}'.format(fname)
return response
......@@ -15,6 +15,7 @@ from swh.web.common.exc import NotFoundExc
from swh.web import config
storage = config.storage()
vault = config.vault()
MAX_LIMIT = 50 # Top limit the users can ask for
......@@ -826,3 +827,15 @@ def lookup_directory_through_revision(revision, path=None,
raise NotFoundExc('Revision with criterion %s not found!' % revision)
return (rev['id'],
lookup_directory_with_revision(rev['id'], path, with_data))
def vault_cook(obj_type, obj_id, email=None):
"""Cook a vault bundle.
"""
return vault.cook(obj_type, obj_id, email=email)
def vault_fetch(obj_type, obj_id):
"""Fetch a vault bundle.
"""
return vault.fetch(obj_type, obj_id)
......@@ -5,6 +5,7 @@
from swh.core import config
from swh.storage import get_storage
from swh.vault.api.client import RemoteVaultClient
DEFAULT_CONFIG = {
'allowed_hosts': ('list', []),
......@@ -14,6 +15,7 @@ DEFAULT_CONFIG = {
'url': 'http://127.0.0.1:5002/',
},
}),
'vault': ('string', 'http://127.0.0.1:5005/'),
'log_dir': ('string', '/tmp/swh/log'),
'debug': ('bool', False),
'host': ('string', '127.0.0.1'), # development property
......@@ -45,6 +47,7 @@ def get_config(config_file='webapp/webapp'):
swhweb_config.update(cfg)
config.prepare_folders(swhweb_config, 'log_dir')
swhweb_config['storage'] = get_storage(**swhweb_config['storage'])
swhweb_config['vault'] = RemoteVaultClient(swhweb_config['vault'])
return swhweb_config
......@@ -53,3 +56,10 @@ def storage():
"""
return get_config()['storage']
def vault():
"""Return the current application's SWH vault.
"""
return get_config()['vault']
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment