From 005da01aedeb002bf19214bf355367e0d9db48e0 Mon Sep 17 00:00:00 2001 From: Philip ABBET <philip.abbet@idiap.ch> Date: Wed, 23 Nov 2016 14:26:30 +0100 Subject: [PATCH] [db] Add supported languages to the 'backend.Environment' model --- .../migrations/0003_auto_20161123_1218.py | 20 +++++++++++ beat/web/backend/admin.py | 9 +++++ beat/web/backend/api.py | 2 ++ .../web/backend/management/commands/qsetup.py | 12 ++++++- .../migrations/0004_environmentlanguage.py | 34 +++++++++++++++++++ beat/web/backend/models.py | 11 ++++++ beat/web/backend/tests.py | 10 +++--- beat/web/backend/utils.py | 17 ++++++++-- beat/web/code/models.py | 11 +++++- beat/web/code/serializers.py | 2 +- .../migrations/0003_auto_20161123_1218.py | 20 +++++++++++ .../migrations/0003_auto_20161123_1218.py | 20 +++++++++++ 12 files changed, 159 insertions(+), 9 deletions(-) create mode 100644 beat/web/algorithms/migrations/0003_auto_20161123_1218.py mode change 100644 => 100755 beat/web/backend/admin.py mode change 100644 => 100755 beat/web/backend/api.py mode change 100644 => 100755 beat/web/backend/management/commands/qsetup.py create mode 100644 beat/web/backend/migrations/0004_environmentlanguage.py mode change 100644 => 100755 beat/web/backend/models.py create mode 100644 beat/web/libraries/migrations/0003_auto_20161123_1218.py create mode 100644 beat/web/plotters/migrations/0003_auto_20161123_1218.py diff --git a/beat/web/algorithms/migrations/0003_auto_20161123_1218.py b/beat/web/algorithms/migrations/0003_auto_20161123_1218.py new file mode 100644 index 000000000..da49951e7 --- /dev/null +++ b/beat/web/algorithms/migrations/0003_auto_20161123_1218.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-11-23 12:18 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('algorithms', '0002_cxx_backend'), + ] + + operations = [ + migrations.AlterField( + model_name='algorithm', + name='language', + field=models.CharField(choices=[(b'U', b'Unknown'), (b'C', b'Cxx'), (b'M', b'Matlab'), (b'P', b'Python'), (b'R', b'R')], default=b'P', max_length=1), + ), + ] diff --git a/beat/web/backend/admin.py b/beat/web/backend/admin.py old mode 100644 new mode 100755 index 8658a41a4..3a113b9e2 --- a/beat/web/backend/admin.py +++ b/beat/web/backend/admin.py @@ -29,6 +29,7 @@ from django.contrib import admin from django import forms from .models import Environment as EnvironmentModel +from .models import EnvironmentLanguage as EnvironmentLanguageModel from .models import Worker as WorkerModel from .models import Queue as QueueModel from .models import Slot as SlotModel @@ -64,6 +65,10 @@ class EnvironmentModelForm(forms.ModelForm): } +class EnvironmentLanguageInline(admin.TabularInline): + model = EnvironmentLanguageModel + + class Environment(admin.ModelAdmin): list_display = ( @@ -87,6 +92,10 @@ class Environment(admin.ModelAdmin): 'name', ) + inlines = [ + EnvironmentLanguageInline + ] + form = EnvironmentModelForm filter_horizontal = [ diff --git a/beat/web/backend/api.py b/beat/web/backend/api.py old mode 100644 new mode 100755 index 258472e8c..f0757c3b6 --- a/beat/web/backend/api.py +++ b/beat/web/backend/api.py @@ -30,6 +30,7 @@ from rest_framework.response import Response from rest_framework import permissions from .models import Environment +from ..code.models import Code @api_view(['GET']) @@ -68,6 +69,7 @@ def accessible_environments_list(request): 'short_description': environment.short_description, 'queues': queues, 'accessibility': accessibility, + 'languages': [ Code.language_identifier(x.language) for x in environment.languages.iterator() ], }) return Response(result) diff --git a/beat/web/backend/management/commands/qsetup.py b/beat/web/backend/management/commands/qsetup.py old mode 100644 new mode 100755 index 080d86964..f903d4524 --- a/beat/web/backend/management/commands/qsetup.py +++ b/beat/web/backend/management/commands/qsetup.py @@ -43,7 +43,9 @@ import socket CORES = psutil.cpu_count() RAM = psutil.virtual_memory().total/(1024*1024) ENVIRONMENT = {'name': 'environment', 'version': '1'} +CXX_ENVIRONMENT = {'name': 'cxx_environment', 'version': '1'} ENVKEY = '%(name)s (%(version)s)' % ENVIRONMENT +CXX_ENVKEY = '%(name)s (%(version)s)' % CXX_ENVIRONMENT HOSTNAME = socket.gethostname() DEFAULT_CONFIGURATION = { @@ -53,7 +55,7 @@ DEFAULT_CONFIGURATION = { "time-limit": 1440, #1 day "cores-per-slot": 1, "max-slots-per-user": CORES, - "environments": [ENVKEY], + "environments": [CXX_ENVKEY, ENVKEY], "slots": { HOSTNAME: { "quantity": CORES, @@ -69,10 +71,18 @@ DEFAULT_CONFIGURATION = { ENVKEY: { "name": ENVIRONMENT['name'], "version": ENVIRONMENT['version'], + "languages": ['python'], "short_description": "Local python interpreter", "description": "Automatically generated local python " \ "interpreter environment", }, + CXX_ENVKEY: { + "name": CXX_ENVIRONMENT['name'], + "version": CXX_ENVIRONMENT['version'], + "languages": ['cxx'], + "short_description": "C++ backend", + "description": "C++ backend running in a docker container", + }, }, "workers": { HOSTNAME: { diff --git a/beat/web/backend/migrations/0004_environmentlanguage.py b/beat/web/backend/migrations/0004_environmentlanguage.py new file mode 100644 index 000000000..53a3594d3 --- /dev/null +++ b/beat/web/backend/migrations/0004_environmentlanguage.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-11-23 12:18 +from __future__ import unicode_literals + +from django.db import migrations, models +import django.db.models.deletion + + +def add_default_language(apps, schema_editor): + Environment = apps.get_model("backend", "Environment") + EnvironmentLanguage = apps.get_model("backend", "EnvironmentLanguage") + + for env in Environment.objects.all(): + lang = EnvironmentLanguage(language='P', environment=env) + lang.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ('backend', '0003_remove_result_syserr'), + ] + + operations = [ + migrations.CreateModel( + name='EnvironmentLanguage', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('language', models.CharField(choices=[(b'U', b'Unknown'), (b'C', b'Cxx'), (b'M', b'Matlab'), (b'P', b'Python'), (b'R', b'R')], default=b'P', max_length=1)), + ('environment', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='languages', to='backend.Environment')), + ], + ), + migrations.RunPython(add_default_language, migrations.RunPython.noop), + ] diff --git a/beat/web/backend/models.py b/beat/web/backend/models.py old mode 100644 new mode 100755 index d896979b1..eb6a447fb --- a/beat/web/backend/models.py +++ b/beat/web/backend/models.py @@ -53,6 +53,7 @@ import beat.core.stats import beat.core.data import beat.core.execution +from ..code.models import Code from ..common.models import Shareable, ShareableManager from ..common.texts import Messages from ..statistics.utils import updateStatistics @@ -164,6 +165,16 @@ class Environment(Shareable): ) +class EnvironmentLanguage(models.Model): + + environment = models.ForeignKey(Environment, + related_name='languages' + ) + + language = models.CharField(max_length=1, choices=Code.CODE_LANGUAGE, + default=Code.PYTHON) + + #---------------------------------------------------------- diff --git a/beat/web/backend/tests.py b/beat/web/backend/tests.py index cebfc4368..f51d93957 100755 --- a/beat/web/backend/tests.py +++ b/beat/web/backend/tests.py @@ -133,6 +133,7 @@ QUEUES_WITHOUT_PRIORITY = { "version": '1', "short_description": "Test", "description": "Test environment", + "languages": "python", }, }, } @@ -222,6 +223,7 @@ PRIORITY_QUEUES = { "version": '1', "short_description": "Test", "description": "Test environment", + "languages": "python", }, }, } @@ -380,7 +382,7 @@ class BaseBackendTestCase(TestCase): setup_backend(qsetup.DEFAULT_CONFIGURATION) Worker.objects.update(active=True) - env = Environment.objects.first() + env = Environment.objects.get(name='environment') queue = Queue.objects.first() template_data = dict( @@ -1959,7 +1961,7 @@ class SchedulingPriority(BaseBackendTestCase): q1 = Queue.objects.get(name='q1') q2 = Queue.objects.get(name='q2') - env = Environment.objects.get() + env = Environment.objects.get(name='environment') # reset queue and environment to new backend configuration self.set_globals(xp, q1, env) @@ -2006,7 +2008,7 @@ class SchedulingPriority(BaseBackendTestCase): q1 = Queue.objects.get(name='q1') q4 = Queue.objects.get(name='q4') - env = Environment.objects.get() + env = Environment.objects.get(name='environment') # reset queue and environment to new backend configuration self.set_globals(xp, q1, env) @@ -2046,7 +2048,7 @@ class SchedulingPriority(BaseBackendTestCase): Worker.objects.update(active=True) q1 = Queue.objects.get(name='q1') - env = Environment.objects.get() + env = Environment.objects.get(name='environment') fullname = 'user/user/single/1/single' xp = Experiment.objects.get(name=fullname.split(os.sep)[-1]) diff --git a/beat/web/backend/utils.py b/beat/web/backend/utils.py index 209cd9bdf..3ebfbe959 100755 --- a/beat/web/backend/utils.py +++ b/beat/web/backend/utils.py @@ -43,9 +43,10 @@ from django.db import transaction from django.contrib.auth.models import Group from guardian.shortcuts import assign_perm +from ..code.models import Code from ..common.models import Shareable from ..experiments.models import CachedFile, Block, Experiment -from .models import Queue, Worker, Job, Environment, Slot +from .models import Queue, Worker, Job, Environment, EnvironmentLanguage, Slot def cleanup_cache(path, age_in_minutes=0, delete=False): @@ -219,6 +220,13 @@ def setup_backend(d): logger.info("Creating `%s'...", env) env.save() + for language in attrs['languages']: + lang = EnvironmentLanguage( + language=Code.language_db(language), + environment=env + ) + lang.save() + # 8.1 Create new workers config_workers = set(d['workers'].keys()) current_workers = set(Worker.objects.values_list('name', flat=True)) @@ -338,9 +346,14 @@ def setup_backend(d): def dump_backend(): '''Returns a dictionary that represents the current backend configuration''' + environments = {} + for env in Environment.objects.all(): + environments[str(env)] = env.as_dict() + environments[str(env)]['languages'] = [ Code.language_identifier(x.language) for x in env.languages.iterator() ] + return dict( queues=dict([(k.name, k.as_dict()) for k in Queue.objects.all()]), - environments=dict([(str(k), k.as_dict()) for k in Environment.objects.all()]), + environments=environments, workers=dict([(k.name, k.as_dict()) for k in Worker.objects.all()]), ) diff --git a/beat/web/code/models.py b/beat/web/code/models.py index 33d98329b..c7053c6bf 100755 --- a/beat/web/code/models.py +++ b/beat/web/code/models.py @@ -487,7 +487,16 @@ class Code(StoredContribution): def json_language(self): - return filter(lambda x: x[0] == self.language, Code.CODE_LANGUAGE)[0][1].lower() + return Code.language_identifier(self.language) + + + @staticmethod + def language_identifier(db_language): + return filter(lambda x: x[0] == db_language, iter(Code.CODE_LANGUAGE))[0][1].lower() + + @staticmethod + def language_db(language_identifier): + return filter(lambda x: x[1].lower() == language_identifier, iter(Code.CODE_LANGUAGE))[0][0] #_____ Overrides __________ diff --git a/beat/web/code/serializers.py b/beat/web/code/serializers.py index 9662168fe..08307391e 100755 --- a/beat/web/code/serializers.py +++ b/beat/web/code/serializers.py @@ -88,7 +88,7 @@ class CodeSerializer(ContributionSerializer): return open_source def get_language(self, obj): - return filter(lambda x: x[0] == obj.language, iter(Code.CODE_LANGUAGE))[0][1].lower() + return Code.language_identifier(obj.language) def get_accessibility(self, obj): if obj.sharing == Code.PUBLIC: diff --git a/beat/web/libraries/migrations/0003_auto_20161123_1218.py b/beat/web/libraries/migrations/0003_auto_20161123_1218.py new file mode 100644 index 000000000..a9cf143a8 --- /dev/null +++ b/beat/web/libraries/migrations/0003_auto_20161123_1218.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-11-23 12:18 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('libraries', '0002_cxx_backend'), + ] + + operations = [ + migrations.AlterField( + model_name='library', + name='language', + field=models.CharField(choices=[(b'U', b'Unknown'), (b'C', b'Cxx'), (b'M', b'Matlab'), (b'P', b'Python'), (b'R', b'R')], default=b'P', max_length=1), + ), + ] diff --git a/beat/web/plotters/migrations/0003_auto_20161123_1218.py b/beat/web/plotters/migrations/0003_auto_20161123_1218.py new file mode 100644 index 000000000..7bae8a1cd --- /dev/null +++ b/beat/web/plotters/migrations/0003_auto_20161123_1218.py @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- +# Generated by Django 1.9.11 on 2016-11-23 12:18 +from __future__ import unicode_literals + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('plotters', '0002_cxx_backend'), + ] + + operations = [ + migrations.AlterField( + model_name='plotter', + name='language', + field=models.CharField(choices=[(b'U', b'Unknown'), (b'C', b'Cxx'), (b'M', b'Matlab'), (b'P', b'Python'), (b'R', b'R')], default=b'P', max_length=1), + ), + ] -- GitLab