#
-# (c) Copyright 2013-2014 Hewlett-Packard Development Company, L.P.
+# (c) Copyright 2013 Hewlett-Packard Development Company, L.P.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
HP3PAR_SAN_SSH_PRIVATE = 'foobar'
-class HP3PARBaseDriver():
+class HP3PARBaseDriver(object):
VOLUME_ID = 'd03338a9-9115-48a3-8dfc-35cdfcdc15a7'
CLONE_ID = 'd03338a9-9115-48a3-8dfc-000000000000'
self.VOLUME_3PAR_NAME,
'osv-0DM4qZEVSKON-AAAAAAAAA',
HP3PAR_CPG,
- HP3PAR_CPG_SNAP, True),
+ {'snapCPG': 'OpenStackCPGSnap', 'tpvv': True,
+ 'online': True}),
mock.call.logout()]
mock_client.assert_has_calls(expected)
# and return the mock HTTP 3PAR client
mock_client = self.setup_driver()
mock_client.getPorts.return_value = {
- 'members': [{
- 'portPos': {'node': 0, 'slot': 8, 'cardPort': 2},
- 'protocol': 2,
- 'IPAddr': '10.10.120.252',
- 'linkState': 4,
- 'device': [],
- 'iSCSIName': 'iqn.2000-05.com.3pardata:21810002ac00383d',
- 'mode': 2,
- 'HWAddr': '2C27D75375D2',
- 'type': 8}, {
- 'portPos': {'node': 1, 'slot': 8, 'cardPort': 1},
- 'protocol': 2,
- 'IPAddr': '10.10.220.253',
- 'linkState': 4,
- 'device': [],
- 'iSCSIName': 'iqn.2000-05.com.3pardata:21810002ac00383d',
- 'mode': 2,
- 'HWAddr': '2C27D75375D6',
- 'type': 8}, {
- 'portWWN': '20210002AC00383D',
- 'protocol': 1,
- 'linkState': 4,
- 'mode': 2,
- 'device': ['cage2'],
- 'nodeWWN': '20210002AC00383D',
- 'type': 2,
- 'portPos': {'node': 0, 'slot': 6, 'cardPort': 3}}]}
+ 'members': [
+ {'portPos': {'node': 0, 'slot': 8, 'cardPort': 2},
+ 'protocol': 2,
+ 'IPAddr': '10.10.120.252',
+ 'linkState': 4,
+ 'device': [],
+ 'iSCSIName': 'iqn.2000-05.com.3pardata:21810002ac00383d',
+ 'mode': 2,
+ 'HWAddr': '2C27D75375D2',
+ 'type': 8},
+ {'portPos': {'node': 1, 'slot': 8, 'cardPort': 1},
+ 'protocol': 2,
+ 'IPAddr': '10.10.220.253',
+ 'linkState': 4,
+ 'device': [],
+ 'iSCSIName': 'iqn.2000-05.com.3pardata:21810002ac00383d',
+ 'mode': 2,
+ 'HWAddr': '2C27D75375D6',
+ 'type': 8},
+ {'portWWN': '20210002AC00383D',
+ 'protocol': 1,
+ 'linkState': 4,
+ 'mode': 2,
+ 'device': ['cage2'],
+ 'nodeWWN': '20210002AC00383D',
+ 'type': 2,
+ 'portPos': {'node': 0, 'slot': 6, 'cardPort': 3}}]}
ports = self.driver.common.get_ports()['members']
self.assertEqual(len(ports), 3)
conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getCPG(HP3PAR_CPG),
- mock.call.setHighConnections(),
mock.call.logout()]
mock_client.assert_has_calls(expected)
mock_client.reset_mock()
conn_timeout=HP3PAR_SAN_SSH_CON_TIMEOUT),
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getCPG(HP3PAR_CPG),
- mock.call.setHighConnections(),
mock.call.logout(),
mock.call.login(HP3PAR_USER_NAME, HP3PAR_USER_PASS),
mock.call.getPorts(),
mock_client = self.setup_driver()
mock_client.getVolume.return_value = {'userCPG': HP3PAR_CPG}
mock_client.getCPG.return_value = {}
- mock_client.getHost.side_effect = [{
- 'name': self.FAKE_HOST, 'FCPaths': []}, {
- 'name': self.FAKE_HOST,
- 'FCPaths': [{'wwn': '123456789012345'}, {
- 'wwn': '123456789054321'}]}]
+ mock_client.getHost.side_effect = [
+ {'name': self.FAKE_HOST, 'FCPaths': []},
+ {'name': self.FAKE_HOST,
+ 'FCPaths': [{'wwn': '123456789012345'},
+ {'wwn': '123456789054321'}]}]
host = self.driver._create_host(self.volume, self.connector)
config.iscsi_ip_address = '10.10.10.10'
mock_conf = {
'getPorts.return_value': {
- 'members': [{
- 'portPos': {'node': 1, 'slot': 8, 'cardPort': 2},
- 'protocol': 2,
- 'IPAddr': '10.10.220.252',
- 'linkState': 4,
- 'device': [],
- 'iSCSIName': self.TARGET_IQN,
- 'mode': 2,
- 'HWAddr': '2C27D75375D2',
- 'type': 8}, {
- 'portPos': {'node': 1, 'slot': 8, 'cardPort': 1},
- 'protocol': 2,
- 'IPAddr': '10.10.220.253',
- 'linkState': 4,
- 'device': [],
- 'iSCSIName': self.TARGET_IQN,
- 'mode': 2,
- 'HWAddr': '2C27D75375D6',
- 'type': 8}]}}
+ 'members': [
+ {'portPos': {'node': 1, 'slot': 8, 'cardPort': 2},
+ 'protocol': 2,
+ 'IPAddr': '10.10.220.252',
+ 'linkState': 4,
+ 'device': [],
+ 'iSCSIName': self.TARGET_IQN,
+ 'mode': 2,
+ 'HWAddr': '2C27D75375D2',
+ 'type': 8},
+ {'portPos': {'node': 1, 'slot': 8, 'cardPort': 1},
+ 'protocol': 2,
+ 'IPAddr': '10.10.220.253',
+ 'linkState': 4,
+ 'device': [],
+ 'iSCSIName': self.TARGET_IQN,
+ 'mode': 2,
+ 'HWAddr': '2C27D75375D6',
+ 'type': 8}]}}
# no valid ip addr should be configured.
self.assertRaises(exception.InvalidInput,
"""
Volume driver common utilities for HP 3PAR Storage array
-The 3PAR drivers requires 3.1.2 MU3 firmware on the 3PAR array.
+The 3PAR drivers requires 3.1.3 firmware on the 3PAR array.
You will need to install the python hp3parclient.
sudo pip install hp3parclient
LOG = logging.getLogger(__name__)
-MIN_CLIENT_VERSION = '2.9.0'
+MIN_CLIENT_VERSION = '3.0.0'
hp3par_opts = [
cfg.StrOpt('hp3par_api_url',
1.2.6 - Allow optional specifying n:s:p for vlun creation bug #1269515
This update now requires 3.1.2 MU3 firmware
1.3.0 - Removed all SSH code. We rely on the hp3parclient now.
+ 2.0.0 - Update hp3parclient API uses 3.0.x
"""
- VERSION = "1.3.0"
+ VERSION = "2.0.0"
stats = {}
try:
# make sure the default CPG exists
self.validate_cpg(self.config.hp3par_cpg)
- self.client.setHighConnections()
finally:
self.client_logout()
try:
self._delete_3par_host(hostname)
+ self._remove_hosts_naming_dict_host(hostname)
except hpexceptions.HTTPConflict as ex:
# host will only be removed after all vluns
# have been removed
else:
raise
+ def _remove_hosts_naming_dict_host(self, hostname):
+ items = self.hosts_naming_dict.items()
+ lkey = None
+ for key, value in items:
+ if value == hostname:
+ lkey = key
+ if lkey is not None:
+ del self.hosts_naming_dict[lkey]
+
def _get_volume_type(self, type_id):
ctxt = context.get_admin_context()
return volume_types.get_volume_type(ctxt, type_id)
tpvv=True):
# Virtual volume sets are not supported with the -online option
LOG.debug('Creating clone of a volume %s' % src_name)
- self.client.copyVolume(src_name, dest_name, cpg,
- snap_cpg, tpvv)
+ optional = {'tpvv': tpvv, 'online': True}
+ if snap_cpg is not None:
+ optional['snapCPG'] = snap_cpg
+
+ self.client.copyVolume(src_name, dest_name, cpg, optional)
def get_next_word(self, s, search_string):
"""Return the next word.
# volume set name in the error.
try:
self.client.deleteVolume(volume_name)
+ except hpexceptions.HTTPBadRequest as ex:
+ if ex.get_code() == 29:
+ if self.client.isOnlinePhysicalCopy(volume_name):
+ LOG.debug(_("Found an online copy for %(volume)s")
+ % {'volume': volume_name})
+ # the volume is in process of being cloned.
+ # stopOnlinePhysicalCopy will also delete
+ # the volume once it stops the copy.
+ self.client.stopOnlinePhysicalCopy(volume_name)
+ else:
+ LOG.error(str(ex))
+ raise ex
+ else:
+ LOG.error(str(ex))
+ raise ex
except hpexceptions.HTTPConflict as ex:
if ex.get_code() == 34:
# This is a special case which means the
#
"""
Volume driver for HP 3PAR Storage array.
-This driver requires 3.1.2 MU2 firmware on the 3PAR array, using
-the 2.x version of the hp3parclient.
+This driver requires 3.1.3 firmware on the 3PAR array, using
+the 3.x version of the hp3parclient.
You will need to install the python hp3parclient.
-sudo pip install --upgrade "hp3parclient>=2.0"
+sudo pip install --upgrade "hp3parclient>=3.0"
Set the following in the cinder.conf file to enable the
3PAR Fibre Channel Driver along with the required flags:
1.2.3 - Added ability to add WWNs to host.
1.2.4 - Added metadata during attach/detach bug #1258033.
1.3.0 - Removed all SSH code. We rely on the hp3parclient now.
+ 2.0.0 - Update hp3parclient API uses 3.0.x
"""
- VERSION = "1.3.0"
+ VERSION = "2.0.0"
def __init__(self, *args, **kwargs):
super(HP3PARFCDriver, self).__init__(*args, **kwargs)
@utils.synchronized('3par', external=True)
def extend_volume(self, volume, new_size):
- self.common.extend_volume(volume, new_size)
+ self.common.client_login()
+ try:
+ self.common.extend_volume(volume, new_size)
+ finally:
+ self.common.client_logout()
@utils.synchronized('3par', external=True)
def attach_volume(self, context, volume, instance_uuid, host_name,
#
"""
Volume driver for HP 3PAR Storage array.
-This driver requires 3.1.2 MU3 firmware on the 3PAR array, using
-the 2.x version of the hp3parclient.
+This driver requires 3.1.3 firmware on the 3PAR array, using
+the 3.x version of the hp3parclient.
You will need to install the python hp3parclient.
-sudo pip install --upgrade "hp3parclient>=2.0"
+sudo pip install --upgrade "hp3parclient>=3.0"
Set the following in the cinder.conf file to enable the
3PAR iSCSI Driver along with the required flags:
1.2.6 - Use least-used iscsi n:s:p for iscsi volume attach bug #1269515
This update now requires 3.1.2 MU3 firmware
1.3.0 - Removed all SSH code. We rely on the hp3parclient now.
+ 2.0.0 - Update hp3parclient API uses 3.0.x
"""
- VERSION = "1.3.0"
+ VERSION = "2.0.0"
def __init__(self, *args, **kwargs):
super(HP3PARISCSIDriver, self).__init__(*args, **kwargs)
@utils.synchronized('3par', external=True)
def extend_volume(self, volume, new_size):
- self.common.extend_volume(volume, new_size)
+ self.common.client_login()
+ try:
+ self.common.extend_volume(volume, new_size)
+ finally:
+ self.common.client_logout()
@utils.synchronized('3par', external=True)
def attach_volume(self, context, volume, instance_uuid, host_name,