Skip to content
Snippets Groups Projects
Commit 0a107453 authored by André Anjos's avatar André Anjos :speech_balloon:
Browse files

Fix natural-key usage throughout scheduler branch mods (closes #433)

parent 7b8daabd
No related branches found
No related tags found
1 merge request!195Issue 433
...@@ -63,12 +63,12 @@ from ..statistics.utils import updateStatistics ...@@ -63,12 +63,12 @@ from ..statistics.utils import updateStatistics
class EnvironmentManager(ShareableManager): class EnvironmentManager(ShareableManager):
def get_by_natural_key(self, key): def get_by_natural_key(self, name, version):
name, version = key.rsplit(' ', 1) return self.get(name=name, version=version)
return self.get(
name=name, def get_by_fullname(self, fullname):
version=version[1:-1], name, version = fullname.rsplit(' ', 1)
) return self.get_by_natural_key(name, version[1:-1])
class Environment(Shareable): class Environment(Shareable):
...@@ -128,7 +128,7 @@ class Environment(Shareable): ...@@ -128,7 +128,7 @@ class Environment(Shareable):
def natural_key(self): def natural_key(self):
return self.fullname() return (self.name, self.version)
#_____ Utilities __________ #_____ Utilities __________
...@@ -229,7 +229,7 @@ class Worker(models.Model): ...@@ -229,7 +229,7 @@ class Worker(models.Model):
def natural_key(self): def natural_key(self):
return self.name return (self.name,)
def get_admin_change_url(self): def get_admin_change_url(self):
...@@ -303,7 +303,7 @@ class Worker(models.Model): ...@@ -303,7 +303,7 @@ class Worker(models.Model):
wishlist = Environment.objects.filter(queues__in=queues, active=True) wishlist = Environment.objects.filter(queues__in=queues, active=True)
wishlist = wishlist.order_by('id').distinct() wishlist = wishlist.order_by('id').distinct()
required = [k.natural_key() for k in wishlist] required = [k.fullname() for k in wishlist]
missing = [k for k in required if k not in environments] missing = [k for k in required if k not in environments]
unused = [k for k in environments if k not in required] unused = [k for k in environments if k not in required]
...@@ -532,6 +532,8 @@ class Queue(models.Model): ...@@ -532,6 +532,8 @@ class Queue(models.Model):
related_name='queues', related_name='queues',
) )
objects = QueueManager()
#_____ Meta parameters __________ #_____ Meta parameters __________
class Meta: class Meta:
...@@ -553,7 +555,7 @@ class Queue(models.Model): ...@@ -553,7 +555,7 @@ class Queue(models.Model):
def natural_key(self): def natural_key(self):
return self.name return (self.name,)
def get_admin_change_url(self): def get_admin_change_url(self):
...@@ -620,7 +622,7 @@ class Queue(models.Model): ...@@ -620,7 +622,7 @@ class Queue(models.Model):
'time-limit': self.time_limit, 'time-limit': self.time_limit,
'cores-per-slot': self.cores_per_slot, 'cores-per-slot': self.cores_per_slot,
'max-slots-per-user': self.max_slots_per_user, 'max-slots-per-user': self.max_slots_per_user,
'environments': [k.natural_key() for k in self.environments.all()], 'environments': [k.fullname() for k in self.environments.all()],
'slots': dict([(s.worker.name, dict(quantity=s.quantity, 'slots': dict([(s.worker.name, dict(quantity=s.quantity,
priority=s.priority)) for s in self.slots.all()]), priority=s.priority)) for s in self.slots.all()]),
'groups': [k.name for k in Group.objects.all() if 'can_access' in get_perms(k, self)] 'groups': [k.name for k in Group.objects.all() if 'can_access' in get_perms(k, self)]
......
...@@ -280,7 +280,7 @@ def setup_backend(d): ...@@ -280,7 +280,7 @@ def setup_backend(d):
# Associates environments with queues # Associates environments with queues
for envkey in attrs['environments']: for envkey in attrs['environments']:
env = Environment.objects.get_by_natural_key(envkey) env = Environment.objects.get_by_fullname(envkey)
logger.info("Appending `%s' to `%s'...", env, queue) logger.info("Appending `%s' to `%s'...", env, queue)
queue.environments.add(env) queue.environments.add(env)
...@@ -317,7 +317,7 @@ def setup_backend(d): ...@@ -317,7 +317,7 @@ def setup_backend(d):
# 10.3 Associate and dissociate environments # 10.3 Associate and dissociate environments
queue.environments.clear() queue.environments.clear()
for e in attrs['environments']: for e in attrs['environments']:
env = Environment.objects.get_by_natural_key(e) env = Environment.objects.get_by_fullname(e)
logger.info("Appending `%s' to `%s'...", env, queue) logger.info("Appending `%s' to `%s'...", env, queue)
queue.environments.add(env) queue.environments.add(env)
...@@ -369,7 +369,7 @@ def find_environments(paths=None): ...@@ -369,7 +369,7 @@ def find_environments(paths=None):
Returns: Returns:
dict: A dictionary containing each environment available using as key the dict: A dictionary containing each environment available using as key the
natural key for environments (i.e., ``name (version)``) and as values fullname for environments (i.e., ``name (version)``) and as values
another dictionary with these keys: another dictionary with these keys:
* name: The environment name (str) * name: The environment name (str)
...@@ -407,5 +407,5 @@ def pick_execute(split, environments): ...@@ -407,5 +407,5 @@ def pick_execute(split, environments):
"""Resolves the path to the ``execute`` program to use for the split""" """Resolves the path to the ``execute`` program to use for the split"""
# Check we have a compatible environment to execute the user algorithm # Check we have a compatible environment to execute the user algorithm
envinfo = environments.get(split.job.block.environment.natural_key()) envinfo = environments.get(split.job.block.environment.fullname())
return envinfo['execute'] if envinfo else None return envinfo['execute'] if envinfo else None
...@@ -422,6 +422,12 @@ class DatabaseSetTemplateOutput(models.Model): ...@@ -422,6 +422,12 @@ class DatabaseSetTemplateOutput(models.Model):
#---------------------------------------------------------- #----------------------------------------------------------
class DatabaseSetOutputManager(models.Manager):
def get_by_natural_key(self, hash):
return self.get(hash=hash)
class DatabaseSetOutput(models.Model): class DatabaseSetOutput(models.Model):
template = models.ForeignKey(DatabaseSetTemplateOutput, template = models.ForeignKey(DatabaseSetTemplateOutput,
related_name='instances', on_delete=models.CASCADE) related_name='instances', on_delete=models.CASCADE)
...@@ -429,6 +435,8 @@ class DatabaseSetOutput(models.Model): ...@@ -429,6 +435,8 @@ class DatabaseSetOutput(models.Model):
on_delete=models.CASCADE) on_delete=models.CASCADE)
hash = models.CharField(max_length=64, unique=True) hash = models.CharField(max_length=64, unique=True)
objects = DatabaseSetOutputManager()
def __str__(self): def __str__(self):
return self.fullname() return self.fullname()
...@@ -445,3 +453,6 @@ class DatabaseSetOutput(models.Model): ...@@ -445,3 +453,6 @@ class DatabaseSetOutput(models.Model):
def all_needed_dataformats(self): def all_needed_dataformats(self):
return self.template.all_needed_dataformats() return self.template.all_needed_dataformats()
def natural_key(self):
return (self.hash,)
...@@ -1253,7 +1253,7 @@ class CachedFile(models.Model): ...@@ -1253,7 +1253,7 @@ class CachedFile(models.Model):
def natural_key(self): def natural_key(self):
return self.hash return (self.hash,)
def path(self): def path(self):
...@@ -1310,12 +1310,16 @@ class CachedFile(models.Model): ...@@ -1310,12 +1310,16 @@ class CachedFile(models.Model):
class BlockInputManager(models.Manager): class BlockInputManager(models.Manager):
def get_by_natural_key(self, hash): def get_by_natural_key(self, name, experiment_author,
candidate = self.filter(cache__hash=hash) toolchain_author, toolchain_name,
if candidate: toolchain_version, experiment_name, cache_hash, database_hash):
return candidate[0] block = Block.objects.get_by_natural_key(name, experiment_author,
toolchain_author, toolchain_name, toolchain_version,
experiment_name)
if cache_hash:
return self.get(cache__hash=cache_hash, block=block)
else: else:
return self.get(database__hash=hash) return self.get(database__hash=database_hash, block=block)
class BlockInput(models.Model): class BlockInput(models.Model):
...@@ -1337,7 +1341,9 @@ class BlockInput(models.Model): ...@@ -1337,7 +1341,9 @@ class BlockInput(models.Model):
objects = BlockInputManager() objects = BlockInputManager()
def natural_key(self): def natural_key(self):
return self.has, cache_hash = self.cache and self.cache.hash
database_hash = self.database and self.database.hash
return self.block.natural_key() + (cache_hash, database_hash)
#---------------------------------------------------------- #----------------------------------------------------------
......
...@@ -40,7 +40,7 @@ import datetime ...@@ -40,7 +40,7 @@ import datetime
from django.core.management import call_command from django.core.management import call_command
from django.core.management.base import BaseCommand from django.core.management.base import BaseCommand
from django.conf import settings from django.conf import settings
from django.apps import apps from django.apps import apps, registry
from ....import __version__ from ....import __version__
...@@ -133,19 +133,24 @@ class Command(BaseCommand): ...@@ -133,19 +133,24 @@ class Command(BaseCommand):
], ],
) )
# remove uninstalled apps
global APPS
installed_apps = registry.apps.all_models.keys()
use_apps = [app for app in APPS if app in installed_apps]
try: try:
tmpdir = tempfile.mkdtemp('.backup', 'beat.web-') tmpdir = tempfile.mkdtemp('.backup', 'beat.web-')
# backs-up everything else first # backs-up everything else first
arguments = copy.deepcopy(dump_arguments) arguments = copy.deepcopy(dump_arguments)
arguments['exclude'] += APPS arguments['exclude'] += use_apps
destfile = os.path.join(tmpdir, 'initial.json') destfile = os.path.join(tmpdir, 'initial.json')
logger.info("Dumping initial (unspecified) data -> `%s'", destfile) logger.info("Dumping initial (unspecified) data -> `%s'", destfile)
arguments['output'] = destfile #new in Django-1.8.x arguments['output'] = destfile #new in Django-1.8.x
call_command('xdumpdata', **arguments) call_command('xdumpdata', **arguments)
# and backs-up the apps respecting the imposed order # and backs-up the apps respecting the imposed order
for app in APPS: for app in use_apps:
destfile = os.path.join(tmpdir, '%s.json' % app) destfile = os.path.join(tmpdir, '%s.json' % app)
arguments = copy.deepcopy(dump_arguments) arguments = copy.deepcopy(dump_arguments)
......
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