Ejemplo n.º 1
0
 def __init__(self):
     self.run = True
     libvirt.virEventRegisterDefaultImpl()
     self.__thread = threading.Thread(target=self.__run,
                                      name="libvirtEventLoop")
     self.__thread.setDaemon(True)
     self.__thread.start()
Ejemplo n.º 2
0
 def _createEventLoop(self):
     libvirt.virEventRegisterDefaultImpl()
     if self.eventLoopThread is not None and self.eventLoopThread.isAlive():
         self.eventLoopThread.terminate()
     self.eventLoopThread = VirEventLoopThread(self.logger, name="libvirtEventLoop")
     self.eventLoopThread.setDaemon(True)
     self.eventLoopThread.start()
def virEventLoopNativeStart():
    global eventLoopThread
    libvirt.virEventRegisterDefaultImpl()
    eventLoopThread = threading.Thread(target=virEventLoopNativeRun,
                                       name="libvirtEventLoop")
    eventLoopThread.setDaemon(True)
    eventLoopThread.start()
Ejemplo n.º 4
0
def main(args):
    if args.events:
        debug("Turning on libvirt\'s events handler.", args.verbose)
        libvirt.virEventRegisterDefaultImpl()
        event_loop_thread = threading.Thread(target=_event_loop_run,
                                             name="EventLoop")
        event_loop_thread.setDaemon(True)
        event_loop_thread.start()

    # Open a connection with libvirt
    conn = libvirt.open('qemu:///system')

    if args.capabilities:
        debug("Scanning for host capabilities.", args.verbose)
        _set_capabilities(conn)

    if args.domain_name != None:
        debug("Printing XML for given domain.", args.verbose)
        domain = conn.lookupByName(args.domain_name)
        print_domain_xml(domain)
        return

    debug("No given DOMAIN_NAME. Looking for running domains...", args.verbose)
    domain_ids = conn.listDomainsID()
    if len(domain_ids) < 1:
        print "No given DOMAIN_NAME or running domain at this moment. Exiting."
        return

    for id in domain_ids:
        domain = conn.lookupByID(id)
        print_domain_xml(domain)
        print "==========================================================="
Ejemplo n.º 5
0
 def __init__(self):
     self._qdb = {}
     self._qdb_events = {}
     self.block_callback = None
     self.meminfo_callback = None
     self.domain_callback = None
     libvirt.virEventRegisterDefaultImpl()
     # open new libvirt connection because above
     # virEventRegisterDefaultImpl is in practice effective only for new
     # connections
     self.libvirt_conn = libvirt.open(defaults['libvirt_uri'])
     self.libvirt_conn.domainEventRegisterAny(
         None,
         libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
         self._domain_list_changed, None)
     self.libvirt_conn.domainEventRegisterAny(
         None,
         libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
         self._device_removed, None)
     # TODO: device attach libvirt event
     for vm in vmm.libvirt_conn.listAllDomains():
         try:
             if vm.isActive():
                 self._register_watches(vm)
         except libvirt.libvirtError as e:
             # this will happen if we loose a race with another tool,
             # which can just remove the domain
             if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
                 pass
             raise
     # and for dom0
     self._register_watches(None)
Ejemplo n.º 6
0
    def __init__(self, **args):
        Machine.__init__(self, **args)

        self.run_dir = os.path.join(self.test_dir, "run")

        self._image_image = os.path.join(self.run_dir, "%s.qcow2" % (self.image))
        self._image_additional_iso = os.path.join(self.run_dir, "%s.iso" % (self.image))

        self._images_dir = os.path.join(self.test_data, "images")
        self._image_original = os.path.join(self._images_dir, "%s.qcow2" % (self.image))
        self._iso_original = os.path.join(self._images_dir, "%s.iso" % (self.image))
        self._checksum_original = os.path.join(self._images_dir, "%s-checksum" % (self.image))

        self._fixed_mac_flavors = self._get_fixed_mac_flavors()
        self._network_description = etree.parse(open("./guest/network-cockpit.xml"))

        # it is ESSENTIAL to register the default implementation of the event loop before opening a connection
        # otherwise messages may be delayed or lost
        libvirt.virEventRegisterDefaultImpl()
        self.virt_connection = self._libvirt_connection(hypervisor = "qemu:///session")
        self.event_handler = VirtEventHandler(libvirt_connection=self.virt_connection, verbose=self.verbose)

        # network names are currently hardcoded into network-cockpit.xml
        self.network_name = self._read_network_name()
        self.system_connection = self._libvirt_connection(hypervisor = "qemu:///system", read_only = True)
        self.dhcp_net = self.system_connection.networkLookupByName(self.network_name)

        # we can't see the network itself as non-root, create it using vm-prep as root

        # Unique identifiers for hostnet config
        self._hostnet = 8

        # init variables needed for running a vm
        self._cleanup()
Ejemplo n.º 7
0
 def __run(self):
     try:
         libvirt.virEventRegisterDefaultImpl()
         while self.run:
             libvirt.virEventRunDefaultImpl()
     finally:
         self.run = False
Ejemplo n.º 8
0
    def __init__(self, **args):
        Machine.__init__(self, **args)

        self.run_dir = os.path.join(self.test_dir, "tmp", "run")

        self.image_base = os.path.join(self.test_dir, "images", self.image)
        self.image_file = os.path.join(self.run_dir, "%s.qcow2" % (self.image))

        self._network_description = etree.parse(open(os.path.join(self.test_dir, "guest/network-cockpit.xml")))

        self.test_disk_desc_original = None

        # it is ESSENTIAL to register the default implementation of the event loop before opening a connection
        # otherwise messages may be delayed or lost
        libvirt.virEventRegisterDefaultImpl()
        self.virt_connection = self._libvirt_connection(hypervisor = "qemu:///session")
        self.event_handler = VirtEventHandler(libvirt_connection=self.virt_connection, verbose=self.verbose)

        # network names are currently hardcoded into network-cockpit.xml
        self.network_name = self._read_network_name()

        # we can't see the network itself as non-root, create it using vm-prep as root

        # Unique identifiers for hostnet config
        self._hostnet = 8

        self._domain = None

        # init variables needed for running a vm
        self._cleanup()
