summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZuul <zuul@review.opendev.org>2023-04-26 15:09:20 +0000
committerGerrit Code Review <review@openstack.org>2023-04-26 15:09:20 +0000
commit96f28eb35c16b2feef1465ef46f19b5407eb4833 (patch)
treed67db9b48af1ae9edf55a2983245357f44736cb8
parent6741951591ca7d6144f6089678df8cee4f0a7030 (diff)
parent27ab8a6aeb7a59bc56ed0ad26ffb5a83d426b447 (diff)
downloadglance_store-96f28eb35c16b2feef1465ef46f19b5407eb4833.tar.gz
Merge "RBD: Wrap RBD calls in native threads"
-rw-r--r--glance_store/_drivers/rbd.py12
-rw-r--r--glance_store/tests/unit/test_rbd_store.py50
2 files changed, 58 insertions, 4 deletions
diff --git a/glance_store/_drivers/rbd.py b/glance_store/_drivers/rbd.py
index f45a909..2dd6ac5 100644
--- a/glance_store/_drivers/rbd.py
+++ b/glance_store/_drivers/rbd.py
@@ -22,6 +22,7 @@ import logging
import math
import urllib
+from eventlet import tpool
from oslo_config import cfg
from oslo_utils import encodeutils
from oslo_utils import units
@@ -290,6 +291,9 @@ class Store(driver.Store):
def get_schemes(self):
return ('rbd',)
+ def RBDProxy(self):
+ return tpool.Proxy(rbd.RBD())
+
@contextlib.contextmanager
def get_connection(self, conffile, rados_id):
client = rados.Rados(conffile=conffile, rados_id=rados_id)
@@ -431,12 +435,12 @@ class Store(driver.Store):
:returns: `glance_store.rbd.StoreLocation` object
"""
- librbd = rbd.RBD()
features = conn.conf_get('rbd_default_features')
if ((features is None) or (int(features) == 0)):
features = rbd.RBD_FEATURE_LAYERING
- librbd.create(ioctx, image_name, size, order, old_format=False,
- features=int(features))
+ self.RBDProxy().create(ioctx, image_name, size, order,
+ old_format=False,
+ features=int(features))
return StoreLocation({
'fsid': fsid,
'pool': self.pool,
@@ -496,7 +500,7 @@ class Store(driver.Store):
raise exceptions.InUseByStore()
# Then delete image.
- rbd.RBD().remove(ioctx, image_name)
+ self.RBDProxy().remove(ioctx, image_name)
except rbd.ImageHasSnapshots:
log_msg = (_LW("Remove image %(img_name)s failed. "
"It has snapshot(s) left.") %
diff --git a/glance_store/tests/unit/test_rbd_store.py b/glance_store/tests/unit/test_rbd_store.py
index 08ade51..09eddc4 100644
--- a/glance_store/tests/unit/test_rbd_store.py
+++ b/glance_store/tests/unit/test_rbd_store.py
@@ -692,3 +692,53 @@ class TestStore(base.StoreBaseTest,
self.assertEqual(self.called_commands_expected,
self.called_commands_actual)
super(TestStore, self).tearDown()
+
+ def test_create_image_in_native_thread(self):
+ # Tests that we use non-0 features from ceph.conf and cast to int.
+ fsid = 'fake'
+ features = '3'
+ conf_get_mock = mock.Mock(return_value=features)
+ conn = mock.Mock(conf_get=conf_get_mock)
+ ioctxt = mock.sentinel.ioctxt
+ name = '1'
+ size = 1024
+ order = 3
+ fake_proxy = mock.MagicMock()
+ fake_rbd = mock.MagicMock()
+
+ with mock.patch.object(rbd_store.tpool, 'Proxy') as tpool_mock, \
+ mock.patch.object(rbd_store.rbd, 'RBD') as rbd_mock:
+ tpool_mock.return_value = fake_proxy
+ rbd_mock.return_value = fake_rbd
+ location = self.store._create_image(
+ fsid, conn, ioctxt, name, size, order)
+ self.assertEqual(fsid, location.specs['fsid'])
+ self.assertEqual(rbd_store.DEFAULT_POOL, location.specs['pool'])
+ self.assertEqual(name, location.specs['image'])
+ self.assertEqual(rbd_store.DEFAULT_SNAPNAME,
+ location.specs['snapshot'])
+
+ tpool_mock.assert_called_once_with(fake_rbd)
+ fake_proxy.create.assert_called_once_with(ioctxt, name, size, order,
+ old_format=False, features=3)
+
+ def test_delete_image_in_native_thread(self):
+ fake_proxy = mock.MagicMock()
+ fake_rbd = mock.MagicMock()
+ fake_ioctx = mock.MagicMock()
+
+ with mock.patch.object(rbd_store.tpool, 'Proxy') as tpool_mock, \
+ mock.patch.object(rbd_store.rbd, 'RBD') as rbd_mock, \
+ mock.patch.object(self.store, 'get_connection') as mock_conn:
+
+ mock_get_conn = mock_conn.return_value.__enter__.return_value
+ mock_ioctx = mock_get_conn.open_ioctx.return_value.__enter__
+ mock_ioctx.return_value = fake_ioctx
+ tpool_mock.return_value = fake_proxy
+ rbd_mock.return_value = fake_rbd
+
+ self.store._delete_image('fake_pool', self.location.image)
+
+ tpool_mock.assert_called_once_with(fake_rbd)
+ fake_proxy.remove.assert_called_once_with(fake_ioctx,
+ self.location.image)