Pass valid IP address to os-brick

While fetching connector information the cinder driver of
glance-store is passing 'hostname' as IP address whereas it
actually needs IP address.

This path fetches the IPV4 or IPV6 address from the available
'hostname' and passes it to os-brick.

This worked for other cinder backends which don't rely specifically
on IP address for initializing connection like fibre channel, nfs etc
and even for some iscsi backends since, in some environments,
the hostname is same as the ip address. This is not the case always
and we should pass the correct IPv4/IPv6 address of the host to
avoid this issue.

Closes-Bug: #1955668

Change-Id: Ic79815972e654a8bfe2775f57c68cfa0bf115e2f
This commit is contained in:
whoami-rajat 2021-12-23 12:46:32 +00:00
parent 63d6f8341a
commit 8b4d97a6f7
4 changed files with 48 additions and 11 deletions

View File

@ -685,6 +685,12 @@ class Store(glance_store.driver.Store):
"""
return os.path.join(mount_point_base, self.get_hash_str(share))
def _get_host_ip(self, host):
try:
return socket.getaddrinfo(host, None, socket.AF_INET6)[0][4][0]
except socket.gaierror:
return socket.getaddrinfo(host, None, socket.AF_INET)[0][4][0]
@contextlib.contextmanager
def _open_cinder_volume(self, client, volume, mode):
attach_mode = 'rw' if mode == 'wb' else 'ro'
@ -692,13 +698,14 @@ class Store(glance_store.driver.Store):
root_helper = self.get_root_helper()
priv_context.init(root_helper=shlex.split(root_helper))
host = socket.gethostname()
my_ip = self._get_host_ip(host)
use_multipath = self.store_conf.cinder_use_multipath
enforce_multipath = self.store_conf.cinder_enforce_multipath
mount_point_base = self.store_conf.cinder_mount_point_base
volume_id = volume.id
connector_prop = connector.get_connector_properties(
root_helper, host, use_multipath, enforce_multipath)
root_helper, my_ip, use_multipath, enforce_multipath, host=host)
if volume.multiattach:
attachment = attachment_state_manager.attach(client, volume_id,

View File

@ -221,7 +221,17 @@ class TestCinderStore(base.StoreBaseTest,
mock.patch.object(cinder_utils.API,
'attachment_get') as attach_get, \
mock.patch.object(cinder_utils.API,
'attachment_complete') as attach_complete:
'attachment_complete') as attach_complete, \
mock.patch.object(socket,
'gethostname') as mock_get_host, \
mock.patch.object(socket,
'getaddrinfo') as mock_get_host_ip:
fake_host = 'fake_host'
fake_addr_info = [[0, 1, 2, 3, ['127.0.0.1']]]
fake_ip = fake_addr_info[0][4][0]
mock_get_host.return_value = fake_host
mock_get_host_ip.return_value = fake_addr_info
with mock.patch.object(connector,
'get_connector_properties',
@ -247,8 +257,9 @@ class TestCinderStore(base.StoreBaseTest,
if not (encrypted_nfs or qcow2_vol):
mock_conn.assert_called_once_with(
root_helper, socket.gethostname(),
multipath_supported, enforce_multipath)
root_helper, fake_ip,
multipath_supported, enforce_multipath,
host=fake_host)
fake_connector.connect_volume.assert_called_once_with(
mock.ANY)
fake_connector.disconnect_volume.assert_called_once_with(
@ -267,8 +278,9 @@ class TestCinderStore(base.StoreBaseTest,
fake_client, fake_attachment_id)
else:
mock_conn.assert_called_once_with(
root_helper, socket.gethostname(),
multipath_supported, enforce_multipath)
root_helper, fake_ip,
multipath_supported, enforce_multipath,
host=fake_host)
fake_connector.connect_volume.assert_not_called()
fake_connector.disconnect_volume.assert_not_called()
fake_conn_obj.assert_called_once_with(

View File

@ -255,7 +255,17 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
mock.patch.object(cinder_utils.API,
'attachment_get') as attach_get, \
mock.patch.object(cinder_utils.API,
'attachment_complete') as attach_complete:
'attachment_complete') as attach_complete, \
mock.patch.object(socket,
'gethostname') as mock_get_host, \
mock.patch.object(socket,
'getaddrinfo') as mock_get_host_ip:
fake_host = 'fake_host'
fake_addr_info = [[0, 1, 2, 3, ['127.0.0.1']]]
fake_ip = fake_addr_info[0][4][0]
mock_get_host.return_value = fake_host
mock_get_host_ip.return_value = fake_addr_info
with mock.patch.object(connector,
'get_connector_properties',
@ -280,8 +290,9 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
do_open()
if not (encrypted_nfs or qcow2_vol):
mock_conn.assert_called_once_with(
root_helper, socket.gethostname(),
multipath_supported, enforce_multipath)
root_helper, fake_ip,
multipath_supported, enforce_multipath,
host=fake_host)
fake_connector.connect_volume.assert_called_once_with(
mock.ANY)
fake_connector.disconnect_volume.assert_called_once_with(
@ -300,8 +311,9 @@ class TestMultiCinderStore(base.MultiStoreBaseTest,
fake_attachment_id)
else:
mock_conn.assert_called_once_with(
root_helper, socket.gethostname(),
multipath_supported, enforce_multipath)
root_helper, fake_ip,
multipath_supported, enforce_multipath,
host=fake_host)
fake_connector.connect_volume.assert_not_called()
fake_connector.disconnect_volume.assert_not_called()
fake_conn_obj.assert_called_once_with(

View File

@ -0,0 +1,6 @@
---
fixes:
- |
`Bug #1955668 <https://bugs.launchpad.net/glance-store/+bug/1955668>`_:
Fixed issue with glance cinder store passing hostname instead of IP
address to os-brick while getting connector information.