libvirtobject: Add decorator for lifecycle events

That does the appropriate event loop updating, if needed.
This commit is contained in:
Cole Robinson
2015-04-09 18:27:45 -04:00
parent a3f8d73a9c
commit c9b882619e
5 changed files with 53 additions and 45 deletions

View File

@@ -1075,9 +1075,9 @@ class vmmDomain(vmmLibvirtObject):
self._snapshot_list = newlist
return self._snapshot_list[:]
@vmmLibvirtObject.lifecycle_action
def revert_to_snapshot(self, snap):
self._backend.revertToSnapshot(snap.get_backend())
self.idle_add(self.force_update_status)
def create_snapshot(self, xml, redefine=False):
flags = 0
@@ -1359,28 +1359,29 @@ class vmmDomain(vmmLibvirtObject):
reboot_listener, self)
self.idle_add(add_reboot)
@vmmLibvirtObject.lifecycle_action
def shutdown(self):
self._install_abort = True
self._unregister_reboot_listener()
self._backend.shutdown()
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def reboot(self):
self._install_abort = True
self._backend.reboot(0)
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def destroy(self):
self._install_abort = True
self._unregister_reboot_listener()
self._backend.destroy()
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def reset(self):
self._install_abort = True
self._backend.reset(0)
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def startup(self):
if self.get_cloning():
raise RuntimeError(_("Cannot start guest while cloning "
@@ -1393,12 +1394,12 @@ class vmmDomain(vmmLibvirtObject):
raise RuntimeError(error)
self._backend.create()
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def suspend(self):
self._backend.suspend()
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def delete(self, force=True):
flags = 0
if force:
@@ -1415,13 +1416,24 @@ class vmmDomain(vmmLibvirtObject):
"falling back to old style")
self._backend.undefine()
@vmmLibvirtObject.lifecycle_action
def resume(self):
if self.get_cloning():
raise RuntimeError(_("Cannot resume guest while cloning "
"operation in progress"))
self._backend.resume()
self.idle_add(self.force_update_status)
@vmmLibvirtObject.lifecycle_action
def save(self, filename=None, meter=None):
self._install_abort = True
if meter:
start_job_progress_thread(self, meter, _("Saving domain to disk"))
if not self.managedsave_supported:
self._backend.save(filename)
else:
self._backend.managedSave(0)
def has_managed_save(self):
if not self.managedsave_supported:
@@ -1443,19 +1455,6 @@ class vmmDomain(vmmLibvirtObject):
self._backend.managedSaveRemove(0)
self._has_managed_save = None
def save(self, filename=None, meter=None):
self._install_abort = True
if meter:
start_job_progress_thread(self, meter, _("Saving domain to disk"))
if not self.managedsave_supported:
self._backend.save(filename)
else:
self._backend.managedSave(0)
self.idle_add(self.force_update_status)
def support_downtime(self):
return self.conn.check_support(

View File

@@ -45,8 +45,6 @@ class vmmInterface(vmmLibvirtObject):
def _get_backend_status(self):
return self._backend_get_active()
def _kick_conn(self):
self.conn.schedule_priority_tick(polliface=True)
def tick(self):
self.force_update_status()
@@ -55,20 +53,17 @@ class vmmInterface(vmmLibvirtObject):
# Object operations #
#####################
@vmmLibvirtObject.lifecycle_action
def start(self):
self._backend.create(0)
self.idle_add(self.refresh_xml)
self._kick_conn()
@vmmLibvirtObject.lifecycle_action
def stop(self):
self._backend.destroy(0)
self.idle_add(self.refresh_xml)
self._kick_conn()
@vmmLibvirtObject.lifecycle_action
def delete(self, force=True):
ignore = force
self._backend.undefine()
self._kick_conn()
################

View File

@@ -77,6 +77,26 @@ class vmmLibvirtObject(vmmGObject):
tofile="New XML"))
logging.debug("Redefining %s with XML diff:\n%s", objname, diff)
@staticmethod
def lifecycle_action(fn):
"""
Decorator for object lifecycle actions like start, stop, delete.
Will make sure any necessary state is updated accordingly.
"""
def newfn(self, *args, **kwargs):
ret = fn(self, *args, **kwargs)
# If events are supported, this is a no-op, but the event loop
# will trigger force_status_update, which will refresh_xml as well.
#
# If events aren't supported, the priority tick will call
# self.tick(), which will call force_status_update
tick_kwargs = {self._conn_tick_poll_param: True}
self.conn.schedule_priority_tick(**tick_kwargs)
return ret
return newfn
def _cleanup(self):
pass
@@ -176,13 +196,13 @@ class vmmLibvirtObject(vmmGObject):
# This will send state-change for us
self.refresh_xml(forcesignal=True)
except:
except Exception, e:
# If we hit an exception here, it's often that the object
# disappeared, so request the poll loop to be updated
logging.debug("Error polling status for %s: %s", self, e)
if self._conn_tick_poll_param:
logging.debug("force_update_status: Triggering %s "
"list refresh", self.__class__)
kwargs = {"force": True, self._conn_tick_poll_param: True}
logging.debug("Scheduling priority tick with: %s", kwargs)
self.conn.schedule_priority_tick(**kwargs)
def _backend_get_active(self):

View File

@@ -63,8 +63,6 @@ class vmmNetwork(vmmLibvirtObject):
def _get_backend_status(self):
return self._backend_get_active()
def _kick_conn(self):
self.conn.schedule_priority_tick(pollnet=True)
def tick(self):
self.force_update_status()
@@ -73,19 +71,19 @@ class vmmNetwork(vmmLibvirtObject):
# Actions #
###########
@vmmLibvirtObject.lifecycle_action
def start(self):
self._backend.create()
self._kick_conn()
@vmmLibvirtObject.lifecycle_action
def stop(self):
self._backend.destroy()
self._kick_conn()
@vmmLibvirtObject.lifecycle_action
def delete(self, force=True):
ignore = force
self._backend.undefine()
self._backend = None
self._kick_conn()
###############################

View File

@@ -128,8 +128,6 @@ class vmmStoragePool(vmmLibvirtObject):
def _get_backend_status(self):
return self._backend_get_active()
def _kick_conn(self):
self.conn.schedule_priority_tick(pollpool=True)
def tick(self):
self.force_update_status()
@@ -138,21 +136,19 @@ class vmmStoragePool(vmmLibvirtObject):
# Actions #
###########
@vmmLibvirtObject.lifecycle_action
def start(self):
self._backend.create(0)
self._kick_conn()
self.idle_add(self.refresh_xml)
@vmmLibvirtObject.lifecycle_action
def stop(self):
self._backend.destroy()
self._kick_conn()
self.idle_add(self.refresh_xml)
@vmmLibvirtObject.lifecycle_action
def delete(self, force=True):
ignore = force
self._backend.undefine()
self._backend = None
self._kick_conn()
def refresh(self):
if not self.is_active():