From 5c48b6fc32b474b7f6f0995dc24d52aeb282b228 Mon Sep 17 00:00:00 2001 From: Atsushi Kawai Date: Fri, 25 Feb 2022 07:31:22 +0000 Subject: [PATCH] Hitachi: Support AIX as host OS type This patch support AIX as host OS type for the Hitachi VSP driver. When running "cinder attachment-create" command with the option "--ostype aix", "AIX" is set as host OS type. Implements: blueprint hitachi-vsp-aix-os-type Change-Id: Ia3378099789f13d60ba3657d1d3a626e7bc9dced --- .../hitachi/test_hitachi_hbsd_rest_fc.py | 44 +++++++++++++++++ .../hitachi/test_hitachi_hbsd_rest_iscsi.py | 47 +++++++++++++++++++ cinder/volume/drivers/hitachi/hbsd_common.py | 4 +- cinder/volume/drivers/hitachi/hbsd_rest_fc.py | 7 ++- .../volume/drivers/hitachi/hbsd_rest_iscsi.py | 8 +++- ...achi-vsp-aix-os-type-23bf7cc3b98dff3a.yaml | 7 +++ 6 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 releasenotes/notes/hitachi-vsp-aix-os-type-23bf7cc3b98dff3a.yaml diff --git a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py index da884836618..356401c8810 100644 --- a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py +++ b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_fc.py @@ -73,6 +73,14 @@ DEFAULT_CONNECTOR = { 'multipath': False, } +DEFAULT_CONNECTOR_AIX = { + 'os_type': 'aix', + 'host': 'host', + 'ip': CONFIG_MAP['my_ip'], + 'wwpns': [CONFIG_MAP['host_wwn']], + 'multipath': False, +} + CTXT = cinder_context.get_admin_context() TEST_VOLUME = [] @@ -318,6 +326,12 @@ def _brick_get_connector_properties(multipath=False, enforce_multipath=False): return DEFAULT_CONNECTOR +def _brick_get_connector_properties_aix( + multipath=False, enforce_multipath=False): + """Return a predefined connector object.""" + return DEFAULT_CONNECTOR_AIX + + def reduce_retrying_time(func): @functools.wraps(func) def wrapper(*args, **kwargs): @@ -579,6 +593,36 @@ class HBSDRESTFCDriverTest(test.TestCase): self.driver.common.client.keep_session_loop.stop() self.driver.common.client.keep_session_loop.wait() + @mock.patch.object(requests.Session, "request") + @mock.patch.object( + volume_utils, 'brick_get_connector_properties', + side_effect=_brick_get_connector_properties_aix) + def test_do_setup_create_hg_aix( + self, brick_get_connector_properties, request): + """Normal case: The host group not exists in AIX.""" + drv = hbsd_fc.HBSDFCDriver( + configuration=self.configuration) + self._setup_config() + request.side_effect = [FakeResponse(200, POST_SESSIONS_RESULT), + FakeResponse(200, GET_PORTS_RESULT), + FakeResponse(200, NOTFOUND_RESULT), + FakeResponse(200, NOTFOUND_RESULT), + FakeResponse(200, NOTFOUND_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)] + drv.do_setup(None) + self.assertEqual( + {CONFIG_MAP['port_id']: CONFIG_MAP['target_wwn']}, + drv.common.storage_info['wwns']) + self.assertEqual(1, brick_get_connector_properties.call_count) + self.assertEqual(8, request.call_count) + kargs1 = request.call_args_list[6][1] + self.assertEqual('AIX', kargs1['json']['hostMode']) + # stop the Loopingcall within the do_setup treatment + self.driver.common.client.keep_session_loop.stop() + self.driver.common.client.keep_session_loop.wait() + @mock.patch.object(requests.Session, "request") @mock.patch.object( volume_utils, 'brick_get_connector_properties', diff --git a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py index 262c582d84d..867a888b3cd 100644 --- a/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py +++ b/cinder/tests/unit/volume/drivers/hitachi/test_hitachi_hbsd_rest_iscsi.py @@ -64,6 +64,14 @@ DEFAULT_CONNECTOR = { 'multipath': False, } +DEFAULT_CONNECTOR_AIX = { + 'os_type': 'aix', + 'host': 'host', + 'ip': CONFIG_MAP['my_ip'], + 'initiator': CONFIG_MAP['host_iscsi_name'], + 'multipath': False, +} + CTXT = cinder_context.get_admin_context() TEST_VOLUME = [] @@ -264,6 +272,12 @@ def _brick_get_connector_properties(multipath=False, enforce_multipath=False): return DEFAULT_CONNECTOR +def _brick_get_connector_properties_aix( + multipath=False, enforce_multipath=False): + """Return a predefined connector object.""" + return DEFAULT_CONNECTOR_AIX + + class FakeResponse(): def __init__(self, status_code, data=None, headers=None): @@ -486,6 +500,39 @@ class HBSDRESTISCSIDriverTest(test.TestCase): self.driver.common.client.keep_session_loop.stop() self.driver.common.client.keep_session_loop.wait() + @mock.patch.object(requests.Session, "request") + @mock.patch.object( + volume_utils, 'brick_get_connector_properties', + side_effect=_brick_get_connector_properties_aix) + def test_do_setup_create_hg_aix( + self, brick_get_connector_properties, request): + """Normal case: The host group not exists in AIX.""" + drv = hbsd_iscsi.HBSDISCSIDriver( + configuration=self.configuration) + self._setup_config() + request.side_effect = [FakeResponse(200, POST_SESSIONS_RESULT), + FakeResponse(200, GET_PORTS_RESULT), + FakeResponse(200, GET_PORT_RESULT), + FakeResponse(200, NOTFOUND_RESULT), + FakeResponse(200, NOTFOUND_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT), + FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)] + drv.do_setup(None) + self.assertEqual( + {CONFIG_MAP['port_id']: + '%(ip)s:%(port)s' % { + 'ip': CONFIG_MAP['ipv4Address'], + 'port': CONFIG_MAP['tcpPort']}}, + drv.common.storage_info['portals']) + self.assertEqual(1, brick_get_connector_properties.call_count) + self.assertEqual(8, request.call_count) + kargs1 = request.call_args_list[6][1] + self.assertEqual('AIX', kargs1['json']['hostMode']) + # stop the Loopingcall within the do_setup treatment + self.driver.common.client.keep_session_loop.stop() + self.driver.common.client.keep_session_loop.wait() + @mock.patch.object(requests.Session, "request") def test_extend_volume(self, request): request.side_effect = [FakeResponse(200, GET_LDEV_RESULT), diff --git a/cinder/volume/drivers/hitachi/hbsd_common.py b/cinder/volume/drivers/hitachi/hbsd_common.py index 5fc67ca23be..6de294a3e8c 100644 --- a/cinder/volume/drivers/hitachi/hbsd_common.py +++ b/cinder/volume/drivers/hitachi/hbsd_common.py @@ -547,7 +547,7 @@ class HBSDCommon(): """Create a host group or an iSCSI target on the specified port.""" raise NotImplementedError() - def set_target_mode(self, port, gid): + def set_target_mode(self, port, gid, connector): """Configure the target to meet the environment.""" raise NotImplementedError() @@ -568,7 +568,7 @@ class HBSDCommon(): '%(target)s' % {'port': port, 'gid': gid, 'target': target_name}) try: - self.set_target_mode(port, gid) + self.set_target_mode(port, gid, connector) self.set_hba_ids(port, gid, hba_ids) except Exception: with excutils.save_and_reraise_exception(): diff --git a/cinder/volume/drivers/hitachi/hbsd_rest_fc.py b/cinder/volume/drivers/hitachi/hbsd_rest_fc.py index 36fd262330e..4f5e9cf79a1 100644 --- a/cinder/volume/drivers/hitachi/hbsd_rest_fc.py +++ b/cinder/volume/drivers/hitachi/hbsd_rest_fc.py @@ -144,9 +144,12 @@ class HBSDRESTFC(rest.HBSDREST): gid=gid) self.raise_error(msg) - def set_target_mode(self, port, gid): + def set_target_mode(self, port, gid, connector): """Configure the host group to meet the environment.""" - body = {'hostMode': 'LINUX/IRIX'} + if connector.get('os_type', None) == 'aix': + body = {'hostMode': 'AIX'} + else: + body = {'hostMode': 'LINUX/IRIX'} if self.conf.hitachi_rest_disable_io_wait: body['hostModeOptions'] = [_FC_HMO_DISABLE_IO] if self.conf.hitachi_host_mode_options: diff --git a/cinder/volume/drivers/hitachi/hbsd_rest_iscsi.py b/cinder/volume/drivers/hitachi/hbsd_rest_iscsi.py index 3236fe938c7..a580bde9e72 100644 --- a/cinder/volume/drivers/hitachi/hbsd_rest_iscsi.py +++ b/cinder/volume/drivers/hitachi/hbsd_rest_iscsi.py @@ -116,9 +116,13 @@ class HBSDRESTISCSI(rest.HBSDREST): """Connect the specified HBA with the specified port.""" self.client.add_hba_iscsi(port, gid, hba_ids) - def set_target_mode(self, port, gid): + def set_target_mode(self, port, gid, connector): """Configure the iSCSI target to meet the environment.""" - body = {'hostMode': 'LINUX/IRIX', + if connector.get('os_type', None) == 'aix': + host_mode = 'AIX' + else: + host_mode = 'LINUX/IRIX' + body = {'hostMode': host_mode, 'hostModeOptions': [_ISCSI_HMO_REPORT_FULL_PORTAL]} if self.conf.hitachi_rest_disable_io_wait: body['hostModeOptions'].append(_ISCSI_HMO_DISABLE_IO) diff --git a/releasenotes/notes/hitachi-vsp-aix-os-type-23bf7cc3b98dff3a.yaml b/releasenotes/notes/hitachi-vsp-aix-os-type-23bf7cc3b98dff3a.yaml new file mode 100644 index 00000000000..c652bcc5829 --- /dev/null +++ b/releasenotes/notes/hitachi-vsp-aix-os-type-23bf7cc3b98dff3a.yaml @@ -0,0 +1,7 @@ +--- +features: + - | + Hitachi driver: Support AIX as host OS type. + When running ``cinder attachment-create`` command with the option + ``--ostype aix``, ``AIX`` is set as host OS type. +