Skip to content
Snippets Groups Projects
Commit 8455cf70 authored by Anael Beutot's avatar Anael Beutot
Browse files

hypervisor.kvm: fix domain XML update while running

When we update a VM configuration while it is running, for example a change in
the network interfaces, we recreate a domain from the running XML which is fine
but this is not valid anymore when the VM is stopped.
So in the latter case, we keep an attribute on the VM indicating if we need to
recreate the VM instance from the XML when it stops.
parent 80f2bcb4
No related branches found
No related tags found
No related merge requests found
...@@ -96,6 +96,8 @@ class VirtualMachine(object): ...@@ -96,6 +96,8 @@ class VirtualMachine(object):
self.from_stream = None # buffer self.from_stream = None # buffer
self.stream_handling = 0 # libvirt stream event mask self.stream_handling = 0 # libvirt stream event mask
self.redefine_on_stop = False # for XML update (see KVM class)
@property @property
def state(self): def state(self):
return self._state return self._state
......
...@@ -120,19 +120,22 @@ class KVM(object): ...@@ -120,19 +120,22 @@ class KVM(object):
return return
# update Storage pools in case VM has volumes that were created # update Storage pools in case VM has volumes that were created
self.storage.update() self.storage.update()
# if vm is redefined while running we need to refresh its devices
# when stopped
redefine_on_stop = False
if dom.name() in self.domains: if dom.name() in self.domains:
# sometimes libvirt send us the same event multiple times # sometimes libvirt send us the same event multiple times
# this can be the result of a change in the domain configuration # this can be the result of a change in the domain configuration
# we first remove the old domain # we first remove the old domain
vm = self.domains.pop(dom.name()) vm = self.domains.pop(dom.name())
self.handler.tag_db.remove_sub_object(vm.name) self.handler.tag_db.remove_sub_object(vm.name)
if vm.state not in ('stopped', 'crashed'):
# if the vm was updated while it was "on", then the
# modifications will not be reflected since we construct the
# object/tags from running XML
redefine_on_stop = True
logger.debug('Domain %s recreated', dom.name()) logger.debug('Domain %s recreated', dom.name())
vm = VirtualMachine(dom, self) self.vm_register(dom, redefine_on_stop)
logger.info('Created domain %s', vm.name)
self.domains[vm.name] = vm
self.handler.tag_db.add_sub_object(vm.name, vm.tags.itervalues(),
'vm')
self.update_domain_count()
elif event == 'Removed': elif event == 'Removed':
vm_name = dom.name() vm_name = dom.name()
self.vm_unregister(vm_name) self.vm_unregister(vm_name)
...@@ -155,9 +158,28 @@ class KVM(object): ...@@ -155,9 +158,28 @@ class KVM(object):
else: else:
logger.info('Domain change state from %s to %s', vm.state, logger.info('Domain change state from %s to %s', vm.state,
state) state)
vm.state = state if event == 'Stopped' and vm.redefine_on_stop:
# if the vm was changed while it was running, then we
# need to recreate it now as stated above
self.vm_unregister(vm.name)
self.vm_register(dom)
else:
vm.state = state
self.update_domain_count() self.update_domain_count()
def vm_register(self, dom, redefine_on_stop=False):
"""Register a VM to the hypervisor object.
:param dom: libvirt domain instance
:param redefine_on_stop: if we need to reread the domain XML on stop
"""
vm = VirtualMachine(dom, self)
logger.info('Created domain %s', vm.name)
vm.redefine_on_stop = redefine_on_stop
self.domains[vm.name] = vm
self.handler.tag_db.add_sub_object(vm.name, vm.tags.itervalues(), 'vm')
self.update_domain_count()
def vm_unregister(self, name): def vm_unregister(self, name):
"""Unregister a VM from the cc-server and remove it from the index.""" """Unregister a VM from the cc-server and remove it from the index."""
try: try:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment