Skip to content

Commit

Permalink
tests: improve VMs cleanup wrt custom templates
Browse files Browse the repository at this point in the history
Cleanup VMs in template reverse topological order, not network one.
Network can be set to None to break dependency, but template can't. For
netvm to be changed, kill VMs first (kill doesn't check network
dependency), so netvm change will not trigger side effects (runtime
change, which could fail).

This fixes cleanup for tests creating custom templates - previously
order was undefined and if template was tried removed before its child
VMs, it fails. All the relevant files were removed later anyway, but it
lead to python objects leaks.
  • Loading branch information
marmarek committed Oct 27, 2018
1 parent 4e76278 commit 08ddeee
Showing 1 changed file with 22 additions and 11 deletions.
33 changes: 22 additions & 11 deletions qubes/tests/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -789,13 +789,6 @@ def _remove_vm_qubes(self, vm):
vmname = vm.name
app = vm.app

try:
# XXX .is_running() may throw libvirtError if undefined
if vm.is_running():
self.loop.run_until_complete(vm.kill())
except: # pylint: disable=bare-except
pass

try:
self.loop.run_until_complete(vm.remove_from_disk())
except: # pylint: disable=bare-except
Expand Down Expand Up @@ -876,18 +869,36 @@ def remove_vms(self, vms):
vms = list(vms)
if not vms:
return
# first kill all the domains, to avoid side effects of changing netvm
for vm in vms:
try:
# XXX .is_running() may throw libvirtError if undefined
if vm.is_running():
self.loop.run_until_complete(vm.kill())
except: # pylint: disable=bare-except
pass
# break dependencies
for vm in vms:
vm.default_dispvm = None
# then remove in reverse topological order (wrt netvm), using naive
vm.netvm = None
# take app instance from any VM to be removed
app = vms[0].app
if app.default_dispvm in vms:
app.default_dispvm = None
if app.default_netvm in vms:
app.default_netvm = None
del app
# then remove in reverse topological order (wrt template), using naive
# algorithm
# this heavily depends on lack of netvm loops
# this heavily depends on lack of template loops, but those are
# impossible
while vms:
vm = vms.pop(0)
# make sure that all connected VMs are going to be removed,
# otherwise this will loop forever
assert all(x in vms for x in vm.connected_vms)
if list(vm.connected_vms):
child_vms = list(getattr(vm, 'appvms', []))
assert all(x in vms for x in child_vms)
if child_vms:
# if still something use this VM, put it at the end of queue
# and try next one
vms.append(vm)
Expand Down

0 comments on commit 08ddeee

Please sign in to comment.