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

Imporved and fixed bug in task creation. Minor other fixes.

parent 5d90f24d
No related branches found
No related tags found
No related merge requests found
...@@ -307,6 +307,7 @@ print(port) ...@@ -307,6 +307,7 @@ print(port)
logger.info('Setting task "{}" to ip "{}" and port "{}"'.format(task.uuid, task_ip, task_port)) logger.info('Setting task "{}" to ip "{}" and port "{}"'.format(task.uuid, task_ip, task_port))
task.status = TaskStatuses.running task.status = TaskStatuses.running
task.ip = task_ip task.ip = task_ip
if task.container.supports_dynamic_ports:
task.port = int(task_port) task.port = int(task_port)
task.save() task.save()
......
...@@ -317,8 +317,8 @@ class SlurmComputingManager(ComputingManager): ...@@ -317,8 +317,8 @@ class SlurmComputingManager(ComputingManager):
# Submit the job # Submit the job
if task.container.type == 'singularity': if task.container.type == 'singularity':
if not task.container.supports_dynamic_ports: #if not task.container.supports_dynamic_ports:
raise Exception('This task does not support dynamic port allocation and is therefore not supported using singularity on Slurm') # raise Exception('This task does not support dynamic port allocation and is therefore not supported using singularity on Slurm')
# Set pass if any # Set pass if any
if task.auth_pass: if task.auth_pass:
......
...@@ -80,7 +80,7 @@ class Container(models.Model): ...@@ -80,7 +80,7 @@ class Container(models.Model):
image = models.CharField('Container image', max_length=255, blank=False, null=False) image = models.CharField('Container image', max_length=255, blank=False, null=False)
type = models.CharField('Container type', max_length=36, blank=False, null=False) type = models.CharField('Container type', max_length=36, blank=False, null=False)
registry = models.CharField('Container registry', max_length=255, blank=False, null=False) registry = models.CharField('Container registry', max_length=255, blank=False, null=False)
ports = models.CharField('Container service ports', max_length=36, blank=True, null=True) ports = models.CharField('Container ports', max_length=36, blank=True, null=True)
# Capabilities # Capabilities
supports_dynamic_ports = models.BooleanField(default=False) supports_dynamic_ports = models.BooleanField(default=False)
...@@ -106,6 +106,13 @@ class Container(models.Model): ...@@ -106,6 +106,13 @@ class Container(models.Model):
color_map_index = string_int_hash % len(color_map) color_map_index = string_int_hash % len(color_map)
return color_map[color_map_index] return color_map[color_map_index]
@property
def port(self):
if not self.ports:
return None
return(int(self.ports.split(',')[0]))
#========================= #=========================
......
...@@ -105,7 +105,7 @@ ...@@ -105,7 +105,7 @@
</div> </div>
<div style="margin-bottom:10px; text-align:center"> <div style="margin-bottom:10px; text-align:center">
<a href="/create_task?container_uuid={{ container.uuid }}" class="btn btn-light" style="border: #c0c0c0 1px solid">&nbsp;<i class="fa fa-play" style="color:green"></i></a> <a href="/create_task?task_container_uuid={{ container.uuid }}" class="btn btn-light" style="border: #c0c0c0 1px solid">&nbsp;<i class="fa fa-play" style="color:green"></i></a>
</div> </div>
......
...@@ -83,16 +83,23 @@ ...@@ -83,16 +83,23 @@
{% else %} {% else %}
<!-- <a href=?uuid={{task.uuid}}&action=start>Start</a> | --> <!-- <a href=?uuid={{task.uuid}}&action=start>Start</a> | -->
<font color="#c0c0c0">Stop</font> | <font color="#c0c0c0">Stop</font> |
{% endif %} {% endif %}
<a href="?uuid={{task.uuid}}&action=delete&details=False">Delete</a> <a href="?uuid={{task.uuid}}&action=delete&details=False">Delete</a>
{% if task.port %}
{% if task.status == "running" %} {% if task.status == "running" %}
| <a href="?uuid={{task.uuid}}&action=connect">Connect</a> | <a href="?uuid={{task.uuid}}&action=connect">Connect</a>
{% else %} {% else %}
| <font color="#c0c0c0">Connect</font> | <font color="#c0c0c0">Connect</font>
{% endif%} {% endif%}
{% endif %}
{% if task.status == "created" %}
| <font color="#c0c0c0">View Log</font>
{% else %}
| <a href="/task_log/?uuid={{task.uuid}}&action=viewlog">View Log</a> | <a href="/task_log/?uuid={{task.uuid}}&action=viewlog">View Log</a>
{% endif %}
</td> </td>
...@@ -144,23 +151,28 @@ ...@@ -144,23 +151,28 @@
<div style="margin-bottom:10px; text-align:center; padding:5px"> <div style="margin-bottom:10px; text-align:center; padding:5px">
<!-- Stop / Delete --> <!-- Stop / Delete / Cancel -->
{% if task.status == "stopped" %} {% if task.status == "stopped" or task.status == "created" %}
<a href="?uuid={{task.uuid}}&action=delete&fromlist=True" class="btn btn-action">Delete</a> <a href="?uuid={{task.uuid}}&action=delete&fromlist=True" class="btn btn-action">Delete</a>
{% else %} {% else %}
<a href="?uuid={{task.uuid}}&action=stop&fromlist=True" class="btn btn-action">Stop</a> <a href="?uuid={{task.uuid}}&action=stop&fromlist=True" class="btn btn-action">Stop</a>
{% endif %} {% endif %}
<!-- Connect --> <!-- Connect -->
{% if task.port %}
{% if task.status == "running" %} {% if task.status == "running" %}
<a href="?uuid={{task.uuid}}&action=connect" class="btn btn-connect">Connect</a> <a href="?uuid={{task.uuid}}&action=connect" class="btn btn-connect">Connect</a>
{% else %} {% else %}
<a href="" class="btn btn-disabled">Connect</a> <a href="" class="btn btn-disabled">Connect</a>
{% endif %} {% endif %}
{% endif %}
<!-- View log --> <!-- View log -->
{% if task.status == "created" %}
<a href="" class="btn btn-disabled">Logs</a>
{% else %}
<a href="/task_log/?uuid={{task.uuid}}&action=viewlog" class="btn btn-action">Logs</a> <a href="/task_log/?uuid={{task.uuid}}&action=viewlog" class="btn btn-action">Logs</a>
{% endif %}
</div> </div>
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
<table class="dashboard" style="max-width:700px"> <table class="dashboard" style="max-width:700px">
<tr><td></td></tr> <tr><td colspan="2"></td></tr>
<tr> <tr>
<td><b>Task name </b></td> <td><b>Task name </b></td>
...@@ -34,9 +34,9 @@ ...@@ -34,9 +34,9 @@
<tr> <tr>
<td><b>Task container</b></td><td> <td><b>Task container</b></td><td>
{% if data.container %} {% if data.task_container %}
<select name="task_container_uuid"> <select name="task_container_uuid">
<option value="{{data.container.uuid}}" selected>{{data.container.name}} ({{data.container.type.title}})</option> <option value="{{data.task_container.uuid}}" selected>{{data.task_container.name}} ({{data.task_container.type.title}})</option>
</select> </select>
{% else %} {% else %}
<select name="task_container_uuid" > <select name="task_container_uuid" >
...@@ -45,18 +45,16 @@ ...@@ -45,18 +45,16 @@
{% endfor %} {% endfor %}
</select> </select>
{% endif %} {% endif %}
<!-- &nbsp; | <a href="/add_container">Add new...</a> -->
</td> </td>
</tr> </tr>
<tr> <tr>
<td><b>Computing resource</b></td><td> <td><b>Computing resource</b></td><td>
<select name="task_computing" > <select name="task_computing_uuid" >
{% for computing in data.computings %}} {% for computing in data.computings %}}
<option value="{{ computing.uuid }}">{{ computing.name}}</option> <!-- ({% if computing.user %}{{ computing.user }}{% else %}platform{% endif %}) --> <option value="{{ computing.uuid }}">{{ computing.name}}</option>
{% endfor %} {% endfor %}
</select> </select>
<!-- &nbsp; | <a href="/add_computing">Add new...</a>-->
</td> </td>
</tr> </tr>
...@@ -70,30 +68,60 @@ ...@@ -70,30 +68,60 @@
{% elif data.step == 'two' %} {% elif data.step == 'two' %}
<h3>Step 2: authentication and computing details</h3> <h3>Step 2: add authentication and computing details</h3>
<br/> <br/>
<table class="dashboard" style="max-width:700px">
<tr><td colspan="2"></td></tr>
<tr>
<td><b>Task name </b></td>
<td>
<input type="text" name="task_name_RECAP" value="{{ data.task_name }}" placeholder="" size="23" disabled />
</td>
</tr>
<tr>
<td><b>Task container</b></td><td>
<select name="task_container_uuid_RECAP">
<option value="" selected>{{data.task_container.name}} ({{data.task_container.type.title}})</option>
</select>
</td>
</tr>
<tr>
<td><b>Computing resource</b></td><td>
<select name="task_computing_uuid_RECAP" >
<option value="">{{ data.task_computing.name}}</option>
</select>
</td>
</tr>
</table>
{% if data.task.container.type == 'singularity' and not data.task.container.supports_dynamic_ports %} <br>
<div> <p style="font-size:15px; max-width:700px; margin-bottom:20px"> {% if data.task_container.type == 'singularity' and not data.task_container.supports_dynamic_ports %}
<div> <p style="font-size:15px; max-width:700px; margin-bottom:20px; margin-left:5px">
<i class="fa fa-exclamation-triangle" style="color:orange"></i> This container does not support dynamic ports and you are running it with Singularity, without network insulation. This means that if the container port is already occupied, it will not be able to start. <i class="fa fa-exclamation-triangle" style="color:orange"></i> This container does not support dynamic ports and you are running it with Singularity, without network insulation. This means that if the container port is already occupied, it will not be able to start.
</p></div> </p></div>
{% endif %} {% endif %}
{% if data.task.container.ports and not data.task.container.supports_pass_auth %} {% if data.task_container.ports and not data.task_container.supports_pass_auth %}
<div> <p style="font-size:15px; max-width:700px; margin-bottom:20px"> <div> <p style="font-size:15px; max-width:700px; margin-bottom:20px; margin-left:5px">
<i class="fa fa-exclamation-triangle" style="color:orange"></i> This container does not support any authentication. This means that anyone running on the same network will be able to access it services. <i class="fa fa-exclamation-triangle" style="color:orange"></i> This container does not support configuring any authentication. This means that unless it is built-in within the container, anyone running on the same network will be able to access it.
</p></div> </p></div>
{% endif %} {% endif %}
<form action="/create_task/" method="POST"> <form action="/create_task/" method="POST">
{% csrf_token %} {% csrf_token %}
<input type="hidden" name="step" value="two" /> <input type="hidden" name="step" value="two" />
<input type="hidden" name="task_uuid" value="{{ data.task.uuid }}" /> <input type="hidden" name="task_name" value="{{ data.task_name }}" />
<input type="hidden" name="task_container_uuid" value="{{ data.task_container.uuid }}" />
<input type="hidden" name="task_computing_uuid" value="{{ data.task_computing.uuid }}" />
<table class="dashboard" style="max-width:700px"> <table class="dashboard" style="max-width:700px">
<tr><td></td></tr> <tr><td colspan="2"></td></tr>
{% if data.task.container.supports_user_auth %} {% if data.task_container.supports_user_auth %}
<tr> <tr>
<td><b>Task user</b></td> <td><b>Task user</b></td>
<td> <td>
...@@ -102,7 +130,7 @@ ...@@ -102,7 +130,7 @@
</tr> </tr>
{% endif %} {% endif %}
{% if data.task.container.supports_pass_auth %} {% if data.task_container.supports_pass_auth %}
<tr> <tr>
<td valign="top"><b>Set task password</b></td> <td valign="top"><b>Set task password</b></td>
<td> <td>
...@@ -131,7 +159,7 @@ ...@@ -131,7 +159,7 @@
</td> </td>
</tr> --> </tr> -->
{% if data.task.computing.type == 'slurm' %} {% if data.task_computing.type == 'slurm' %}
<tr> <tr>
<td><b>Computing options</b></td> <td><b>Computing options</b></td>
<td> <td>
......
...@@ -466,12 +466,12 @@ def create_task(request): ...@@ -466,12 +466,12 @@ def create_task(request):
step = request.POST.get('step', None) step = request.POST.get('step', None)
# Container uuid if any # Container uuid if any
container_uuid = request.GET.get('container_uuid', None) container_uuid = request.GET.get('task_container_uuid', None)
if container_uuid: if container_uuid:
try: try:
data['container'] = Container.objects.get(uuid=container_uuid, user=request.user) data['task_container'] = Container.objects.get(uuid=container_uuid, user=request.user)
except Container.DoesNotExist: except Container.DoesNotExist:
data['container'] = Container.objects.get(uuid=container_uuid, user=None) data['task_container'] = Container.objects.get(uuid=container_uuid, user=None)
else: else:
# Get containers # Get containers
data['containers'] = list(Container.objects.filter(user=None)) + list(Container.objects.filter(user=request.user)) data['containers'] = list(Container.objects.filter(user=None)) + list(Container.objects.filter(user=request.user))
...@@ -480,11 +480,14 @@ def create_task(request): ...@@ -480,11 +480,14 @@ def create_task(request):
data['computings'] = list(Computing.objects.filter(user=None)) + list(Computing.objects.filter(user=request.user)) data['computings'] = list(Computing.objects.filter(user=None)) + list(Computing.objects.filter(user=request.user))
# Handle step
if step:
if step == 'one': # Task name
# We have a step one submitted, get the first tab parameters
task_name = request.POST.get('task_name', None) task_name = request.POST.get('task_name', None)
if not task_name:
raise ErrorMessage('Missing task name')
data['task_name'] = task_name
# Task container # Task container
task_container_uuid = request.POST.get('task_container_uuid', None) task_container_uuid = request.POST.get('task_container_uuid', None)
...@@ -495,9 +498,10 @@ def create_task(request): ...@@ -495,9 +498,10 @@ def create_task(request):
task_container = Container.objects.get(uuid=task_container_uuid, user=request.user) task_container = Container.objects.get(uuid=task_container_uuid, user=request.user)
except Container.DoesNotExist: except Container.DoesNotExist:
raise Exception('Consistency error, container with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_container_uuid, request.user.email)) raise Exception('Consistency error, container with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_container_uuid, request.user.email))
data['task_container'] = task_container
# task computing # Task computing
task_computing_uuid = request.POST.get('task_computing', None) task_computing_uuid = request.POST.get('task_computing_uuid', None)
try: try:
task_computing = Computing.objects.get(uuid=task_computing_uuid, user=None) task_computing = Computing.objects.get(uuid=task_computing_uuid, user=None)
except Computing.DoesNotExist: except Computing.DoesNotExist:
...@@ -505,7 +509,15 @@ def create_task(request): ...@@ -505,7 +509,15 @@ def create_task(request):
task_computing = Computing.objects.get(uuid=task_computing_uuid, user=request.user) task_computing = Computing.objects.get(uuid=task_computing_uuid, user=request.user)
except Computing.DoesNotExist: except Computing.DoesNotExist:
raise Exception('Consistency error, computing with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_computing_uuid, request.user.email)) raise Exception('Consistency error, computing with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_computing_uuid, request.user.email))
data['task_computing'] = task_computing
# Handle step one/two
if step == 'one':
# Set step and task uuid
data['step'] = 'two'
elif step == 'two':
# Generate the task uuid # Generate the task uuid
task_uuid = str(uuid.uuid4()) task_uuid = str(uuid.uuid4())
...@@ -518,19 +530,6 @@ def create_task(request): ...@@ -518,19 +530,6 @@ def create_task(request):
container = task_container, container = task_container,
computing = task_computing) computing = task_computing)
# Save the task in the cache
_task_cache[task_uuid] = task
# Set step and task uuid
data['step'] = 'two'
data['task'] = task
elif step == 'two':
# Get back the task
task_uuid = request.POST.get('task_uuid', None)
task = _task_cache[task_uuid]
# Add auth # Add auth
task.auth_user = request.POST.get('auth_user', None) task.auth_user = request.POST.get('auth_user', None)
task.auth_pass = request.POST.get('auth_password', None) task.auth_pass = request.POST.get('auth_password', None)
...@@ -562,20 +561,26 @@ def create_task(request): ...@@ -562,20 +561,26 @@ def create_task(request):
if computing_options: if computing_options:
task.computing_options = computing_options task.computing_options = computing_options
logger.debug('computing_options="{}"'.format(computing_options))
# Save the task in the DB
task.save()
# Attach user config to computing # Attach user config to computing
task.computing.attach_user_conf_data(task.user) task.computing.attach_user_conf_data(task.user)
# Set port if not dynamic ports
if not task.container.supports_dynamic_ports:
if task.container.ports:
task.port = task.container.port
# Save the task before starting it, or the computing manager will not be able to work properly
task.save()
# Start the task # Start the task
#try: try:
task.computing.manager.start_task(task) task.computing.manager.start_task(task)
#except: except:
# task.delete() # Delete the task if could not start it
# raise task.delete()
# ..and re-raise
raise
# Set step # Set step
data['step'] = 'created' data['step'] = 'created'
...@@ -585,8 +590,6 @@ def create_task(request): ...@@ -585,8 +590,6 @@ def create_task(request):
# Set step # Set step
data['step'] = 'one' data['step'] = 'one'
return render(request, 'create_task.html', {'data': data}) return render(request, 'create_task.html', {'data': data})
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment