Commit 8d7d535a by Dudás Ádám

storage: save_as functionality for Disk

parent a27b6095
......@@ -66,6 +66,15 @@ class Disk(TimeStampedModel):
return ("Operation can't be invoked on a disk of type '%s'." %
class DiskInUseError(Exception):
def __init__(self, disk):
self.disk = disk
def __str__(self):
return ("The requested operation can't be performed on disk "
"'%s (%s)' because it is in use." %
(, self.disk.filename))
def path(self):
return self.datastore.path + '/' + self.filename
......@@ -88,6 +97,9 @@ class Disk(TimeStampedModel):
'iso': 'hd',
def is_in_use(self):
return self.instance_set.exclude(state='SHUTOFF').exists()
def get_exclusive(self):
"""Get an instance of the disk for exclusive usage.
......@@ -199,6 +211,45 @@ class Disk(TimeStampedModel):
local_tasks.restore.apply_async(args=[self, user],
def save_as(self, name, user=None, task_uuid=None):
mapping = {
'qcow2-snap': ('qcow2-norm', self.base),
if self.type not in mapping.keys():
raise self.WrongDiskTypeError(self.type)
if self.is_in_use():
raise self.DiskInUseError(self)
# from this point on, the caller has to guarantee that the disk is not
# going to be used until the operation is complete
act = DiskActivity(activity_code='storage.Disk.save_as')
act.disk = self
act.started =
act.state = 'PENDING'
act.task_uuid = task_uuid
act.user = user
filename = str(uuid.uuid4())
new_type, new_base = mapping[self.type]
disk = Disk.objects.create(base=new_base, datastore=self.datastore,
filename=filename, name=name,
size=self.size, type=new_type)
queue_name = self.datastore.hostname + ".storage"
disk.ready = True
return disk
class DiskActivity(TimeStampedModel):
activity_code = CharField(verbose_name=_('activity_code'), max_length=100)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment