Skip to content
Snippets Groups Projects
Commit 859a2277 authored by Stefano Alberto Russo's avatar Stefano Alberto Russo
Browse files

Added spinnig loader when importing repositories as containers and created the required API calls.

parent 113dc850
No related branches found
No related tags found
No related merge requests found
......@@ -11,7 +11,7 @@ from django.conf import settings
from rest_framework.response import Response
from rest_framework import status, serializers, viewsets
from rest_framework.views import APIView
from .utils import format_exception, send_email, os_shell, now_t, get_ssh_access_mode_credentials
from .utils import format_exception, send_email, os_shell, now_t, get_ssh_access_mode_credentials, get_or_create_container_from_repository
from .models import Profile, Task, TaskStatuses, Computing, Storage, KeyPair
from .exceptions import ConsistencyException
import json
......@@ -1093,6 +1093,43 @@ class FileManagerAPI(PrivateGETAPI, PrivatePOSTAPI):
return ok200('ok')
#==============================
# Import repository APIs
#==============================
class ImportRepositoryAPI(PrivateGETAPI):
"""
get:
Import a repository as a container and get the container uuid.
"""
def _get(self, request):
repository_url = request.GET.get('repository_url', None)
repository_tag = request.GET.get('repository_tag', None)
container_name = request.GET.get('container_name', None)
container_description = request.GET.get('container_description', None)
if not repository_url:
return error400('Missing "repository_url"')
if not repository_tag:
return error400('Missing "repository_tag"')
logger.debug('Importing repository "%s" with tag "%s"', repository_url, repository_tag)
results = {}
try:
container = get_or_create_container_from_repository(request.user, repository_url, repository_tag, container_name, container_description)
except Exception as e:
results['import_succeded'] = False
results['error_message'] = str(e)
else:
results['import_succeded'] = True
results['container_uuid'] = str(container.uuid)
return ok200(results)
......
......@@ -20,8 +20,8 @@
<br/>
{% if data.new_container_from == 'registry' %}
<div style="font-size:1.2em; background:whitesmoke; display:inline-block; padding:2px 15px 2px 15px">New container from registry</div>
<div style="font-size:1.2em; background:white; display:inline-block; padding:2px 15px 2px 15px"><a href="?new_container_from=repository">New container from Git repository</a></div>
<div style="font-size:1.1em; background:whitesmoke; display:inline-block; padding:2px 15px 2px 15px">New container from registry</div>
<div style="font-size:1.1em; background:white; display:inline-block; padding:2px 15px 2px 15px"><a href="?new_container_from=repository">New container from Git repository</a></div>
<hr style="margin-top:0;">
<h4>Basics</h4>
......@@ -166,8 +166,8 @@
{% else %}
<div style="font-size:1.2em; background:white; display:inline-block; padding:2px 15px 2px 15px"><a href="?new_container_from=registry">New container from registry</a></div>
<div style="font-size:1.2em; background:whitesmoke; display:inline-block; padding:2px 15px 2px 15px">New container from Git repository</div>
<div style="font-size:1.1em; background:white; display:inline-block; padding:2px 15px 2px 15px"><a href="?new_container_from=registry">New container from registry</a></div>
<div style="font-size:1.1em; background:whitesmoke; display:inline-block; padding:2px 15px 2px 15px">New container from Git repository</div>
<hr style="margin-top:0;">
<h4>Basics</h4>
......@@ -238,7 +238,7 @@
{% else %}
Ok, software container added. Go back to <a href="/software">software</a>.
Ok, software container added. Go to <a href="/software">software</a>.
{% endif %}
......
{% load static %}
{% include "header.html" %}
{% include "navigation.html" %}
<br/>
<br/>
<div class="container">
<div class="dashboard">
<div class="span8 offset2">
{% if data.mode == 'new_task' %}
<h1>New Task</h1>
{% elif data.mode == 'new_container' %}
<h1>Add software container</h1>
{% else %}
<h1>Importing repository</h1>
{% endif %}
<hr>
<div id="importing">
Importing repository <code>{{ data.repository_url }}</code>...
<br>
<br>
<br>
<br>
<center><img src="/static/img/ajax-loader.gif"></center>
</div>
<div id="import_succeded" style="display:none">
Ok, software container added. Go to <a href="/software">software</a>.
</div>
<div id="import_failed" style="display:none">
FAILED: <span id="import_failed_text"></span>
</div>
<script type="text/javascript">
var apiUrl = '/api/v1/import_repository/?repository_url={{data.repository_url}}&repository_tag={{data.repository_tag}}&container_name={{data.container_name}}&container_description={{data.container_description}}';
fetch(apiUrl).then(response => {
console.log(response)
if (response.status != 200){
// Throw the error catched below
throw response.statusText;
}
return response.json();
}).then(data => {
// Work with JSON data here
console.log(data)
if (data.results.import_succeded){
// Terrbile django templating mixed with javascript
{% if data.mode == 'new_task' %}
window.location.replace("/new_task/?step=two&task_container_uuid="+data.results.container_uuid)
{% else %}
$("#importing").hide();
$("#import_succeded").show();
{% endif %}
} else {
throw data.results.error_message
}
}).catch(error => {
// Do something for an error here
console.log(error)
$("#importing").hide();
$("#import_failed").show();
$("#import_failed_text").html(error);
});
</script>
</div>
</div>
</div>
<br/>
<br/>
<br/>
<br/>
<br/>
<br/>
{% include "footer.html" %}
......@@ -1005,11 +1005,14 @@ def add_software(request):
elif new_container_from == 'repository':
container_description = request.POST.get('container_description', None)
repository_url = request.POST.get('repository_url', None)
repository_tag = request.POST.get('repository_tag', None)
repository_tag = request.POST.get('repository_tag', 'HEAD')
return HttpResponseRedirect('/import_repository/?repository_url={}&repository_tag={}&container_name={}&container_description={}'.format(repository_url,repository_tag,container_name,container_description))
# The return type here is a container, not created
get_or_create_container_from_repository(request.user, repository_url, repository_tag=repository_tag, container_name=container_name, container_description=container_description)
#get_or_create_container_from_repository(request.user, repository_url, repository_tag=repository_tag, container_name=container_name, container_description=container_description)
else:
raise Exception('Unknown new container mode "{}"'.format(new_container_from))
......@@ -1217,20 +1220,38 @@ def new_binder_task(request, repository):
repository_tag = repository.split('/')[-1]
repository_url = repository.replace('/'+repository_tag, '')
container = get_or_create_container_from_repository(request.user, repository_url, repository_tag)
data['repository_url'] = repository_url
data['repository_tag'] = repository_tag
# Set the container
data['task_container'] = container
data['mode'] = 'new_task' #new container
# List all computing resources
data['computings'] = list(Computing.objects.filter(group=None)) + list(Computing.objects.filter(group__user=request.user))
# Render the import page. This will call an API, and when the import is done, it
# will automatically redirect to the page "new_task/?step=two&task_container_uuid=..."
return render(request, 'import_repository.html', {'data': data})
data['step'] = 'two'
data['next_step'] = 'three'
# Render the new task page and handle the rest from there
return render(request, 'new_task.html', {'data': data})
#=========================
# Import repository
#=========================
@private_view
def import_repository(request):
# Init data
data={}
data['user'] = request.user
data['repository_url'] = request.GET.get('repository_url', None)
data['repository_tag'] = request.GET.get('repository_tag', 'HEAD')
if not data['repository_tag']:
data['repository_tag']='HEAD'
data['container_name'] = request.GET.get('container_name', None)
data['container_description'] = request.GET.get('container_description', None)
data['mode'] = 'new_container'
# Render the import page. This will call an API, and when the import is done, it
# will automatically say "Ok, crrated, go to software".
return render(request, 'import_repository.html', {'data': data})
......@@ -51,6 +51,7 @@ urlpatterns = [
# Software
url(r'^software/$', core_app_views.software),
url(r'^add_software/$', core_app_views.add_software),
url(r'^import_repository/$', core_app_views.import_repository),
#Computing
url(r'^computing/$', core_app_views.computing),
......@@ -84,6 +85,7 @@ urlpatterns = [
path('api/v1/base/logout/', core_app_api.logout_api.as_view(), name='logout_api'),
path('api/v1/base/agent/', core_app_api.agent_api.as_view(), name='agent_api'),
path('api/v1/filemanager/', core_app_api.FileManagerAPI.as_view(), name='filemanager_api'),
path('api/v1/import_repository/', core_app_api.ImportRepositoryAPI.as_view(), name='import_repository_api'),
# Binder compatibility
path('v2/git/<path:repository>', core_app_views.new_binder_task),
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment