Merge lp:~nuclearbob/utah/vm-teardown-fix into lp:utah

Proposed by Max Brustkern
Status: Merged
Approved by: Javier Collado
Approved revision: 725
Merged at revision: 755
Proposed branch: lp:~nuclearbob/utah/vm-teardown-fix
Merge into: lp:utah
Diff against target: 116 lines (+35/-16)
2 files modified
utah/provisioning/vm/libvirtvm.py (+34/-16)
utah/provisioning/vm/vm.py (+1/-0)
To merge this branch: bzr merge lp:~nuclearbob/utah/vm-teardown-fix
Reviewer Review Type Date Requested Status
Javier Collado (community) Approve
Max Brustkern (community) Needs Resubmitting
Review via email: mp+131082@code.launchpad.net

Description of the change

This branch wraps checks if self.vm is None in virtual machine classes to handle things correctly when self.vm has not yet been setup. Also, self.disks in destroy is similarly wrapped in a try/except block to workaround problems.

To post a comment you must log in.
Revision history for this message
Javier Collado (javier.collado) wrote :

I'm not sure about how all this works, but I think that `vm` attribute
should be initialized to None in the __init_ method and that all the
try/except blocks should be transformed to checks to ensure that `vm`
is not `None`.

Revision history for this message
Max Brustkern (nuclearbob) wrote :

That makes sense. I'll make that change and resubmit later.

Revision history for this message
Javier Collado (javier.collado) wrote :

@Max

Thanks for the update.

Looking at the code, something I find a little bit weird is that activecheck
and _start call themselves recursively and there isn't a clear base case defined
in the code to stop the recursion.

What I mean is that if lv.lookupByName misbehaves and returns None, then _load
will be useless and activecheck/_start will call themselves indefinitely until
a stack overflow exception is raised.

Aside from that, I've seen that lv.lookupByName might raise libvirtError and
indeed there's a try/except block to detect that when calling _load from _provision.
Shouldn't activecheck and _start take that into account as well?

review: Needs Information
lp:~nuclearbob/utah/vm-teardown-fix updated
722. By Max Brustkern

Merged latest changes and rewrote behavior of _start and activecheck
* Merged initial arm support
* Pushing version to 0.5 to create a new stable version before UDS
* phoenix - Fix comment for fetch_method.
* phoenix - Adjust default ts_control to be more informative

723. By Max Brustkern

Merged latest changes
Dashboard integration merge

Revision history for this message
Max Brustkern (nuclearbob) wrote :

activecheck and _start shouldn't really be concerned with provisioning. activecheck runs provisioncheck, so if the machine isn't provisioned properly, something else should raise an exception. Just in case we somehow get past that, activecheck and start will now raise exceptions if self.vm isn't defined. Other than that, their behavior should be somewhat simpler, mostly assuming that provisioncheck either does its job or raises an exception.

This is some of the first code I wrote for UTAH, and I think I've learned a lot since then. Let me know what you think of the new changes. I've also merged the latest stuff from the dev branch.

review: Needs Resubmitting
lp:~nuclearbob/utah/vm-teardown-fix updated
724. By Max Brustkern

Changed CustomVM _start to be more like LibvirtVM _start

725. By Max Brustkern

Updated destroy method

Revision history for this message
Javier Collado (javier.collado) wrote :

