示例#1
0
 def wrapper(*args, **kwargs):
     try:
         ret = f(*args, **kwargs)
         if isinstance(ret, libvirt.virDomain):
             for name in dir(ret):
                 method = getattr(ret, name)
                 if callable(method) and name[0] != '_':
                     setattr(ret, name,
                             wrapMethod(function.weakmethod(method)))
         return ret
     except libvirt.libvirtError as e:
         edom = e.get_error_domain()
         ecode = e.get_error_code()
         EDOMAINS = (libvirt.VIR_FROM_REMOTE, libvirt.VIR_FROM_RPC)
         ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
                   libvirt.VIR_ERR_INTERNAL_ERROR,
                   libvirt.VIR_ERR_NO_CONNECT,
                   libvirt.VIR_ERR_INVALID_CONN)
         if edom in EDOMAINS and ecode in ECODES:
             try:
                 __connections.get(id(target)).pingLibvirt()
             except libvirt.libvirtError as e:
                 edom = e.get_error_domain()
                 ecode = e.get_error_code()
                 if edom in EDOMAINS and ecode in ECODES:
                     log.warning(
                         'connection to libvirt broken.'
                         ' ecode: %d edom: %d', ecode, edom)
                     if killOnFailure:
                         log.critical('taking calling process down.')
                         os.kill(os.getpid(), signal.SIGTERM)
                     else:
                         raise
         raise
示例#2
0
 def test_raise_on_invalid_weakref(self):
     obj = ObjectWithDel()
     method = function.weakmethod(obj.public)
     obj.public = method
     self.assertEqual(obj.public(), ("public", (), {}))
     del obj
     self.assertRaises(function.InvalidatedWeakRef, method)
示例#3
0
 def test_without_reference_cycle(self):
     obj = ObjectWithDel()
     obj.public = function.weakmethod(obj.public)
     self.assertEqual(obj.public(), ("public", (), {}))
     del obj
     gc.collect()
     self.assertNotIn(ObjectWithDel, [type(obj) for obj in gc.garbage])
示例#4
0
 def wrapper(*args, **kwargs):
     try:
         ret = f(*args, **kwargs)
         if isinstance(ret, libvirt.virDomain):
             for name in dir(ret):
                 method = getattr(ret, name)
                 if callable(method) and name[0] != '_':
                     setattr(ret, name,
                             wrapMethod(function.weakmethod(method)))
         return ret
     except libvirt.libvirtError as e:
         edom = e.get_error_domain()
         ecode = e.get_error_code()
         EDOMAINS = (libvirt.VIR_FROM_REMOTE,
                     libvirt.VIR_FROM_RPC)
         ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
                   libvirt.VIR_ERR_INTERNAL_ERROR,
                   libvirt.VIR_ERR_NO_CONNECT,
                   libvirt.VIR_ERR_INVALID_CONN)
         if edom in EDOMAINS and ecode in ECODES:
             try:
                 __connections.get(id(target)).pingLibvirt()
             except libvirt.libvirtError as e:
                 edom = e.get_error_domain()
                 ecode = e.get_error_code()
                 if edom in EDOMAINS and ecode in ECODES:
                     log.warning('connection to libvirt broken.'
                                 ' ecode: %d edom: %d', ecode, edom)
                     if killOnFailure:
                         log.critical('taking calling process down.')
                         os.kill(os.getpid(), signal.SIGTERM)
                     else:
                         raise
         raise
示例#5
0
 def test_raise_on_invalid_weakref(self):
     obj = ObjectWithDel()
     method = function.weakmethod(obj.public)
     obj.public = method
     self.assertEqual(obj.public(), ("public", (), {}))
     del obj
     self.assertRaises(function.InvalidatedWeakRef, method)
示例#6
0
 def test_without_reference_cycle(self):
     obj = ObjectWithDel()
     obj.public = function.weakmethod(obj.public)
     self.assertEqual(obj.public(), ("public", (), {}))
     del obj
     gc.collect()
     self.assertNotIn(ObjectWithDel, [type(obj) for obj in gc.garbage])
