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