It's been a while since I reviewed this branch, but I no longer see the issues in my previous comment, so I'm approving the merge request.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'utah/provisioning/vm/libvirtvm.py'
--- utah/provisioning/vm/libvirtvm.py 2012-10-19 21:57:01 +0000
+++ utah/provisioning/vm/libvirtvm.py 2012-11-08 18:18:27 +0000
@@ -91,17 +91,24 @@
91 """91 """
92 self.logger.debug('Checking if VM is active')92 self.logger.debug('Checking if VM is active')
93 self.provisioncheck()93 self.provisioncheck()
94 if self.vm.isActive() == 0:94 if self.vm is not None:
95 self._start()95 if self.vm.isActive() == 0:
96 self._start()
97 else:
98 self.active = True
96 else:99 else:
97 self.active = True100 raise UTAHVMProvisioningException('Failed to provision VM')
98101
99 def _start(self):102 def _start(self):
100 """103 """
101 Verify the machine is provisioned, then start it.104 Start the VM.
102 """105 """
103 self.logger.info('Starting VM')106 self.logger.info('Starting VM')
104 self.vm.create()107 if self.vm is not None:
108 if self.vm.isActive() == 0:
109 self.vm.create()
110 else:
111 raise UTAHVMProvisioningException('Failed to provision VM')
105 self.active = True112 self.active = True
106113
107 def stop(self, force=False):114 def stop(self, force=False):
@@ -111,14 +118,17 @@
111 one.118 one.
112 """119 """
113 self.logger.info('Stopping VM')120 self.logger.info('Stopping VM')
114 if self.vm.isActive() == 0:121 if self.vm is not None:
115 self.logger.info('VM is already stopped')122 if self.vm.isActive() == 0:
123 self.logger.info('VM is already stopped')
124 else:
125 if force:
126 self.logger.info('Forced shutdown requested')
127 self.vm.destroy()
128 else:
129 self.vm.shutdown()
116 else:130 else:
117 if force:131 self.logger.info('VM not yet created')
118 self.logger.info('Forced shutdown requested')
119 self.vm.destroy()
120 else:
121 self.vm.shutdown()
122 self.active = False132 self.active = False
123133
124 def libvirterrorhandler(self, _context, err):134 def libvirterrorhandler(self, _context, err):
@@ -367,6 +377,7 @@
367 self.disksizes = [8]377 self.disksizes = [8]
368 else:378 else:
369 self.disksizes = disksizes379 self.disksizes = disksizes
380 self.disks = []
370 if name is None:381 if name is None:
371 autoname = True382 autoname = True
372 name = '-'.join([str(prefix), str(machineid)])383 name = '-'.join([str(prefix), str(machineid)])
@@ -423,7 +434,6 @@
423 self.logger.info('Creating disks')434 self.logger.info('Creating disks')
424 if disksizes is None:435 if disksizes is None:
425 disksizes = self.disksizes436 disksizes = self.disksizes
426 self.disks = []
427 for index, size in enumerate(disksizes):437 for index, size in enumerate(disksizes):
428 disksize = '{}G'.format(size)438 disksize = '{}G'.format(size)
429 basename = 'disk{}.qcow2'.format(index)439 basename = 'disk{}.qcow2'.format(index)
@@ -689,10 +699,14 @@
689699
690 def _start(self):700 def _start(self):
691 """701 """
692 Start the machine.702 Start the VM.
693 """703 """
694 self.logger.info('Starting CustomVM')704 self.logger.info('Starting CustomVM')
695 self.vm.create()705 if self.vm is not None:
706 if self.vm.isActive() == 0:
707 self.vm.create()
708 else:
709 raise UTAHVMProvisioningException('Failed to provision VM')
696 self.logger.info('Waiting ' + str(self.boottimeout) +710 self.logger.info('Waiting ' + str(self.boottimeout) +
697 ' seconds to allow machine to boot')711 ' seconds to allow machine to boot')
698 self.sshpoll(self.boottimeout)712 self.sshpoll(self.boottimeout)
@@ -702,9 +716,13 @@
702 """716 """
703 Remove the machine from libvirt and remove all the disk files.717 Remove the machine from libvirt and remove all the disk files.
704 """718 """
719 # TODO: make this use standard cleanup
705 super(CustomVM, self).destroy(*args, **kw)720 super(CustomVM, self).destroy(*args, **kw)
706 self.stop(force=True)721 self.stop(force=True)
707 self.vm.undefine()722 if self.vm is not None:
723 self.vm.undefine()
724 else:
725 self.logger.info('VM not created')
708 for disk in self.disks:726 for disk in self.disks:
709 os.unlink(disk['file'])727 os.unlink(disk['file'])
710 shutil.rmtree(self.directory)728 shutil.rmtree(self.directory)
711729
=== modified file 'utah/provisioning/vm/vm.py'
--- utah/provisioning/vm/vm.py 2012-08-22 15:20:25 +0000
+++ utah/provisioning/vm/vm.py 2012-11-08 18:18:27 +0000
@@ -12,4 +12,5 @@
12 """12 """
13 def __init__(self, *args, **kw):13 def __init__(self, *args, **kw):
14 super(VM, self).__init__(*args, **kw)14 super(VM, self).__init__(*args, **kw)
15 self.vm = None
15 self.logger.debug('VM init finished')16 self.logger.debug('VM init finished')

Subscribers

People subscribed via source and target branches