From 5d29dccaf91c697ffc12a7289ce16cd83e60b07f Mon Sep 17 00:00:00 2001 From: Jared Winborne Date: Tue, 2 Apr 2019 12:22:37 -0500 Subject: [PATCH] Leave brackets on Ceph IP addresses for libguestfs Brackets are removed from all IPv6 addresses when getting Ceph monitor addresses. This is correct for libvirt's XML files but not for libguestfs. This adds a 'strip_brackets' argument for get_mon_addrs method. It is default 'True' to not interfere anywhere this is used with no arguments. Uses strip_brackets=False when getting the hosts and ports for RBDImage, which is used for libguestfs. Change-Id: I378998a73046b9b9a33e30d0e06c4721d712da65 Closes-Bug: 1822689 --- nova/tests/unit/virt/libvirt/storage/test_rbd.py | 8 ++++++++ nova/tests/unit/virt/libvirt/test_imagebackend.py | 13 +++++++++---- nova/virt/libvirt/imagebackend.py | 5 ++++- nova/virt/libvirt/storage/rbd_utils.py | 6 ++++-- 4 files changed, 25 insertions(+), 7 deletions(-) diff --git a/nova/tests/unit/virt/libvirt/storage/test_rbd.py b/nova/tests/unit/virt/libvirt/storage/test_rbd.py index 5d885c512df0..5f0b7f4d4390 100644 --- a/nova/tests/unit/virt/libvirt/storage/test_rbd.py +++ b/nova/tests/unit/virt/libvirt/storage/test_rbd.py @@ -179,6 +179,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 e2c4fae0d645..7d0bd2264f82 100644 --- a/nova/tests/unit/virt/libvirt/test_imagebackend.py +++ b/nova/tests/unit/virt/libvirt/test_imagebackend.py @@ -1513,9 +1513,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 @@ -1526,7 +1531,7 @@ class RbdTestCase(_ImageTestCase, test.NoDBTestCase): "FakePool", "FakeUser", b"MTIzNDU2Cg==", - ["server1:1899", "server2:1920"]), + ["server1:1899", "server2:1920", "[::1]:1930"]), model) def test_import_file(self): diff --git a/nova/virt/libvirt/imagebackend.py b/nova/virt/libvirt/imagebackend.py index ad8422c3f483..24c15601afcf 100644 --- a/nova/virt/libvirt/imagebackend.py +++ b/nova/virt/libvirt/imagebackend.py @@ -960,7 +960,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 d51d8e51afd6..754cc8753049 100644 --- a/nova/virt/libvirt/storage/rbd_utils.py +++ b/nova/virt/libvirt/storage/rbd_utils.py @@ -160,7 +160,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') @@ -173,7 +173,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