Ejemplo n.º 9
0
    def listen(self):
        """Prepares the environment before starts to accept connections

        Initializes and destroy the resources needed to accept connection.
        """
        libvirt.virEventRegisterDefaultImpl()
        try:
            guest = LibvirtGuest(self._guest_name, self._uri, self.name)

        except Exception as e:
            wok_log.error(
                '[%s] Cannot open the guest %s due to %s',
                self.name,
                self._guest_name,
                str(e),
            )
            self._socket.close()
            sys.exit(1)

        except (KeyboardInterrupt, SystemExit):
            self._socket.close()
            sys.exit(1)

        console = None
        try:
            console = guest.get_console()
            if console is None:
                wok_log.error(
                    '[%s] Cannot get the console to %s', self.name, self._guest_name
                )
                return

            if not self._is_vm_listening_serial(console):
                sys.exit(1)

            self._listen(guest, console)

        # clear resources aquired when the process is killed
        except (KeyboardInterrupt, SystemExit):
            pass

        finally:
            wok_log.info(
                '[%s] Shutting down the socket server to %s console',
                self.name,
                self._guest_name,
            )
            self._socket.close()
            if os.path.exists(self._server_addr):
                os.unlink(self._server_addr)

            try:
                console.eventRemoveCallback()

            except Exception as e:
                wok_log.info(
                    '[%s] Callback is probably removed: %s', self.name, str(e))

            guest.close()
Ejemplo n.º 10
0
 def start(self):
     assert not self.run
     libvirt.virEventRegisterDefaultImpl()
     self.__thread = threading.Thread(target=self.__run,
                                      name="libvirtEventLoop")
     self.__thread.setDaemon(True)
     self.run = True
     self.__thread.start()
Ejemplo n.º 11
0
def loop_start():
    """start running default event handler implementation"""
    global LoopThread
    libvirt.virEventRegisterDefaultImpl()
    loop_run_arg = ()
    LoopThread = threading.Thread(target=loop_run, args=loop_run_arg, name="libvirtEventLoop")
    LoopThread.setDaemon(True)
    LoopThread.start()
Ejemplo n.º 12
0
 def start(self):
     """ start event loop by spawning a new thread
     """
     libvirt.virEventRegisterDefaultImpl()
     self.running = True
     self._thread = threading.Thread(target=self._event_loop_native,
                                    name="libvirtEventLoop")
     self._thread.setDaemon(True)
     self._thread.start()
Ejemplo n.º 13
0
def start_event_loop():
    """Defines eventLoopThread global and starts the thread"""

    global event_loop_thread
    libvirt.virEventRegisterDefaultImpl()
    event_loop_thread = threading.Thread(target=run_native_event_loop,
                                         name="libvirtEventLoop")
    event_loop_thread.setDaemon(True)
    event_loop_thread.start()
Ejemplo n.º 14
0
def init_loop():

    def loop():
        while True:
            libvirt.virEventRunDefaultImpl()
    libvirt.virEventRegisterDefaultImpl()
    eventLoopThread = threading.Thread(target=loop)
    eventLoopThread.setDaemon(True)
    eventLoopThread.start()
Ejemplo n.º 15
0
def main():
    libvirt.virEventRegisterDefaultImpl()
    libvirt.registerErrorHandler(handleLibvirtLibraryError, None)

    worker = threading.Thread(target=work)
    worker.setDaemon(True)
    worker.start()

    eventLoop = threading.Thread(target=virEventLoopNativeRun)
    eventLoop.setDaemon(True)
    eventLoop.start()

    while True:
        time.sleep(1)
Ejemplo n.º 16
0
def main():
    libvirt.virEventRegisterDefaultImpl()
    libvirt.registerErrorHandler(handleLibvirtLibraryError, None)

    worker = threading.Thread(target=work)
    worker.setDaemon(True)
    worker.start()

    eventLoop = threading.Thread(target=virEventLoopNativeRun)
    eventLoop.setDaemon(True)
    eventLoop.start()

    while True:
       time.sleep(1)
Ejemplo n.º 17
0
    def initialize(self):
        # prepare libvirt
        libvirt.registerErrorHandler(self._native_libvirt_error_handler, None)
        libvirt.virEventRegisterDefaultImpl()

        # start native listening thread
        self._native_event_queue = native_queue.Queue()
        self._event_thread = native_threading.Thread(
            target=self._native_thread)
        self._event_thread.setDaemon(True)
        self._event_thread.start()

        # prepare dispatching greenthread
        eventlet.spawn_n(self._dispatch_event)
Ejemplo n.º 18
0
    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
        # register the default event implementation
        # of libvirt, as we do not have an existing
        # event loop.
        libvirt.virEventRegisterDefaultImpl()

        if name is None:
            name = 'libvirt event loop'

        super(wvmEventLoop, self).__init__(group, target, name, args, kwargs)

        # we run this thread in deamon mode, so it does
        # not block shutdown of the server
        self.daemon = True
Ejemplo n.º 19
0
    def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
        # register the default event implementation
        # of libvirt, as we do not have an existing
        # event loop.
        libvirt.virEventRegisterDefaultImpl()

        if name is None:
            name = 'libvirt event loop'

        super(wvmEventLoop, self).__init__(group, target, name, args, kwargs)

        # we run this thread in deamon mode, so it does
        # not block shutdown of the server
        self.daemon = True
Ejemplo n.º 20
0
def up(virt_lightning_yaml, configuration, context, **kwargs):
    def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
        if state == 1:
            logger.info("%s %s QEMU agent found", symbols.CUSTOMS.value,
                        dom.name())

    loop = asyncio.get_event_loop()
    try:
        import libvirtaio

        libvirtaio.virEventRegisterAsyncIOImpl(loop=loop)
    except ImportError:
        libvirt.virEventRegisterDefaultImpl()
        pass
    conn = libvirt.open(configuration.libvirt_uri)
    hv = vl.LibvirtHypervisor(conn)

    conn.setKeepAlive(5, 3)
    conn.domainEventRegisterAny(
        None,
        libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
        myDomainEventAgentLifecycleCallback,
        None,
    )

    hv.init_network(configuration.network_name, configuration.network_cidr)
    hv.init_storage_pool(configuration.storage_pool)

    pool = ThreadPoolExecutor(max_workers=10)

    async def deploy():
        futures = []
        for host in virt_lightning_yaml:
            futures.append(
                loop.run_in_executor(pool, _start_domain, hv, host, context,
                                     configuration))

        domain_reachable_futures = []
        for f in futures:
            await f
            domain = f.result()
            if domain:
                domain_reachable_futures.append(domain.reachable())
        logger.info("%s ok Waiting...", symbols.HOURGLASS.value)

        await asyncio.gather(*domain_reachable_futures)

    loop.run_until_complete(deploy())
    logger.info("%s You are all set", symbols.THUMBS_UP.value)
