On 03/24/2016 03:59 PM, pvital(a)linux.vnet.ibm.com wrote:
From: Paulo Vital <pvital(a)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(a)linux.vnet.ibm.com>
---
i18n.py | 4 ++
model/libvirtevents.py | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++
model/model.py | 6 ++-
3 files changed, 108 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..44da18f
--- /dev/null
+++ b/model/libvirtevents.py
@@ -0,0 +1,99 @@
+#
+# 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')
+
+ # List to control which domains are using events
+ self.vms_tracked = []
+
Shouldn't it be generic? Of any libvirt event.
+ # 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 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)
+
is it generic but only for domains?
+ def register_common_events(self, conn):
+ """
+ Register the most common Libvirt 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.event_generic_cb, ev)
diff --git a/model/model.py b/model/model.py
index e44f804..dd50ec2 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_events(self.conn)
+ kargs = {'objstore': self.objstore, 'conn': self.conn,
+ 'eventsloop': self.events}
models = []
Maybe it is good to send the whole patch set at once. That way would be
easier to review and link pieces.
# Import task model from Wok
--
2.5.0