[Kimchi-devel] [PATCH V2] [Kimchi] Add support to Libvirt Events.
pvital at linux.vnet.ibm.com
pvital at linux.vnet.ibm.com
Thu Mar 31 21:01:09 UTC 2016
From: Paulo Vital <pvital at linux.vnet.ibm.com>
This patch adds support to handle in Kimchi any Libvirt Event, just by adding
a callback to process the event and register the event with the callback.
A method called register_common_events() is responsible to register the common
domain events to use a generic callback that logs into error log, the event
happened and it's details.
This patch is part of the solution for Kimchi Issue #817
Signed-off-by: Paulo Vital <pvital at linux.vnet.ibm.com>
---
i18n.py | 4 +++
model/libvirtevents.py | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++
model/model.py | 6 +++-
3 files changed, 106 insertions(+), 1 deletion(-)
create mode 100644 model/libvirtevents.py
diff --git a/i18n.py b/i18n.py
index 6214687..3939aba 100644
--- a/i18n.py
+++ b/i18n.py
@@ -326,4 +326,8 @@ messages = {
"KCHLVMS0001E": _("Invalid volume group name parameter: %(name)s."),
+ "KCHEVENT0001E": _("Failed to register the default event implementation."),
+ "KCHEVENT0002E": _("Failed to register timeout event."),
+ "KCHEVENT0003E": _("Failed to Run the default event implementation."),
+
}
diff --git a/model/libvirtevents.py b/model/libvirtevents.py
new file mode 100644
index 0000000..2775476
--- /dev/null
+++ b/model/libvirtevents.py
@@ -0,0 +1,97 @@
+#
+# Project Kimchi
+#
+# Copyright IBM, Corp. 2016
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+import cherrypy
+import libvirt
+import time
+
+from wok.exception import OperationFailed
+from wok.utils import wok_log
+
+
+class LibvirtEvents(object):
+ def __init__(self):
+ # Register default implementation of event handlers
+ if libvirt.virEventRegisterDefaultImpl() < 0:
+ raise OperationFailed('KCHEVENT0001E')
+
+ # Run a background thread with the event loop. Using cherrypy
+ # BackgroundTask class due to issues when using threading module with
+ # cherrypy.
+ self.event_loop_thread = cherrypy.process.plugins.BackgroundTask(
+ 2,
+ self._event_loop_run
+ )
+ self.event_loop_thread.setName('KimchiLibvirtEventLoop')
+ self.event_loop_thread.setDaemon(True)
+ self.event_loop_thread.start()
+
+ # Set an event timeout to control the self._event_loop_run
+ if libvirt.virEventAddTimeout(0, self._kimchi_EventTimeout, None) < 0:
+ raise OperationFailed('KCHEVENT0002E')
+
+ # Event loop method to be executed in background as thread
+ def _event_loop_run(self):
+ while True:
+ if libvirt.virEventRunDefaultImpl() < 0:
+ raise OperationFailed('KCHEVENT0003E')
+
+ def is_event_loop_alive(self):
+ return self.event_loop_thread.isAlive()
+
+ # Event loop handler used to limit length of waiting for any other event.
+ def _kimchi_EventTimeout(self, timer, opaque):
+ time.sleep(1)
+
+ def domain_event_generic_cb(self, conn, dom, event, detail, *args):
+ """
+ Generic callback to handle Domain (VMs) events.
+ """
+ evStrings = ("Defined", "Undefined", "Started", "Suspended", "Resumed",
+ "Stopped", "Shutdown", "PMSuspended", "Crashed")
+ evDetails = (("Added", "Updated"),
+ ("Removed", ),
+ ("Booted", "Migrated", "Restored", "Snapshot", "Wakeup"),
+ ("Paused", "Migrated", "IOError", "Watchdog", "Restored",
+ "Snapshot", "API error"),
+ ("Unpaused", "Migrated", "Snapshot"),
+ ("Shutdown", "Destroyed", "Crashed", "Migrated", "Saved",
+ "Failed", "Snapshot"),
+ ("Finished", ),
+ ("Memory", "Disk"),
+ ("Panicked"))
+ msg = "Libvirt Event: Domain %s %s %s" % (dom.name(), evStrings[event],
+ evDetails[event][detail])
+
+ wok_log.error(msg)
+
+ def register_common_domain_events(self, conn):
+ """
+ Register the most common Libvirt domain events to be handled.
+ """
+ conn = conn.get()
+ for ev in (libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
+ libvirt.VIR_DOMAIN_EVENT_ID_REBOOT,
+ libvirt.VIR_DOMAIN_EVENT_ID_RTC_CHANGE,
+ libvirt.VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON,
+ libvirt.VIR_DOMAIN_EVENT_ID_GRAPHICS,
+ libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB,
+ libvirt.VIR_DOMAIN_EVENT_ID_WATCHDOG):
+ conn.domainEventRegisterAny(None, ev, self.domain_event_generic_cb,
+ ev)
diff --git a/model/model.py b/model/model.py
index e44f804..aeb8b7d 100644
--- a/model/model.py
+++ b/model/model.py
@@ -26,6 +26,7 @@ from wok.plugins.kimchi import config
from wok.utils import import_module, listPathModules
from wok.plugins.kimchi.model.libvirtconnection import LibvirtConnection
+from wok.plugins.kimchi.model.libvirtevents import LibvirtEvents
class Model(BaseModel):
@@ -43,8 +44,11 @@ class Model(BaseModel):
return instances
self.objstore = ObjectStore(objstore_loc or config.get_object_store())
+ self.events = LibvirtEvents()
self.conn = LibvirtConnection(libvirt_uri)
- kargs = {'objstore': self.objstore, 'conn': self.conn}
+ self.events.register_common_domain_events(self.conn)
+ kargs = {'objstore': self.objstore, 'conn': self.conn,
+ 'eventsloop': self.events}
models = []
# Import task model from Wok
--
2.5.5
More information about the Kimchi-devel
mailing list