Fix linuxrbd to work with Python 3

All string args used with librbd must be None or utf-8 otherwise
librbd will break. This patch uses convert_str instead of
oslo_utils.encodeutils.

Change-Id: I77aad9f8ddd1b7175ee1521a43d16511059a9ad0
Closes-Bug: #1612290
changes/52/354152/3
Ivan Kolodyazhny 6 years ago
parent f38c6c87be
commit 91ac58fe77
  1. 14
      os_brick/initiator/linuxrbd.py
  2. 9
      os_brick/tests/initiator/connectors/test_rbd.py
  3. 12
      os_brick/tests/initiator/test_linuxrbd.py
  4. 19
      os_brick/utils.py

@ -14,10 +14,10 @@
import io
from oslo_log import log as logging
from oslo_utils import encodeutils
from os_brick import exception
from os_brick.i18n import _, _LE, _LW
from os_brick import utils
try:
import rados
@ -40,7 +40,7 @@ class RBDClient(object):
for attr in ['rbd_user', 'rbd_pool']:
val = getattr(self, attr)
if val is not None:
setattr(self, attr, encodeutils.safe_encode(val))
setattr(self, attr, utils.convert_str(val))
# allow these to be overridden for testing
self.rados = kwargs.get('rados', rados)
@ -98,11 +98,11 @@ class RBDVolume(object):
def __init__(self, client, name, snapshot=None, read_only=False):
if snapshot is not None:
snapshot = encodeutils.safe_encode(snapshot)
snapshot = utils.convert_str(snapshot)
try:
self.image = client.rbd.Image(client.ioctx,
encodeutils.safe_encode(name),
utils.convert_str(name),
snapshot=snapshot,
read_only=read_only)
except client.rbd.Error:
@ -129,9 +129,9 @@ class RBDImageMetadata(object):
"""RBD image metadata to be used with RBDVolumeIOWrapper."""
def __init__(self, image, pool, user, conf):
self.image = image
self.pool = encodeutils.safe_encode(pool or '')
self.user = encodeutils.safe_encode(user or '')
self.conf = encodeutils.safe_encode(conf or '')
self.pool = utils.convert_str(pool or '')
self.user = utils.convert_str(user or '')
self.conf = utils.convert_str(conf or '')
class RBDVolumeIOWrapper(io.RawIOBase):

@ -13,12 +13,11 @@
# under the License.
import mock
from oslo_utils import encodeutils
from os_brick.initiator.connectors import rbd
from os_brick.initiator import linuxrbd
from os_brick.privileged import rootwrap as priv_rootwrap
from os_brick.tests.initiator import test_connector
from os_brick import utils
class RBDConnectorTestCase(test_connector.ConnectorTestCase):
@ -65,18 +64,18 @@ class RBDConnectorTestCase(test_connector.ConnectorTestCase):
# Ensure rados is instantiated correctly
mock_rados.Rados.assert_called_once_with(
clustername='ceph',
rados_id=encodeutils.safe_encode(self.user),
rados_id=utils.convert_str(self.user),
conffile='/etc/ceph/ceph.conf')
# Ensure correct calls to connect to cluster
self.assertEqual(1, mock_rados.Rados.return_value.connect.call_count)
mock_rados.Rados.return_value.open_ioctx.assert_called_once_with(
encodeutils.safe_encode(self.pool))
utils.convert_str(self.pool))
# Ensure rbd image is instantiated correctly
mock_rbd.Image.assert_called_once_with(
mock_rados.Rados.return_value.open_ioctx.return_value,
encodeutils.safe_encode(self.volume), read_only=False,
utils.convert_str(self.volume), read_only=False,
snapshot=None)
# Ensure expected object is returned correctly

@ -14,7 +14,7 @@ import mock
from os_brick.initiator import linuxrbd
from os_brick.tests import base
from oslo_utils import encodeutils
from os_brick import utils
class RBDClientTestCase(base.TestCase):
@ -29,22 +29,20 @@ class RBDClientTestCase(base.TestCase):
# Verify object attributes are assigned as expected
self.assertEqual('/etc/ceph/ceph.conf', client.rbd_conf)
self.assertEqual(encodeutils.safe_encode('test_user'),
client.rbd_user)
self.assertEqual(encodeutils.safe_encode('test_pool'),
client.rbd_pool)
self.assertEqual(utils.convert_str('test_user'), client.rbd_user)
self.assertEqual(utils.convert_str('test_pool'), client.rbd_pool)
# Assert connect is called with correct paramaters
mock_rados.Rados.assert_called_once_with(
clustername='ceph',
rados_id=encodeutils.safe_encode('test_user'),
rados_id=utils.convert_str('test_user'),
conffile='/etc/ceph/ceph.conf')
# Ensure correct calls to connect to cluster
self.assertEqual(
1, mock_rados.Rados.return_value.connect.call_count)
mock_rados.Rados.return_value.open_ioctx.assert_called_once_with(
encodeutils.safe_encode('test_pool'))
utils.convert_str('test_pool'))
self.assertEqual(1, mock_rados.Rados.return_value.shutdown.call_count)

@ -18,6 +18,7 @@ import logging as py_logging
import time
from oslo_log import log as logging
from oslo_utils import encodeutils
import retrying
import six
@ -156,3 +157,21 @@ def trace(f):
'result': result})
return result
return trace_logging_wrapper
def convert_str(text):
"""Convert to native string.
Convert bytes and Unicode strings to native strings:
* convert to bytes on Python 2:
encode Unicode using encodeutils.safe_encode()
* convert to Unicode on Python 3: decode bytes from UTF-8
"""
if six.PY2:
return encodeutils.to_utf8(text)
else:
if isinstance(text, bytes):
return text.decode('utf-8')
else:
return text

Loading…
Cancel
Save