diff --git a/nova/tests/unit/virt/libvirt/storage/test_rbd.py b/nova/tests/unit/virt/libvirt/storage/test_rbd.py index e5489c5ce5dd..2b22d5286213 100644 --- a/nova/tests/unit/virt/libvirt/storage/test_rbd.py +++ b/nova/tests/unit/virt/libvirt/storage/test_rbd.py @@ -239,6 +239,14 @@ class RbdTestCase(test.NoDBTestCase): ports = ['6789', '6790', '6791', '6792', '6791'] self.assertEqual((hosts, ports), self.driver.get_mon_addrs()) + @mock.patch('oslo_concurrency.processutils.execute') + def test_get_mon_addrs_with_brackets(self, mock_execute): + mock_execute.return_value = (CEPH_MON_DUMP, '') + hosts = ['[::1]', '[::1]', '[::1]', '127.0.0.1', 'example.com'] + ports = ['6789', '6790', '6791', '6792', '6791'] + self.assertEqual((hosts, ports), + self.driver.get_mon_addrs(strip_brackets=False)) + @mock.patch.object(rbd_utils.RBDDriver, '_connect_to_rados') def test_rbd_conf_features(self, mock_connect): self.mock_rbd.RBD_FEATURE_LAYERING = 1 diff --git a/nova/tests/unit/virt/libvirt/test_imagebackend.py b/nova/tests/unit/virt/libvirt/test_imagebackend.py index cebeb5eb0017..82428dc2cacc 100644 --- a/nova/tests/unit/virt/libvirt/test_imagebackend.py +++ b/nova/tests/unit/virt/libvirt/test_imagebackend.py @@ -1561,9 +1561,14 @@ class RbdTestCase(_ImageTestCase, test.NoDBTestCase): self.flags(rbd_secret_uuid="3306a5c4-8378-4b3c-aa1f-7b48d3a26172", group='libvirt') - def get_mon_addrs(): - hosts = ["server1", "server2"] - ports = ["1899", "1920"] + # image.get_model() should always pass strip_brackets=False + # for building proper IPv6 address+ports for libguestfs + def get_mon_addrs(strip_brackets=True): + if strip_brackets: + hosts = ["server1", "server2", "::1"] + else: + hosts = ["server1", "server2", "[::1]"] + ports = ["1899", "1920", "1930"] return hosts, ports mock_mon_addrs.side_effect = get_mon_addrs @@ -1574,7 +1579,7 @@ class RbdTestCase(_ImageTestCase, test.NoDBTestCase): "FakePool", "FakeUser", b"MTIzNDU2Cg==", - ["server1:1899", "server2:1920"]), + ["server1:1899", "server2:1920", "[::1]:1930"]), model) @mock.patch.object(rbd_utils.RBDDriver, 'flatten') diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py index 4e59279ac068..c8c7b9ad3b3f 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -989,7 +989,10 @@ class Rbd(Image): CONF.libvirt.rbd_secret_uuid) secret = base64.b64encode(secretobj.value()) - hosts, ports = self.driver.get_mon_addrs() + # Brackets are stripped from IPv6 addresses normally for libvirt XML, + # but the servers list is for libguestfs, which needs the brackets + # so the joined string is similar to '[::1]:6789' + hosts, ports = self.driver.get_mon_addrs(strip_brackets=False) servers = [str(':'.join(k)) for k in zip(hosts, ports)] return imgmodel.RBDImage(self.rbd_name, diff --git a/nova/virt/libvirt/storage/rbd_utils.py b/nova/virt/libvirt/storage/rbd_utils.py index 782a969a5a7a..35316f5c4d22 100644 --- a/nova/virt/libvirt/storage/rbd_utils.py +++ b/nova/virt/libvirt/storage/rbd_utils.py @@ -164,7 +164,7 @@ class RBDDriver(object): args.extend(['--conf', self.ceph_conf]) return args - def get_mon_addrs(self): + def get_mon_addrs(self, strip_brackets=True): args = ['ceph', 'mon', 'dump', '--format=json'] + self.ceph_args() out, _ = processutils.execute(*args) lines = out.split('\n') @@ -177,7 +177,9 @@ class RBDDriver(object): for addr in addrs: host_port = addr[:addr.rindex('/')] host, port = host_port.rsplit(':', 1) - hosts.append(host.strip('[]')) + if strip_brackets: + host = host.strip('[]') + hosts.append(host) ports.append(port) return hosts, ports