示例#7
0
def get(target=None, killOnFailure=True):
    """Return current connection to libvirt or open a new one.
    Use target to get/create the connection object linked to that object.
    target must have a callable attribute named 'dispatchLibvirtEvents' which
    will be registered as a callback on libvirt events.

    Wrap methods of connection object so that they catch disconnection, and
    take the current process down.
    """
    def wrapMethod(f):
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            try:
                ret = f(*args, **kwargs)
                if isinstance(ret, libvirt.virDomain):
                    for name in dir(ret):
                        method = getattr(ret, name)
                        if callable(method) and name[0] != '_':
                            setattr(ret, name,
                                    wrapMethod(function.weakmethod(method)))
                return ret
            except libvirt.libvirtError as e:
                edom = e.get_error_domain()
                ecode = e.get_error_code()
                EDOMAINS = (libvirt.VIR_FROM_REMOTE, libvirt.VIR_FROM_RPC)
                ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
                          libvirt.VIR_ERR_INTERNAL_ERROR,
                          libvirt.VIR_ERR_NO_CONNECT,
                          libvirt.VIR_ERR_INVALID_CONN)
                if edom in EDOMAINS and ecode in ECODES:
                    try:
                        __connections.get(id(target)).pingLibvirt()
                    except libvirt.libvirtError as e:
                        edom = e.get_error_domain()
                        ecode = e.get_error_code()
                        if edom in EDOMAINS and ecode in ECODES:
                            log.warning(
                                'connection to libvirt broken.'
                                ' ecode: %d edom: %d', ecode, edom)
                            if killOnFailure:
                                log.critical('taking calling process down.')
                                os.kill(os.getpid(), signal.SIGTERM)
                            else:
                                raise
                raise

        return wrapper

    with __connectionLock:
        conn = __connections.get(id(target))
        if not conn:
            log.debug('trying to connect libvirt')
            password = ProtectedPassword(libvirt_password())
            conn = open_connection('qemu:///system', SASL_USERNAME, password)
            __connections[id(target)] = conn

            setattr(conn, 'pingLibvirt', getattr(conn, 'getLibVersion'))
            for name in dir(libvirt.virConnect):
                method = getattr(conn, name)
                if callable(method) and name[0] != '_':
                    setattr(conn, name,
                            wrapMethod(function.weakmethod(method)))
            if target is not None:
                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,
                           libvirt.VIR_DOMAIN_EVENT_ID_JOB_COMPLETED,
                           libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD):
                    conn.domainEventRegisterAny(None, ev,
                                                target.dispatchLibvirtEvents,
                                                ev)
            # In case we're running into troubles with keeping the connections
            # alive we should place here:
            # conn.setKeepAlive(interval=5, count=3)
            # However the values need to be considered wisely to not affect
            # hosts which are hosting a lot of virtual machines

        return conn
示例#8
0
def get(target=None, killOnFailure=True):
    """Return current connection to libvirt or open a new one.
    Use target to get/create the connection object linked to that object.
    target must have a callable attribute named 'dispatchLibvirtEvents' which
    will be registered as a callback on libvirt events.

    Wrap methods of connection object so that they catch disconnection, and
    take the current process down.
    """
    def wrapMethod(f):
        @functools.wraps(f)
        def wrapper(*args, **kwargs):
            try:
                ret = f(*args, **kwargs)
                if isinstance(ret, libvirt.virDomain):
                    for name in dir(ret):
                        method = getattr(ret, name)
                        if callable(method) and name[0] != '_':
                            setattr(ret, name,
                                    wrapMethod(function.weakmethod(method)))
                return ret
            except libvirt.libvirtError as e:
                edom = e.get_error_domain()
                ecode = e.get_error_code()
                EDOMAINS = (libvirt.VIR_FROM_REMOTE,
                            libvirt.VIR_FROM_RPC)
                ECODES = (libvirt.VIR_ERR_SYSTEM_ERROR,
                          libvirt.VIR_ERR_INTERNAL_ERROR,
                          libvirt.VIR_ERR_NO_CONNECT,
                          libvirt.VIR_ERR_INVALID_CONN)
                if edom in EDOMAINS and ecode in ECODES:
                    try:
                        __connections.get(id(target)).pingLibvirt()
                    except libvirt.libvirtError as e:
                        edom = e.get_error_domain()
                        ecode = e.get_error_code()
                        if edom in EDOMAINS and ecode in ECODES:
                            log.warning('connection to libvirt broken.'
                                        ' ecode: %d edom: %d', ecode, edom)
                            if killOnFailure:
                                log.critical('taking calling process down.')
                                os.kill(os.getpid(), signal.SIGTERM)
                            else:
                                raise
                raise
        return wrapper

    with __connectionLock:
        conn = __connections.get(id(target))
        if not conn:
            log.debug('trying to connect libvirt')
            password = ProtectedPassword(libvirt_password())
            conn = open_connection('qemu:///system', SASL_USERNAME, password)
            __connections[id(target)] = conn

            setattr(conn, 'pingLibvirt', getattr(conn, 'getLibVersion'))
            for name in dir(libvirt.virConnect):
                method = getattr(conn, name)
                if callable(method) and name[0] != '_':
                    setattr(conn, name,
                            wrapMethod(function.weakmethod(method)))
            if target is not None:
                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,
                           libvirt.VIR_DOMAIN_EVENT_ID_JOB_COMPLETED,
                           libvirt.VIR_DOMAIN_EVENT_ID_DEVICE_REMOVED,
                           libvirt.VIR_DOMAIN_EVENT_ID_BLOCK_THRESHOLD):
                    conn.domainEventRegisterAny(None,
                                                ev,
                                                target.dispatchLibvirtEvents,
                                                ev)
            # In case we're running into troubles with keeping the connections
            # alive we should place here:
            # conn.setKeepAlive(interval=5, count=3)
            # However the values need to be considered wisely to not affect
            # hosts which are hosting a lot of virtual machines

        return conn