Ejemplo n.º 21
0
 def __startVirEventLoop(self):
     """
     Starts the libvirt event loop
     Args:
         None
     Returns:
         Nothing
     """
     def runVirEventLoop():
         while True:
             libvirt.virEventRunDefaultImpl()
     libvirt.virEventRegisterDefaultImpl()
     self.__eventLoopThread = threading.Thread(target=runVirEventLoop, name="libvirt event loop")
     self.__eventLoopThread.setDaemon(True)
     self.__eventLoopThread.start()
Ejemplo n.º 22
0
def startVirEventLoop():
    '''Register Libvirt default event loop
    implementation and call to run event loop on a
    separate native thread forever.
    '''

    # Register libvirts default event loop implementation
    libvirt.virEventRegisterDefaultImpl()

    event_loop_thread = native_threading.Thread(target=_runVirDefaultEventLoop,
                                                name="libvirtEventLoop")
    event_loop_thread.setDaemon(True)
    event_loop_thread.start()

    return event_loop_thread
Ejemplo n.º 23
0
def main():
    print("--> vm_shield_controller started! <--")
    libvirt.virEventRegisterDefaultImpl()
    conn = libvirt.open('qemu:///system')
    domain = conn.lookupByName(vm_name)

    on_start(domain)

    cb_id = conn.domainEventRegisterAny(domain,
                                        libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                        vm_lifecycle_event, None)

    # Blocking loop triggered by VM state changes
    while True:
        libvirt.virEventRunDefaultImpl()
Ejemplo n.º 24
0
    def init_vmm_connection(self):
        if self._libvirt_conn is not None:
            # Already initialized
            return
        if self._offline_mode:
            # Do not initialize in offline mode
            return

        if "xen.lowlevel.xs" in sys.modules:
            self._xs = xen.lowlevel.xs.xs()
        libvirt.virEventRegisterDefaultImpl()
        self._libvirt_conn = libvirt.open(defaults["libvirt_uri"])
        if self._libvirt_conn == None:
            raise QubesException("Failed connect to libvirt driver")
        libvirt.registerErrorHandler(self._libvirt_error_handler, None)
        atexit.register(self._libvirt_conn.close)
Ejemplo n.º 25
0
    def init_vmm_connection(self):
        if self._libvirt_conn is not None:
            # Already initialized
            return
        if self._offline_mode:
            # Do not initialize in offline mode
            return

        if 'xen.lowlevel.xs' in sys.modules:
            self._xs = xen.lowlevel.xs.xs()
        libvirt.virEventRegisterDefaultImpl()
        self._libvirt_conn = libvirt.open(defaults['libvirt_uri'])
        if self._libvirt_conn == None:
            raise QubesException("Failed connect to libvirt driver")
        libvirt.registerErrorHandler(self._libvirt_error_handler, None)
        atexit.register(self._libvirt_conn.close)
Ejemplo n.º 26
0
 def register_default_impl(self):
     try:
         return libvirt.virEventRegisterDefaultImpl()
     except libvirt.libvirtError, e:
         message = e.get_error_message()
         code = e.get_error_code()
         raise exception.LibvirtAPI(message, code)
Ejemplo n.º 27
0
    def __startVirEventLoop(self):
        """
        Starts the libvirt event loop
        Args:
            None
        Returns:
            Nothing
        """
        def runVirEventLoop():
            while True:
                libvirt.virEventRunDefaultImpl()

        libvirt.virEventRegisterDefaultImpl()
        self.__eventLoopThread = threading.Thread(target=runVirEventLoop,
                                                  name="libvirt event loop")
        self.__eventLoopThread.setDaemon(True)
        self.__eventLoopThread.start()
Ejemplo n.º 28
0
def main():
    libconn=libvirt.open("qemu:///system")
    info = libconn.getInfo()
    print info
    libconn.listAllDomains(libvirt.VIR_CONNECT_LIST_DOMAINS_RUNNING)
    libvirt.virEventRegisterDefaultImpl()
    virEventLoopNativeStart()
    #libvirt.virEventRunDefaultImpl()
    #domainEventRegisterAny(self, dom, eventID, cb, opaque)
    dom=libconn.lookupByName("xp")
    print dom.name()
    ret=libconn.domainEventRegisterAny(dom,libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,myDomainEventCallback2, None)
    #libconn.setKeepAlive(5, 3)
    #time.sleep(1)
    #while 1:
    while True:
        time.sleep(1)
Ejemplo n.º 29
0
def start(uri=None, tag_prefix="salt/engines/libvirt_events", filters=None):
    """
    Listen to libvirt events and forward them to salt.

    :param uri: libvirt URI to listen on.
                Defaults to None to pick the first available local hypervisor
    :param tag_prefix: the begining of the salt event tag to use.
                       Defaults to 'salt/engines/libvirt_events'
    :param filters: the list of event of listen on. Defaults to 'all'
    """
    if filters is None:
        filters = ["all"]
    try:
        libvirt.virEventRegisterDefaultImpl()

        cnx = libvirt.openReadOnly(uri)
        log.debug("Opened libvirt uri: %s", cnx.getURI())

        callback_ids = {}
        all_filters = "all" in filters

        for obj, event_defs in CALLBACK_DEFS.items():
            for event, real_id in event_defs:
                event_filter = "/".join((obj, event))
                if (
                    event_filter not in filters
                    and obj not in filters
                    and not all_filters
                ):
                    continue
                registered_id = _register_callback(cnx, tag_prefix, obj, event, real_id)
                if registered_id:
                    _append_callback_id(callback_ids, obj, registered_id)

        exit_loop = False
        while not exit_loop:
            exit_loop = libvirt.virEventRunDefaultImpl() < 0
            log.debug("=== in the loop exit_loop %s ===", exit_loop)

    except Exception as err:  # pylint: disable=broad-except
        log.exception(err)
    finally:
        _callbacks_cleanup(cnx, callback_ids)
        _cleanup(cnx)
