From e8b6b0bc78ec229803d1d27f8a4706e2c425bd77 Mon Sep 17 00:00:00 2001 From: Edward Hope-Morley Date: Thu, 6 Jun 2019 12:26:26 +0100 Subject: [PATCH] Fix python3 compatibility of rbd get_fsid In py3 librados's get_fsid() function returns a binary string which breaks comparison when compared with the same value as a string. This is currently breakin the logic that compares ceph cluster fsids when deciding whether the image used to boot an instance is cow-clonable. Change-Id: I79b40ca40400c67b0805926096317afd875ffabb Closes-Bug: #1816468 --- nova/tests/unit/virt/libvirt/storage/test_rbd.py | 7 +++++++ nova/virt/libvirt/storage/rbd_utils.py | 4 +++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/nova/tests/unit/virt/libvirt/storage/test_rbd.py b/nova/tests/unit/virt/libvirt/storage/test_rbd.py index 5d885c512df0..f6629b79f183 100644 --- a/nova/tests/unit/virt/libvirt/storage/test_rbd.py +++ b/nova/tests/unit/virt/libvirt/storage/test_rbd.py @@ -119,6 +119,13 @@ class RbdTestCase(test.NoDBTestCase): self.assertFalse(self.driver.is_cloneable({'url': loc}, image_meta)) + @mock.patch.object(rbd_utils, 'RADOSClient') + def test_rbddriver(self, mock_client): + client = mock_client.return_value + client.__enter__.return_value = client + client.cluster.get_fsid.side_effect = lambda: b'abc' + self.assertEqual('abc', self.driver.get_fsid()) + @mock.patch.object(rbd_utils.RBDDriver, 'get_fsid') def test_cloneable(self, mock_get_fsid): mock_get_fsid.return_value = 'abc' diff --git a/nova/virt/libvirt/storage/rbd_utils.py b/nova/virt/libvirt/storage/rbd_utils.py index d51d8e51afd6..133f72f410ec 100644 --- a/nova/virt/libvirt/storage/rbd_utils.py +++ b/nova/virt/libvirt/storage/rbd_utils.py @@ -28,6 +28,7 @@ from oslo_concurrency import processutils from oslo_log import log as logging from oslo_serialization import jsonutils from oslo_service import loopingcall +from oslo_utils import encodeutils from oslo_utils import excutils from oslo_utils import units @@ -194,7 +195,7 @@ class RBDDriver(object): def get_fsid(self): with RADOSClient(self) as client: - return client.cluster.get_fsid() + return encodeutils.safe_decode(client.cluster.get_fsid()) def is_cloneable(self, image_location, image_meta): url = image_location['url'] @@ -204,6 +205,7 @@ class RBDDriver(object): LOG.debug('not cloneable: %s', e) return False + fsid = encodeutils.safe_decode(fsid) if self.get_fsid() != fsid: reason = '%s is in a different ceph cluster' % url LOG.debug(reason)