From 797feebd07fcf2625d84df7519ba218eb15925d6 Mon Sep 17 00:00:00 2001 From: Stefano Alberto Russo <stefano.russo@gmail.com> Date: Wed, 24 Nov 2021 01:26:58 +0100 Subject: [PATCH] Added support for extra supported archs, improved arch checks, minor imporvements. --- .../0027_computing_supported_archs.py | 19 ++++++++++++ .../webapp/code/rosetta/core_app/models.py | 9 ++++-- .../core_app/templates/components/task.html | 10 ++++--- .../rosetta/core_app/templates/new_task.html | 6 ++++ .../webapp/code/rosetta/core_app/views.py | 30 ++++++++----------- 5 files changed, 49 insertions(+), 25 deletions(-) create mode 100644 services/webapp/code/rosetta/core_app/migrations/0027_computing_supported_archs.py diff --git a/services/webapp/code/rosetta/core_app/migrations/0027_computing_supported_archs.py b/services/webapp/code/rosetta/core_app/migrations/0027_computing_supported_archs.py new file mode 100644 index 0000000..cb6ee53 --- /dev/null +++ b/services/webapp/code/rosetta/core_app/migrations/0027_computing_supported_archs.py @@ -0,0 +1,19 @@ +# Generated by Django 2.2.1 on 2021-11-24 00:25 + +import django.contrib.postgres.fields.jsonb +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core_app', '0026_auto_20211123_0037'), + ] + + operations = [ + migrations.AddField( + model_name='computing', + name='supported_archs', + field=django.contrib.postgres.fields.jsonb.JSONField(blank=True, null=True, verbose_name='Supported architectures'), + ), + ] diff --git a/services/webapp/code/rosetta/core_app/models.py b/services/webapp/code/rosetta/core_app/models.py index e675c1d..346c996 100644 --- a/services/webapp/code/rosetta/core_app/models.py +++ b/services/webapp/code/rosetta/core_app/models.py @@ -122,7 +122,7 @@ class Container(models.Model): image_name = models.CharField('Image', max_length=255, blank=False, null=False) # Image identifiers - image_tag = models.CharField('Tag', max_length=255, blank=True, null=True, default='latest') + image_tag = models.CharField('Tag', max_length=255, blank=False, null=False, default='latest') image_arch = models.CharField('Architecture', max_length=36, blank=True, null=True) image_os = models.CharField('Operating system', max_length=36, blank=True, null=True) # -- OR -- @@ -183,7 +183,7 @@ class Computing(models.Model): name = models.CharField('Name', max_length=255, blank=False, null=False) description = models.TextField('Description', blank=True, null=True) - # Type (standalone / cluster) and arch + # Type (standalone / cluster) and arch (i.e. amd64) type = models.CharField('Type', max_length=255, blank=False, null=False) arch = models.CharField('Architecture', max_length=255, blank=False, null=False) @@ -196,7 +196,10 @@ class Computing(models.Model): container_runtimes = JSONField('Container runtimes', blank=False, null=False) #container_runtime = models.CharField('Container runtimes', max_length=256, blank=False, null=False) - # Emulated architectures, by container runtime {'docker': ['arm64', 'amd'] + # Supported architectures (i.e. 386 for amd64), as list: ['386'] + supported_archs = JSONField('Supported architectures', blank=True, null=True) + + # Emulated architectures, by container runtime: {'docker': ['arm64/v7', 'arm64/v8'] emulated_archs = JSONField('Emulated architectures', blank=True, null=True) # Conf diff --git a/services/webapp/code/rosetta/core_app/templates/components/task.html b/services/webapp/code/rosetta/core_app/templates/components/task.html index 35ef478..effe0f1 100644 --- a/services/webapp/code/rosetta/core_app/templates/components/task.html +++ b/services/webapp/code/rosetta/core_app/templates/components/task.html @@ -5,6 +5,8 @@ <div style="margin-top:5px; padding:10px; text-align:center; border-bottom: #f8f8f8 solid 1px; "> Task <b>{{data.task.name}}</b> summary </div> + <hr style="margin:0"> + {% else %} <div style="width:350px; float:left; border: #e0e0e0 solid 1px; margin:10px; background:#f8f8f8; margin-bottom:20px"> @@ -27,18 +29,18 @@ </div> --> - <div style="padding:10px;"> + <div style="padding:10px; padding-left:15px; padding-right:15px; text-align:left;"> <!-- <b>Container:</b> {{ task.container.name }} <span style="font-size:14px; background-color:{{task.container.color}}"> </span> <br/> <b>Computing:</b> {{ task.computing.name }} <span style="font-size:14px; background-color:{{task.computing.color}}"> </span><br/> --> - <b>Software:</b> - <a href="/software/?uuid={{ task.container.uuid }}" style="color:{{task.container.color}}">{{ task.container.name }}</a> + <b>Software container:</b> + <a href="/software/?container_uuid={{ task.container.uuid }}" style="color:{{task.container.color}}">{{ task.container.name }}</a> {% if task.container.type == 'docker' %}<img src="/static/img/docker-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %} {% if task.container.type == 'singularity' %}<img src="/static/img/singularity-logo.svg" style="height:18px; width:18px; margin-bottom:4px" />{% endif %} <br/> - <b>Computing:</b> <a href="/computing/?uuid={{ task.computing.uuid }}">{{ task.computing.name }}</a> + <b>Computing resource:</b> <a href="/computing/?uuid={{ task.computing.uuid }}">{{ task.computing.name }}</a> <!-- <a href="/computing/?uuid={{ task.computing.uuid }}" no_style="color:{{task.computing.color}}"><i class="fa fa-external-link" ></i></a><br/> --> <div style="margin-top:2px"> diff --git a/services/webapp/code/rosetta/core_app/templates/new_task.html b/services/webapp/code/rosetta/core_app/templates/new_task.html index c8d9b21..807e554 100644 --- a/services/webapp/code/rosetta/core_app/templates/new_task.html +++ b/services/webapp/code/rosetta/core_app/templates/new_task.html @@ -172,6 +172,12 @@ <i class="fa fa-exclamation-triangle" style="color:orange"></i> The selected software container architecture ({{ data.task_container_arch}}) can only be emulated on this computing resource, meaning the it will probably run quite slow. </p></div> {% endif %} + + {% if data.arch_auto_selection %} + <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> The selected software container does not specify any architecture. This will leave to the container runtime either to auto-select the right image architecture on the registry, or to fallback on emulation if not found. Beware of potential incompatibilities or slowdowns. + </p></div> + {% endif %} <!-- {% if data.task_container.interface_port and not data.task_container.supports_interface_auth %} <div> <p style="font-size:15px; max-width:700px; margin-bottom:20px; margin-left:5px"> diff --git a/services/webapp/code/rosetta/core_app/views.py b/services/webapp/code/rosetta/core_app/views.py index bd1bd89..8af2c5a 100644 --- a/services/webapp/code/rosetta/core_app/views.py +++ b/services/webapp/code/rosetta/core_app/views.py @@ -464,14 +464,6 @@ def new_task(request): raise Exception('Consistency error, container with uuid "{}" does not exists or user "{}" does not have access rights'.format(task_container_uuid, request.user.email)) return task_container - # Get task container arch helper function - def get_task_container_arch(request): - container_arch = request.POST.get('task_container_arch', None) - if not container_arch: - # At the second step the task uuid is set via a GET request - container_arch = request.GET.get('task_container_arch', None) - return container_arch - # Get task computing helper function def get_task_computing(request): task_computing_uuid = request.POST.get('task_computing_uuid', None) @@ -523,24 +515,27 @@ def new_task(request): data['task_computing'] = get_task_computing(request) # Check that container required architecture is compatible with the computing resource + # TODO: support setting the container runtime when creating the task + # TODO: refactor and unroll this code if data['task_container'].image_arch: - if data['task_container'].image_arch != data['task_computing'].arch: - # TODO: support setting the container runtime when creating the task - # TODO: refactor and unroll this code - # TODO: add support for setting the container runtime + if (data['task_container'].image_arch != data['task_computing'].arch) and (data['task_container'].image_arch not in data['task_computing'].supported_archs): + if data['task_computing'].emulated_archs: container_runtime = data['task_computing'].container_runtimes[0] + if container_runtime in data['task_computing'].emulated_archs and data['task_container'].image_arch in data['task_computing'].emulated_archs[container_runtime]: data['arch_emulation'] = True + else: - raise ErrorMessage('This computing resource does not support architecture "{}" nor as native or emulated'.format(data['task_container'].image_arch)) + raise ErrorMessage('This computing resource does not support architecture \'{}\' nor as native or emulated'.format(data['task_container'].image_arch)) + else: - raise ErrorMessage('This computing resource does not support architecture "{}" nor as native or emulated'.format(data['task_container'].image_arch)) + raise ErrorMessage('This computing resource does not support architecture \'{}\' nor as native or emulated'.format(data['task_container'].image_arch)) else: - raise ErrorMessage('Auto detecting architectures is not supported yet') - - + data['arch_auto_selection'] = True + #raise ErrorMessage('Auto selecting architectures is not supported yet') + # Generate random auth token data['task_auth_token'] = str(uuid.uuid4()) @@ -553,7 +548,6 @@ def new_task(request): # Get software container and arch data['task_container'] = get_task_container(request) - data['task_container_arch'] = get_task_container_arch(request) # Get computing resource data['task_computing'] = get_task_computing(request) -- GitLab