Ejemplo n.º 30
0
    def __init__(self, **args):
        Machine.__init__(self, **args)

        self.run_dir = os.path.join(self.test_dir, "run")

        self._image_image = os.path.join(self.run_dir,
                                         "%s.qcow2" % (self.image))
        self._image_additional_iso = os.path.join(self.run_dir,
                                                  "%s.iso" % (self.image))

        self._images_dir = os.path.join(self.test_data, "images")
        self._image_original = os.path.join(self._images_dir,
                                            "%s.qcow2" % (self.image))
        self._iso_original = os.path.join(self._images_dir,
                                          "%s.iso" % (self.image))
        self._checksum_original = os.path.join(self._images_dir,
                                               "%s-checksum" % (self.image))

        self._fixed_mac_flavors = self._get_fixed_mac_flavors()
        self._network_description = etree.parse(
            open("./guest/network-cockpit.xml"))

        # it is ESSENTIAL to register the default implementation of the event loop before opening a connection
        # otherwise messages may be delayed or lost
        libvirt.virEventRegisterDefaultImpl()
        self.virt_connection = self._libvirt_connection(
            hypervisor="qemu:///session")
        self.event_handler = VirtEventHandler(
            libvirt_connection=self.virt_connection, verbose=self.verbose)

        # network names are currently hardcoded into network-cockpit.xml
        self.network_name = self._read_network_name()
        self.system_connection = self._libvirt_connection(
            hypervisor="qemu:///system", read_only=True)
        self.dhcp_net = self.system_connection.networkLookupByName(
            self.network_name)

        # we can't see the network itself as non-root, create it using vm-prep as root

        # Unique identifiers for hostnet config
        self._hostnet = 8

        # init variables needed for running a vm
        self._cleanup()
Ejemplo n.º 31
0
def monitor(uris, callback):
    libvirt.virEventRegisterDefaultImpl()

    conns = {}
    for uri in uris:
        conn = libvirt.openReadOnly(uri)
        conns[uri] = conn

        conn.setKeepAlive(5, 3)

        conn.domainEventRegisterAny(
            dom=None,
            eventID=libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
            cb=_handle_event,
            opaque=dict(uri=uri, callback=callback),
            )

    for uri, conn in conns.iteritems():
        for domain in getAllDomains(conn):
            # inject fake defined event for each domain that
            # exists at startup
            _handle_event(
                conn=conn,
                domain=domain,
                event=libvirt.VIR_DOMAIN_EVENT_DEFINED,
                detail=None,
                opaque=dict(uri=uri, callback=callback),
                )

    # signal that all current vms have been observed; that is, pruning
    # old entries is safe
    callback(dict(type='libvirt_complete'))

    while True:
        libvirt.virEventRunDefaultImpl()

        for uri, conn in conns.iteritems():
            if not conn.isAlive() == 1:
                # conn.close() tends to fail at this point, so don't
                # even try
                raise RuntimeError(
                    'Lost connection to {uri}'.format(uri=uri),
                    )
Ejemplo n.º 32
0
    def listen(self):
        """Prepares the environment before starts to accept connections

        Initializes and destroy the resources needed to accept connection.
        """
        libvirt.virEventRegisterDefaultImpl()
        try:
            guest = LibvirtGuest(self._guest_name, self._uri)

        except Exception as e:
            wok_log.error('Cannot open the guest %s due to %s',
                          self._guest_name, e.message)
            self._socket.close()
            sys.exit(1)

        except (KeyboardInterrupt, SystemExit):
            self._socket.close()
            sys.exit(1)

        console = None
        try:
            console = guest.get_console()
            self._listen(guest, console)

        # clear resources aquired when the process is killed
        except (KeyboardInterrupt, SystemExit):
            pass

        finally:
            wok_log.info("Shutting down the socket server to %s console",
                         self._guest_name)
            self._socket.close()
            if os.path.exists(self._server_addr):
                os.unlink(self._server_addr)

            try:
                console.eventRemoveCallback()

            except Exception as e:
                wok_log.info('Callback is probably removed: %s', e.message)

            guest.close()
Ejemplo n.º 33
0
def start(uri='qemu:///system',
          tag_prefix='salt/engines/libvirt_events',
          filters=None):
    '''
    Listen to libvirt events and forward them to salt.

    :param uri: libvirt URI to listen on.
                Defaults to 'qemu:///system'
    :param tag_prefix: the begining of the salt event tag to use.
                       Defaults to 'salt/engines/libvirt_events'
    :param filters: the list of event of listen on. Defaults to 'all'
    '''
    if filters is None:
        filters = ['all']
    try:
        libvirt.virEventRegisterDefaultImpl()

        log.debug('Opening libvirt uri: %s', uri)
        cnx = libvirt.openReadOnly(uri)

        callback_ids = {}
        all_filters = "all" in filters

        for obj, event_defs in CALLBACK_DEFS.items():
            for event, real_id in event_defs:
                event_filter = "/".join((obj, event))
                if event_filter not in filters and obj not in filters and not all_filters:
                    continue
                registered_id = _register_callback(cnx, tag_prefix,
                                                   obj, event, real_id)
                if registered_id:
                    _append_callback_id(callback_ids, obj, registered_id)

        exit_loop = False
        while not exit_loop:
            exit_loop = libvirt.virEventRunDefaultImpl() < 0

    except Exception as err:  # pylint: disable=broad-except
        log.exception(err)
    finally:
        _callbacks_cleanup(cnx, callback_ids)
        _cleanup(cnx)
Ejemplo n.º 34
0
    def start(self):
        libvirt.virEventRegisterDefaultImpl()
        libvirt.registerErrorHandler(error_handler, None)

        atexit.register(self.reset_term)
        self.attrs = termios.tcgetattr(0)
        tty.setraw(0)

        self.connection = LibvirtConnect.get_connection()
        self.domain = self.connection.lookupByName(self.domain_name)
        self.state = self.domain.state(0)
        self.connection.domainEventRegister(self.lifecycle_callback, self)

        sys.stdout.write('Press Control+] to quit.\n\r')
        sys.stdout.flush()

        libvirt.virEventAddHandle(
            0, libvirt.VIR_EVENT_HANDLE_READABLE, self.stdin_callback, None)

        while self.check_console():
            libvirt.virEventRunDefaultImpl()

        sys.stdout.write('\n\rExited.\n\r')
        sys.stdout.flush()
Ejemplo n.º 35
0
    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')
Ejemplo n.º 36
0
    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')
Ejemplo n.º 37
0
def vir_event_loop_native_start():
    libvirt.virEventRegisterDefaultImpl()
    eventLoopThread = threading.Thread(target=vir_event_loop_native_run,
                                       name="libvirtEventLoop")
    eventLoopThread.setDaemon(True)
    eventLoopThread.start()
Ejemplo n.º 38
0
 def virEventLoopNativeStart(self):
     libvirt.virEventRegisterDefaultImpl()
     eventLoopThread = threading.Thread(target=self.virEventLoopNativeRun,
                                        name="libvirtEventLoop")
     eventLoopThread.setDaemon(True)
     eventLoopThread.start()
Ejemplo n.º 39
0
    console.state = console.domain.state(0)
    logging.info("%s transitioned to state %d, reason %d",
                 console.uuid, console.state[0], console.state[1])

# main
if len(sys.argv) != 3:
    print("Usage:", sys.argv[0], "URI UUID")
    print("for example:", sys.argv[0], "'qemu:///system' '32ad945f-7e78-c33a-e96d-39f25e025d81'")
    sys.exit(1)

uri = sys.argv[1]
uuid = sys.argv[2]

print("Escape character is ^]")
logging.basicConfig(filename='msg.log', level=logging.DEBUG)
logging.info("URI: %s", uri)
logging.info("UUID: %s", uuid)

libvirt.virEventRegisterDefaultImpl()
libvirt.registerErrorHandler(error_handler, None)

atexit.register(reset_term)
attrs = termios.tcgetattr(0)
tty.setraw(0)

console = Console(uri, uuid)
console.stdin_watch = libvirt.virEventAddHandle(0, libvirt.VIR_EVENT_HANDLE_READABLE, stdin_callback, console)

while check_console(console):
    libvirt.virEventRunDefaultImpl()
Ejemplo n.º 40
0
def build(srcpkg, outdir, package, jobid, logfile, arch):
    logging.info('building %s to %s' % (os.path.basename(srcpkg), outdir))

    steptimer.start()
    vmid = 'buildvm_%d' % jobid

    # open a libvirt connection to hypervisor
    libvirt.virInitialize()
    libvirt.virEventRegisterDefaultImpl()
    conn = libvirt.open('qemu:///system')
    if conn == None:
        logging.error('Failed to open connection to the hypervisor')
        return False

    # create VM
    clone_storage = clone(conn, BASE_VMID[arch], vmid)
    steptimer.mark('clone vm')

    domain = conn.lookupByName(vmid)

    # start vm, automatically clean up when we are done, unless debugging
    domain.createWithFlags(libvirt.VIR_DOMAIN_START_AUTODESTROY if not debug else 0)

    # wait for vm to boot up
    wait_for_guest_agent(conn, domain, 5*60)
    guestPing(domain)

    steptimer.mark('boot')

    # ensure directory exists and is empty
    guestExec(domain, 'cmd', ['/C', 'rmdir', '/S', '/Q', r'C:\\vm_in\\'])
    guestExec(domain, 'cmd', ['/C', 'mkdir', r'C:\\vm_in\\'])

    # install build instructions and source
    for f in ['build.sh', 'wrapper.sh', srcpkg]:
        guestFileCopyTo(domain, f, r'C:\\vm_in\\' + os.path.basename(f))

    if package.depends:
        guestFileWrite(domain, r'C:\\vm_in\\depends', bytes(package.depends, 'ascii'))

    steptimer.mark('put')

    # attempt the build
    success = guestExec(domain, bash_path[arch], ['-l','/cygdrive/c/vm_in/wrapper.sh', os.path.basename(srcpkg), r'C:\\vm_out', package.script, package.kind])
    steptimer.mark('build')

    # XXX: guest-agent doesn't seem to be capable of capturing output of cygwin
    # process (for some strange reason), so we arrange to redirect it to a file
    # and collect it here...
    guestFileCopyFrom(domain, r'C:\\vm_in\\output', logfile)
    logging.info('build logfile is %s' % (logfile))

    # if the build was successful, fetch build products from VM
    if success:
        os.makedirs(outdir, exist_ok=True)
        manifest = os.path.join(outdir, 'manifest')
        guestFileCopyFrom(domain, r'C:\\vm_out\\manifest', manifest)

        with open(manifest) as f:
            for l in f:
                l = l.strip()
                fn = os.path.join(outdir, l)
                os.makedirs(os.path.dirname(fn), exist_ok=True)
                winpath = l.replace('/',r'\\')
                guestFileCopyFrom(domain, r'C:\\vm_out\\' + winpath, fn)

    steptimer.mark('fetch')

    if not debug:
        # terminate the VM.  Don't bother giving it a chance to shut down
        # cleanly since we won't be using it again
        domain.destroy()

        # clean up VM
        domain.undefineFlags(libvirt.VIR_DOMAIN_UNDEFINE_MANAGED_SAVE |
                             libvirt.VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA |
                             libvirt.VIR_DOMAIN_UNDEFINE_NVRAM)
        os.remove(clone_storage)
        steptimer.mark('destroy vm')

    status = 'succeeded' if success else 'failed'
    logging.info('build %s, %s' % (status, steptimer.report()))

    return success
Ejemplo n.º 41
0
def virEventLoopNativeStart() -> None:
    global eventLoopThread
    libvirt.virEventRegisterDefaultImpl()
    eventLoopThread = threading.Thread(target=virEventLoopNativeRun, name="libvirtEventLoop")
    eventLoopThread.setDaemon(True)
    eventLoopThread.start()
Ejemplo n.º 42
0
def virEventLoopNativeStart(stop):
    libvirt.virEventRegisterDefaultImpl()
    eventLoopThread = threading.Thread(target=virEventLoopNativeRun, name="EventLoop", args=(stop,))
    eventLoopThread.setDaemon(True)
    eventLoopThread.start()
    return eventLoopThread
 def start_native_loop(self):
     global eventLoopThread
     libvirt.virEventRegisterDefaultImpl()
     eventLoopThread = threading.Thread(target=self._native_loop, name="libvirtEventLoop")
     eventLoopThread.setDaemon(True)
     eventLoopThread.start()
