Commit 1479f83b by Dudás Ádám

vm: 'redeploy' functionality for VM instances

parent 9eb35a7a
...@@ -454,25 +454,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -454,25 +454,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
self.time_of_delete = timezone.now() + self.lease.delete_interval self.time_of_delete = timezone.now() + self.lease.delete_interval
self.save() self.save()
def deploy(self, user=None, task_uuid=None): def __schedule_vm(self, act):
"""Deploy new virtual machine with network """Schedule the virtual machine.
:param self: The virtual machine to deploy. :param self: The virtual machine.
:type self: vm.models.Instance
:param user: The user who's issuing the command. :param act: Parent activity.
:type user: django.contrib.auth.models.User
:param task_uuid: The task's UUID, if the command is being executed
asynchronously.
:type task_uuid: str
""" """
with instance_activity(code_suffix='deploy', instance=self,
task_uuid=task_uuid, user=user) as act:
# Clear destroyed flag
self.destroyed = None
# Find unused port for VNC # Find unused port for VNC
if self.vnc_port is None: if self.vnc_port is None:
self.vnc_port = find_unused_vnc_port() self.vnc_port = find_unused_vnc_port()
...@@ -483,19 +471,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -483,19 +471,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
self.save() self.save()
# Deploy virtual images def __deploy_vm(self, act):
with act.sub_activity('deploying_disks'): """Deploy the virtual machine.
devnums = list(string.lowercase) # a-z
for disk in self.disks.all(): :param self: The virtual machine.
# assign device numbers
if disk.dev_num in devnums:
devnums.remove(disk.dev_num)
else:
disk.dev_num = devnums.pop(0)
disk.save()
# deploy disk
disk.deploy()
:param act: Parent activity.
"""
queue_name = self.get_remote_queue_name('vm') queue_name = self.get_remote_queue_name('vm')
# Deploy VM on remote machine # Deploy VM on remote machine
...@@ -508,9 +490,6 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -508,9 +490,6 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
for net in self.interface_set.all(): for net in self.interface_set.all():
net.deploy() net.deploy()
# Generate context
# TODO
# Resume vm # Resume vm
with act.sub_activity('booting'): with act.sub_activity('booting'):
vm_tasks.resume.apply_async(args=[self.vm_name], vm_tasks.resume.apply_async(args=[self.vm_name],
...@@ -518,18 +497,10 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -518,18 +497,10 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
self.renew('suspend') self.renew('suspend')
def deploy_async(self, user=None): def deploy(self, user=None, task_uuid=None):
"""Execute deploy asynchronously. """Deploy new virtual machine with network
"""
logger.debug('Calling async local_tasks.deploy(%s, %s)',
unicode(self), unicode(user))
return local_tasks.deploy.apply_async(args=[self, user],
queue="localhost.man")
def destroy(self, user=None, task_uuid=None):
"""Remove virtual machine and its networks.
:param self: The virtual machine to destroy. :param self: The virtual machine to deploy.
:type self: vm.models.Instance :type self: vm.models.Instance
:param user: The user who's issuing the command. :param user: The user who's issuing the command.
...@@ -539,13 +510,44 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -539,13 +510,44 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
asynchronously. asynchronously.
:type task_uuid: str :type task_uuid: str
""" """
if self.destroyed: with instance_activity(code_suffix='deploy', instance=self,
return # already destroyed, nothing to do here
with instance_activity(code_suffix='destroy', instance=self,
task_uuid=task_uuid, user=user) as act: task_uuid=task_uuid, user=user) as act:
if self.node: # Clear destroyed flag
self.destroyed = None
self.__schedule_vm(act)
# Deploy virtual images
with act.sub_activity('deploying_disks'):
devnums = list(string.lowercase) # a-z
for disk in self.disks.all():
# assign device numbers
if disk.dev_num in devnums:
devnums.remove(disk.dev_num)
else:
disk.dev_num = devnums.pop(0)
disk.save()
# deploy disk
disk.deploy()
self.__deploy_vm(act)
def deploy_async(self, user=None):
"""Execute deploy asynchronously.
"""
logger.debug('Calling async local_tasks.deploy(%s, %s)',
unicode(self), unicode(user))
return local_tasks.deploy.apply_async(args=[self, user],
queue="localhost.man")
def __destroy_vm(self, act):
"""Destroy the virtual machine and its associated networks.
:param self: The virtual machine.
:param act: Parent activity.
"""
# Destroy networks # Destroy networks
with act.sub_activity('destroying_net'): with act.sub_activity('destroying_net'):
for net in self.interface_set.all(): for net in self.interface_set.all():
...@@ -557,11 +559,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -557,11 +559,13 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
vm_tasks.destroy.apply_async(args=[self.vm_name], vm_tasks.destroy.apply_async(args=[self.vm_name],
queue=queue_name).get() queue=queue_name).get()
# Destroy disks def __cleanup_after_destroy_vm(self, act):
with act.sub_activity('destroying_disks'): """Clean up the virtual machine's data after destroy.
for disk in self.disks.all():
disk.destroy() :param self: The virtual machine.
:param act: Parent activity.
"""
# Delete mem. dump if exists # Delete mem. dump if exists
queue_name = self.mem_dump['datastore'].get_remote_queue_name( queue_name = self.mem_dump['datastore'].get_remote_queue_name(
'storage') 'storage')
...@@ -576,6 +580,66 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel): ...@@ -576,6 +580,66 @@ class Instance(AclBase, VirtualMachineDescModel, TimeStampedModel):
self.node = None self.node = None
self.vnc_port = None self.vnc_port = None
def redeploy(self, user=None, task_uuid=None):
"""Redeploy virtual machine with network
:param self: The virtual machine to redeploy.
:param user: The user who's issuing the command.
:type user: django.contrib.auth.models.User
:param task_uuid: The task's UUID, if the command is being executed
asynchronously.
:type task_uuid: str
"""
with instance_activity(code_suffix='redeploy', instance=self,
task_uuid=task_uuid, user=user) as act:
# Destroy VM
if self.node:
self.__destroy_vm(act)
self.__cleanup_after_destroy_vm(act)
# Deploy VM
self.__schedule_vm(act)
self.__deploy_vm(act)
def redeploy_async(self, user=None):
"""Execute redeploy asynchronously.
"""
return local_tasks.redeploy.apply_async(args=[self, user],
queue="localhost.man")
def destroy(self, user=None, task_uuid=None):
"""Remove virtual machine and its networks.
:param self: The virtual machine to destroy.
:type self: vm.models.Instance
:param user: The user who's issuing the command.
:type user: django.contrib.auth.models.User
:param task_uuid: The task's UUID, if the command is being executed
asynchronously.
:type task_uuid: str
"""
if self.destroyed:
return # already destroyed, nothing to do here
with instance_activity(code_suffix='destroy', instance=self,
task_uuid=task_uuid, user=user) as act:
if self.node:
self.__destroy_vm(act)
# Destroy disks
with act.sub_activity('destroying_disks'):
for disk in self.disks.all():
disk.destroy()
self.__cleanup_after_destroy_vm(act)
self.destroyed = timezone.now() self.destroyed = timezone.now()
self.save() self.save()
......
...@@ -9,6 +9,11 @@ def deploy(instance, user): ...@@ -9,6 +9,11 @@ def deploy(instance, user):
@celery.task @celery.task
def redeploy(instance, user):
instance.redeploy(task_uuid=redeploy.request.id, user=user)
@celery.task
def destroy(instance, user): def destroy(instance, user):
instance.destroy(task_uuid=destroy.request.id, user=user) instance.destroy(task_uuid=destroy.request.id, user=user)
......
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