Hitachi: Make the parameters name variable for supporting OEM storages
This patch makes the parameters name variable for supporting OEM storages Change-Id: Ib5a1f7cfa0f3480dc850bf37b9ce2c988ff0f5d6
This commit is contained in:
parent
2925aa974f
commit
4082ed3bea
@ -95,10 +95,10 @@ from cinder.volume.drivers.fusionstorage import dsware as \
|
|||||||
cinder_volume_drivers_fusionstorage_dsware
|
cinder_volume_drivers_fusionstorage_dsware
|
||||||
from cinder.volume.drivers.hitachi import hbsd_common as \
|
from cinder.volume.drivers.hitachi import hbsd_common as \
|
||||||
cinder_volume_drivers_hitachi_hbsdcommon
|
cinder_volume_drivers_hitachi_hbsdcommon
|
||||||
from cinder.volume.drivers.hitachi import hbsd_fc as \
|
|
||||||
cinder_volume_drivers_hitachi_hbsdfc
|
|
||||||
from cinder.volume.drivers.hitachi import hbsd_rest as \
|
from cinder.volume.drivers.hitachi import hbsd_rest as \
|
||||||
cinder_volume_drivers_hitachi_hbsdrest
|
cinder_volume_drivers_hitachi_hbsdrest
|
||||||
|
from cinder.volume.drivers.hitachi import hbsd_rest_fc as \
|
||||||
|
cinder_volume_drivers_hitachi_hbsdrestfc
|
||||||
from cinder.volume.drivers.hpe import hpe_3par_common as \
|
from cinder.volume.drivers.hpe import hpe_3par_common as \
|
||||||
cinder_volume_drivers_hpe_hpe3parcommon
|
cinder_volume_drivers_hpe_hpe3parcommon
|
||||||
from cinder.volume.drivers.huawei import common as \
|
from cinder.volume.drivers.huawei import common as \
|
||||||
@ -328,8 +328,8 @@ def list_opts():
|
|||||||
cinder_volume_drivers_fujitsu_eternus_dx_eternusdxcommon.
|
cinder_volume_drivers_fujitsu_eternus_dx_eternusdxcommon.
|
||||||
FJ_ETERNUS_DX_OPT_opts,
|
FJ_ETERNUS_DX_OPT_opts,
|
||||||
cinder_volume_drivers_hitachi_hbsdcommon.COMMON_VOLUME_OPTS,
|
cinder_volume_drivers_hitachi_hbsdcommon.COMMON_VOLUME_OPTS,
|
||||||
cinder_volume_drivers_hitachi_hbsdfc.FC_VOLUME_OPTS,
|
|
||||||
cinder_volume_drivers_hitachi_hbsdrest.REST_VOLUME_OPTS,
|
cinder_volume_drivers_hitachi_hbsdrest.REST_VOLUME_OPTS,
|
||||||
|
cinder_volume_drivers_hitachi_hbsdrestfc.FC_VOLUME_OPTS,
|
||||||
cinder_volume_drivers_hpe_hpe3parcommon.hpe3par_opts,
|
cinder_volume_drivers_hpe_hpe3parcommon.hpe3par_opts,
|
||||||
cinder_volume_drivers_huawei_common.huawei_opts,
|
cinder_volume_drivers_huawei_common.huawei_opts,
|
||||||
cinder_volume_drivers_ibm_flashsystemcommon.flashsystem_opts,
|
cinder_volume_drivers_ibm_flashsystemcommon.flashsystem_opts,
|
||||||
|
@ -23,6 +23,7 @@ from requests import models
|
|||||||
|
|
||||||
from cinder import context as cinder_context
|
from cinder import context as cinder_context
|
||||||
from cinder.db.sqlalchemy import api as sqlalchemy_api
|
from cinder.db.sqlalchemy import api as sqlalchemy_api
|
||||||
|
from cinder import exception
|
||||||
from cinder.objects import group_snapshot as obj_group_snap
|
from cinder.objects import group_snapshot as obj_group_snap
|
||||||
from cinder.objects import snapshot as obj_snap
|
from cinder.objects import snapshot as obj_snap
|
||||||
from cinder.tests.unit import fake_group
|
from cinder.tests.unit import fake_group
|
||||||
@ -36,7 +37,6 @@ from cinder.volume.drivers.hitachi import hbsd_common
|
|||||||
from cinder.volume.drivers.hitachi import hbsd_fc
|
from cinder.volume.drivers.hitachi import hbsd_fc
|
||||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||||
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils
|
|
||||||
from cinder.volume import volume_types
|
from cinder.volume import volume_types
|
||||||
from cinder.volume import volume_utils
|
from cinder.volume import volume_utils
|
||||||
from cinder.zonemanager import utils as fczm_utils
|
from cinder.zonemanager import utils as fczm_utils
|
||||||
@ -617,7 +617,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
request.return_value = FakeResponse(
|
request.return_value = FakeResponse(
|
||||||
500, ERROR_RESULT,
|
500, ERROR_RESULT,
|
||||||
headers={'Content-Type': 'json'})
|
headers={'Content-Type': 'json'})
|
||||||
self.assertRaises(hbsd_utils.HBSDError,
|
self.assertRaises(exception.VolumeDriverException,
|
||||||
self.driver.create_volume,
|
self.driver.create_volume,
|
||||||
fake_volume.fake_volume_obj(self.ctxt))
|
fake_volume.fake_volume_obj(self.ctxt))
|
||||||
self.assertGreater(request.call_count, 1)
|
self.assertGreater(request.call_count, 1)
|
||||||
@ -651,7 +651,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
FakeResponse(200, GET_LDEV_RESULT_PAIR),
|
FakeResponse(200, GET_LDEV_RESULT_PAIR),
|
||||||
FakeResponse(200, GET_LDEV_RESULT_PAIR),
|
FakeResponse(200, GET_LDEV_RESULT_PAIR),
|
||||||
FakeResponse(200, GET_LDEV_RESULT_PAIR)]
|
FakeResponse(200, GET_LDEV_RESULT_PAIR)]
|
||||||
self.assertRaises(hbsd_utils.HBSDError,
|
self.assertRaises(exception.VolumeDriverException,
|
||||||
self.driver.delete_volume,
|
self.driver.delete_volume,
|
||||||
TEST_VOLUME[0])
|
TEST_VOLUME[0])
|
||||||
self.assertGreater(request.call_count, 2)
|
self.assertGreater(request.call_count, 2)
|
||||||
@ -741,7 +741,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(fczm_utils, "add_fc_zone")
|
@mock.patch.object(fczm_utils, "add_fc_zone")
|
||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_initialize_connection(self, request, add_fc_zone):
|
def test_initialize_connection(self, request, add_fc_zone):
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
||||||
FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)]
|
FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)]
|
||||||
@ -757,7 +757,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_initialize_connection_already_mapped(self, request, add_fc_zone):
|
def test_initialize_connection_already_mapped(self, request, add_fc_zone):
|
||||||
"""Normal case: ldev have already mapped."""
|
"""Normal case: ldev have already mapped."""
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [
|
request.side_effect = [
|
||||||
FakeResponse(200, GET_HOST_WWNS_RESULT),
|
FakeResponse(200, GET_HOST_WWNS_RESULT),
|
||||||
@ -776,7 +776,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_initialize_connection_shared_target(self, request, add_fc_zone):
|
def test_initialize_connection_shared_target(self, request, add_fc_zone):
|
||||||
"""Normal case: A target shared with other systems."""
|
"""Normal case: A target shared with other systems."""
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, NOTFOUND_RESULT),
|
request.side_effect = [FakeResponse(200, NOTFOUND_RESULT),
|
||||||
FakeResponse(200, NOTFOUND_RESULT),
|
FakeResponse(200, NOTFOUND_RESULT),
|
||||||
@ -794,7 +794,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(fczm_utils, "remove_fc_zone")
|
@mock.patch.object(fczm_utils, "remove_fc_zone")
|
||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_terminate_connection(self, request, remove_fc_zone):
|
def test_terminate_connection(self, request, remove_fc_zone):
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
||||||
FakeResponse(200, GET_LDEV_RESULT_MAPPED),
|
FakeResponse(200, GET_LDEV_RESULT_MAPPED),
|
||||||
@ -809,7 +809,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_terminate_connection_not_connector(self, request, remove_fc_zone):
|
def test_terminate_connection_not_connector(self, request, remove_fc_zone):
|
||||||
"""Normal case: Connector is None."""
|
"""Normal case: Connector is None."""
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, GET_LDEV_RESULT_MAPPED),
|
request.side_effect = [FakeResponse(200, GET_LDEV_RESULT_MAPPED),
|
||||||
FakeResponse(200, GET_HOST_GROUP_RESULT),
|
FakeResponse(200, GET_HOST_GROUP_RESULT),
|
||||||
@ -827,7 +827,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_terminate_connection_not_lun(self, request, remove_fc_zone):
|
def test_terminate_connection_not_lun(self, request, remove_fc_zone):
|
||||||
"""Normal case: Lun already not exist."""
|
"""Normal case: Lun already not exist."""
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
||||||
FakeResponse(200, GET_LDEV_RESULT)]
|
FakeResponse(200, GET_LDEV_RESULT)]
|
||||||
@ -838,7 +838,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(fczm_utils, "add_fc_zone")
|
@mock.patch.object(fczm_utils, "add_fc_zone")
|
||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_initialize_connection_snapshot(self, request, add_fc_zone):
|
def test_initialize_connection_snapshot(self, request, add_fc_zone):
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
||||||
FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)]
|
FakeResponse(202, COMPLETED_SUCCEEDED_RESULT)]
|
||||||
@ -853,7 +853,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(fczm_utils, "remove_fc_zone")
|
@mock.patch.object(fczm_utils, "remove_fc_zone")
|
||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_terminate_connection_snapshot(self, request, remove_fc_zone):
|
def test_terminate_connection_snapshot(self, request, remove_fc_zone):
|
||||||
self.configuration.hitachi_zoning_request = True
|
self.driver.common.conf.hitachi_zoning_request = True
|
||||||
self.driver.common._lookup_service = FakeLookupService()
|
self.driver.common._lookup_service = FakeLookupService()
|
||||||
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
request.side_effect = [FakeResponse(200, GET_HOST_WWNS_RESULT),
|
||||||
FakeResponse(200, GET_LDEV_RESULT_MAPPED),
|
FakeResponse(200, GET_LDEV_RESULT_MAPPED),
|
||||||
@ -1020,7 +1020,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
|
|
||||||
def test_create_group_from_src_volume_error(self):
|
def test_create_group_from_src_volume_error(self):
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
hbsd_utils.HBSDError, self.driver.create_group_from_src,
|
exception.VolumeDriverException, self.driver.create_group_from_src,
|
||||||
self.ctxt, TEST_GROUP[1], [TEST_VOLUME[1]],
|
self.ctxt, TEST_GROUP[1], [TEST_VOLUME[1]],
|
||||||
source_group=TEST_GROUP[0], source_vols=[TEST_VOLUME[3]]
|
source_group=TEST_GROUP[0], source_vols=[TEST_VOLUME[3]]
|
||||||
)
|
)
|
||||||
@ -1036,7 +1036,7 @@ class HBSDRESTFCDriverTest(test.TestCase):
|
|||||||
def test_update_group_error(self, is_group_a_cg_snapshot_type):
|
def test_update_group_error(self, is_group_a_cg_snapshot_type):
|
||||||
is_group_a_cg_snapshot_type.return_value = True
|
is_group_a_cg_snapshot_type.return_value = True
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
hbsd_utils.HBSDError, self.driver.update_group,
|
exception.VolumeDriverException, self.driver.update_group,
|
||||||
self.ctxt, TEST_GROUP[0], add_volumes=[TEST_VOLUME[3]],
|
self.ctxt, TEST_GROUP[0], add_volumes=[TEST_VOLUME[3]],
|
||||||
remove_volumes=[TEST_VOLUME[0]]
|
remove_volumes=[TEST_VOLUME[0]]
|
||||||
)
|
)
|
||||||
|
@ -21,6 +21,7 @@ import requests
|
|||||||
|
|
||||||
from cinder import context as cinder_context
|
from cinder import context as cinder_context
|
||||||
from cinder.db.sqlalchemy import api as sqlalchemy_api
|
from cinder.db.sqlalchemy import api as sqlalchemy_api
|
||||||
|
from cinder import exception
|
||||||
from cinder.objects import group_snapshot as obj_group_snap
|
from cinder.objects import group_snapshot as obj_group_snap
|
||||||
from cinder.objects import snapshot as obj_snap
|
from cinder.objects import snapshot as obj_snap
|
||||||
from cinder.tests.unit import fake_group
|
from cinder.tests.unit import fake_group
|
||||||
@ -34,7 +35,6 @@ from cinder.volume.drivers.hitachi import hbsd_common
|
|||||||
from cinder.volume.drivers.hitachi import hbsd_iscsi
|
from cinder.volume.drivers.hitachi import hbsd_iscsi
|
||||||
from cinder.volume.drivers.hitachi import hbsd_rest
|
from cinder.volume.drivers.hitachi import hbsd_rest
|
||||||
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
from cinder.volume.drivers.hitachi import hbsd_rest_api
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils
|
|
||||||
from cinder.volume import volume_types
|
from cinder.volume import volume_types
|
||||||
from cinder.volume import volume_utils
|
from cinder.volume import volume_utils
|
||||||
|
|
||||||
@ -497,14 +497,14 @@ class HBSDRESTISCSIDriverTest(test.TestCase):
|
|||||||
@mock.patch.object(driver.ISCSIDriver, "get_goodness_function")
|
@mock.patch.object(driver.ISCSIDriver, "get_goodness_function")
|
||||||
@mock.patch.object(driver.ISCSIDriver, "get_filter_function")
|
@mock.patch.object(driver.ISCSIDriver, "get_filter_function")
|
||||||
@mock.patch.object(requests.Session, "request")
|
@mock.patch.object(requests.Session, "request")
|
||||||
def test_get_volume_stats(
|
def test__update_volume_stats(
|
||||||
self, request, get_filter_function, get_goodness_function):
|
self, request, get_filter_function, get_goodness_function):
|
||||||
request.return_value = FakeResponse(200, GET_POOL_RESULT)
|
request.return_value = FakeResponse(200, GET_POOL_RESULT)
|
||||||
get_filter_function.return_value = None
|
get_filter_function.return_value = None
|
||||||
get_goodness_function.return_value = None
|
get_goodness_function.return_value = None
|
||||||
stats = self.driver.get_volume_stats(True)
|
self.driver._update_volume_stats()
|
||||||
self.assertEqual('Hitachi', stats['vendor_name'])
|
self.assertEqual('Hitachi', self.driver._stats['vendor_name'])
|
||||||
self.assertTrue(stats["pools"][0]['multiattach'])
|
self.assertTrue(self.driver._stats["pools"][0]['multiattach'])
|
||||||
self.assertEqual(1, request.call_count)
|
self.assertEqual(1, request.call_count)
|
||||||
self.assertEqual(1, get_filter_function.call_count)
|
self.assertEqual(1, get_filter_function.call_count)
|
||||||
self.assertEqual(1, get_goodness_function.call_count)
|
self.assertEqual(1, get_goodness_function.call_count)
|
||||||
@ -826,7 +826,7 @@ class HBSDRESTISCSIDriverTest(test.TestCase):
|
|||||||
|
|
||||||
def test_create_group_from_src_volume_error(self):
|
def test_create_group_from_src_volume_error(self):
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
hbsd_utils.HBSDError, self.driver.create_group_from_src,
|
exception.VolumeDriverException, self.driver.create_group_from_src,
|
||||||
self.ctxt, TEST_GROUP[1], [TEST_VOLUME[1]],
|
self.ctxt, TEST_GROUP[1], [TEST_VOLUME[1]],
|
||||||
source_group=TEST_GROUP[0], source_vols=[TEST_VOLUME[3]]
|
source_group=TEST_GROUP[0], source_vols=[TEST_VOLUME[3]]
|
||||||
)
|
)
|
||||||
@ -842,7 +842,7 @@ class HBSDRESTISCSIDriverTest(test.TestCase):
|
|||||||
def test_update_group_error(self, is_group_a_cg_snapshot_type):
|
def test_update_group_error(self, is_group_a_cg_snapshot_type):
|
||||||
is_group_a_cg_snapshot_type.return_value = True
|
is_group_a_cg_snapshot_type.return_value = True
|
||||||
self.assertRaises(
|
self.assertRaises(
|
||||||
hbsd_utils.HBSDError, self.driver.update_group,
|
exception.VolumeDriverException, self.driver.update_group,
|
||||||
self.ctxt, TEST_GROUP[0], add_volumes=[TEST_VOLUME[3]],
|
self.ctxt, TEST_GROUP[0], add_volumes=[TEST_VOLUME[3]],
|
||||||
remove_volumes=[TEST_VOLUME[0]]
|
remove_volumes=[TEST_VOLUME[0]]
|
||||||
)
|
)
|
||||||
|
@ -22,12 +22,11 @@ from oslo_utils import excutils
|
|||||||
|
|
||||||
from cinder import coordination
|
from cinder import coordination
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
|
from cinder.i18n import _
|
||||||
from cinder.volume import configuration
|
from cinder.volume import configuration
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
||||||
from cinder.volume import volume_utils
|
from cinder.volume import volume_utils
|
||||||
|
|
||||||
VERSION = '2.2.0'
|
|
||||||
|
|
||||||
_STR_VOLUME = 'volume'
|
_STR_VOLUME = 'volume'
|
||||||
_STR_SNAPSHOT = 'snapshot'
|
_STR_SNAPSHOT = 'snapshot'
|
||||||
|
|
||||||
@ -106,11 +105,6 @@ COMMON_VOLUME_OPTS = [
|
|||||||
'a copy pair deletion or data restoration.'),
|
'a copy pair deletion or data restoration.'),
|
||||||
]
|
]
|
||||||
|
|
||||||
_REQUIRED_COMMON_OPTS = [
|
|
||||||
'hitachi_storage_id',
|
|
||||||
'hitachi_pool',
|
|
||||||
]
|
|
||||||
|
|
||||||
CONF = cfg.CONF
|
CONF = cfg.CONF
|
||||||
CONF.register_opts(COMMON_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
CONF.register_opts(COMMON_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
||||||
|
|
||||||
@ -155,6 +149,10 @@ class HBSDCommon():
|
|||||||
'wwns': {},
|
'wwns': {},
|
||||||
'portals': {},
|
'portals': {},
|
||||||
}
|
}
|
||||||
|
self._required_common_opts = [
|
||||||
|
self.driver_info['param_prefix'] + '_storage_id',
|
||||||
|
self.driver_info['param_prefix'] + '_pool',
|
||||||
|
]
|
||||||
|
|
||||||
def create_ldev(self, size):
|
def create_ldev(self, size):
|
||||||
"""Create an LDEV and return its LDEV number."""
|
"""Create an LDEV and return its LDEV number."""
|
||||||
@ -189,7 +187,7 @@ class HBSDCommon():
|
|||||||
ldev_info = self.get_ldev_info(['status', 'attributes'], pvol)
|
ldev_info = self.get_ldev_info(['status', 'attributes'], pvol)
|
||||||
if ldev_info['status'] != 'NML':
|
if ldev_info['status'] != 'NML':
|
||||||
msg = utils.output_log(MSG.INVALID_LDEV_STATUS_FOR_COPY, ldev=pvol)
|
msg = utils.output_log(MSG.INVALID_LDEV_STATUS_FOR_COPY, ldev=pvol)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
svol = self.create_ldev(size)
|
svol = self.create_ldev(size)
|
||||||
try:
|
try:
|
||||||
self.create_pair_on_storage(pvol, svol, is_snapshot)
|
self.create_pair_on_storage(pvol, svol, is_snapshot)
|
||||||
@ -197,7 +195,7 @@ class HBSDCommon():
|
|||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
try:
|
try:
|
||||||
self.delete_ldev(svol)
|
self.delete_ldev(svol)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=svol)
|
utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=svol)
|
||||||
return svol
|
return svol
|
||||||
|
|
||||||
@ -209,7 +207,7 @@ class HBSDCommon():
|
|||||||
if ldev is None:
|
if ldev is None:
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_LDEV_FOR_VOLUME_COPY, type=src_type, id=src['id'])
|
MSG.INVALID_LDEV_FOR_VOLUME_COPY, type=src_type, id=src['id'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
size = volume['size']
|
size = volume['size']
|
||||||
new_ldev = self._copy_on_storage(ldev, size)
|
new_ldev = self._copy_on_storage(ldev, size)
|
||||||
@ -243,7 +241,7 @@ class HBSDCommon():
|
|||||||
if pair_info['pvol'] == ldev:
|
if pair_info['pvol'] == ldev:
|
||||||
utils.output_log(
|
utils.output_log(
|
||||||
MSG.UNABLE_TO_DELETE_PAIR, pvol=pair_info['pvol'])
|
MSG.UNABLE_TO_DELETE_PAIR, pvol=pair_info['pvol'])
|
||||||
raise utils.HBSDBusy()
|
self.raise_busy()
|
||||||
else:
|
else:
|
||||||
self.delete_pair_based_on_svol(
|
self.delete_pair_based_on_svol(
|
||||||
pair_info['pvol'], pair_info['svol_info'][0])
|
pair_info['pvol'], pair_info['svol_info'][0])
|
||||||
@ -284,8 +282,11 @@ class HBSDCommon():
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.delete_ldev(ldev)
|
self.delete_ldev(ldev)
|
||||||
except utils.HBSDBusy:
|
except exception.VolumeDriverException as ex:
|
||||||
|
if ex.msg == utils.BUSY_MESSAGE:
|
||||||
raise exception.VolumeIsBusy(volume_name=volume['name'])
|
raise exception.VolumeIsBusy(volume_name=volume['name'])
|
||||||
|
else:
|
||||||
|
raise ex
|
||||||
|
|
||||||
def create_snapshot(self, snapshot):
|
def create_snapshot(self, snapshot):
|
||||||
"""Create a snapshot from a volume and return its properties."""
|
"""Create a snapshot from a volume and return its properties."""
|
||||||
@ -295,7 +296,7 @@ class HBSDCommon():
|
|||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_LDEV_FOR_VOLUME_COPY,
|
MSG.INVALID_LDEV_FOR_VOLUME_COPY,
|
||||||
type='volume', id=src_vref['id'])
|
type='volume', id=src_vref['id'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
size = snapshot['volume_size']
|
size = snapshot['volume_size']
|
||||||
new_ldev = self._copy_on_storage(ldev, size, True)
|
new_ldev = self._copy_on_storage(ldev, size, True)
|
||||||
return {
|
return {
|
||||||
@ -312,8 +313,11 @@ class HBSDCommon():
|
|||||||
return
|
return
|
||||||
try:
|
try:
|
||||||
self.delete_ldev(ldev)
|
self.delete_ldev(ldev)
|
||||||
except utils.HBSDBusy:
|
except exception.VolumeDriverException as ex:
|
||||||
|
if ex.msg == utils.BUSY_MESSAGE:
|
||||||
raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
|
raise exception.SnapshotIsBusy(snapshot_name=snapshot['name'])
|
||||||
|
else:
|
||||||
|
raise ex
|
||||||
|
|
||||||
def get_pool_info(self):
|
def get_pool_info(self):
|
||||||
"""Return the total and free capacity of the storage pool."""
|
"""Return the total and free capacity of the storage pool."""
|
||||||
@ -326,8 +330,8 @@ class HBSDCommon():
|
|||||||
self.driver_info['volume_backend_name'])
|
self.driver_info['volume_backend_name'])
|
||||||
data = {
|
data = {
|
||||||
'volume_backend_name': backend_name,
|
'volume_backend_name': backend_name,
|
||||||
'vendor_name': 'Hitachi',
|
'vendor_name': self.driver_info['vendor_name'],
|
||||||
'driver_version': VERSION,
|
'driver_version': self.driver_info['version'],
|
||||||
'storage_protocol': self.storage_info['protocol'],
|
'storage_protocol': self.storage_info['protocol'],
|
||||||
'pools': [],
|
'pools': [],
|
||||||
}
|
}
|
||||||
@ -344,7 +348,7 @@ class HBSDCommon():
|
|||||||
try:
|
try:
|
||||||
(total_capacity, free_capacity,
|
(total_capacity, free_capacity,
|
||||||
provisioned_capacity) = self.get_pool_info()
|
provisioned_capacity) = self.get_pool_info()
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
single_pool.update(dict(
|
single_pool.update(dict(
|
||||||
provisioned_capacity_gb=0,
|
provisioned_capacity_gb=0,
|
||||||
backend_state='down'))
|
backend_state='down'))
|
||||||
@ -387,11 +391,11 @@ class HBSDCommon():
|
|||||||
if ldev is None:
|
if ldev is None:
|
||||||
msg = utils.output_log(MSG.INVALID_LDEV_FOR_EXTENSION,
|
msg = utils.output_log(MSG.INVALID_LDEV_FOR_EXTENSION,
|
||||||
volume_id=volume['id'])
|
volume_id=volume['id'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
if self.check_pair_svol(ldev):
|
if self.check_pair_svol(ldev):
|
||||||
msg = utils.output_log(MSG.INVALID_VOLUME_TYPE_FOR_EXTEND,
|
msg = utils.output_log(MSG.INVALID_VOLUME_TYPE_FOR_EXTEND,
|
||||||
volume_id=volume['id'])
|
volume_id=volume['id'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
self.delete_pair(ldev)
|
self.delete_pair(ldev)
|
||||||
self.extend_ldev(ldev, volume['size'], new_size)
|
self.extend_ldev(ldev, volume['size'], new_size)
|
||||||
|
|
||||||
@ -448,8 +452,11 @@ class HBSDCommon():
|
|||||||
raise exception.VolumeIsBusy(volume_name=volume['name'])
|
raise exception.VolumeIsBusy(volume_name=volume['name'])
|
||||||
try:
|
try:
|
||||||
self.delete_pair(ldev)
|
self.delete_pair(ldev)
|
||||||
except utils.HBSDBusy:
|
except exception.VolumeDriverException as ex:
|
||||||
|
if ex.msg == utils.BUSY_MESSAGE:
|
||||||
raise exception.VolumeIsBusy(volume_name=volume['name'])
|
raise exception.VolumeIsBusy(volume_name=volume['name'])
|
||||||
|
else:
|
||||||
|
raise ex
|
||||||
|
|
||||||
def _range2list(self, param):
|
def _range2list(self, param):
|
||||||
"""Analyze a 'xxx-xxx' string and return a list of two integers."""
|
"""Analyze a 'xxx-xxx' string and return a list of two integers."""
|
||||||
@ -457,7 +464,7 @@ class HBSDCommon():
|
|||||||
self.conf.safe_get(param).split('-')]
|
self.conf.safe_get(param).split('-')]
|
||||||
if len(values) != 2 or None in values or values[0] > values[1]:
|
if len(values) != 2 or None in values or values[0] > values[1]:
|
||||||
msg = utils.output_log(MSG.INVALID_PARAMETER, param=param)
|
msg = utils.output_log(MSG.INVALID_PARAMETER, param=param)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
return values
|
return values
|
||||||
|
|
||||||
def check_param_iscsi(self):
|
def check_param_iscsi(self):
|
||||||
@ -466,38 +473,37 @@ class HBSDCommon():
|
|||||||
if not self.conf.chap_username:
|
if not self.conf.chap_username:
|
||||||
msg = utils.output_log(MSG.INVALID_PARAMETER,
|
msg = utils.output_log(MSG.INVALID_PARAMETER,
|
||||||
param='chap_username')
|
param='chap_username')
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
if not self.conf.chap_password:
|
if not self.conf.chap_password:
|
||||||
msg = utils.output_log(MSG.INVALID_PARAMETER,
|
msg = utils.output_log(MSG.INVALID_PARAMETER,
|
||||||
param='chap_password')
|
param='chap_password')
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
def check_param(self):
|
def check_param(self):
|
||||||
"""Check parameter values and consistency among them."""
|
"""Check parameter values and consistency among them."""
|
||||||
utils.check_opt_value(self.conf, _INHERITED_VOLUME_OPTS)
|
utils.check_opt_value(self.conf, _INHERITED_VOLUME_OPTS)
|
||||||
utils.check_opts(self.conf, COMMON_VOLUME_OPTS)
|
self.check_opts(self.conf, COMMON_VOLUME_OPTS)
|
||||||
utils.check_opts(self.conf, self.driver_info['volume_opts'])
|
|
||||||
if self.conf.hitachi_ldev_range:
|
if self.conf.hitachi_ldev_range:
|
||||||
self.storage_info['ldev_range'] = self._range2list(
|
self.storage_info['ldev_range'] = self._range2list(
|
||||||
'hitachi_ldev_range')
|
self.driver_info['param_prefix'] + '_ldev_range')
|
||||||
if (not self.conf.hitachi_target_ports and
|
if (not self.conf.hitachi_target_ports and
|
||||||
not self.conf.hitachi_compute_target_ports):
|
not self.conf.hitachi_compute_target_ports):
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_PARAMETER,
|
MSG.INVALID_PARAMETER,
|
||||||
param='hitachi_target_ports or '
|
param='hitachi_target_ports or '
|
||||||
'hitachi_compute_target_ports')
|
'hitachi_compute_target_ports')
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
if (self.conf.hitachi_group_delete and
|
if (self.conf.hitachi_group_delete and
|
||||||
not self.conf.hitachi_group_create):
|
not self.conf.hitachi_group_create):
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_PARAMETER,
|
MSG.INVALID_PARAMETER,
|
||||||
param='hitachi_group_delete or '
|
param='hitachi_group_delete or '
|
||||||
'hitachi_group_create')
|
'hitachi_group_create')
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
for opt in _REQUIRED_COMMON_OPTS:
|
for opt in self._required_common_opts:
|
||||||
if not self.conf.safe_get(opt):
|
if not self.conf.safe_get(opt):
|
||||||
msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
|
msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
if self.storage_info['protocol'] == 'iSCSI':
|
if self.storage_info['protocol'] == 'iSCSI':
|
||||||
self.check_param_iscsi()
|
self.check_param_iscsi()
|
||||||
|
|
||||||
@ -535,7 +541,7 @@ class HBSDCommon():
|
|||||||
return connector[self.driver_info['hba_id']]
|
return connector[self.driver_info['hba_id']]
|
||||||
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
||||||
resource=self.driver_info['hba_id_type'])
|
resource=self.driver_info['hba_id_type'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
def create_target_to_storage(self, port, connector, hba_ids):
|
def create_target_to_storage(self, port, connector, hba_ids):
|
||||||
"""Create a host group or an iSCSI target on the specified port."""
|
"""Create a host group or an iSCSI target on the specified port."""
|
||||||
@ -579,7 +585,7 @@ class HBSDCommon():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
self._create_target(targets, port, connector, hba_ids)
|
self._create_target(targets, port, connector, hba_ids)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(
|
utils.output_log(
|
||||||
self.driver_info['msg_id']['target'], port=port)
|
self.driver_info['msg_id']['target'], port=port)
|
||||||
|
|
||||||
@ -604,7 +610,7 @@ class HBSDCommon():
|
|||||||
self.conf.hitachi_group_create):
|
self.conf.hitachi_group_create):
|
||||||
self.create_mapping_targets(targets, connector)
|
self.create_mapping_targets(targets, connector)
|
||||||
|
|
||||||
utils.require_target_existed(targets)
|
self.require_target_existed(targets)
|
||||||
|
|
||||||
def do_setup(self, context):
|
def do_setup(self, context):
|
||||||
"""Prepare for the startup of the driver."""
|
"""Prepare for the startup of the driver."""
|
||||||
@ -627,12 +633,12 @@ class HBSDCommon():
|
|||||||
not self.storage_info['controller_ports']):
|
not self.storage_info['controller_ports']):
|
||||||
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
||||||
resource="Target ports")
|
resource="Target ports")
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
if (self.conf.hitachi_compute_target_ports and
|
if (self.conf.hitachi_compute_target_ports and
|
||||||
not self.storage_info['compute_ports']):
|
not self.storage_info['compute_ports']):
|
||||||
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
||||||
resource="Compute target ports")
|
resource="Compute target ports")
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
utils.output_log(MSG.SET_CONFIG_VALUE, object='target port list',
|
utils.output_log(MSG.SET_CONFIG_VALUE, object='target port list',
|
||||||
value=self.storage_info['controller_ports'])
|
value=self.storage_info['controller_ports'])
|
||||||
utils.output_log(MSG.SET_CONFIG_VALUE,
|
utils.output_log(MSG.SET_CONFIG_VALUE,
|
||||||
@ -694,8 +700,9 @@ class HBSDCommon():
|
|||||||
|
|
||||||
# A synchronization to prevent conflicts between host group creation
|
# A synchronization to prevent conflicts between host group creation
|
||||||
# and deletion.
|
# and deletion.
|
||||||
@coordination.synchronized('hbsd-host-{self.conf.hitachi_storage_id}-'
|
@coordination.synchronized(
|
||||||
'{connector[host]}')
|
'{self.driver_info[driver_file_prefix]}-host-'
|
||||||
|
'{self.conf.hitachi_storage_id}-{connector[host]}')
|
||||||
def initialize_connection(self, volume, connector):
|
def initialize_connection(self, volume, connector):
|
||||||
"""Initialize connection between the server and the volume."""
|
"""Initialize connection between the server and the volume."""
|
||||||
targets = {
|
targets = {
|
||||||
@ -709,7 +716,7 @@ class HBSDCommon():
|
|||||||
if ldev is None:
|
if ldev is None:
|
||||||
msg = utils.output_log(MSG.INVALID_LDEV_FOR_CONNECTION,
|
msg = utils.output_log(MSG.INVALID_LDEV_FOR_CONNECTION,
|
||||||
volume_id=volume['id'])
|
volume_id=volume['id'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
target_lun = self.attach_ldev(volume, ldev, connector, targets)
|
target_lun = self.attach_ldev(volume, ldev, connector, targets)
|
||||||
|
|
||||||
@ -758,7 +765,8 @@ class HBSDCommon():
|
|||||||
# A synchronization to prevent conflicts between host group creation
|
# A synchronization to prevent conflicts between host group creation
|
||||||
# and deletion.
|
# and deletion.
|
||||||
@coordination.synchronized(
|
@coordination.synchronized(
|
||||||
'hbsd-host-%(storage_id)s-%(host)s' % {
|
'%(prefix)s-host-%(storage_id)s-%(host)s' % {
|
||||||
|
'prefix': self.driver_info['driver_file_prefix'],
|
||||||
'storage_id': self.conf.hitachi_storage_id,
|
'storage_id': self.conf.hitachi_storage_id,
|
||||||
'host': connector.get('host'),
|
'host': connector.get('host'),
|
||||||
}
|
}
|
||||||
@ -819,3 +827,34 @@ class HBSDCommon():
|
|||||||
|
|
||||||
def delete_group_snapshot(self, group_snapshot, snapshots):
|
def delete_group_snapshot(self, group_snapshot, snapshots):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
def check_opts(self, conf, opts):
|
||||||
|
"""Check if the specified configuration is valid."""
|
||||||
|
names = []
|
||||||
|
for opt in opts:
|
||||||
|
if opt.required and not conf.safe_get(opt.name):
|
||||||
|
msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt.name)
|
||||||
|
self.raise_error(msg)
|
||||||
|
names.append(opt.name)
|
||||||
|
utils.check_opt_value(conf, names)
|
||||||
|
|
||||||
|
def require_target_existed(self, targets):
|
||||||
|
"""Check if the target list includes one or more members."""
|
||||||
|
if not targets['list']:
|
||||||
|
msg = utils.output_log(MSG.NO_CONNECTED_TARGET)
|
||||||
|
self.raise_error(msg)
|
||||||
|
|
||||||
|
def raise_error(self, msg):
|
||||||
|
"""Raise a VolumeDriverException by driver error message."""
|
||||||
|
message = _(
|
||||||
|
'%(prefix)s error occurred. %(msg)s' % {
|
||||||
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
|
'msg': msg,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raise exception.VolumeDriverException(message)
|
||||||
|
|
||||||
|
def raise_busy(self):
|
||||||
|
"""Raise a VolumeDriverException by driver busy message."""
|
||||||
|
message = _(utils.BUSY_MESSAGE)
|
||||||
|
raise exception.VolumeDriverException(message)
|
||||||
|
@ -14,28 +14,21 @@
|
|||||||
#
|
#
|
||||||
"""Fibre channel module for Hitachi HBSD Driver."""
|
"""Fibre channel module for Hitachi HBSD Driver."""
|
||||||
|
|
||||||
from oslo_config import cfg
|
import os
|
||||||
|
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
|
|
||||||
from cinder import interface
|
from cinder import interface
|
||||||
from cinder.volume import configuration
|
|
||||||
from cinder.volume import driver
|
from cinder.volume import driver
|
||||||
from cinder.volume.drivers.hitachi import hbsd_common as common
|
from cinder.volume.drivers.hitachi import hbsd_common as common
|
||||||
|
from cinder.volume.drivers.hitachi import hbsd_rest_fc as rest_fc
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
||||||
from cinder.volume import volume_utils
|
from cinder.volume import volume_utils
|
||||||
|
|
||||||
FC_VOLUME_OPTS = [
|
|
||||||
cfg.BoolOpt(
|
|
||||||
'hitachi_zoning_request',
|
|
||||||
default=False,
|
|
||||||
help='If True, the driver will configure FC zoning between the server '
|
|
||||||
'and the storage system provided that FC zoning manager is '
|
|
||||||
'enabled.'),
|
|
||||||
]
|
|
||||||
|
|
||||||
MSG = utils.HBSDMsg
|
MSG = utils.HBSDMsg
|
||||||
|
|
||||||
_DRIVER_INFO = {
|
_DRIVER_INFO = {
|
||||||
|
'version': utils.VERSION,
|
||||||
'proto': 'FC',
|
'proto': 'FC',
|
||||||
'hba_id': 'wwpns',
|
'hba_id': 'wwpns',
|
||||||
'hba_id_type': 'World Wide Name',
|
'hba_id_type': 'World Wide Name',
|
||||||
@ -45,13 +38,19 @@ _DRIVER_INFO = {
|
|||||||
'volume_backend_name': '%(prefix)sFC' % {
|
'volume_backend_name': '%(prefix)sFC' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': utils.DRIVER_PREFIX,
|
||||||
},
|
},
|
||||||
'volume_opts': FC_VOLUME_OPTS,
|
|
||||||
'volume_type': 'fibre_channel',
|
'volume_type': 'fibre_channel',
|
||||||
|
'param_prefix': utils.PARAM_PREFIX,
|
||||||
|
'vendor_name': utils.VENDOR_NAME,
|
||||||
|
'driver_prefix': utils.DRIVER_PREFIX,
|
||||||
|
'driver_file_prefix': utils.DRIVER_FILE_PREFIX,
|
||||||
|
'target_prefix': utils.TARGET_PREFIX,
|
||||||
|
'hdp_vol_attr': utils.HDP_VOL_ATTR,
|
||||||
|
'hdt_vol_attr': utils.HDT_VOL_ATTR,
|
||||||
|
'nvol_ldev_type': utils.NVOL_LDEV_TYPE,
|
||||||
|
'target_iqn_suffix': utils.TARGET_IQN_SUFFIX,
|
||||||
|
'pair_attr': utils.PAIR_ATTR,
|
||||||
}
|
}
|
||||||
|
|
||||||
CONF = cfg.CONF
|
|
||||||
CONF.register_opts(FC_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
|
||||||
|
|
||||||
|
|
||||||
@interface.volumedriver
|
@interface.volumedriver
|
||||||
class HBSDFCDriver(driver.FibreChannelDriver):
|
class HBSDFCDriver(driver.FibreChannelDriver):
|
||||||
@ -67,13 +66,14 @@ class HBSDFCDriver(driver.FibreChannelDriver):
|
|||||||
API for communication with the storage backend.
|
API for communication with the storage backend.
|
||||||
2.1.0 - Add Cinder generic volume groups.
|
2.1.0 - Add Cinder generic volume groups.
|
||||||
2.2.0 - Add maintenance parameters.
|
2.2.0 - Add maintenance parameters.
|
||||||
|
2.2.1 - Make the parameters name variable for supporting OEM storages.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = common.VERSION
|
VERSION = utils.VERSION
|
||||||
|
|
||||||
# ThirdPartySystems wiki page
|
# ThirdPartySystems wiki page
|
||||||
CI_WIKI_NAME = "Hitachi_VSP_CI"
|
CI_WIKI_NAME = utils.CI_WIKI_NAME
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize instance variables."""
|
"""Initialize instance variables."""
|
||||||
@ -83,9 +83,12 @@ class HBSDFCDriver(driver.FibreChannelDriver):
|
|||||||
super(HBSDFCDriver, self).__init__(*args, **kwargs)
|
super(HBSDFCDriver, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.configuration.append_config_values(common.COMMON_VOLUME_OPTS)
|
self.configuration.append_config_values(common.COMMON_VOLUME_OPTS)
|
||||||
self.configuration.append_config_values(FC_VOLUME_OPTS)
|
self.configuration.append_config_values(rest_fc.FC_VOLUME_OPTS)
|
||||||
self.common = utils.import_object(
|
os.environ['LANG'] = 'C'
|
||||||
self.configuration, _DRIVER_INFO, kwargs.get('db'))
|
self.common = self._init_common(self.configuration, kwargs.get('db'))
|
||||||
|
|
||||||
|
def _init_common(self, conf, db):
|
||||||
|
return rest_fc.HBSDRESTFC(conf, _DRIVER_INFO, db)
|
||||||
|
|
||||||
def check_for_setup_error(self):
|
def check_for_setup_error(self):
|
||||||
pass
|
pass
|
||||||
|
@ -14,17 +14,21 @@
|
|||||||
#
|
#
|
||||||
"""iSCSI module for Hitachi HBSD Driver."""
|
"""iSCSI module for Hitachi HBSD Driver."""
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
|
|
||||||
from cinder import interface
|
from cinder import interface
|
||||||
from cinder.volume import driver
|
from cinder.volume import driver
|
||||||
from cinder.volume.drivers.hitachi import hbsd_common as common
|
from cinder.volume.drivers.hitachi import hbsd_common as common
|
||||||
|
from cinder.volume.drivers.hitachi import hbsd_rest_iscsi as rest_iscsi
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
||||||
from cinder.volume import volume_utils
|
from cinder.volume import volume_utils
|
||||||
|
|
||||||
MSG = utils.HBSDMsg
|
MSG = utils.HBSDMsg
|
||||||
|
|
||||||
_DRIVER_INFO = {
|
_DRIVER_INFO = {
|
||||||
|
'version': utils.VERSION,
|
||||||
'proto': 'iSCSI',
|
'proto': 'iSCSI',
|
||||||
'hba_id': 'initiator',
|
'hba_id': 'initiator',
|
||||||
'hba_id_type': 'iSCSI initiator IQN',
|
'hba_id_type': 'iSCSI initiator IQN',
|
||||||
@ -34,8 +38,17 @@ _DRIVER_INFO = {
|
|||||||
'volume_backend_name': '%(prefix)siSCSI' % {
|
'volume_backend_name': '%(prefix)siSCSI' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': utils.DRIVER_PREFIX,
|
||||||
},
|
},
|
||||||
'volume_opts': [],
|
|
||||||
'volume_type': 'iscsi',
|
'volume_type': 'iscsi',
|
||||||
|
'param_prefix': utils.PARAM_PREFIX,
|
||||||
|
'vendor_name': utils.VENDOR_NAME,
|
||||||
|
'driver_prefix': utils.DRIVER_PREFIX,
|
||||||
|
'driver_file_prefix': utils.DRIVER_FILE_PREFIX,
|
||||||
|
'target_prefix': utils.TARGET_PREFIX,
|
||||||
|
'hdp_vol_attr': utils.HDP_VOL_ATTR,
|
||||||
|
'hdt_vol_attr': utils.HDT_VOL_ATTR,
|
||||||
|
'nvol_ldev_type': utils.NVOL_LDEV_TYPE,
|
||||||
|
'target_iqn_suffix': utils.TARGET_IQN_SUFFIX,
|
||||||
|
'pair_attr': utils.PAIR_ATTR,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -53,13 +66,14 @@ class HBSDISCSIDriver(driver.ISCSIDriver):
|
|||||||
API for communication with the storage backend.
|
API for communication with the storage backend.
|
||||||
2.1.0 - Add Cinder generic volume groups.
|
2.1.0 - Add Cinder generic volume groups.
|
||||||
2.2.0 - Add maintenance parameters.
|
2.2.0 - Add maintenance parameters.
|
||||||
|
2.2.1 - Make the parameters name variable for supporting OEM storages.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
VERSION = common.VERSION
|
VERSION = utils.VERSION
|
||||||
|
|
||||||
# ThirdPartySystems wiki page
|
# ThirdPartySystems wiki page
|
||||||
CI_WIKI_NAME = "Hitachi_VSP_CI"
|
CI_WIKI_NAME = utils.CI_WIKI_NAME
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
"""Initialize instance variables."""
|
"""Initialize instance variables."""
|
||||||
@ -69,8 +83,11 @@ class HBSDISCSIDriver(driver.ISCSIDriver):
|
|||||||
super(HBSDISCSIDriver, self).__init__(*args, **kwargs)
|
super(HBSDISCSIDriver, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
self.configuration.append_config_values(common.COMMON_VOLUME_OPTS)
|
self.configuration.append_config_values(common.COMMON_VOLUME_OPTS)
|
||||||
self.common = utils.import_object(
|
os.environ['LANG'] = 'C'
|
||||||
self.configuration, _DRIVER_INFO, kwargs.get('db'))
|
self.common = self._init_common(self.configuration, kwargs.get('db'))
|
||||||
|
|
||||||
|
def _init_common(self, conf, db):
|
||||||
|
return rest_iscsi.HBSDRESTISCSI(conf, _DRIVER_INFO, db)
|
||||||
|
|
||||||
def check_for_setup_error(self):
|
def check_for_setup_error(self):
|
||||||
pass
|
pass
|
||||||
|
@ -38,12 +38,6 @@ _LUN_TIMEOUT = 50
|
|||||||
_LUN_RETRY_INTERVAL = 1
|
_LUN_RETRY_INTERVAL = 1
|
||||||
_RESTORE_TIMEOUT = 24 * 60 * 60
|
_RESTORE_TIMEOUT = 24 * 60 * 60
|
||||||
_STATE_TRANSITION_TIMEOUT = 15 * 60
|
_STATE_TRANSITION_TIMEOUT = 15 * 60
|
||||||
PAIR_ATTR = 'HTI'
|
|
||||||
_SNAP_MODE = 'A'
|
|
||||||
_CLONE_MODE = 'C'
|
|
||||||
_NORMAL_MODE = '-'
|
|
||||||
|
|
||||||
_PERMITTED_TYPES = set(['CVS', 'HDP', 'HDT'])
|
|
||||||
|
|
||||||
_CHECK_LDEV_MANAGEABILITY_KEYS = (
|
_CHECK_LDEV_MANAGEABILITY_KEYS = (
|
||||||
'emulationType', 'numOfPorts', 'attributes', 'status')
|
'emulationType', 'numOfPorts', 'attributes', 'status')
|
||||||
@ -75,9 +69,6 @@ _STATUS_TABLE = {
|
|||||||
'SMPP': SMPP,
|
'SMPP': SMPP,
|
||||||
}
|
}
|
||||||
|
|
||||||
SNAP_NAME = 'HBSD-snap'
|
|
||||||
CLONE_NAME = 'HBSD-clone'
|
|
||||||
|
|
||||||
_SNAP_HASH_SIZE = 8
|
_SNAP_HASH_SIZE = 8
|
||||||
|
|
||||||
EX_ENOOBJ = 'EX_ENOOBJ'
|
EX_ENOOBJ = 'EX_ENOOBJ'
|
||||||
@ -202,13 +193,13 @@ LOG = logging.getLogger(__name__)
|
|||||||
MSG = utils.HBSDMsg
|
MSG = utils.HBSDMsg
|
||||||
|
|
||||||
|
|
||||||
def _is_valid_target(target, target_name, target_ports):
|
def _is_valid_target(self, target, target_name, target_ports):
|
||||||
"""Check if the specified target is valid."""
|
"""Check if the specified target is valid."""
|
||||||
return (target[:utils.PORT_ID_LENGTH] in target_ports and
|
return (target[:utils.PORT_ID_LENGTH] in target_ports and
|
||||||
target_name.startswith(utils.TARGET_PREFIX))
|
target_name.startswith(self.driver_info['target_prefix']))
|
||||||
|
|
||||||
|
|
||||||
def _check_ldev_manageability(ldev_info, ldev, existing_ref):
|
def _check_ldev_manageability(self, ldev_info, ldev, existing_ref):
|
||||||
"""Check if the LDEV meets the criteria for being managed."""
|
"""Check if the LDEV meets the criteria for being managed."""
|
||||||
if ldev_info['status'] != NORMAL_STS:
|
if ldev_info['status'] != NORMAL_STS:
|
||||||
msg = utils.output_log(MSG.INVALID_LDEV_FOR_MANAGE)
|
msg = utils.output_log(MSG.INVALID_LDEV_FOR_MANAGE)
|
||||||
@ -216,9 +207,12 @@ def _check_ldev_manageability(ldev_info, ldev, existing_ref):
|
|||||||
existing_ref=existing_ref, reason=msg)
|
existing_ref=existing_ref, reason=msg)
|
||||||
attributes = set(ldev_info['attributes'])
|
attributes = set(ldev_info['attributes'])
|
||||||
if (not ldev_info['emulationType'].startswith('OPEN-V') or
|
if (not ldev_info['emulationType'].startswith('OPEN-V') or
|
||||||
len(attributes) < 2 or not attributes.issubset(_PERMITTED_TYPES)):
|
len(attributes) < 2 or
|
||||||
|
not attributes.issubset(
|
||||||
|
set(['CVS', self.driver_info['hdp_vol_attr'],
|
||||||
|
self.driver_info['hdt_vol_attr']]))):
|
||||||
msg = utils.output_log(MSG.INVALID_LDEV_ATTR_FOR_MANAGE, ldev=ldev,
|
msg = utils.output_log(MSG.INVALID_LDEV_ATTR_FOR_MANAGE, ldev=ldev,
|
||||||
ldevtype=utils.NVOL_LDEV_TYPE)
|
ldevtype=self.driver_info['nvol_ldev_type'])
|
||||||
raise exception.ManageExistingInvalidReference(
|
raise exception.ManageExistingInvalidReference(
|
||||||
existing_ref=existing_ref, reason=msg)
|
existing_ref=existing_ref, reason=msg)
|
||||||
if ldev_info['numOfPorts']:
|
if ldev_info['numOfPorts']:
|
||||||
@ -262,6 +256,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
self.conf.hitachi_storage_id,
|
self.conf.hitachi_storage_id,
|
||||||
self.conf.san_login,
|
self.conf.san_login,
|
||||||
self.conf.san_password,
|
self.conf.san_password,
|
||||||
|
self.driver_info['driver_prefix'],
|
||||||
tcp_keepalive=self.conf.hitachi_rest_tcp_keepalive,
|
tcp_keepalive=self.conf.hitachi_rest_tcp_keepalive,
|
||||||
verify=verify)
|
verify=verify)
|
||||||
self.client.login()
|
self.client.login()
|
||||||
@ -343,12 +338,12 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if not loop.start(interval=interval).wait():
|
if not loop.start(interval=interval).wait():
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.PAIR_STATUS_WAIT_TIMEOUT, svol=ldev)
|
MSG.PAIR_STATUS_WAIT_TIMEOUT, svol=ldev)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
def _create_snap_pair(self, pvol, svol):
|
def _create_snap_pair(self, pvol, svol):
|
||||||
"""Create a snapshot copy pair on the storage."""
|
"""Create a snapshot copy pair on the storage."""
|
||||||
snapshot_name = '%(prefix)s%(svol)s' % {
|
snapshot_name = '%(prefix)s%(svol)s' % {
|
||||||
'prefix': SNAP_NAME,
|
'prefix': self.driver_info['driver_prefix'] + '-snap',
|
||||||
'svol': svol % _SNAP_HASH_SIZE,
|
'svol': svol % _SNAP_HASH_SIZE,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
@ -360,13 +355,14 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
"canCascade": True,
|
"canCascade": True,
|
||||||
"isDataReductionForceCopy": True}
|
"isDataReductionForceCopy": True}
|
||||||
self.client.add_snapshot(body)
|
self.client.add_snapshot(body)
|
||||||
except utils.HBSDError as ex:
|
except exception.VolumeDriverException as ex:
|
||||||
if (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
if (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
||||||
rest_api.INVALID_SNAPSHOT_POOL and
|
rest_api.INVALID_SNAPSHOT_POOL and
|
||||||
not self.conf.hitachi_snap_pool):
|
not self.conf.hitachi_snap_pool):
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_PARAMETER, param='hitachi_snap_pool')
|
MSG.INVALID_PARAMETER,
|
||||||
raise utils.HBSDError(msg)
|
param=self.driver_info['param_prefix'] + '_snap_pool')
|
||||||
|
self.raise_error(msg)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
try:
|
try:
|
||||||
@ -375,14 +371,14 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
try:
|
try:
|
||||||
self._delete_pair_from_storage(pvol, svol)
|
self._delete_pair_from_storage(pvol, svol)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(
|
utils.output_log(
|
||||||
MSG.DELETE_PAIR_FAILED, pvol=pvol, svol=svol)
|
MSG.DELETE_PAIR_FAILED, pvol=pvol, svol=svol)
|
||||||
|
|
||||||
def _create_clone_pair(self, pvol, svol):
|
def _create_clone_pair(self, pvol, svol):
|
||||||
"""Create a clone copy pair on the storage."""
|
"""Create a clone copy pair on the storage."""
|
||||||
snapshot_name = '%(prefix)s%(svol)s' % {
|
snapshot_name = '%(prefix)s%(svol)s' % {
|
||||||
'prefix': CLONE_NAME,
|
'prefix': self.driver_info['driver_prefix'] + '-clone',
|
||||||
'svol': svol % _SNAP_HASH_SIZE,
|
'svol': svol % _SNAP_HASH_SIZE,
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
@ -401,13 +397,14 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
"copySpeed": pace,
|
"copySpeed": pace,
|
||||||
"isDataReductionForceCopy": True}
|
"isDataReductionForceCopy": True}
|
||||||
self.client.add_snapshot(body)
|
self.client.add_snapshot(body)
|
||||||
except utils.HBSDError as ex:
|
except exception.VolumeDriverException as ex:
|
||||||
if (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
if (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
||||||
rest_api.INVALID_SNAPSHOT_POOL and
|
rest_api.INVALID_SNAPSHOT_POOL and
|
||||||
not self.conf.hitachi_snap_pool):
|
not self.conf.hitachi_snap_pool):
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_PARAMETER, param='hitachi_snap_pool')
|
MSG.INVALID_PARAMETER,
|
||||||
raise utils.HBSDError(msg)
|
param=self.driver_info['param_prefix'] + '_snap_pool')
|
||||||
|
self.raise_error(msg)
|
||||||
else:
|
else:
|
||||||
raise
|
raise
|
||||||
try:
|
try:
|
||||||
@ -416,7 +413,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
try:
|
try:
|
||||||
self._delete_pair_from_storage(pvol, svol)
|
self._delete_pair_from_storage(pvol, svol)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(
|
utils.output_log(
|
||||||
MSG.DELETE_PAIR_FAILED, pvol=pvol, svol=svol)
|
MSG.DELETE_PAIR_FAILED, pvol=pvol, svol=svol)
|
||||||
|
|
||||||
@ -444,7 +441,8 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
"""Raise True if the LDEV is no longer in a copy pair."""
|
"""Raise True if the LDEV is no longer in a copy pair."""
|
||||||
ldev_info = self.get_ldev_info(['status', 'attributes'], ldev)
|
ldev_info = self.get_ldev_info(['status', 'attributes'], ldev)
|
||||||
if (ldev_info['status'] != NORMAL_STS or
|
if (ldev_info['status'] != NORMAL_STS or
|
||||||
PAIR_ATTR not in ldev_info['attributes']):
|
self.driver_info['pair_attr'] not in
|
||||||
|
ldev_info['attributes']):
|
||||||
raise loopingcall.LoopingCallDone()
|
raise loopingcall.LoopingCallDone()
|
||||||
if utils.timed_out(
|
if utils.timed_out(
|
||||||
start_time, _STATE_TRANSITION_TIMEOUT):
|
start_time, _STATE_TRANSITION_TIMEOUT):
|
||||||
@ -455,7 +453,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if not loop.start(interval=interval).wait():
|
if not loop.start(interval=interval).wait():
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.PAIR_STATUS_WAIT_TIMEOUT, svol=ldev)
|
MSG.PAIR_STATUS_WAIT_TIMEOUT, svol=ldev)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
def _delete_pair_from_storage(self, pvol, svol):
|
def _delete_pair_from_storage(self, pvol, svol):
|
||||||
"""Disconnect the volume pair that consists of the specified LDEVs."""
|
"""Disconnect the volume pair that consists of the specified LDEVs."""
|
||||||
@ -479,23 +477,23 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
# If the pair status does not satisfy the execution condition,
|
# If the pair status does not satisfy the execution condition,
|
||||||
if not (svol_info['is_psus'] or
|
if not (svol_info['is_psus'] or
|
||||||
_STATUS_TABLE.get(svol_info['status']) == SMPP):
|
_STATUS_TABLE.get(svol_info['status']) == SMPP):
|
||||||
msg = utils.output_log(
|
utils.output_log(
|
||||||
MSG.UNABLE_TO_DELETE_PAIR, pvol=pvol, svol=svol_info['ldev'])
|
MSG.UNABLE_TO_DELETE_PAIR, pvol=pvol, svol=svol_info['ldev'])
|
||||||
raise utils.HBSDBusy(msg)
|
self.raise_busy()
|
||||||
|
|
||||||
self._delete_pair_from_storage(pvol, svol_info['ldev'])
|
self._delete_pair_from_storage(pvol, svol_info['ldev'])
|
||||||
|
|
||||||
def check_param(self):
|
def check_param(self):
|
||||||
"""Check parameter values and consistency among them."""
|
"""Check parameter values and consistency among them."""
|
||||||
super(HBSDREST, self).check_param()
|
super(HBSDREST, self).check_param()
|
||||||
utils.check_opts(self.conf, REST_VOLUME_OPTS)
|
self.check_opts(self.conf, REST_VOLUME_OPTS)
|
||||||
utils.check_opts(self.conf, san.san_opts)
|
self.check_opts(self.conf, san.san_opts)
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
'Setting ldev_range: %s', self.storage_info['ldev_range'])
|
'Setting ldev_range: %s', self.storage_info['ldev_range'])
|
||||||
for opt in _REQUIRED_REST_OPTS:
|
for opt in _REQUIRED_REST_OPTS:
|
||||||
if not self.conf.safe_get(opt):
|
if not self.conf.safe_get(opt):
|
||||||
msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
|
msg = utils.output_log(MSG.INVALID_PARAMETER, param=opt)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
if not self.conf.safe_get('san_api_port'):
|
if not self.conf.safe_get('san_api_port'):
|
||||||
self.conf.san_api_port = _REST_DEFAULT_PORT
|
self.conf.san_api_port = _REST_DEFAULT_PORT
|
||||||
|
|
||||||
@ -552,7 +550,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
lun2 = self._run_add_lun(ldev, port, gid, lun=lun)
|
lun2 = self._run_add_lun(ldev, port, gid, lun=lun)
|
||||||
if lun2 is not None:
|
if lun2 is not None:
|
||||||
targets['lun'][port] = True
|
targets['lun'][port] = True
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.MAP_LDEV_FAILED, ldev=ldev,
|
utils.output_log(MSG.MAP_LDEV_FAILED, ldev=ldev,
|
||||||
port=port, id=gid, lun=lun)
|
port=port, id=gid, lun=lun)
|
||||||
return lun
|
return lun
|
||||||
@ -565,7 +563,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
self.conf.hitachi_group_create):
|
self.conf.hitachi_group_create):
|
||||||
self.create_mapping_targets(targets, connector)
|
self.create_mapping_targets(targets, connector)
|
||||||
|
|
||||||
utils.require_target_existed(targets)
|
self.require_target_existed(targets)
|
||||||
|
|
||||||
targets['list'].sort()
|
targets['list'].sort()
|
||||||
for port in target_ports:
|
for port in target_ports:
|
||||||
@ -578,7 +576,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if not ldev_info['ports']:
|
if not ldev_info['ports']:
|
||||||
return
|
return
|
||||||
for port_info in ldev_info['ports']:
|
for port_info in ldev_info['ports']:
|
||||||
if _is_valid_target(port_info['portId'],
|
if _is_valid_target(self, port_info['portId'],
|
||||||
port_info['hostGroupName'],
|
port_info['hostGroupName'],
|
||||||
target_ports):
|
target_ports):
|
||||||
targets['list'].append(port_info)
|
targets['list'].append(port_info)
|
||||||
@ -631,7 +629,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
try:
|
try:
|
||||||
self.client.delete_host_grp(port, gid)
|
self.client.delete_host_grp(port, gid)
|
||||||
result = 0
|
result = 0
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.DELETE_TARGET_FAILED, port=port, id=gid)
|
utils.output_log(MSG.DELETE_TARGET_FAILED, port=port, id=gid)
|
||||||
else:
|
else:
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
@ -701,7 +699,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if 'errorSource' in result:
|
if 'errorSource' in result:
|
||||||
msg = utils.output_log(MSG.POOL_NOT_FOUND,
|
msg = utils.output_log(MSG.POOL_NOT_FOUND,
|
||||||
pool=self.storage_info['pool_id'])
|
pool=self.storage_info['pool_id'])
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
tp_cap = result['totalPoolCapacity'] / units.Ki
|
tp_cap = result['totalPoolCapacity'] / units.Ki
|
||||||
ta_cap = result['availableVolumeCapacity'] / units.Ki
|
ta_cap = result['availableVolumeCapacity'] / units.Ki
|
||||||
@ -715,7 +713,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
ldev = utils.get_ldev(volume)
|
ldev = utils.get_ldev(volume)
|
||||||
try:
|
try:
|
||||||
self.client.discard_zero_page(ldev)
|
self.client.discard_zero_page(ldev)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.DISCARD_ZERO_PAGE_FAILED, ldev=ldev)
|
utils.output_log(MSG.DISCARD_ZERO_PAGE_FAILED, ldev=ldev)
|
||||||
|
|
||||||
def _get_copy_pair_info(self, ldev):
|
def _get_copy_pair_info(self, ldev):
|
||||||
@ -747,7 +745,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
pair_info = {}
|
pair_info = {}
|
||||||
ldev_info = self.get_ldev_info(['status', 'attributes'], ldev)
|
ldev_info = self.get_ldev_info(['status', 'attributes'], ldev)
|
||||||
if (ldev_info['status'] != NORMAL_STS or
|
if (ldev_info['status'] != NORMAL_STS or
|
||||||
PAIR_ATTR not in ldev_info['attributes']):
|
self.driver_info['pair_attr'] not in ldev_info['attributes']):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
pvol, svol_info = self._get_copy_pair_info(ldev)
|
pvol, svol_info = self._get_copy_pair_info(ldev)
|
||||||
@ -791,7 +789,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
"""Check if the LDEV meets the criteria for being managed."""
|
"""Check if the LDEV meets the criteria for being managed."""
|
||||||
ldev_info = self.get_ldev_info(
|
ldev_info = self.get_ldev_info(
|
||||||
_CHECK_LDEV_MANAGEABILITY_KEYS, ldev)
|
_CHECK_LDEV_MANAGEABILITY_KEYS, ldev)
|
||||||
_check_ldev_manageability(ldev_info, ldev, existing_ref)
|
_check_ldev_manageability(self, ldev_info, ldev, existing_ref)
|
||||||
|
|
||||||
def get_ldev_size_in_gigabyte(self, ldev, existing_ref):
|
def get_ldev_size_in_gigabyte(self, ldev, existing_ref):
|
||||||
"""Return the size[GB] of the specified LDEV."""
|
"""Return the size[GB] of the specified LDEV."""
|
||||||
@ -819,7 +817,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if self.storage_info['pool_id'] is None:
|
if self.storage_info['pool_id'] is None:
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.POOL_NOT_FOUND, pool=self.conf.hitachi_pool)
|
MSG.POOL_NOT_FOUND, pool=self.conf.hitachi_pool)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
snap_pool = self.conf.hitachi_snap_pool
|
snap_pool = self.conf.hitachi_snap_pool
|
||||||
if snap_pool is not None:
|
if snap_pool is not None:
|
||||||
@ -831,7 +829,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if self.storage_info['snap_pool_id'] is None:
|
if self.storage_info['snap_pool_id'] is None:
|
||||||
msg = utils.output_log(MSG.POOL_NOT_FOUND,
|
msg = utils.output_log(MSG.POOL_NOT_FOUND,
|
||||||
pool=self.conf.hitachi_snap_pool)
|
pool=self.conf.hitachi_snap_pool)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
else:
|
else:
|
||||||
self.storage_info['snap_pool_id'] = self.storage_info['pool_id']
|
self.storage_info['snap_pool_id'] = self.storage_info['pool_id']
|
||||||
|
|
||||||
@ -883,7 +881,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
"""Check if the volume have the pair of the snapshot."""
|
"""Check if the volume have the pair of the snapshot."""
|
||||||
ldev_info = self.get_ldev_info(['status', 'attributes'], svol)
|
ldev_info = self.get_ldev_info(['status', 'attributes'], svol)
|
||||||
if (ldev_info['status'] != NORMAL_STS or
|
if (ldev_info['status'] != NORMAL_STS or
|
||||||
PAIR_ATTR not in ldev_info['attributes']):
|
self.driver_info['pair_attr'] not in ldev_info['attributes']):
|
||||||
return False
|
return False
|
||||||
params_s = {"svolLdevId": svol}
|
params_s = {"svolLdevId": svol}
|
||||||
result = self.client.get_snapshots(params_s)
|
result = self.client.get_snapshots(params_s)
|
||||||
@ -908,7 +906,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
else:
|
else:
|
||||||
self.delete_volume(obj)
|
self.delete_volume(obj)
|
||||||
obj_update['status'] = 'deleted'
|
obj_update['status'] = 'deleted'
|
||||||
except (utils.HBSDError, exception.VolumeIsBusy,
|
except (exception.VolumeDriverException, exception.VolumeIsBusy,
|
||||||
exception.SnapshotIsBusy) as exc:
|
exception.SnapshotIsBusy) as exc:
|
||||||
obj_update['status'] = 'available' if isinstance(
|
obj_update['status'] = 'available' if isinstance(
|
||||||
exc, (exception.VolumeIsBusy,
|
exc, (exception.VolumeIsBusy,
|
||||||
@ -954,7 +952,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
MSG.INVALID_LDEV_FOR_VOLUME_COPY,
|
MSG.INVALID_LDEV_FOR_VOLUME_COPY,
|
||||||
type='snapshot' if from_snapshot else 'volume',
|
type='snapshot' if from_snapshot else 'volume',
|
||||||
id=src.id)
|
id=src.id)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
volume_model_update.update(
|
volume_model_update.update(
|
||||||
self.create_volume_from_snapshot(volume, src) if
|
self.create_volume_from_snapshot(volume, src) if
|
||||||
from_snapshot else self.create_cloned_volume(volume,
|
from_snapshot else self.create_cloned_volume(volume,
|
||||||
@ -984,13 +982,13 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
if ldev is not None:
|
if ldev is not None:
|
||||||
new_ldevs.append(ldev)
|
new_ldevs.append(ldev)
|
||||||
if not is_success:
|
if not is_success:
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
except Exception:
|
except Exception:
|
||||||
with excutils.save_and_reraise_exception():
|
with excutils.save_and_reraise_exception():
|
||||||
for new_ldev in new_ldevs:
|
for new_ldev in new_ldevs:
|
||||||
try:
|
try:
|
||||||
self.delete_ldev(new_ldev)
|
self.delete_ldev(new_ldev)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=new_ldev)
|
utils.output_log(MSG.DELETE_LDEV_FAILED, ldev=new_ldev)
|
||||||
return None, volumes_model_update
|
return None, volumes_model_update
|
||||||
|
|
||||||
@ -1003,7 +1001,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
volume_id=volume.id,
|
volume_id=volume.id,
|
||||||
group='consistency group',
|
group='consistency group',
|
||||||
group_id=group.id)
|
group_id=group.id)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
def _create_non_cgsnapshot(self, group_snapshot, snapshots):
|
def _create_non_cgsnapshot(self, group_snapshot, snapshots):
|
||||||
@ -1044,7 +1042,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
now = timeutils.utcnow()
|
now = timeutils.utcnow()
|
||||||
strnow = now.strftime("%y%m%d%H%M%S%f")
|
strnow = now.strftime("%y%m%d%H%M%S%f")
|
||||||
ctg_name = '%(prefix)sC%(ldev)s%(time)s' % {
|
ctg_name = '%(prefix)sC%(ldev)s%(time)s' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
'ldev': "{0:06X}".format(ldev),
|
'ldev': "{0:06X}".format(ldev),
|
||||||
'time': strnow[:len(strnow) - 3],
|
'time': strnow[:len(strnow) - 3],
|
||||||
}
|
}
|
||||||
@ -1054,7 +1052,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
for pair in pairs:
|
for pair in pairs:
|
||||||
try:
|
try:
|
||||||
self._delete_pair_from_storage(pair['pvol'], pair['svol'])
|
self._delete_pair_from_storage(pair['pvol'], pair['svol'])
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.DELETE_PAIR_FAILED, pvol=pair['pvol'],
|
utils.output_log(MSG.DELETE_PAIR_FAILED, pvol=pair['pvol'],
|
||||||
svol=pair['svol'])
|
svol=pair['svol'])
|
||||||
|
|
||||||
@ -1073,19 +1071,21 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
"canCascade": True,
|
"canCascade": True,
|
||||||
"isDataReductionForceCopy": True}
|
"isDataReductionForceCopy": True}
|
||||||
self.client.add_snapshot(body)
|
self.client.add_snapshot(body)
|
||||||
except utils.HBSDError as ex:
|
except exception.VolumeDriverException as ex:
|
||||||
if ((utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
if ((utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
||||||
_MAX_CTG_COUNT_EXCEEDED_ADD_SNAPSHOT) or
|
_MAX_CTG_COUNT_EXCEEDED_ADD_SNAPSHOT) or
|
||||||
(utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
(utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
||||||
_MAX_PAIR_COUNT_IN_CTG_EXCEEDED_ADD_SNAPSHOT)):
|
_MAX_PAIR_COUNT_IN_CTG_EXCEEDED_ADD_SNAPSHOT)):
|
||||||
msg = utils.output_log(MSG.FAILED_CREATE_CTG_SNAPSHOT)
|
msg = utils.output_log(MSG.FAILED_CREATE_CTG_SNAPSHOT)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
elif (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
elif (utils.safe_get_err_code(ex.kwargs.get('errobj')) ==
|
||||||
rest_api.INVALID_SNAPSHOT_POOL and
|
rest_api.INVALID_SNAPSHOT_POOL and
|
||||||
not self.conf.hitachi_snap_pool):
|
not self.conf.hitachi_snap_pool):
|
||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_PARAMETER, param='hitachi_snap_pool')
|
MSG.INVALID_PARAMETER,
|
||||||
raise utils.HBSDError(msg)
|
param=self.driver_info['param_prefix'] +
|
||||||
|
'_snap_pool')
|
||||||
|
self.raise_error(msg)
|
||||||
raise
|
raise
|
||||||
self._wait_copy_pair_status(pair['svol'], PAIR)
|
self._wait_copy_pair_status(pair['svol'], PAIR)
|
||||||
self.client.split_snapshotgroup(snapshotgroup_name)
|
self.client.split_snapshotgroup(snapshotgroup_name)
|
||||||
@ -1108,7 +1108,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_LDEV_FOR_VOLUME_COPY,
|
MSG.INVALID_LDEV_FOR_VOLUME_COPY,
|
||||||
type='volume', id=snapshot.volume_id)
|
type='volume', id=snapshot.volume_id)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
size = snapshot.volume_size
|
size = snapshot.volume_size
|
||||||
pair['svol'] = self.create_ldev(size)
|
pair['svol'] = self.create_ldev(size)
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
@ -1122,7 +1122,7 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
msg = utils.output_log(
|
msg = utils.output_log(
|
||||||
MSG.INVALID_LDEV_FOR_VOLUME_COPY, type='volume',
|
MSG.INVALID_LDEV_FOR_VOLUME_COPY, type='volume',
|
||||||
id=snapshot.volume_id)
|
id=snapshot.volume_id)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
for snapshot in snapshots:
|
for snapshot in snapshots:
|
||||||
loop = loopingcall.FixedIntervalLoopingCall(
|
loop = loopingcall.FixedIntervalLoopingCall(
|
||||||
_create_cgsnapshot_volume, snapshot)
|
_create_cgsnapshot_volume, snapshot)
|
||||||
@ -1136,14 +1136,14 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
msg = pair['msg']
|
msg = pair['msg']
|
||||||
pairs.append(pair)
|
pairs.append(pair)
|
||||||
if not is_success:
|
if not is_success:
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
self._create_ctg_snap_pair(pairs)
|
self._create_ctg_snap_pair(pairs)
|
||||||
except Exception:
|
except Exception:
|
||||||
for pair in pairs:
|
for pair in pairs:
|
||||||
if 'svol' in pair and pair['svol'] is not None:
|
if 'svol' in pair and pair['svol'] is not None:
|
||||||
try:
|
try:
|
||||||
self.delete_ldev(pair['svol'])
|
self.delete_ldev(pair['svol'])
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(
|
utils.output_log(
|
||||||
MSG.DELETE_LDEV_FAILED, ldev=pair['svol'])
|
MSG.DELETE_LDEV_FAILED, ldev=pair['svol'])
|
||||||
model_update = {'status': fields.GroupSnapshotStatus.ERROR}
|
model_update = {'status': fields.GroupSnapshotStatus.ERROR}
|
||||||
@ -1169,26 +1169,41 @@ class HBSDREST(common.HBSDCommon):
|
|||||||
def init_timer_values(self):
|
def init_timer_values(self):
|
||||||
global _LUN_TIMEOUT, _LUN_RETRY_INTERVAL
|
global _LUN_TIMEOUT, _LUN_RETRY_INTERVAL
|
||||||
global _RESTORE_TIMEOUT, _STATE_TRANSITION_TIMEOUT
|
global _RESTORE_TIMEOUT, _STATE_TRANSITION_TIMEOUT
|
||||||
_LUN_TIMEOUT = self.conf.hitachi_lun_timeout
|
_LUN_TIMEOUT = self.conf.safe_get(
|
||||||
_LUN_RETRY_INTERVAL = self.conf.hitachi_lun_retry_interval
|
self.driver_info['param_prefix'] + '_lun_timeout')
|
||||||
_RESTORE_TIMEOUT = self.conf.hitachi_restore_timeout
|
_LUN_RETRY_INTERVAL = self.conf.safe_get(
|
||||||
_STATE_TRANSITION_TIMEOUT = self.conf.hitachi_state_transition_timeout
|
self.driver_info['param_prefix'] + '_lun_retry_interval')
|
||||||
rest_api._LOCK_TIMEOUT = self.conf.hitachi_lock_timeout
|
_RESTORE_TIMEOUT = self.conf.safe_get(
|
||||||
rest_api._REST_TIMEOUT = self.conf.hitachi_rest_timeout
|
self.driver_info['param_prefix'] + '_restore_timeout')
|
||||||
rest_api._EXTEND_TIMEOUT = self.conf.hitachi_extend_timeout
|
_STATE_TRANSITION_TIMEOUT = self.conf.safe_get(
|
||||||
rest_api._EXEC_RETRY_INTERVAL = self.conf.hitachi_exec_retry_interval
|
self.driver_info['param_prefix'] + '_state_transition_timeout')
|
||||||
rest_api._DEFAULT_CONNECT_TIMEOUT = (
|
rest_api._LOCK_TIMEOUT = self.conf.safe_get(
|
||||||
self.conf.hitachi_rest_connect_timeout)
|
self.driver_info['param_prefix'] + '_lock_timeout')
|
||||||
rest_api._JOB_API_RESPONSE_TIMEOUT = (
|
rest_api._REST_TIMEOUT = self.conf.safe_get(
|
||||||
self.conf.hitachi_rest_job_api_response_timeout)
|
self.driver_info['param_prefix'] + '_rest_timeout')
|
||||||
rest_api._GET_API_RESPONSE_TIMEOUT = (
|
rest_api._EXTEND_TIMEOUT = self.conf.safe_get(
|
||||||
self.conf.hitachi_rest_get_api_response_timeout)
|
self.driver_info['param_prefix'] + '_extend_timeout')
|
||||||
rest_api._REST_SERVER_BUSY_TIMEOUT = (
|
rest_api._EXEC_RETRY_INTERVAL = self.conf.safe_get(
|
||||||
self.conf.hitachi_rest_server_busy_timeout)
|
self.driver_info['param_prefix'] + '_exec_retry_interval')
|
||||||
rest_api._KEEP_SESSION_LOOP_INTERVAL = (
|
rest_api._DEFAULT_CONNECT_TIMEOUT = self.conf.safe_get(
|
||||||
self.conf.hitachi_rest_keep_session_loop_interval)
|
self.driver_info['param_prefix'] + '_rest_connect_timeout')
|
||||||
rest_api._ANOTHER_LDEV_MAPPED_RETRY_TIMEOUT = (
|
rest_api._JOB_API_RESPONSE_TIMEOUT = self.conf.safe_get(
|
||||||
self.conf.hitachi_rest_another_ldev_mapped_retry_timeout)
|
self.driver_info['param_prefix'] +
|
||||||
rest_api._TCP_KEEPIDLE = self.conf.hitachi_rest_tcp_keepidle
|
'_rest_job_api_response_timeout')
|
||||||
rest_api._TCP_KEEPINTVL = self.conf.hitachi_rest_tcp_keepintvl
|
rest_api._GET_API_RESPONSE_TIMEOUT = self.conf.safe_get(
|
||||||
rest_api._TCP_KEEPCNT = self.conf.hitachi_rest_tcp_keepcnt
|
self.driver_info['param_prefix'] +
|
||||||
|
'_rest_get_api_response_timeout')
|
||||||
|
rest_api._REST_SERVER_BUSY_TIMEOUT = self.conf.safe_get(
|
||||||
|
self.driver_info['param_prefix'] + '_rest_server_busy_timeout')
|
||||||
|
rest_api._KEEP_SESSION_LOOP_INTERVAL = self.conf.safe_get(
|
||||||
|
self.driver_info['param_prefix'] +
|
||||||
|
'_rest_keep_session_loop_interval')
|
||||||
|
rest_api._ANOTHER_LDEV_MAPPED_RETRY_TIMEOUT = self.conf.safe_get(
|
||||||
|
self.driver_info['param_prefix'] +
|
||||||
|
'_rest_another_ldev_mapped_retry_timeout')
|
||||||
|
rest_api._TCP_KEEPIDLE = self.conf.safe_get(
|
||||||
|
self.driver_info['param_prefix'] + '_rest_tcp_keepidle')
|
||||||
|
rest_api._TCP_KEEPINTVL = self.conf.safe_get(
|
||||||
|
self.driver_info['param_prefix'] + '_rest_tcp_keepintvl')
|
||||||
|
rest_api._TCP_KEEPCNT = self.conf.safe_get(
|
||||||
|
self.driver_info['param_prefix'] + '_rest_tcp_keepcnt')
|
||||||
|
@ -29,6 +29,8 @@ from requests.adapters import HTTPAdapter
|
|||||||
from requests.packages.urllib3.connection import HTTPConnection
|
from requests.packages.urllib3.connection import HTTPConnection
|
||||||
from requests.packages.urllib3.poolmanager import PoolManager
|
from requests.packages.urllib3.poolmanager import PoolManager
|
||||||
|
|
||||||
|
from cinder import exception
|
||||||
|
from cinder.i18n import _
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
||||||
from cinder.volume import volume_utils
|
from cinder.volume import volume_utils
|
||||||
|
|
||||||
@ -217,7 +219,7 @@ class ResponseData(dict):
|
|||||||
class RestApiClient():
|
class RestApiClient():
|
||||||
|
|
||||||
def __init__(self, ip_addr, ip_port, storage_device_id,
|
def __init__(self, ip_addr, ip_port, storage_device_id,
|
||||||
user_id, user_pass, tcp_keepalive=False,
|
user_id, user_pass, driver_prefix, tcp_keepalive=False,
|
||||||
verify=False, connect_timeout=_DEFAULT_CONNECT_TIMEOUT):
|
verify=False, connect_timeout=_DEFAULT_CONNECT_TIMEOUT):
|
||||||
"""Initialize instance variables."""
|
"""Initialize instance variables."""
|
||||||
self.ip_addr = ip_addr
|
self.ip_addr = ip_addr
|
||||||
@ -244,6 +246,7 @@ class RestApiClient():
|
|||||||
}
|
}
|
||||||
self.headers = {"content-type": "application/json",
|
self.headers = {"content-type": "application/json",
|
||||||
"accept": "application/json"}
|
"accept": "application/json"}
|
||||||
|
self.driver_prefix = driver_prefix
|
||||||
|
|
||||||
class Session(requests.auth.AuthBase):
|
class Session(requests.auth.AuthBase):
|
||||||
|
|
||||||
@ -312,7 +315,13 @@ class RestApiClient():
|
|||||||
MSG.REST_SERVER_CONNECT_FAILED,
|
MSG.REST_SERVER_CONNECT_FAILED,
|
||||||
exception=type(e), message=e,
|
exception=type(e), message=e,
|
||||||
method=method, url=url, params=params, body=body)
|
method=method, url=url, params=params, body=body)
|
||||||
raise utils.HBSDError(msg)
|
message = _(
|
||||||
|
'%(prefix)s error occurred. %(msg)s' % {
|
||||||
|
'prefix': self.driver_prefix,
|
||||||
|
'msg': msg,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raise exception.VolumeDriverException(message)
|
||||||
|
|
||||||
response = ResponseData(rsp)
|
response = ResponseData(rsp)
|
||||||
if (response['status_code'] == httpclient.INTERNAL_SERVER_ERROR and
|
if (response['status_code'] == httpclient.INTERNAL_SERVER_ERROR and
|
||||||
@ -348,7 +357,14 @@ class RestApiClient():
|
|||||||
params=params, body=body,
|
params=params, body=body,
|
||||||
**response.get_errobj())
|
**response.get_errobj())
|
||||||
if kwargs['do_raise']:
|
if kwargs['do_raise']:
|
||||||
raise utils.HBSDError(msg, errobj=errobj)
|
message = _(
|
||||||
|
'%(prefix)s error occurred. %(msg)s' % {
|
||||||
|
'prefix': self.driver_prefix,
|
||||||
|
'msg': msg,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raise exception.VolumeDriverException(
|
||||||
|
message, errobj=errobj)
|
||||||
return False, rsp_body, errobj
|
return False, rsp_body, errobj
|
||||||
else:
|
else:
|
||||||
LOG.debug("The resource group to which the operation object ",
|
LOG.debug("The resource group to which the operation object ",
|
||||||
@ -402,7 +418,14 @@ class RestApiClient():
|
|||||||
method=method, url=url,
|
method=method, url=url,
|
||||||
params=params, body=body)
|
params=params, body=body)
|
||||||
if kwargs['do_raise']:
|
if kwargs['do_raise']:
|
||||||
raise utils.HBSDError(msg, errobj=errobj)
|
message = _(
|
||||||
|
'%(prefix)s error occurred. %(msg)s' % {
|
||||||
|
'prefix': self.driver_prefix,
|
||||||
|
'msg': msg,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raise exception.VolumeDriverException(
|
||||||
|
message, errobj=errobj)
|
||||||
return False, rsp_body, errobj
|
return False, rsp_body, errobj
|
||||||
|
|
||||||
if errobj:
|
if errobj:
|
||||||
@ -425,7 +448,14 @@ class RestApiClient():
|
|||||||
method=method, url=url,
|
method=method, url=url,
|
||||||
params=params, body=body)
|
params=params, body=body)
|
||||||
if kwargs['do_raise']:
|
if kwargs['do_raise']:
|
||||||
raise utils.HBSDError(msg, errobj=errobj)
|
message = _(
|
||||||
|
'%(prefix)s error occurred. %(msg)s' % {
|
||||||
|
'prefix': self.driver_prefix,
|
||||||
|
'msg': msg,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
raise exception.VolumeDriverException(
|
||||||
|
message, errobj=errobj)
|
||||||
return retry, rsp_body, errobj
|
return retry, rsp_body, errobj
|
||||||
|
|
||||||
def set_my_session(self, session):
|
def set_my_session(self, session):
|
||||||
@ -469,7 +499,7 @@ class RestApiClient():
|
|||||||
if session is not None:
|
if session is not None:
|
||||||
self.get_session(session.id, no_retry=True, no_log=True)
|
self.get_session(session.id, no_retry=True, no_log=True)
|
||||||
has_session = True
|
has_session = True
|
||||||
except utils.HBSDError as ex:
|
except exception.VolumeDriverException as ex:
|
||||||
LOG.debug('Failed to get session info: %s', ex)
|
LOG.debug('Failed to get session info: %s', ex)
|
||||||
return has_session
|
return has_session
|
||||||
|
|
||||||
|
@ -14,17 +14,32 @@
|
|||||||
#
|
#
|
||||||
"""REST interface fibre channel module for Hitachi HBSD Driver."""
|
"""REST interface fibre channel module for Hitachi HBSD Driver."""
|
||||||
|
|
||||||
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
|
from cinder import exception
|
||||||
|
from cinder.volume import configuration
|
||||||
from cinder.volume.drivers.hitachi import hbsd_rest as rest
|
from cinder.volume.drivers.hitachi import hbsd_rest as rest
|
||||||
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
from cinder.volume.drivers.hitachi import hbsd_utils as utils
|
||||||
from cinder.zonemanager import utils as fczm_utils
|
from cinder.zonemanager import utils as fczm_utils
|
||||||
|
|
||||||
|
FC_VOLUME_OPTS = [
|
||||||
|
cfg.BoolOpt(
|
||||||
|
'hitachi_zoning_request',
|
||||||
|
default=False,
|
||||||
|
help='If True, the driver will configure FC zoning between the server '
|
||||||
|
'and the storage system provided that FC zoning manager is '
|
||||||
|
'enabled.'),
|
||||||
|
]
|
||||||
|
|
||||||
_FC_HMO_DISABLE_IO = 91
|
_FC_HMO_DISABLE_IO = 91
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
MSG = utils.HBSDMsg
|
MSG = utils.HBSDMsg
|
||||||
|
|
||||||
|
CONF = cfg.CONF
|
||||||
|
CONF.register_opts(FC_VOLUME_OPTS, group=configuration.SHARED_CONF_GROUP)
|
||||||
|
|
||||||
|
|
||||||
class HBSDRESTFC(rest.HBSDREST):
|
class HBSDRESTFC(rest.HBSDREST):
|
||||||
"""REST interface fibre channel class for Hitachi HBSD Driver."""
|
"""REST interface fibre channel class for Hitachi HBSD Driver."""
|
||||||
@ -89,11 +104,16 @@ class HBSDRESTFC(rest.HBSDREST):
|
|||||||
utils.output_log(MSG.SET_CONFIG_VALUE, object='port-wwn list',
|
utils.output_log(MSG.SET_CONFIG_VALUE, object='port-wwn list',
|
||||||
value=self.storage_info['wwns'])
|
value=self.storage_info['wwns'])
|
||||||
|
|
||||||
|
def check_param(self):
|
||||||
|
"""Check parameter values and consistency among them."""
|
||||||
|
super(HBSDRESTFC, self).check_param()
|
||||||
|
self.check_opts(self.conf, FC_VOLUME_OPTS)
|
||||||
|
|
||||||
def create_target_to_storage(self, port, connector, hba_ids):
|
def create_target_to_storage(self, port, connector, hba_ids):
|
||||||
"""Create a host group on the specified port."""
|
"""Create a host group on the specified port."""
|
||||||
wwpns = self.get_hba_ids_from_connector(connector)
|
wwpns = self.get_hba_ids_from_connector(connector)
|
||||||
target_name = '%(prefix)s-%(wwpns)s' % {
|
target_name = '%(prefix)s-%(wwpns)s' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
'wwpns': min(wwpns),
|
'wwpns': min(wwpns),
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
@ -116,13 +136,13 @@ class HBSDRESTFC(rest.HBSDREST):
|
|||||||
try:
|
try:
|
||||||
self.client.add_hba_wwn(port, gid, wwn, no_log=True)
|
self.client.add_hba_wwn(port, gid, wwn, no_log=True)
|
||||||
registered_wwns.append(wwn)
|
registered_wwns.append(wwn)
|
||||||
except utils.HBSDError:
|
except exception.VolumeDriverException:
|
||||||
utils.output_log(MSG.ADD_HBA_WWN_FAILED, port=port, gid=gid,
|
utils.output_log(MSG.ADD_HBA_WWN_FAILED, port=port, gid=gid,
|
||||||
wwn=wwn)
|
wwn=wwn)
|
||||||
if not registered_wwns:
|
if not registered_wwns:
|
||||||
msg = utils.output_log(MSG.NO_HBA_WWN_ADDED_TO_HOST_GRP, port=port,
|
msg = utils.output_log(MSG.NO_HBA_WWN_ADDED_TO_HOST_GRP, port=port,
|
||||||
gid=gid)
|
gid=gid)
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
|
|
||||||
def set_target_mode(self, port, gid):
|
def set_target_mode(self, port, gid):
|
||||||
"""Configure the host group to meet the environment."""
|
"""Configure the host group to meet the environment."""
|
||||||
@ -193,14 +213,14 @@ class HBSDRESTFC(rest.HBSDREST):
|
|||||||
wwpns = self.get_hba_ids_from_connector(connector)
|
wwpns = self.get_hba_ids_from_connector(connector)
|
||||||
target_names = [
|
target_names = [
|
||||||
'%(prefix)s-%(wwpns)s' % {
|
'%(prefix)s-%(wwpns)s' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
'wwpns': min(wwpns),
|
'wwpns': min(wwpns),
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
if 'ip' in connector:
|
if 'ip' in connector:
|
||||||
target_names.append(
|
target_names.append(
|
||||||
'%(prefix)s-%(ip)s' % {
|
'%(prefix)s-%(ip)s' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
'ip': connector['ip'],
|
'ip': connector['ip'],
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -91,14 +91,14 @@ class HBSDRESTISCSI(rest.HBSDREST):
|
|||||||
def create_target_to_storage(self, port, connector, hba_ids):
|
def create_target_to_storage(self, port, connector, hba_ids):
|
||||||
"""Create an iSCSI target on the specified port."""
|
"""Create an iSCSI target on the specified port."""
|
||||||
target_name = '%(prefix)s-%(ip)s' % {
|
target_name = '%(prefix)s-%(ip)s' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
'ip': connector['ip'],
|
'ip': connector['ip'],
|
||||||
}
|
}
|
||||||
body = {'portId': port, 'hostGroupName': target_name}
|
body = {'portId': port, 'hostGroupName': target_name}
|
||||||
if hba_ids:
|
if hba_ids:
|
||||||
body['iscsiName'] = '%(id)s%(suffix)s' % {
|
body['iscsiName'] = '%(id)s%(suffix)s' % {
|
||||||
'id': hba_ids,
|
'id': hba_ids,
|
||||||
'suffix': utils.TARGET_IQN_SUFFIX,
|
'suffix': self.driver_info['target_iqn_suffix'],
|
||||||
}
|
}
|
||||||
try:
|
try:
|
||||||
gid = self.client.add_host_grp(body, no_log=True)
|
gid = self.client.add_host_grp(body, no_log=True)
|
||||||
@ -184,7 +184,7 @@ class HBSDRESTISCSI(rest.HBSDREST):
|
|||||||
targets['info'][port] = False
|
targets['info'][port] = False
|
||||||
if 'ip' in connector:
|
if 'ip' in connector:
|
||||||
target_name = '%(prefix)s-%(ip)s' % {
|
target_name = '%(prefix)s-%(ip)s' % {
|
||||||
'prefix': utils.DRIVER_PREFIX,
|
'prefix': self.driver_info['driver_prefix'],
|
||||||
'ip': connector['ip'],
|
'ip': connector['ip'],
|
||||||
}
|
}
|
||||||
if self._set_target_info_by_name(
|
if self._set_target_info_by_name(
|
||||||
@ -215,7 +215,7 @@ class HBSDRESTISCSI(rest.HBSDREST):
|
|||||||
if not iqn:
|
if not iqn:
|
||||||
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
msg = utils.output_log(MSG.RESOURCE_NOT_FOUND,
|
||||||
resource='Target IQN')
|
resource='Target IQN')
|
||||||
raise utils.HBSDError(msg)
|
self.raise_error(msg)
|
||||||
targets['iqns'][target] = iqn
|
targets['iqns'][target] = iqn
|
||||||
LOG.debug(
|
LOG.debug(
|
||||||
'Found target iqn of host group. (port: %(port)s, '
|
'Found target iqn of host group. (port: %(port)s, '
|
||||||
|
@ -16,34 +16,31 @@
|
|||||||
|
|
||||||
import enum
|
import enum
|
||||||
import logging as base_logging
|
import logging as base_logging
|
||||||
import os
|
|
||||||
|
|
||||||
from oslo_config import cfg
|
from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
from oslo_utils import excutils
|
from oslo_utils import excutils
|
||||||
from oslo_utils import importutils
|
|
||||||
from oslo_utils import timeutils
|
from oslo_utils import timeutils
|
||||||
from oslo_utils import units
|
from oslo_utils import units
|
||||||
|
|
||||||
from cinder import exception
|
from cinder import exception
|
||||||
from cinder.i18n import _
|
|
||||||
|
|
||||||
_DRIVER_DIR = 'cinder.volume.drivers.hitachi'
|
|
||||||
|
|
||||||
_DRIVERS = {
|
|
||||||
'REST': {
|
|
||||||
'FC': 'hbsd_rest_fc.HBSDRESTFC',
|
|
||||||
'iSCSI': 'hbsd_rest_iscsi.HBSDRESTISCSI',
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
|
VERSION = '2.2.1'
|
||||||
|
CI_WIKI_NAME = 'Hitachi_VSP_CI'
|
||||||
|
PARAM_PREFIX = 'hitachi'
|
||||||
|
VENDOR_NAME = 'Hitachi'
|
||||||
DRIVER_PREFIX = 'HBSD'
|
DRIVER_PREFIX = 'HBSD'
|
||||||
|
DRIVER_FILE_PREFIX = 'hbsd'
|
||||||
TARGET_PREFIX = 'HBSD-'
|
TARGET_PREFIX = 'HBSD-'
|
||||||
|
HDP_VOL_ATTR = 'HDP'
|
||||||
|
HDT_VOL_ATTR = 'HDT'
|
||||||
|
NVOL_LDEV_TYPE = 'DP-VOL'
|
||||||
TARGET_IQN_SUFFIX = '.hbsd-target'
|
TARGET_IQN_SUFFIX = '.hbsd-target'
|
||||||
|
PAIR_ATTR = 'HTI'
|
||||||
|
|
||||||
GIGABYTE_PER_BLOCK_SIZE = units.Gi / 512
|
GIGABYTE_PER_BLOCK_SIZE = units.Gi / 512
|
||||||
|
|
||||||
NORMAL_LDEV_TYPE = 'Normal'
|
NORMAL_LDEV_TYPE = 'Normal'
|
||||||
NVOL_LDEV_TYPE = 'DP-VOL'
|
|
||||||
|
|
||||||
INFO_SUFFIX = 'I'
|
INFO_SUFFIX = 'I'
|
||||||
WARNING_SUFFIX = 'W'
|
WARNING_SUFFIX = 'W'
|
||||||
@ -51,13 +48,7 @@ ERROR_SUFFIX = 'E'
|
|||||||
|
|
||||||
PORT_ID_LENGTH = 5
|
PORT_ID_LENGTH = 5
|
||||||
|
|
||||||
|
BUSY_MESSAGE = "Device or resource is busy."
|
||||||
class HBSDError(exception.VolumeDriverException):
|
|
||||||
message = _("HBSD error occurred. %(message)s")
|
|
||||||
|
|
||||||
|
|
||||||
class HBSDBusy(HBSDError):
|
|
||||||
message = _("Device or resource is busy.")
|
|
||||||
|
|
||||||
|
|
||||||
@enum.unique
|
@enum.unique
|
||||||
@ -464,18 +455,6 @@ def timed_out(start_time, timeout):
|
|||||||
return timeutils.is_older_than(start_time, timeout)
|
return timeutils.is_older_than(start_time, timeout)
|
||||||
|
|
||||||
|
|
||||||
def import_object(conf, driver_info, db):
|
|
||||||
"""Import a class and return an instance of it."""
|
|
||||||
os.environ['LANG'] = 'C'
|
|
||||||
cli = _DRIVERS.get('REST')
|
|
||||||
return importutils.import_object(
|
|
||||||
'%(dir)s.%(proto)s' % {
|
|
||||||
'dir': _DRIVER_DIR,
|
|
||||||
'proto': cli[driver_info['proto']],
|
|
||||||
},
|
|
||||||
conf, driver_info, db)
|
|
||||||
|
|
||||||
|
|
||||||
def check_opt_value(conf, names):
|
def check_opt_value(conf, names):
|
||||||
"""Check if the parameter names and values are valid."""
|
"""Check if the parameter names and values are valid."""
|
||||||
for name in names:
|
for name in names:
|
||||||
@ -486,24 +465,6 @@ def check_opt_value(conf, names):
|
|||||||
output_log(MSG.INVALID_PARAMETER, param=name)
|
output_log(MSG.INVALID_PARAMETER, param=name)
|
||||||
|
|
||||||
|
|
||||||
def check_opts(conf, opts):
|
|
||||||
"""Check if the specified configuration is valid."""
|
|
||||||
names = []
|
|
||||||
for opt in opts:
|
|
||||||
if opt.required and not conf.safe_get(opt.name):
|
|
||||||
msg = output_log(MSG.INVALID_PARAMETER, param=opt.name)
|
|
||||||
raise HBSDError(msg)
|
|
||||||
names.append(opt.name)
|
|
||||||
check_opt_value(conf, names)
|
|
||||||
|
|
||||||
|
|
||||||
def require_target_existed(targets):
|
|
||||||
"""Check if the target list includes one or more members."""
|
|
||||||
if not targets['list']:
|
|
||||||
msg = output_log(MSG.NO_CONNECTED_TARGET)
|
|
||||||
raise HBSDError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def build_initiator_target_map(connector, target_wwns, lookup_service):
|
def build_initiator_target_map(connector, target_wwns, lookup_service):
|
||||||
"""Return a dictionary mapping server-wwns and lists of storage-wwns."""
|
"""Return a dictionary mapping server-wwns and lists of storage-wwns."""
|
||||||
init_targ_map = {}
|
init_targ_map = {}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user