Ejemplo n.º 44
0
def main():
    ccl = j.clients.osis.getNamespace('cloudbroker')
    scl = j.clients.osis.getNamespace('system')
    pcl = j.clients.portal.getByInstance('main')

    libvirt.virEventRegisterDefaultImpl()
    rocon = libvirt.open()
    def get_vm_tags(vm):
        vm = ccl.vmachine.get(vm['id'])
        cloudspace = ccl.cloudspace.get(vm.cloudspaceId)
        return 'machineId:{} cloudspaceId:{} accountId:{}'.format(vm.id, cloudspace.id, cloudspace.accountId)

    def callback(con, domain, event, detail, opaque):
        name = domain.name()
        print('State change for {} {} {}'.format(name, event, detail))
        vm = next(iter(ccl.vmachine.search({'referenceId': domain.UUIDString()})[1:]), None)
        tags = ''
        if vm:
            if event == libvirt.VIR_DOMAIN_EVENT_STOPPED and detail in [libvirt.VIR_DOMAIN_EVENT_STOPPED_FAILED, libvirt.VIR_DOMAIN_EVENT_STOPPED_CRASHED]:
                msg = ''
                if name.startswith('vm-'):
                    machineId = int(name.split('-')[-1])
                    msg = "VM {} has crashed".format(machineId)
                    tags = get_vm_tags(vm)
                    pcl.actors.cloudapi.machines.start(machineId)
                elif name.startswith('routeros_'):
                    networkid = int(name.split('_')[-1], 16)
                    cloudspaces = ccl.cloudspace.search({'networkId': networkid})[1:]
                    if not cloudspaces:
                        return  # orphan vm we dont care
                    tags = 'cloudspaceId:{}'.format(cloudspaces[0]['id'])
                    domain.create()

                print('VM {} crashed, starting it again'.format(name))
                j.errorconditionhandler.raiseOperationalWarning(msg, 'selfhealing', tags=tags)
                return
            newstate = None
            if event == libvirt.VIR_DOMAIN_EVENT_STARTED:
                newstate = 'RUNNING'
            elif event == libvirt.VIR_DOMAIN_EVENT_STOPPED:
                newstate = 'HALTED'
            if newstate is not None:
                print('Updating state for vm {} to {}'.format(name, newstate))
                # update the state if its not destroyed already
                update = ccl.vmachine.updateSearch({'id': vm['id'], 'status': {'$nin': ['DELETED', 'DESTROYED']}}, {'$set': {'status': newstate}})
                if newstate == 'HALTED' and update['nModified'] == 1:
                    # check if lock exists on vm
                    lockname = 'cloudbroker_vmachine_{}'.format(vm['id'])
                    if not scl.lock.exists(lockname):
                        # no action lock and we change status we should create and audit for this case
                        audit = scl.audit.new()
                        audit.user = '******'
                        audit.tags = get_vm_tags(vm)
                        audit.statuscode = 200
                        audit.call = '/restmachine/cloudapi/machines/stop'
                        audit.timestamp = time.time()
                        audit.responsetime = 0
                        audit.args = 'null'
                        audit.kwargs = 'null'
                        audit.result = 'null'
                        scl.audit.set(audit)
                        cloudspace = ccl.cloudspace.get(vm['cloudspaceId'])
                        j.system.ovsnetconfig.cleanupIfUnused(cloudspace.networkId)

    rocon.domainEventRegisterAny(None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
                                 callback, rocon)
    while True:
        libvirt.virEventRunDefaultImpl()
Ejemplo n.º 45
0
def up(virt_lightning_yaml, configuration, context, **kwargs):
    def myDomainEventAgentLifecycleCallback(conn, dom, state, reason, opaque):
        if state == 1:
            logger.info("%s %s QEMU agent found", symbols.CUSTOMS.value, dom.name())

    async def deploy():
        futures = []
        for host in virt_lightning_yaml:
            futures.append(loop.run_in_executor(pool, start_domain, host))

        domain_reachable_futures = []
        for f in futures:
            await f
            domain_reachable_futures.append(f.result().reachable())
        logger.info("%s ok Waiting...", symbols.HOURGLASS.value)

        await asyncio.gather(*domain_reachable_futures)

    loop = asyncio.get_event_loop()
    try:
        import libvirtaio

        libvirtaio.virEventRegisterAsyncIOImpl(loop=loop)
    except ImportError:
        libvirt.virEventRegisterDefaultImpl()
        pass
    conn = libvirt.open(configuration.libvirt_uri)
    hv = vl.LibvirtHypervisor(conn)

    conn.setKeepAlive(5, 3)
    conn.domainEventRegisterAny(
        None,
        libvirt.VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE,
        myDomainEventAgentLifecycleCallback,
        None,
    )

    hv.init_network(configuration.network_name, configuration.network_cidr)
    hv.init_storage_pool(configuration.storage_pool)

    def start_domain(host):
        if host["distro"] not in hv.distro_available():
            logger.error("distro not available: %s", host["distro"])
            logger.info(
                "Please select on of the following distro: %s", hv.distro_available()
            )
            exit()

        if "name" not in host:
            host["name"] = re.sub(r"\W+", "", host["distro"])

        if hv.get_domain_by_name(host["name"]):
            logger.error("Domain {name} already exists!".format(**host))
            exit(1)

        # Unfortunatly, i can't decode that symbol
        # that symbol more well add to check encoding block
        logger.info(
            "{lightning} {name} ".format(lightning=symbols.LIGHTNING.value, **host)
        )
        domain = hv.create_domain(name=host["name"], distro=host["distro"])
        domain.context = context
        domain.load_ssh_key_file(configuration.ssh_key_file)
        domain.username = configuration.username
        domain.root_password = host.get("root_password", configuration.root_password)

        domain.vcpus(host.get("vcpus"))
        domain.memory(host.get("memory", 768))
        root_disk_path = hv.create_disk(name=host["name"], backing_on=host["distro"])
        domain.add_root_disk(root_disk_path)
        domain.attachNetwork(configuration.network_name)
        domain.ipv4 = hv.get_free_ipv4()
        domain.add_swap_disk(hv.create_disk(host["name"] + "-swap", size=1))
        hv.start(domain)
        return domain

    pool = ThreadPoolExecutor(max_workers=10)
    loop.run_until_complete(deploy())
    logger.info("%s You are all set", symbols.THUMBS_UP.value)
Ejemplo n.º 46
0
    def event_register():

        libvirt.virEventRegisterDefaultImpl()
Ejemplo n.º 47
0
    logging.info("%s transitioned to state %d, reason %d",
                 console.uuid, console.state[0], console.state[1])


