"""
iSCSI Cinder Volume driver for Hitachi Unified Storage (HUS-HNAS) platform.
"""
-
+import os
from xml.etree import ElementTree as ETree
from oslo.utils import excutils
from oslo_config import cfg
from cinder import exception
-from cinder.i18n import _LE, _LI
+from cinder.i18n import _LE, _LI, _LW
from cinder.openstack.common import log as logging
from cinder.volume import driver
from cinder.volume.drivers.hds.hnas_backend import HnasBackend
def _loc_info(loc):
"""Parse info from location string."""
- LOG.info("Parse_loc: %s" % loc)
+ LOG.info(_LI("Parse_loc: %s"), loc)
info = {}
tup = loc.split(',')
if len(tup) < 5:
try:
val = root.findtext(element)
- LOG.info(_LI("%(element)s: %(val)s")
- % {'element': element,
- 'val': val})
+ LOG.info(_LI("%(element)s: %(val)s"), {'element': element, 'val': val})
if val:
return val.strip()
if check:
except ETree.ParseError:
if check:
with excutils.save_and_reraise_exception():
- LOG.error(_LE("XML exception reading "
- "parameter: %s") % element)
+ LOG.error(_LE("XML exception reading parameter: %s"), element)
else:
- LOG.info(_LI("XML exception reading parameter: %s") % element)
+ LOG.info(_LI("XML exception reading parameter: %s"), element)
return None
def _read_config(xml_config_file):
"""Read hds driver specific xml config file."""
+ if not os.access(xml_config_file, os.R_OK):
+ raise exception.NotFound(_LE("Can't open config file: %s"),
+ xml_config_file)
+
try:
root = ETree.parse(xml_config_file).getroot()
except Exception:
- raise exception.NotFound(message='config file not found: '
- + xml_config_file)
+ raise exception.ConfigNotFound(_LE("Error parsing config file: %s"),
+ xml_config_file)
# mandatory parameters
config = {}
self.type = 'HNAS'
self.platform = self.type.lower()
- LOG.info(_LI("Backend type: %s") % self.type)
+ LOG.info(_LI("Backend type: %s"), self.type)
self.bend = factory_bend(self.type)
def _array_info_get(self):
conf[ip]['ctl'] = ctl
conf[ip]['port'] = port
conf[ip]['iscsi_port'] = ipp
- msg = ('portal: %(ip)s:%(ipp)s, CTL: %(ctl)s, port: %(port)s')
- LOG.debug(msg
- % {'ip': ip,
- 'ipp': ipp,
- 'ctl': ctl,
- 'port': port})
+ msg = "portal: %(ip)s:%(ipp)s, CTL: %(ctl)s, port: %(pt)s"
+ LOG.debug(msg, {'ip': ip, 'ipp': ipp, 'ctl': ctl, 'pt': port})
return conf
if label not in self.config['services'].keys():
# default works if no match is found
label = 'default'
- LOG.info(_LI("Using default: instead of %s") % label)
- LOG.info(_LI("Available services: %s")
- % self.config['services'].keys())
+ LOG.info(_LI("Using default: instead of %s"), label)
+ LOG.info(_LI("Available services: %s"),
+ self.config['services'].keys())
if label in self.config['services'].keys():
svc = self.config['services'][label]
if self.config['chap_enabled'] == 'True':
# it may not exist, create and set secret
if 'iscsi_secret' not in svc:
- LOG.info(_LI("Retrieving secret for service: %s")
- % label)
+ LOG.info(_LI("Retrieving secret for service: %s"), label)
out = self.bend.get_targetsecret(self.config['hnas_cmd'],
self.config['mgmt_ip0'],
svc['hdp'],
svc['iscsi_secret'])
- LOG.info("Set tgt CHAP secret for service: %s"
- % (label))
+ LOG.info(_LI("Set tgt CHAP secret for service: %s"),
+ label)
else:
# We set blank password when the client does not
# support CHAP. Later on, if the client tries to create a new
# value and use a temporary dummy password.
if 'iscsi_secret' not in svc:
# Warns in the first time
- LOG.info("CHAP authentication disabled")
+ LOG.info(_LE("CHAP authentication disabled"))
svc['iscsi_secret'] = ""
if 'iscsi_target' not in svc:
- LOG.info(_LI("Retrieving target for service: %s") % label)
+ LOG.info(_LI("Retrieving target for service: %s"), label)
out = self.bend.get_targetiqn(self.config['hnas_cmd'],
self.config['mgmt_ip0'],
svc['port'], svc['hdp'], svc['iscsi_target'],
svc['iscsi_secret'])
else:
- LOG.info(_LI("Available services: %s")
- % self.config['services'].keys())
- LOG.error(_LE("No configuration found for service: %s")
- % label)
+ LOG.info(_LI("Available services: %s"),
+ self.config['services'].keys())
+ LOG.error(_LE("No configuration found for service: %s"), label)
raise exception.ParameterNotFound(param=label)
return service
total_cap += int(size)
total_used += int(used)
- LOG.info("stats: total: %d used: %d" % (total_cap, total_used))
+ LOG.info(_LI("stats: total: %(cap)d used: %(used)d"),
+ {'cap': total_cap, 'used': total_used})
hnas_stat = {}
hnas_stat['total_capacity_gb'] = int(total_cap / units.Ki) # in GB
hnas_stat['QoS_support'] = False
hnas_stat['reserved_percentage'] = 0
- LOG.info(_LI("stats: stats: %s") % hnas_stat)
+ LOG.info(_LI("stats: stats: %s"), hnas_stat)
return hnas_stat
def _get_hdp_list(self):
hdp_list.extend(inf[1:2])
# returns a list of HDP IDs
- LOG.info(_LI("HDP list: %s") % hdp_list)
+ LOG.info(_LI("HDP list: %s"), hdp_list)
return hdp_list
def _check_hdp_list(self):
for hdp in lst:
if hdp not in hdpl:
- LOG.error(_LE("HDP not found: %s") % hdp)
+ LOG.error(_LE("HDP not found: %s"), hdp)
err = "HDP not found: " + hdp
raise exception.ParameterNotFound(param=err)
# status, verify corresponding status is Normal
self._check_hdp_list()
iscsi_info = self._get_iscsi_info()
- LOG.info(_LI("do_setup: %s") % iscsi_info)
+ LOG.info(_LI("do_setup: %s"), iscsi_info)
for svc in self.config['services'].keys():
svc_ip = self.config['services'][svc]['iscsi_ip']
if svc_ip in iscsi_info.keys():
- LOG.info(_LI("iSCSI portal found for service: %s") % svc_ip)
+ LOG.info(_LI("iSCSI portal found for service: %s"), svc_ip)
self.config['services'][svc]['port'] = \
iscsi_info[svc_ip]['port']
self.config['services'][svc]['ctl'] = iscsi_info[svc_ip]['ctl']
iscsi_info[svc_ip]['iscsi_port']
else: # config iscsi address not found on device!
LOG.error(_LE("iSCSI portal not found "
- "for service: %s") % svc_ip)
+ "for service: %s"), svc_ip)
raise exception.ParameterNotFound(param=svc_ip)
def ensure_export(self, context, volume):
"""
name = volume['name']
- LOG.debug("create_export %(name)s" % {'name': name})
+ LOG.debug("create_export %s", name)
pass
provider = volume['provider_location']
name = volume['name']
- LOG.debug("remove_export provider %(provider)s on %(name)s"
- % {'provider': provider,
- 'name': name})
+ LOG.debug("remove_export provider %(provider)s on %(name)s",
+ {'provider': provider, 'name': name})
pass
'%s' % (int(volume['size']) * units.Ki),
volume['name'])
- LOG.info(_LI("create_volume: create_lu returns %s") % out)
+ LOG.info(_LI("create_volume: create_lu returns %s"), out)
lun = self.arid + '.' + out.split()[1]
sz = int(out.split()[5])
# Example: 92210013.volume-44d7e29b-2aa4-4606-8bc4-9601528149fd
- LOG.info(_LI("LUN %(lun)s of size %(sz)s MB is created.")
- % {'lun': lun, 'sz': sz})
+ LOG.info(_LI("LUN %(lun)s of size %(sz)s MB is created."),
+ {'lun': lun, 'sz': sz})
return {'provider_location': lun}
def create_cloned_volume(self, dst, src):
lun = self.arid + '.' + out.split()[1]
size = int(out.split()[5])
- LOG.debug("LUN %(lun)s of size %(size)s MB is cloned."
- % {'lun': lun,
- 'size': size})
+ LOG.debug("LUN %(lun)s of size %(size)s MB is cloned.",
+ {'lun': lun, 'size': size})
return {'provider_location': lun}
def extend_volume(self, volume, new_size):
'%s' % (new_size * units.Ki),
volume['name'])
- LOG.info(_LI("LUN %(lun)s extended to %(size)s GB.")
- % {'lun': lun, 'size': new_size})
+ LOG.info(_LI("LUN %(lun)s extended to %(size)s GB."),
+ {'lun': lun, 'size': new_size})
def delete_volume(self, volume):
"""Delete an LU on HNAS.
prov_loc = volume['provider_location']
if prov_loc is None:
- LOG.error("delete_vol: provider location empty.")
+ LOG.error(_LE("delete_vol: provider location empty."))
return
info = _loc_info(prov_loc)
(arid, lun) = info['id_lu']
if 'tgt' in info.keys(): # connected?
- LOG.info("delete lun loc %s" % info['tgt'])
+ LOG.info(_LI("delete lun loc %s"), info['tgt'])
# loc = id.lun
(_portal, iqn, loc, ctl, port, hlun) = info['tgt']
self.bend.del_iscsi_conn(self.config['hnas_cmd'],
name = self.hnas_name
- LOG.debug("delete lun %(lun)s on %(name)s"
- % {'lun': lun,
- 'name': name})
+ LOG.debug("delete lun %(lun)s on %(name)s", {'lun': lun, 'name': name})
service = self._get_service(volume)
(_ip, _ipp, _ctl, _port, hdp, target, secret) = service
:param connector: dictionary connector reference
"""
- LOG.info("initialize volume %s connector %s" % (volume, connector))
+ LOG.info(_LI("initialize volume %(vol)s connector %(conn)s"),
+ {'vol': volume, 'conn': connector})
# connector[ip, host, wwnns, unititator, wwp/
service = self._get_service(volume)
tgt = hnas_portal + ',' + iqn + ',' + loc + ',' + ctl + ','
tgt += port + ',' + hlun
- LOG.info("initiate: connection %s" % tgt)
+ LOG.info(_LI("initiate: connection %s"), tgt)
properties = {}
properties['provider_location'] = tgt
info = _loc_info(volume['provider_location'])
if 'tgt' not in info.keys(): # spurious disconnection
- LOG.warn("terminate_conn: provider location empty.")
+ LOG.warn(_LW("terminate_conn: provider location empty."))
return
(arid, lun) = info['id_lu']
(_portal, iqn, loc, ctl, port, hlun) = info['tgt']
- LOG.info("terminate: connection %s" % volume['provider_location'])
+ LOG.info(_LI("terminate: connection %s"), volume['provider_location'])
self.bend.del_iscsi_conn(self.config['hnas_cmd'],
self.config['mgmt_ip0'],
self.config['username'],
lun = self.arid + '.' + out.split()[1]
sz = int(out.split()[5])
- LOG.debug("LUN %(lun)s of size %(sz)s MB is created from snapshot."
- % {'lun': lun, 'sz': sz})
+ LOG.debug("LUN %(lun)s of size %(sz)s MB is created from snapshot.",
+ {'lun': lun, 'sz': sz})
return {'provider_location': lun}
def create_snapshot(self, snapshot):
lun = self.arid + '.' + out.split()[1]
size = int(out.split()[5])
- LOG.debug("LUN %(lun)s of size %(size)s MB is created."
- % {'lun': lun, 'size': size})
+ LOG.debug("LUN %(lun)s of size %(size)s MB is created.",
+ {'lun': lun, 'size': size})
return {'provider_location': lun}
def delete_snapshot(self, snapshot):
myid = self.arid
if arid != myid:
- LOG.error(_LE('Array mismatch %(myid)s vs %(arid)s')
- % {'myid': myid,
- 'arid': arid})
+ LOG.error(_LE("Array mismatch %(myid)s vs %(arid)s"),
+ {'myid': myid, 'arid': arid})
msg = 'Array id mismatch in delete snapshot'
raise exception.VolumeBackendAPIException(data=msg)
self.bend.delete_lu(self.config['hnas_cmd'],
try:
val = root.findtext(element)
- LOG.info(_LI("%(element)s: %(val)s")
- % {'element': element,
- 'val': val})
+ LOG.info(_LI("%(element)s: %(val)s"), {'element': element, 'val': val})
if val:
return val.strip()
if check:
except ETree.ParseError:
if check:
with excutils.save_and_reraise_exception():
- LOG.error(_LE("XML exception reading parameter: %s") % element)
+ LOG.error(_LE("XML exception reading parameter: %s"), element)
else:
- LOG.info(_LI("XML exception reading parameter: %s") % element)
+ LOG.info(_LI("XML exception reading parameter: %s"), element)
return None
"""
if not os.access(xml_config_file, os.R_OK):
- raise exception.NotFound(message=_LE('Can\'t open config file: ')
- + xml_config_file)
+ raise exception.NotFound(_LE("Can't open config file: %s"),
+ xml_config_file)
try:
root = ETree.parse(xml_config_file).getroot()
except Exception:
- raise exception.ConfigNotFound(
- message=_LE('Error parsing config file: ') + xml_config_file)
+ raise exception.ConfigNotFound(_LE("Error parsing config file: %s"),
+ xml_config_file)
# mandatory parameters
config = {}
label = 'default'
if label in self.config['services'].keys():
svc = self.config['services'][label]
- LOG.info("Get service: %s->%s" % (label, svc['fslabel']))
+ LOG.info(_LI("Get service: %(lbl)s->%(svc)s"),
+ {'lbl': label, 'svc': svc['fslabel']})
service = (svc['hdp'], svc['path'], svc['fslabel'])
else:
- LOG.info(_LI("Available services: %s")
- % self.config['services'].keys())
- LOG.error(_LE("No configuration found for service: %s") % label)
+ LOG.info(_LI("Available services: %s"),
+ self.config['services'].keys())
+ LOG.error(_LE("No configuration found for service: %s"),
+ label)
raise exception.ParameterNotFound(param=label)
return service
path = self._get_volume_path(nfs_mount, volume['name'])
# Resize the image file on share to new size.
- LOG.debug('Checking file for resize')
+ LOG.debug("Checking file for resize")
if self._is_file_size_equal(path, new_size):
return
else:
- LOG.info(_LI('Resizing file to %sG'), new_size)
+ LOG.info(_LI("Resizing file to %sG"), new_size)
image_utils.resize_image(path, new_size)
if self._is_file_size_equal(path, new_size):
- LOG.info(_LI("LUN %(id)s extended to %(size)s GB.")
- % {'id': volume['id'], 'size': new_size})
+ LOG.info(_LI("LUN %(id)s extended to %(size)s GB."),
+ {'id': volume['id'], 'size': new_size})
return
else:
raise exception.InvalidResults(
- _('Resizing image file failed.'))
+ _("Resizing image file failed."))
def _is_file_size_equal(self, path, size):
"""Checks if file size at path is equal to size."""
def create_volume_from_snapshot(self, volume, snapshot):
"""Creates a volume from a snapshot."""
- LOG.debug('create_volume_from %s', volume)
+ LOG.debug("create_volume_from %s", volume)
vol_size = volume['size']
snap_size = snapshot['volume_size']
if vol_size != snap_size:
- msg = _('Cannot create volume of size %(vol_size)s from '
- 'snapshot of size %(snap_size)s')
+ msg = _("Cannot create volume of size %(vol_size)s from "
+ "snapshot of size %(snap_size)s")
msg_fmt = {'vol_size': vol_size, 'snap_size': snap_size}
raise exception.CinderException(msg % msg_fmt)
src_vol_size = src_vref['size']
if vol_size != src_vol_size:
- msg = _('Cannot create clone of size %(vol_size)s from '
- 'volume of size %(src_vol_size)s')
+ msg = _("Cannot create clone of size %(vol_size)s from "
+ "volume of size %(src_vol_size)s")
msg_fmt = {'vol_size': vol_size, 'src_vol_size': src_vol_size}
raise exception.CinderException(msg % msg_fmt)
conf[key]['path'] = path
conf[key]['hdp'] = hdp
conf[key]['fslabel'] = fslabel
- msg = _('nfs_info: %(key)s: %(path)s, HDP: \
- %(fslabel)s FSID: %(hdp)s')
- LOG.info(msg
- % {'key': key,
- 'path': path,
- 'fslabel': fslabel,
- 'hdp': hdp})
+ msg = _("nfs_info: %(key)s: %(path)s, HDP: \
+ %(fslabel)s FSID: %(hdp)s")
+ LOG.info(msg, {'key': key, 'path': path, 'fslabel': fslabel,
+ 'hdp': hdp})
return conf
self._load_shares_config(getattr(self.configuration,
self.driver_prefix +
'_shares_config'))
- LOG.info("Review shares: %s" % self.shares)
+ LOG.info(_LI("Review shares: %s"), self.shares)
nfs_info = self._get_nfs_info()
for share in self.shares:
#export = share.split(':')[1]
if share in nfs_info.keys():
- LOG.info("share: %s -> %s" % (share, nfs_info[share]['path']))
+ LOG.info(_LI("share: %(share)s -> %(info)s"),
+ {'share': share, 'info': nfs_info[share]['path']})
for svc in self.config['services'].keys():
if share == self.config['services'][svc]['hdp']:
nfs_info[share]['hdp']
self.config['services'][svc]['fslabel'] = \
nfs_info[share]['fslabel']
- LOG.info("Save service info for %s -> %s, %s"
- % (svc, nfs_info[share]['hdp'],
- nfs_info[share]['path']))
+ LOG.info(_LI("Save service info for"
+ " %(svc)s -> %(hdp)s, %(path)s"),
+ {'svc': svc, 'hdp': nfs_info[share]['hdp'],
+ 'path': nfs_info[share]['path']})
break
if share != self.config['services'][svc]['hdp']:
- LOG.error("NFS share %s has no service entry: %s -> %s"
- % (share, svc,
- self.config['services'][svc]['hdp']))
+ LOG.error(_LE("NFS share %(share)s has no service entry:"
+ " %(svc)s -> %(hdp)s"),
+ {'share': share, 'svc': svc,
+ 'hdp': self.config['services'][svc]['hdp']})
raise exception.ParameterNotFound(param=svc)
else:
- LOG.info("share: %s incorrect entry" % share)
+ LOG.info(_LI("share: %s incorrect entry"), share)
def _clone_volume(self, volume_name, clone_name, volume_id):
"""Clones mounted volume using the HNAS file_clone.
export_path = self._get_export_path(volume_id)
# volume-ID snapshot-ID, /cinder
- LOG.info("Cloning with volume_name %s clone_name %s export_path %s"
- % (volume_name, clone_name, export_path))
+ LOG.info(_LI("Cloning with volume_name %(vname)s clone_name %(cname)s"
+ " export_path %(epath)s"), {'vname': volume_name,
+ 'cname': clone_name,
+ 'epath': export_path})
source_vol = self._id_to_vol(volume_id)
# sps; added target