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
1=== modified file 'utah/provisioning/vm/libvirtvm.py'
2--- utah/provisioning/vm/libvirtvm.py 2012-10-19 21:57:01 +0000
3+++ utah/provisioning/vm/libvirtvm.py 2012-11-08 18:18:27 +0000
4@@ -91,17 +91,24 @@
5 """
6 self.logger.debug('Checking if VM is active')
7 self.provisioncheck()
8- if self.vm.isActive() == 0:
9- self._start()
10+ if self.vm is not None:
11+ if self.vm.isActive() == 0:
12+ self._start()
13+ else:
14+ self.active = True
15 else:
16- self.active = True
17+ raise UTAHVMProvisioningException('Failed to provision VM')
18
19 def _start(self):
20 """
21- Verify the machine is provisioned, then start it.
22+ Start the VM.
23 """
24 self.logger.info('Starting VM')
25- self.vm.create()
26+ if self.vm is not None:
27+ if self.vm.isActive() == 0:
28+ self.vm.create()
29+ else:
30+ raise UTAHVMProvisioningException('Failed to provision VM')
31 self.active = True
32
33 def stop(self, force=False):
34@@ -111,14 +118,17 @@
35 one.
36 """
37 self.logger.info('Stopping VM')
38- if self.vm.isActive() == 0:
39- self.logger.info('VM is already stopped')
40+ if self.vm is not None:
41+ if self.vm.isActive() == 0:
42+ self.logger.info('VM is already stopped')
43+ else:
44+ if force:
45+ self.logger.info('Forced shutdown requested')
46+ self.vm.destroy()
47+ else:
48+ self.vm.shutdown()
49 else:
50- if force:
51- self.logger.info('Forced shutdown requested')
52- self.vm.destroy()
53- else:
54- self.vm.shutdown()
55+ self.logger.info('VM not yet created')
56 self.active = False
57
58 def libvirterrorhandler(self, _context, err):
59@@ -367,6 +377,7 @@
60 self.disksizes = [8]
61 else:
62 self.disksizes = disksizes
63+ self.disks = []
64 if name is None:
65 autoname = True
66 name = '-'.join([str(prefix), str(machineid)])
67@@ -423,7 +434,6 @@
68 self.logger.info('Creating disks')
69 if disksizes is None:
70 disksizes = self.disksizes
71- self.disks = []
72 for index, size in enumerate(disksizes):
73 disksize = '{}G'.format(size)
74 basename = 'disk{}.qcow2'.format(index)
75@@ -689,10 +699,14 @@
76
77 def _start(self):
78 """
79- Start the machine.
80+ Start the VM.
81 """
82 self.logger.info('Starting CustomVM')
83- self.vm.create()
84+ if self.vm is not None:
85+ if self.vm.isActive() == 0:
86+ self.vm.create()
87+ else:
88+ raise UTAHVMProvisioningException('Failed to provision VM')
89 self.logger.info('Waiting ' + str(self.boottimeout) +
90 ' seconds to allow machine to boot')
91 self.sshpoll(self.boottimeout)
92@@ -702,9 +716,13 @@
93 """
94 Remove the machine from libvirt and remove all the disk files.
95 """
96+ # TODO: make this use standard cleanup
97 super(CustomVM, self).destroy(*args, **kw)
98 self.stop(force=True)
99- self.vm.undefine()
100+ if self.vm is not None:
101+ self.vm.undefine()
102+ else:
103+ self.logger.info('VM not created')
104 for disk in self.disks:
105 os.unlink(disk['file'])
106 shutil.rmtree(self.directory)
107
108=== modified file 'utah/provisioning/vm/vm.py'
109--- utah/provisioning/vm/vm.py 2012-08-22 15:20:25 +0000
110+++ utah/provisioning/vm/vm.py 2012-11-08 18:18:27 +0000
111@@ -12,4 +12,5 @@
112 """
113 def __init__(self, *args, **kw):
114 super(VM, self).__init__(*args, **kw)
115+ self.vm = None
116 self.logger.debug('VM init finished')

Subscribers

People subscribed via source and target branches