The 3PAR REST API server has a limited number of active sessions.
This change to the driver removes the ability of keeping the
REST API session alive for the life of the driver. Now on every
driver entry point, which is synchronized, we login to the 3PAR
and when the work is complete, we log out of the 3PAR. This has
the side affect of more overhead to the 3PAR but helps eliminate
failed commands due to maximum sessions reached to the 3PAR.
This patch also changes the locking to be the same lock for all
driver entry points and adds locking around the volume stats.
This patch also migrates all of the client code access to the common
class, which simplifies the drivers.
Change-Id: Ibcec4cf1781262521ccbdf99c4ba4167634a09c4
'desc': "HOST '%s' was not found" % hostname}
raise hpexceptions.HTTPNotFound(msg)
else:
- self._hosts[hostname] = None
+ del self._hosts[hostname]
def fake_create_3par_vlun(self, volume, hostname):
- self.driver.client.createVLUN(volume, 19, hostname)
+ self.driver.common.client.createVLUN(volume, 19, hostname)
def fake_get_ports(self):
return {'FC': self.FAKE_FC_PORTS, 'iSCSI': self.FAKE_ISCSI_PORTS}
self.flags(lock_path=self.tempdir)
self.driver.delete_volume(self.volume)
self.assertRaises(hpexceptions.HTTPNotFound,
- self.driver.client.getVolume,
+ self.driver.common.client.getVolume,
self.VOLUME_ID)
def test_create_snapshot(self):
self.driver.create_snapshot(self.snapshot)
# check to see if the snapshot was created
- snap_vol = self.driver.client.getVolume(self.SNAPSHOT_3PAR_NAME)
+ snap_vol = self.driver.common.client.getVolume(self.SNAPSHOT_3PAR_NAME)
self.assertEqual(snap_vol['name'], self.SNAPSHOT_3PAR_NAME)
def test_delete_snapshot(self):
self.driver.create_snapshot(self.snapshot)
#make sure it exists first
- vol = self.driver.client.getVolume(self.SNAPSHOT_3PAR_NAME)
+ vol = self.driver.common.client.getVolume(self.SNAPSHOT_3PAR_NAME)
self.assertEqual(vol['name'], self.SNAPSHOT_3PAR_NAME)
self.driver.delete_snapshot(self.snapshot)
# the snapshot should be deleted now
self.assertRaises(hpexceptions.HTTPNotFound,
- self.driver.client.getVolume,
+ self.driver.common.client.getVolume,
self.SNAPSHOT_3PAR_NAME)
def test_create_volume_from_snapshot(self):
self.flags(lock_path=self.tempdir)
self.driver.create_volume_from_snapshot(self.volume, self.snapshot)
- snap_vol = self.driver.client.getVolume(self.VOLUME_3PAR_NAME)
+ snap_vol = self.driver.common.client.getVolume(self.VOLUME_3PAR_NAME)
self.assertEqual(snap_vol['name'], self.VOLUME_3PAR_NAME)
volume = self.volume.copy()
self.flags(lock_path=self.tempdir)
#setup the connections
self.driver.initialize_connection(self.volume, self.connector)
- vlun = self.driver.client.getVLUN(self.VOLUME_3PAR_NAME)
+ vlun = self.driver.common.client.getVLUN(self.VOLUME_3PAR_NAME)
self.assertEqual(vlun['volumeName'], self.VOLUME_3PAR_NAME)
self.driver.terminate_connection(self.volume, self.connector, True)
# vlun should be gone.
self.assertRaises(hpexceptions.HTTPNotFound,
- self.driver.client.getVLUN,
+ self.driver.common.client.getVLUN,
self.VOLUME_3PAR_NAME)
configuration.san_password = 'test'
configuration.hp3par_snapshot_expiration = ""
configuration.hp3par_snapshot_retention = ""
- self.stubs.Set(hpfcdriver.HP3PARFCDriver, "_create_client",
+ self.stubs.Set(hpfcdriver.hpcommon.HP3PARCommon, "_create_client",
self.fake_create_client)
self.stubs.Set(hpfcdriver.HP3PARFCDriver,
"_create_3par_fibrechan_host",
host = self.fake_get_3par_host(self.FAKE_HOST)
self.assertEquals(self.FAKE_HOST, host['name'])
self.assertEquals(HP3PAR_DOMAIN, host['domain'])
- vlun = self.driver.client.getVLUN(self.VOLUME_3PAR_NAME)
+ vlun = self.driver.common.client.getVLUN(self.VOLUME_3PAR_NAME)
self.assertEquals(self.VOLUME_3PAR_NAME, vlun['volumeName'])
self.assertEquals(self.FAKE_HOST, vlun['hostname'])
self.assertEquals(stats['free_capacity_gb'], 'infinite')
#modify the CPG to have a limit
- old_cpg = self.driver.client.getCPG(HP3PAR_CPG)
+ old_cpg = self.driver.common.client.getCPG(HP3PAR_CPG)
options = {'SDGrowth': {'limitMiB': 8192}}
- self.driver.client.deleteCPG(HP3PAR_CPG)
- self.driver.client.createCPG(HP3PAR_CPG, options)
+ self.driver.common.client.deleteCPG(HP3PAR_CPG)
+ self.driver.common.client.createCPG(HP3PAR_CPG, options)
const = 0.0009765625
stats = self.driver.get_volume_stats(True)
self.assertEquals(stats['total_capacity_gb'], total_capacity_gb)
free_capacity_gb = int((8192 - old_cpg['UsrUsage']['usedMiB']) * const)
self.assertEquals(stats['free_capacity_gb'], free_capacity_gb)
- self.driver.client.deleteCPG(HP3PAR_CPG)
- self.driver.client.createCPG(HP3PAR_CPG, {})
+ self.driver.common.client.deleteCPG(HP3PAR_CPG)
+ self.driver.common.client.createCPG(HP3PAR_CPG, {})
def test_create_host(self):
self.flags(lock_path=self.tempdir)
configuration.hp3par_snapshot_expiration = ""
configuration.hp3par_snapshot_retention = ""
- self.stubs.Set(hpdriver.HP3PARISCSIDriver, "_create_client",
+ self.stubs.Set(hpdriver.hpcommon.HP3PARCommon, "_create_client",
self.fake_create_client)
self.stubs.Set(hpdriver.HP3PARISCSIDriver,
"_iscsi_discover_target_iqn",
host = self.fake_get_3par_host(self.FAKE_HOST)
self.assertEquals(self.FAKE_HOST, host['name'])
self.assertEquals(HP3PAR_DOMAIN, host['domain'])
- vlun = self.driver.client.getVLUN(self.VOLUME_3PAR_NAME)
+ vlun = self.driver.common.client.getVLUN(self.VOLUME_3PAR_NAME)
self.assertEquals(self.VOLUME_3PAR_NAME, vlun['volumeName'])
self.assertEquals(self.FAKE_HOST, vlun['hostname'])
self.assertEquals(stats['free_capacity_gb'], 'infinite')
#modify the CPG to have a limit
- old_cpg = self.driver.client.getCPG(HP3PAR_CPG)
+ old_cpg = self.driver.common.client.getCPG(HP3PAR_CPG)
options = {'SDGrowth': {'limitMiB': 8192}}
- self.driver.client.deleteCPG(HP3PAR_CPG)
- self.driver.client.createCPG(HP3PAR_CPG, options)
+ self.driver.common.client.deleteCPG(HP3PAR_CPG)
+ self.driver.common.client.createCPG(HP3PAR_CPG, options)
const = 0.0009765625
stats = self.driver.get_volume_stats(True)
self.assertEquals(stats['total_capacity_gb'], total_capacity_gb)
free_capacity_gb = int((8192 - old_cpg['UsrUsage']['usedMiB']) * const)
self.assertEquals(stats['free_capacity_gb'], free_capacity_gb)
- self.driver.client.deleteCPG(HP3PAR_CPG)
- self.driver.client.createCPG(HP3PAR_CPG, {})
+ self.driver.common.client.deleteCPG(HP3PAR_CPG)
+ self.driver.common.client.createCPG(HP3PAR_CPG, {})
def test_create_host(self):
self.flags(lock_path=self.tempdir)
import uuid
from eventlet import greenthread
+from hp3parclient import client
from hp3parclient import exceptions as hpexceptions
from oslo.config import cfg
]
-class HP3PARCommon():
+class HP3PARCommon(object):
stats = {}
self.sshpool = None
self.config = config
self.hosts_naming_dict = dict()
+ self.client = None
def check_flags(self, options, required_flags):
for flag in required_flags:
if not getattr(options, flag, None):
raise exception.InvalidInput(reason=_('%s is not set') % flag)
+ def _create_client(self):
+ return client.HP3ParClient(self.config.hp3par_api_url)
+
+ def client_login(self):
+ try:
+ LOG.debug("Connecting to 3PAR")
+ self.client.login(self.config.hp3par_username,
+ self.config.hp3par_password)
+ except hpexceptions.HTTPUnauthorized as ex:
+ LOG.warning("Failed to connect to 3PAR (%s) because %s" %
+ (self.config.hp3par_api_url, str(ex)))
+ msg = _("Login to 3PAR array invalid")
+ raise exception.InvalidInput(reason=msg)
+
+ def client_logout(self):
+ self.client.logout()
+ LOG.debug("Disconnect from 3PAR")
+
+ def do_setup(self, context):
+ self.client = self._create_client()
+ if self.config.hp3par_debug:
+ self.client.debug_rest(True)
+
+ self.client_login()
+
+ # make sure the CPG exists
+ try:
+ cpg = self.client.getCPG(self.config.hp3par_cpg)
+ except hpexceptions.HTTPNotFound as ex:
+ err = (_("CPG (%s) doesn't exist on array")
+ % self.config.hp3par_cpg)
+ LOG.error(err)
+ raise exception.InvalidInput(reason=err)
+
+ if ('domain' not in cpg
+ and cpg['domain'] != self.config.hp3par_domain):
+ err = ("CPG's domain '%s' and config option hp3par_domain '%s'"
+ " must be the same" %
+ (cpg['domain'], self.config.hp3par_domain))
+ LOG.error(err)
+ raise exception.InvalidInput(reason=err)
+
+ self.client_logout()
+
def _get_3par_vol_name(self, volume_id):
"""
Converts the openstack volume id from
LOG.debug("PORTS = %s" % pprint.pformat(ports))
return ports
- def get_volume_stats(self, refresh, client):
+ def get_volume_stats(self, refresh):
if refresh:
- self._update_volume_stats(client)
+ self._update_volume_stats()
return self.stats
- def _update_volume_stats(self, client):
+ def _update_volume_stats(self):
# const to convert MiB to GB
const = 0.0009765625
'volume_backend_name': None}
try:
- cpg = client.getCPG(self.config.hp3par_cpg)
+ cpg = self.client.getCPG(self.config.hp3par_cpg)
if 'limitMiB' not in cpg['SDGrowth']:
total_capacity = 'infinite'
free_capacity = 'infinite'
self.stats = stats
- def create_vlun(self, volume, host, client):
+ def create_vlun(self, volume, host):
"""
In order to export a volume on a 3PAR box, we have to
create a VLUN.
"""
volume_name = self._get_3par_vol_name(volume['id'])
self._create_3par_vlun(volume_name, host['name'])
- return client.getVLUN(volume_name)
+ return self.client.getVLUN(volume_name)
- def delete_vlun(self, volume, hostname, client):
+ def delete_vlun(self, volume, hostname):
volume_name = self._get_3par_vol_name(volume['id'])
- vlun = client.getVLUN(volume_name)
- client.deleteVLUN(volume_name, vlun['lun'], hostname)
+ vlun = self.client.getVLUN(volume_name)
+ self.client.deleteVLUN(volume_name, vlun['lun'], hostname)
self._delete_3par_host(hostname)
def _get_volume_type(self, type_id):
persona_id = persona_value.split(' ')
return persona_id[0]
- def create_volume(self, volume, client):
+ def create_volume(self, volume):
LOG.debug("CREATE VOLUME (%s : %s %s)" %
(volume['display_name'], volume['name'],
self._get_3par_vol_name(volume['id'])))
capacity = self._capacity_from_size(volume['size'])
volume_name = self._get_3par_vol_name(volume['id'])
- client.createVolume(volume_name, cpg, capacity, extras)
+ self.client.createVolume(volume_name, cpg, capacity, extras)
except hpexceptions.HTTPConflict:
raise exception.Duplicate(_("Volume (%s) already exists on array")
word = re.search(search_string.strip(' ') + ' ([^ ]*)', s)
return word.groups()[0].strip(' ')
- @utils.synchronized('3parclone', external=True)
- def create_cloned_volume(self, volume, src_vref, client):
+ def create_cloned_volume(self, volume, src_vref):
try:
orig_name = self._get_3par_vol_name(volume['source_volid'])
vol_name = self._get_3par_vol_name(volume['id'])
# We need to create a new volume first. Otherwise you
# can't delete the original
- new_vol = self.create_volume(volume, client)
+ new_vol = self.create_volume(volume)
# make the 3PAR copy the contents.
# can't delete the original until the copy is done.
return None
- def delete_volume(self, volume, client):
+ def delete_volume(self, volume):
try:
volume_name = self._get_3par_vol_name(volume['id'])
- client.deleteVolume(volume_name)
+ self.client.deleteVolume(volume_name)
except hpexceptions.HTTPNotFound as ex:
# We'll let this act as if it worked
# it helps clean up the cinder entries.
LOG.error(str(ex))
raise exception.CinderException(ex.get_description())
- def create_volume_from_snapshot(self, volume, snapshot, client):
+ def create_volume_from_snapshot(self, volume, snapshot):
"""
Creates a volume from a snapshot.
optional = {'comment': json.dumps(extra),
'readOnly': False}
- client.createSnapshot(vol_name, snap_name, optional)
+ self.client.createSnapshot(vol_name, snap_name, optional)
except hpexceptions.HTTPForbidden:
raise exception.NotAuthorized()
except hpexceptions.HTTPNotFound:
raise exception.NotFound()
- def create_snapshot(self, snapshot, client):
+ def create_snapshot(self, snapshot):
LOG.debug("Create Snapshot\n%s" % pprint.pformat(snapshot))
try:
optional['retentionHours'] = (
self.config.hp3par_snapshot_retention)
- client.createSnapshot(snap_name, vol_name, optional)
+ self.client.createSnapshot(snap_name, vol_name, optional)
except hpexceptions.HTTPForbidden:
raise exception.NotAuthorized()
except hpexceptions.HTTPNotFound:
raise exception.NotFound()
- def delete_snapshot(self, snapshot, client):
+ def delete_snapshot(self, snapshot):
LOG.debug("Delete Snapshot\n%s" % pprint.pformat(snapshot))
try:
snap_name = self._get_3par_snap_name(snapshot['id'])
- client.deleteVolume(snap_name)
+ self.client.deleteVolume(snap_name)
except hpexceptions.HTTPForbidden:
raise exception.NotAuthorized()
except hpexceptions.HTTPNotFound as ex:
if (wwn_iqn.upper() in showhost.upper()):
return showhost.split(',')[1]
- def terminate_connection(self, volume, hostname, wwn_iqn, client):
+ def terminate_connection(self, volume, hostname, wwn_iqn):
""" Driver entry point to unattach a volume from an instance."""
try:
# does 3par know this host by a different name?
if hostname in self.hosts_naming_dict:
hostname = self.hosts_naming_dict.get(hostname)
- self.delete_vlun(volume, hostname, client)
+ self.delete_vlun(volume, hostname)
return
except hpexceptions.HTTPNotFound as e:
if 'host does not exist' in e.get_description():
raise
#try again with name retrieved from 3par
- self.delete_vlun(volume, hostname, client)
+ self.delete_vlun(volume, hostname)
def parse_create_host_error(self, hostname, out):
search_str = "already used by host "
volume_driver=cinder.volume.drivers.san.hp.hp_3par_fc.HP3PARFCDriver
"""
-from hp3parclient import client
from hp3parclient import exceptions as hpexceptions
from oslo.config import cfg
def __init__(self, *args, **kwargs):
super(HP3PARFCDriver, self).__init__(*args, **kwargs)
- self.client = None
self.common = None
self.configuration.append_config_values(hpcommon.hp3par_opts)
self.configuration.append_config_values(san.san_opts)
'san_ip', 'san_login', 'san_password']
self.common.check_flags(self.configuration, required_flags)
- def _create_client(self):
- return client.HP3ParClient(self.configuration.hp3par_api_url)
-
+ @utils.synchronized('3par', external=True)
def get_volume_stats(self, refresh):
- stats = self.common.get_volume_stats(refresh, self.client)
+ self.common.client_login()
+ stats = self.common.get_volume_stats(refresh)
stats['storage_protocol'] = 'FC'
backend_name = self.configuration.safe_get('volume_backend_name')
stats['volume_backend_name'] = backend_name or self.__class__.__name__
+ self.common.client_logout()
return stats
def do_setup(self, context):
self.common = self._init_common()
self._check_flags()
- self.client = self._create_client()
- if self.configuration.hp3par_debug:
- self.client.debug_rest(True)
-
- try:
- LOG.debug("Connecting to 3PAR")
- self.client.login(self.configuration.hp3par_username,
- self.configuration.hp3par_password)
- except hpexceptions.HTTPUnauthorized as ex:
- LOG.warning("Failed to connect to 3PAR (%s) because %s" %
- (self.configuration.hp3par_api_url, str(ex)))
- msg = _("Login to 3PAR array invalid")
- raise exception.InvalidInput(reason=msg)
-
- # make sure the CPG exists
- try:
- cpg = self.client.getCPG(self.configuration.hp3par_cpg)
- except hpexceptions.HTTPNotFound as ex:
- err = (_("CPG (%s) doesn't exist on array")
- % self.configuration.hp3par_cpg)
- LOG.error(err)
- raise exception.InvalidInput(reason=err)
-
- if ('domain' not in cpg
- and cpg['domain'] != self.configuration.hp3par_domain):
- err = "CPG's domain '%s' and config option hp3par_domain '%s' \
-must be the same" % (cpg['domain'], self.configuration.hp3par_domain)
- LOG.error(err)
- raise exception.InvalidInput(reason=err)
+ self.common.do_setup(context)
def check_for_setup_error(self):
"""Returns an error if prerequisites aren't met."""
self._check_flags()
- @utils.synchronized('3par-vol', external=True)
+ @utils.synchronized('3par', external=True)
def create_volume(self, volume):
- metadata = self.common.create_volume(volume, self.client)
+ self.common.client_login()
+ metadata = self.common.create_volume(volume)
+ self.common.client_logout()
return {'metadata': metadata}
+ @utils.synchronized('3par', external=True)
def create_cloned_volume(self, volume, src_vref):
- new_vol = self.common.create_cloned_volume(volume, src_vref,
- self.client)
+ self.common.client_login()
+ new_vol = self.common.create_cloned_volume(volume, src_vref)
+ self.common.client_logout()
return {'metadata': new_vol}
- @utils.synchronized('3par-vol', external=True)
+ @utils.synchronized('3par', external=True)
def delete_volume(self, volume):
- self.common.delete_volume(volume, self.client)
+ self.common.client_login()
+ self.common.delete_volume(volume)
+ self.common.client_logout()
- @utils.synchronized('3par-vol', external=True)
+ @utils.synchronized('3par', external=True)
def create_volume_from_snapshot(self, volume, snapshot):
"""
Creates a volume from a snapshot.
TODO: support using the size from the user.
"""
- self.common.create_volume_from_snapshot(volume, snapshot, self.client)
+ self.common.client_login()
+ self.common.create_volume_from_snapshot(volume, snapshot)
+ self.common.client_logout()
- @utils.synchronized('3par-snap', external=True)
+ @utils.synchronized('3par', external=True)
def create_snapshot(self, snapshot):
- self.common.create_snapshot(snapshot, self.client)
+ self.common.client_login()
+ self.common.create_snapshot(snapshot)
+ self.common.client_logout()
- @utils.synchronized('3par-snap', external=True)
+ @utils.synchronized('3par', external=True)
def delete_snapshot(self, snapshot):
- self.common.delete_snapshot(snapshot, self.client)
+ self.common.client_login()
+ self.common.delete_snapshot(snapshot)
+ self.common.client_logout()
- @utils.synchronized('3par-attach', external=True)
+ @utils.synchronized('3par', external=True)
def initialize_connection(self, volume, connector):
"""Assigns the volume to a server.
* Create a VLUN for that HOST with the volume we want to export.
"""
+ self.common.client_login()
# we have to make sure we have a host
host = self._create_host(volume, connector)
# now that we have a host, create the VLUN
- vlun = self.common.create_vlun(volume, host, self.client)
+ vlun = self.common.create_vlun(volume, host)
ports = self.common.get_ports()
+ self.common.client_logout()
info = {'driver_volume_type': 'fibre_channel',
'data': {'target_lun': vlun['lun'],
'target_discovered': True,
'target_wwn': ports['FC']}}
return info
- @utils.synchronized('3par-attach', external=True)
+ @utils.synchronized('3par', external=True)
def terminate_connection(self, volume, connector, force):
"""Driver entry point to unattach a volume from an instance."""
+ self.common.client_login()
self.common.terminate_connection(volume,
connector['host'],
- connector['wwpns'],
- self.client)
+ connector['wwpns'])
+ self.common.client_logout()
def _create_3par_fibrechan_host(self, hostname, wwn, domain, persona_id):
"""Create a 3PAR host.
return host
- @utils.synchronized('3par-exp', external=True)
+ @utils.synchronized('3par', external=True)
def create_export(self, context, volume):
pass
- @utils.synchronized('3par-exp', external=True)
+ @utils.synchronized('3par', external=True)
def ensure_export(self, context, volume):
pass
- @utils.synchronized('3par-exp', external=True)
+ @utils.synchronized('3par', external=True)
def remove_export(self, context, volume):
pass
volume_driver=cinder.volume.drivers.san.hp.hp_3par_iscsi.HP3PARISCSIDriver
"""
-from hp3parclient import client
from hp3parclient import exceptions as hpexceptions
from cinder import exception
"""
def __init__(self, *args, **kwargs):
super(HP3PARISCSIDriver, self).__init__(*args, **kwargs)
- self.client = None
self.common = None
self.configuration.append_config_values(hpcommon.hp3par_opts)
self.configuration.append_config_values(san.san_opts)
'san_password']
self.common.check_flags(self.configuration, required_flags)
- def _create_client(self):
- return client.HP3ParClient(self.configuration.hp3par_api_url)
-
+ @utils.synchronized('3par', external=True)
def get_volume_stats(self, refresh):
- stats = self.common.get_volume_stats(refresh, self.client)
+ self.common.client_login()
+ stats = self.common.get_volume_stats(refresh)
stats['storage_protocol'] = 'iSCSI'
backend_name = self.configuration.safe_get('volume_backend_name')
stats['volume_backend_name'] = backend_name or self.__class__.__name__
+ self.common.client_logout()
return stats
def do_setup(self, context):
self.common = self._init_common()
self._check_flags()
- self.client = self._create_client()
- if self.configuration.hp3par_debug:
- self.client.debug_rest(True)
-
- try:
- LOG.debug("Connecting to 3PAR")
- self.client.login(self.configuration.hp3par_username,
- self.configuration.hp3par_password)
- except hpexceptions.HTTPUnauthorized as ex:
- LOG.warning("Failed to connect to 3PAR (%s) because %s" %
- (self.configuration.hp3par_api_url, str(ex)))
- msg = _("Login to 3PAR array invalid")
- raise exception.InvalidInput(reason=msg)
-
- # make sure the CPG exists
- try:
- cpg = self.client.getCPG(self.configuration.hp3par_cpg)
- except hpexceptions.HTTPNotFound as ex:
- err = (_("CPG (%s) doesn't exist on array")
- % self.configuration.hp3par_cpg)
- LOG.error(err)
- raise exception.InvalidInput(reason=err)
-
- if ('domain' not in cpg and
- cpg['domain'] != self.configuration.hp3par_domain):
- err = "CPG's domain '%s' and config option hp3par_domain '%s' \
-must be the same" % (cpg['domain'], self.configuration.hp3par_domain)
- LOG.error(err)
- raise exception.InvalidInput(reason=err)
+ self.common.do_setup(context)
# make sure ssh works.
self._iscsi_discover_target_iqn(self.configuration.iscsi_ip_address)
"""Returns an error if prerequisites aren't met."""
self._check_flags()
- @utils.synchronized('3par-vol', external=True)
+ @utils.synchronized('3par', external=True)
def create_volume(self, volume):
- metadata = self.common.create_volume(volume, self.client)
+ self.common.client_login()
+ metadata = self.common.create_volume(volume)
+ self.common.client_logout()
return {'provider_location': "%s:%s" %
(self.configuration.iscsi_ip_address,
self.configuration.iscsi_port),
'metadata': metadata}
+ @utils.synchronized('3par', external=True)
def create_cloned_volume(self, volume, src_vref):
""" Clone an existing volume. """
- new_vol = self.common.create_cloned_volume(volume, src_vref,
- self.client)
+ self.common.client_login()
+ new_vol = self.common.create_cloned_volume(volume, src_vref)
+ self.common.client_logout()
+
return {'provider_location': "%s:%s" %
(self.configuration.iscsi_ip_address,
self.configuration.iscsi_port),
'metadata': new_vol}
- @utils.synchronized('3par-vol', external=True)
+ @utils.synchronized('3par', external=True)
def delete_volume(self, volume):
- self.common.delete_volume(volume, self.client)
+ self.common.client_login()
+ self.common.delete_volume(volume)
+ self.common.client_logout()
- @utils.synchronized('3par-vol', external=True)
+ @utils.synchronized('3par', external=True)
def create_volume_from_snapshot(self, volume, snapshot):
"""
Creates a volume from a snapshot.
TODO: support using the size from the user.
"""
- self.common.create_volume_from_snapshot(volume, snapshot, self.client)
+ self.common.client_login()
+ self.common.create_volume_from_snapshot(volume, snapshot)
+ self.common.client_logout()
- @utils.synchronized('3par-snap', external=True)
+ @utils.synchronized('3par', external=True)
def create_snapshot(self, snapshot):
- self.common.create_snapshot(snapshot, self.client)
+ self.common.client_login()
+ self.common.create_snapshot(snapshot)
+ self.common.client_logout()
- @utils.synchronized('3par-snap', external=True)
+ @utils.synchronized('3par', external=True)
def delete_snapshot(self, snapshot):
- self.common.delete_snapshot(snapshot, self.client)
+ self.common.client_login()
+ self.common.delete_snapshot(snapshot)
+ self.common.client_logout()
- @utils.synchronized('3par-attach', external=True)
+ @utils.synchronized('3par', external=True)
def initialize_connection(self, volume, connector):
"""Assigns the volume to a server.
* Create a host on the 3par
* create vlun on the 3par
"""
+ self.common.client_login()
# get the target_iqn on the 3par interface.
target_iqn = self._iscsi_discover_target_iqn(
self.configuration.iscsi_ip_address)
host = self._create_host(volume, connector)
# now that we have a host, create the VLUN
- vlun = self.common.create_vlun(volume, host, self.client)
+ vlun = self.common.create_vlun(volume, host)
+ self.common.client_logout()
info = {'driver_volume_type': 'iscsi',
'data': {'target_portal': "%s:%s" %
(self.configuration.iscsi_ip_address,
}
return info
- @utils.synchronized('3par-attach', external=True)
+ @utils.synchronized('3par', external=True)
def terminate_connection(self, volume, connector, force):
"""Driver entry point to unattach a volume from an instance."""
+ self.common.client_login()
self.common.terminate_connection(volume,
connector['host'],
- connector['initiator'],
- self.client)
+ connector['initiator'])
+ self.common.client_logout()
def _iscsi_discover_target_iqn(self, remote_ip):
result = self.common._cli_run('showport -ids', None)
return host
- @utils.synchronized('3par-exp', external=True)
+ @utils.synchronized('3par', external=True)
def create_export(self, context, volume):
pass
- @utils.synchronized('3par-exp', external=True)
+ @utils.synchronized('3par', external=True)
def ensure_export(self, context, volume):
pass
- @utils.synchronized('3par-exp', external=True)
+ @utils.synchronized('3par', external=True)
def remove_export(self, context, volume):
pass