[Kimchi-devel] [PATCH V2] [Kimchi] Add support to Libvirt Events.

Lucio Correia luciojhc at linux.vnet.ibm.com
Wed Apr 6 14:15:20 UTC 2016


Reviewed-By: Lucio Correia <luciojhc at linux.vnet.ibm.com>

On 31-03-2016 18:01, pvital at linux.vnet.ibm.com wrote:
> 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
>
> _______________________________________________
> Kimchi-devel mailing list
> Kimchi-devel at ovirt.org
> http://lists.ovirt.org/mailman/listinfo/kimchi-devel
>


-- 
Lucio Correia
Software Engineer
IBM LTC Brazil




More information about the Kimchi-devel mailing list