Fix bug with not implemented virConnect.registerCloseCallback
The unit test test_connection_to_primitive fails many times due to "virConnect instance has no attribute 'registerCloseCallback'". registerCloseCallback has been added since original(community's) python-libvirt v1.0.0, and v1.2.0 also contains the method. However ubuntu cloud's v1.0.1 does not contain the method, and current version check of python-libvirt does not work. This patch tries to operate the method and catch TypeError exception if the method does not exist instead of the version check. Co-Authored-By: Sahid Orentino Ferdjaoui <sahid.ferdjaoui@cloudwatt.com> Closes-Bug: #1266711 Change-Id: I4ec9ff9a684639ae5b146f400c90115c83afcda7
This commit is contained in:
parent
b1cf26bab4
commit
85068cc9f6
|
@ -642,6 +642,9 @@ class Connection(object):
|
||||||
def domainEventRegisterAny(self, dom, eventid, callback, opaque):
|
def domainEventRegisterAny(self, dom, eventid, callback, opaque):
|
||||||
self._event_callbacks[eventid] = [callback, opaque]
|
self._event_callbacks[eventid] = [callback, opaque]
|
||||||
|
|
||||||
|
def registerCloseCallback(self, cb, opaque):
|
||||||
|
pass
|
||||||
|
|
||||||
def getCapabilities(self):
|
def getCapabilities(self):
|
||||||
"""Return spoofed capabilities."""
|
"""Return spoofed capabilities."""
|
||||||
return '''<capabilities>
|
return '''<capabilities>
|
||||||
|
|
|
@ -705,8 +705,15 @@ class LibvirtConnTestCase(test.TestCase):
|
||||||
self.assertThat(expected, matchers.DictMatches(result))
|
self.assertThat(expected, matchers.DictMatches(result))
|
||||||
|
|
||||||
def test_close_callback(self):
|
def test_close_callback(self):
|
||||||
def get_lib_version_stub():
|
class FakeConn(object):
|
||||||
return (1 * 1000 * 1000) + (0 * 1000) + 1
|
def getLibVersion(self):
|
||||||
|
return (1 * 1000 * 1000) + (0 * 1000) + 1
|
||||||
|
|
||||||
|
def domainEventRegisterAny(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def registerCloseCallback(self, cb, opaque):
|
||||||
|
pass
|
||||||
|
|
||||||
self.close_callback = None
|
self.close_callback = None
|
||||||
|
|
||||||
|
@ -714,32 +721,80 @@ class LibvirtConnTestCase(test.TestCase):
|
||||||
self.close_callback = cb
|
self.close_callback = cb
|
||||||
|
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
self.stubs.Set(self.conn, "getLibVersion", get_lib_version_stub)
|
conn._wrapped_conn = FakeConn()
|
||||||
|
|
||||||
self.mox.StubOutWithMock(conn, '_connect')
|
self.mox.StubOutWithMock(conn, '_connect')
|
||||||
self.mox.StubOutWithMock(self.conn, 'registerCloseCallback')
|
self.mox.StubOutWithMock(conn._conn, 'registerCloseCallback')
|
||||||
self.mox.StubOutWithMock(conn, 'set_host_enabled')
|
self.mox.StubOutWithMock(conn, 'set_host_enabled')
|
||||||
|
|
||||||
conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.conn)
|
conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn._conn)
|
||||||
self.conn.registerCloseCallback(
|
conn._conn.registerCloseCallback(
|
||||||
mox.IgnoreArg(), mox.IgnoreArg()).WithSideEffects(
|
mox.IgnoreArg(), mox.IgnoreArg()
|
||||||
set_close_callback)
|
).WithSideEffects(set_close_callback)
|
||||||
conn.set_host_enabled('fake-mini', True)
|
conn.set_host_enabled('fake-mini', True)
|
||||||
conn.set_host_enabled('fake-mini', 'Connection to libvirt lost: 1')
|
conn.set_host_enabled('fake-mini', 'Connection to libvirt lost: 1')
|
||||||
conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(self.conn)
|
conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn._conn)
|
||||||
conn.set_host_enabled('fake-mini', True)
|
conn.set_host_enabled('fake-mini', True)
|
||||||
self.conn.registerCloseCallback(mox.IgnoreArg(), mox.IgnoreArg())
|
conn._conn.registerCloseCallback(mox.IgnoreArg(), mox.IgnoreArg())
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
# verify that the driver registers for the close callback
|
# verify that the driver registers for the close callback
|
||||||
# and re-connects after receiving the callback
|
# and re-connects after receiving the callback
|
||||||
conn._get_connection()
|
conn._get_new_connection()
|
||||||
|
|
||||||
self.assertTrue(self.close_callback)
|
self.assertTrue(self.close_callback)
|
||||||
self.close_callback(self.conn, 1, None)
|
self.close_callback(conn._conn, 1, None)
|
||||||
|
|
||||||
conn._get_connection()
|
conn._get_connection()
|
||||||
self.mox.UnsetStubs()
|
self.mox.UnsetStubs()
|
||||||
|
|
||||||
|
def test_close_callback_bad_signature(self):
|
||||||
|
class FakeConn(object):
|
||||||
|
def getLibVersion(self):
|
||||||
|
return (1 * 1000 * 1000) + (0 * 1000) + 0
|
||||||
|
|
||||||
|
def domainEventRegisterAny(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def registerCloseCallback(self, cb, opaque, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
|
conn._wrapped_conn = FakeConn()
|
||||||
|
|
||||||
|
self.mox.StubOutWithMock(conn, '_connect')
|
||||||
|
self.mox.StubOutWithMock(conn._conn, 'registerCloseCallback')
|
||||||
|
self.mox.StubOutWithMock(conn, 'set_host_enabled')
|
||||||
|
|
||||||
|
conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn._conn)
|
||||||
|
conn.set_host_enabled('fake-mini', True)
|
||||||
|
conn._conn.registerCloseCallback(
|
||||||
|
mox.IgnoreArg(), mox.IgnoreArg()).AndRaise(TypeError)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
conn._get_new_connection()
|
||||||
|
|
||||||
|
def test_close_callback_not_defined(self):
|
||||||
|
class FakeConn():
|
||||||
|
def getLibVersion(self):
|
||||||
|
return (0 * 1000 * 1000) + (9 * 1000) + 0
|
||||||
|
|
||||||
|
def domainEventRegisterAny(self, *args, **kwargs):
|
||||||
|
pass
|
||||||
|
|
||||||
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
|
conn._wrapped_conn = FakeConn()
|
||||||
|
|
||||||
|
self.mox.StubOutWithMock(conn, '_connect')
|
||||||
|
self.mox.StubOutWithMock(conn, 'set_host_enabled')
|
||||||
|
|
||||||
|
conn._connect(mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(
|
||||||
|
conn._wrapped_conn)
|
||||||
|
conn.set_host_enabled('fake-mini', True)
|
||||||
|
|
||||||
|
self.mox.ReplayAll()
|
||||||
|
conn._get_new_connection()
|
||||||
|
|
||||||
def test_cpu_features_bug_1217630(self):
|
def test_cpu_features_bug_1217630(self):
|
||||||
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
conn = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
|
|
||||||
|
@ -7606,18 +7661,26 @@ class LibvirtNonblockingTestCase(test.TestCase):
|
||||||
jsonutils.to_primitive(connection._conn, convert_instances=True)
|
jsonutils.to_primitive(connection._conn, convert_instances=True)
|
||||||
|
|
||||||
def test_tpool_execute_calls_libvirt(self):
|
def test_tpool_execute_calls_libvirt(self):
|
||||||
self.mox.StubOutWithMock(eventlet.tpool, 'execute')
|
|
||||||
conn = libvirt.virConnect()
|
conn = libvirt.virConnect()
|
||||||
conn.is_expected = True
|
conn.is_expected = True
|
||||||
|
|
||||||
|
self.mox.StubOutWithMock(eventlet.tpool, 'execute')
|
||||||
eventlet.tpool.execute(
|
eventlet.tpool.execute(
|
||||||
libvirt.openAuth, 'test:///default',
|
libvirt.openAuth,
|
||||||
mox.IgnoreArg(), mox.IgnoreArg()).AndReturn(conn)
|
'test:///default',
|
||||||
|
mox.IgnoreArg(),
|
||||||
|
mox.IgnoreArg()).AndReturn(conn)
|
||||||
eventlet.tpool.execute(
|
eventlet.tpool.execute(
|
||||||
conn.domainEventRegisterAny,
|
conn.domainEventRegisterAny,
|
||||||
None,
|
None,
|
||||||
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
||||||
mox.IgnoreArg(),
|
mox.IgnoreArg(),
|
||||||
mox.IgnoreArg())
|
mox.IgnoreArg())
|
||||||
|
if hasattr(libvirt.virConnect, 'registerCloseCallback'):
|
||||||
|
eventlet.tpool.execute(
|
||||||
|
conn.registerCloseCallback,
|
||||||
|
mox.IgnoreArg(),
|
||||||
|
mox.IgnoreArg())
|
||||||
self.mox.ReplayAll()
|
self.mox.ReplayAll()
|
||||||
|
|
||||||
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
driver = libvirt_driver.LibvirtDriver(fake.FakeVirtAPI(), True)
|
||||||
|
|
|
@ -323,7 +323,6 @@ MIN_LIBVIRT_VERSION = (0, 9, 6)
|
||||||
# When the above version matches/exceeds this version
|
# When the above version matches/exceeds this version
|
||||||
# delete it & corresponding code using it
|
# delete it & corresponding code using it
|
||||||
MIN_LIBVIRT_HOST_CPU_VERSION = (0, 9, 10)
|
MIN_LIBVIRT_HOST_CPU_VERSION = (0, 9, 10)
|
||||||
MIN_LIBVIRT_CLOSE_CALLBACK_VERSION = (1, 0, 1)
|
|
||||||
MIN_LIBVIRT_DEVICE_CALLBACK_VERSION = (1, 1, 1)
|
MIN_LIBVIRT_DEVICE_CALLBACK_VERSION = (1, 1, 1)
|
||||||
# Live snapshot requirements
|
# Live snapshot requirements
|
||||||
REQ_HYPERVISOR_LIVESNAPSHOT = "QEMU"
|
REQ_HYPERVISOR_LIVESNAPSHOT = "QEMU"
|
||||||
|
@ -634,7 +633,7 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
self._wrapped_conn = wrapped_conn
|
self._wrapped_conn = wrapped_conn
|
||||||
|
|
||||||
try:
|
try:
|
||||||
LOG.debug(_("Registering for lifecycle events %s") % str(self))
|
LOG.debug(_("Registering for lifecycle events %s"), self)
|
||||||
wrapped_conn.domainEventRegisterAny(
|
wrapped_conn.domainEventRegisterAny(
|
||||||
None,
|
None,
|
||||||
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
libvirt.VIR_DOMAIN_EVENT_ID_LIFECYCLE,
|
||||||
|
@ -644,17 +643,23 @@ class LibvirtDriver(driver.ComputeDriver):
|
||||||
LOG.warn(_("URI %(uri)s does not support events: %(error)s"),
|
LOG.warn(_("URI %(uri)s does not support events: %(error)s"),
|
||||||
{'uri': self.uri(), 'error': e})
|
{'uri': self.uri(), 'error': e})
|
||||||
|
|
||||||
if self._has_min_version(wrapped_conn,
|
try:
|
||||||
MIN_LIBVIRT_CLOSE_CALLBACK_VERSION):
|
LOG.debug(_("Registering for connection events: %s") %
|
||||||
try:
|
str(self))
|
||||||
LOG.debug(_("Registering for connection events: %s") %
|
wrapped_conn.registerCloseCallback(self._close_callback, None)
|
||||||
str(self))
|
except (TypeError, AttributeError) as e:
|
||||||
wrapped_conn.registerCloseCallback(
|
# NOTE: The registerCloseCallback of python-libvirt 1.0.1+
|
||||||
self._close_callback, None)
|
# is defined with 3 arguments, and the above registerClose-
|
||||||
except libvirt.libvirtError as e:
|
# Callback succeeds. However, the one of python-libvirt 1.0.0
|
||||||
LOG.warn(_("URI %(uri)s does not support connection"
|
# is defined with 4 arguments and TypeError happens here.
|
||||||
" events: %(error)s"),
|
# Then python-libvirt 0.9 does not define a method register-
|
||||||
{'uri': self.uri(), 'error': e})
|
# CloseCallback.
|
||||||
|
LOG.debug(_("The version of python-libvirt does not support "
|
||||||
|
"registerCloseCallback or is too old: %s"), e)
|
||||||
|
except libvirt.libvirtError as e:
|
||||||
|
LOG.warn(_("URI %(uri)s does not support connection"
|
||||||
|
" events: %(error)s"),
|
||||||
|
{'uri': self.uri(), 'error': e})
|
||||||
|
|
||||||
return wrapped_conn
|
return wrapped_conn
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue