From f6e1dcbe524d2c16bf3c1bd5beeac4e26c1260a7 Mon Sep 17 00:00:00 2001 From: Guba Sándor <guba.sandor@cloud.bme.hu> Date: Tue, 18 Mar 2014 11:05:07 +0100 Subject: [PATCH] save_as fixes --- circle/storage/models.py | 20 +++++++++++++++++--- circle/storage/tasks/periodic_tasks.py | 11 ++++++----- circle/vm/models/instance.py | 33 ++++++++++++++++++--------------- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/circle/storage/models.py b/circle/storage/models.py index 9e50bcb..d5b6f59 100644 --- a/circle/storage/models.py +++ b/circle/storage/models.py @@ -107,6 +107,18 @@ class Disk(AclBase, TimeStampedModel): self.disk = disk + class DiskIsNotReady(Exception): + + def __init__(self, disk, message=None): + if message is None: + message = ("The requested operation can'T be performed on " + "disk '%s (%s)' because it has never been" + "deployed." % (disk.name, disk.filename)) + + Exception.__init__(self, message) + + self.disk = disk + @property def ready(self): return self.activity_log.filter(activity_code__endswith="deploy", @@ -306,6 +318,7 @@ class Disk(AclBase, TimeStampedModel): datastore = params.pop('datastore', DataStore.objects.get()) disk = cls(filename=str(uuid.uuid4()), datastore=datastore, **params) disk.save() + logger.debug("Disk created: %s", params) with disk_activity(code_suffix="create", user=user, disk=disk): @@ -366,8 +379,6 @@ class Disk(AclBase, TimeStampedModel): kwargs.setdefault('name', url.split('/')[-1]) disk = Disk.create(type="iso", instance=instance, user=user, size=None, **kwargs) - # TODO get proper datastore - disk.datastore = DataStore.objects.get() queue_name = disk.get_remote_queue_name('storage') def __on_abort(activity, error): @@ -439,6 +450,7 @@ class Disk(AclBase, TimeStampedModel): """ mapping = { 'qcow2-snap': ('qcow2-norm', self.base), + 'qcow2-norm': ('qcow2-norm', self), } if self.type not in mapping.keys(): raise self.WrongDiskTypeError(self.type) @@ -446,6 +458,9 @@ class Disk(AclBase, TimeStampedModel): if self.is_in_use: raise self.DiskInUseError(self) + if not self.ready: + raise self.DiskIsNotReady(self) + # from this point on, the caller has to guarantee that the disk is not # going to be used until the operation is complete @@ -455,7 +470,6 @@ class Disk(AclBase, TimeStampedModel): name=self.name, size=self.size, type=new_type) - disk.save() with disk_activity(code_suffix="save_as", disk=self, user=user, task_uuid=task_uuid): with disk_activity(code_suffix="deploy", disk=disk, diff --git a/circle/storage/tasks/periodic_tasks.py b/circle/storage/tasks/periodic_tasks.py index 6dcafd8..ed37e9b 100644 --- a/circle/storage/tasks/periodic_tasks.py +++ b/circle/storage/tasks/periodic_tasks.py @@ -1,5 +1,4 @@ from storage.models import DataStore -import os from manager.mancelery import celery import logging from storage.tasks import remote_tasks @@ -16,13 +15,15 @@ def garbage_collector(timeout=15): deletes oldest images from trash. :param timeout: Seconds before TimeOut exception - :type timeoit: int + :type timeout: int """ for ds in DataStore.objects.all(): - file_list = os.listdir(ds.path) - disk_list = ds.get_deletable_disks() queue_name = ds.get_remote_queue_name('storage') - for i in set(file_list).intersection(disk_list): + files = set(remote_tasks.list_files.apply_async( + args=[ds.path], queue=queue_name).get(timeout=timeout)) + disks = set(ds.get_deletable_disks()) + queue_name = ds.get_remote_queue_name('storage') + for i in disks & files: logger.info("Image: %s at Datastore: %s moved to trash folder." % (i, ds.path)) remote_tasks.move_to_trash.apply_async( diff --git a/circle/vm/models/instance.py b/circle/vm/models/instance.py index f1f5bc2..d8de345 100644 --- a/circle/vm/models/instance.py +++ b/circle/vm/models/instance.py @@ -1128,20 +1128,23 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, with instance_activity(code_suffix="save_as_template", instance=self, task_uuid=task_uuid, user=user) as act: # prepare parameters - kwargs.setdefault('name', name) - kwargs.setdefault('description', self.description) - kwargs.setdefault('parent', self.template) - kwargs.setdefault('num_cores', self.num_cores) - kwargs.setdefault('ram_size', self.ram_size) - kwargs.setdefault('max_ram_size', self.max_ram_size) - kwargs.setdefault('arch', self.arch) - kwargs.setdefault('priority', self.priority) - kwargs.setdefault('boot_menu', self.boot_menu) - kwargs.setdefault('raw_data', self.raw_data) - kwargs.setdefault('lease', self.lease) - kwargs.setdefault('access_method', self.access_method) - kwargs.setdefault('system', self.template.system - if self.template else None) + params = { + 'access_method': self.access_method, + 'arch': self.arch, + 'boot_menu': self.boot_menu, + 'description': self.description, + 'lease': self.lease, # Can be problem in new VM + 'max_ram_size': self.max_ram_size, + 'name': name, + 'num_cores': self.num_cores, + 'owner': user, + 'parent': self.template, # Can be problem + 'priority': self.priority, + 'ram_size': self.ram_size, + 'raw_data': self.raw_data, + 'system': self.template.system if self.template else "", + } + params.update(kwargs) def __try_save_disk(disk): try: @@ -1150,7 +1153,7 @@ class Instance(AclBase, VirtualMachineDescModel, StatusModel, return disk # create template and do additional setup - tmpl = InstanceTemplate(**kwargs) + tmpl = InstanceTemplate(**params) tmpl.full_clean() # Avoiding database errors. tmpl.save() with act.sub_activity('saving_disks'): -- libgit2 0.26.0