# main
if len(sys.argv) != 3:
    print("Usage:", sys.argv[0], "URI UUID")
    print("for example:", sys.argv[0], "'qemu:///system' '32ad945f-7e78-c33a-e96d-39f25e025d81'")
    sys.exit(1)

uri = sys.argv[1]
uuid = sys.argv[2]

print("Escape character is ^]")
logging.basicConfig(filename='msg.log', level=logging.DEBUG)
logging.info("URI: %s", uri)
logging.info("UUID: %s", uuid)

libvirt.virEventRegisterDefaultImpl()
libvirt.registerErrorHandler(error_handler, None)

atexit.register(reset_term)
attrs = termios.tcgetattr(0)
tty.setraw(0)

console = Console(uri, uuid)
console.stdin_watch = libvirt.virEventAddHandle(0, libvirt.VIR_EVENT_HANDLE_READABLE, stdin_callback, console)

while check_console(console):
    libvirt.virEventRunDefaultImpl()
Ejemplo n.º 48
0
 def _vir_event_loop_native_start(self):
     libvirt.virEventRegisterDefaultImpl()
     self.event_loop_thread = threading.Thread(
         target=self._vir_event_loop_native_run, name="lib_virt_eventLoop")
     self.event_loop_thread.setDaemon(True)
     self.event_loop_thread.start()
Ejemplo n.º 49
0
 def __run(self):
     libvirt.virEventRegisterDefaultImpl()
     while self.run:
         libvirt.virEventRunDefaultImpl()
Ejemplo n.º 50
0
def start(uri="qemu:///system",
          tag_prefix="salt/engines/libvirt_events",
          filters=["all"]):
    try:
        libvirt.virEventRegisterDefaultImpl()

        log.debug('Opening libvirt uri: %s' % uri)
        cnx = libvirt.openReadOnly(uri)

        def cleanup():
            log.debug('Closing libvirt connection: %s' % uri)
            cnx.close()

        atexit.register(cleanup)

        callbacks = {
            'domain': {
                'callbacks': {},
                'register': 'domainEventRegisterAny',
                'deregister': 'domainEventDeregisterAny'
            },
            'network': {
                'callbacks': {},
                'register': 'networkEventRegisterAny',
                'deregister': 'networkEventDeregisterAny'
            },
            'pool': {
                'callbacks': {},
                'register': 'storagePoolEventRegisterAny',
                'deregister': 'storagePoolEventDeregisterAny',
            },
            'nodedev': {
                'callbacks': {},
                'register': 'nodeDeviceEventRegisterAny',
                'deregister': 'nodeDeviceEventDeregisterAny',
            },
            'secret': {
                'callbacks': {},
                'register': 'secretEventRegisterAny',
                'deregister': 'secretEventDeregisterAny',
            }
        }

        def addCallback(obj, event, event_id, callback):
            try:
                libvirt_id = getattr(libvirt, event_id)

                callbacks[obj]['callbacks'][event] = {
                    'type': event_id,
                    'callback': callback
                }
            except AttributeError:
                log.warn('Skip "%s/%s" events: libvirt too old' % (obj, event))

        # Domain callbacks
        addCallback('domain', 'lifecycle', 'VIR_DOMAIN_EVENT_ID_LIFECYCLE',
                    domainEventLifecycleCallback)
        addCallback('domain', 'reboot', 'VIR_DOMAIN_EVENT_ID_REBOOT',
                    domainEventRebootCallback)
        addCallback('domain', 'rtcchange', 'VIR_DOMAIN_EVENT_ID_RTC_CHANGE',
                    domainEventRTCChangeCallback)
        addCallback('domain', 'watchdog', 'VIR_DOMAIN_EVENT_ID_WATCHDOG',
                    domainEventWatchdogCallback)
        addCallback('domain', 'graphics', 'VIR_DOMAIN_EVENT_ID_GRAPHICS',
                    domainEventGraphicsCallback)
        addCallback('domain', 'ioerror', 'VIR_DOMAIN_EVENT_ID_IO_ERROR_REASON',
                    domainEventIOErrorReasonCallback)
        addCallback('domain', 'control error',
                    'VIR_DOMAIN_EVENT_ID_CONTROL_ERROR',
                    domainEventControlErrorCallback)
        addCallback('domain', 'disk change', 'VIR_DOMAIN_EVENT_ID_DISK_CHANGE',
                    domainEventDiskChangeCallback)
        addCallback('domain', 'tray change', 'VIR_DOMAIN_EVENT_ID_TRAY_CHANGE',
                    domainEventTrayChangeCallback)
        addCallback('domain', 'pmwakeup', 'VIR_DOMAIN_EVENT_ID_PMWAKEUP',
                    domainEventPMWakeupCallback)
        addCallback('domain', 'pmsuspend', 'VIR_DOMAIN_EVENT_ID_PMSUSPEND',
                    domainEventPMSuspendCallback)
        addCallback('domain', 'balloon change',
                    'VIR_DOMAIN_EVENT_ID_BALLOON_CHANGE',
                    domainEventBalloonChangeCallback)
        addCallback('domain', 'pmsuspenddisk',
                    'VIR_DOMAIN_EVENT_ID_PMSUSPEND_DISK',
                    domainEventPMSuspendDiskCallback)

        # Handle either BLOCK_JOB or BLOCK_JOB_2, but prefer the latter
        try:
            blockJobId = libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB_2
        except AttributeError:
            blockJobId = libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_JOB
        addCallback('domain', 'block job', blockJobId,
                    domainEventBlockJobCallback)

        addCallback('domain', 'device removed',
                    'VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED',
                    domainEventDeviceRemovedCallback)

        addCallback('domain', 'tunable', 'VIR_DOMAIN_EVENT_ID_TUNABLE',
                    domainEventTunableCallback)

        addCallback('domain', 'agent lifecycle',
                    'VIR_DOMAIN_EVENT_ID_AGENT_LIFECYCLE',
                    domainEventAgentLifecycleCallback)

        addCallback('domain', 'device added',
                    'VIR_DOMAIN_EVENT_ID_DEVICE_ADDED',
                    domainEventDeviceAddedCallback)

        addCallback('domain', 'migration iteration',
                    'VIR_DOMAIN_EVENT_ID_MIGRATION_ITERATION',
                    domainEventMigrationIteration)

        addCallback('domain', 'job completed',
                    'VIR_DOMAIN_EVENT_ID_JOB_COMPLETED',
                    domainEventJobCompletedCallback)

        addCallback('domain', 'device removal failed',
                    'VIR_DOMAIN_EVENT_ID_DEVICE_REMOVAL_FAILED',
                    domainEventDeviceRemovalFailedCallback)

        addCallback('domain', 'event metadata change',
                    'VIR_DOMAIN_EVENT_ID_METADATA_CHANGE',
                    domainEventMetadataChangeCallback)

        addCallback('domain', 'block threshold',
                    'VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD',
                    domainEventBlockThresholdCallback)

        # Network callbacks
        addCallback('network', 'lifecycle', 'VIR_NETWORK_EVENT_ID_LIFECYCLE',
                    networkEventLifecycleCallback)

        # Pool callbacks
        addCallback('pool', 'lifecycle', 'VIR_STORAGE_POOL_EVENT_ID_LIFECYCLE',
                    storagePoolEventLifecycleCallback)

        addCallback('pool', 'refresh', 'VIR_STORAGE_POOL_EVENT_ID_REFRESH',
                    storagePoolEventRefreshCallback)

        # Node device callbacks
        addCallback('nodedev', 'lifecycle',
                    'VIR_NODE_DEVICE_EVENT_ID_LIFECYCLE',
                    nodeDeviceEventLifecycleCallback)

        addCallback('nodedev', 'update', 'VIR_NODE_DEVICE_EVENT_ID_UPDATE',
                    nodeDeviceEventUpdateCallback)

        # Secret callbacks
        addCallback('secret', 'lifecycle', 'VIR_SECRET_EVENT_ID_LIFECYCLE',
                    secretEventLifecycleCallback)

        addCallback('secret', 'value changed',
                    'VIR_SECRET_EVENT_ID_VALUE_CHANGED',
                    secretEventValueChangedCallback)

        callbackIds = {}
        allFilters = "all" in filters

        for obj, obj_data in callbacks.items():
            for event_type, callback in obj_data['callbacks'].items():
                event = "/".join((obj, event_type))
                if event in filters or allFilters:
                    register = getattr(cnx, obj_data['register'])
                    id = register(None, callback['type'], callback['callback'],
                                  {
                                      'prefix': tag_prefix,
                                      'object': obj,
                                      'event': event_type
                                  })

                    if obj not in callbackIds:
                        callbackIds[obj] = []

                    callbackIds[obj].append(id)

        def callbacksCleanup():
            for obj, ids in callbackIds.items():
                deregister = getattr(cnx, callbacks[obj]['deregister'])
                for callbackId in ids:
                    deregister(callbackId)

        atexit.register(callbacksCleanup)

        while True:
            libvirt.virEventRunDefaultImpl()

    except Exception:
        raise Exception('%s' % traceback.format_exc())
Ejemplo n.º 51
0
def main():
    ccl = j.clients.osis.getNamespace("cloudbroker")
    scl = j.clients.osis.getNamespace("system")
    pcl = j.clients.portal.getByInstance("main")

    libvirt.virEventRegisterDefaultImpl()
    rocon = libvirt.open()

    def get_vm_tags(vm):
        vm = ccl.vmachine.get(vm["id"])
        cloudspace = ccl.cloudspace.get(vm.cloudspaceId)
        return "machineId:{} cloudspaceId:{} accountId:{}".format(
            vm.id, cloudspace.id, cloudspace.accountId
        )

    def callback(con, domain, event, detail, opaque):
        name = domain.name()
        print("State change for {} {} {}".format(name, event, detail))
        vm = next(
            iter(ccl.vmachine.search({"referenceId": domain.UUIDString()})[1:]), None
        )
        tags = ""
        if vm:
            if event == libvirt.VIR_DOMAIN_EVENT_STOPPED and detail in [
                libvirt.VIR_DOMAIN_EVENT_STOPPED_FAILED,
                libvirt.VIR_DOMAIN_EVENT_STOPPED_CRASHED,
            ]:
                msg = ""
                if name.startswith("vm-"):
                    machineId = int(name.split("-")[-1])
                    msg = "VM {} has crashed".format(machineId)
                    tags = get_vm_tags(vm)
                    pcl.actors.cloudapi.machines.start(machineId)
                elif name.startswith("routeros_"):
                    networkid = int(name.split("_")[-1], 16)
                    cloudspaces = ccl.cloudspace.search({"networkId": networkid})[1:]
                    if not cloudspaces:
                        return  # orphan vm we dont care
                    tags = "cloudspaceId:{}".format(cloudspaces[0]["id"])
                    domain.create()

                print("VM {} crashed, starting it again".format(name))
                j.errorconditionhandler.raiseOperationalWarning(
                    msg, "selfhealing", tags=tags
                )
                return
            newstate = None
            if event == libvirt.VIR_DOMAIN_EVENT_STARTED:
                newstate = "RUNNING"
            elif event == libvirt.VIR_DOMAIN_EVENT_STOPPED:
                newstate = "HALTED"
            if newstate is not None:
                print("Updating state for vm {} to {}".format(name, newstate))
                # update the state if its not destroyed already
                update = ccl.vmachine.updateSearch(
                    {"id": vm["id"], "status": {"$nin": ["DELETED", "DESTROYED"]}},
                    {"$set": {"status": newstate}},
                )
                if newstate == "HALTED" and update["nModified"] == 1:
                    # check if lock exists on vm
                    lockname = "cloudbroker_vmachine_{}".format(vm["id"])
                    if not scl.lock.exists(lockname):
                        # no action lock and we change status we should create and audit for this case
                        audit = scl.audit.new()
                        audit.user = "******"
                        audit.tags = get_vm_tags(vm)
                        audit.statuscode = 200
                        audit.call = "/restmachine/cloudapi/machines/stop"
                        audit.timestamp = time.time()
                        audit.responsetime = 0
                        audit.args = "null"
                        audit.kwargs = "null"
                        audit.result = "null"
                        scl.audit.set(audit)
                        cloudspace = ccl.cloudspace.get(vm["cloudspaceId"])
                        j.system.ovsnetconfig.cleanupIfUnused(cloudspace.networkId)

    rocon.domainEventRegisterAny(
        None, libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE, callback, rocon
    )
    while True:
        libvirt.virEventRunDefaultImpl()