From 39c30022bf4c40240e507059e30d32d1b771a8b9 Mon Sep 17 00:00:00 2001 From: zhangchao010 Date: Thu, 12 Sep 2013 22:34:22 +0800 Subject: [PATCH] Improves the parsing way of ssh returns Huawei driver failed to parse ssh result when firstly logging in storage system on paramiko 1.8.0. The update of paramiko make the order of ssh returns changed. This patch improves the parsing way of ssh returns. This patch also does some changes for log punctuations. fixes bug 1224499 Change-Id: Ia8761081dff998884f45312355b62aa27ab5417c --- cinder/volume/drivers/huawei/huawei_t.py | 16 +++--- cinder/volume/drivers/huawei/ssh_common.py | 57 ++++++++++++---------- 2 files changed, 38 insertions(+), 35 deletions(-) diff --git a/cinder/volume/drivers/huawei/huawei_t.py b/cinder/volume/drivers/huawei/huawei_t.py index 911727bffab..67ca7d2d65e 100644 --- a/cinder/volume/drivers/huawei/huawei_t.py +++ b/cinder/volume/drivers/huawei/huawei_t.py @@ -95,8 +95,8 @@ def delete_snapshot(self, snapshot): def initialize_connection(self, volume, connector): """Map a volume to a host and return target iSCSI information.""" - LOG.debug(_('initialize_connection: volume name: %(vol)s ' - 'host: %(host)s initiator: %(ini)s') + LOG.debug(_('initialize_connection: volume name: %(vol)s, ' + 'host: %(host)s, initiator: %(ini)s') % {'vol': volume['name'], 'host': connector['host'], 'ini': connector['initiator']}) @@ -227,7 +227,7 @@ def _get_tgt_iqn(self, port_ip): iqn = iqn_prefix + ':' + iqn_suffix + ':' + port_info[3] - LOG.debug(_('_get_tgt_iqn: iSCSI target iqn is %s') % iqn) + LOG.debug(_('_get_tgt_iqn: iSCSI target iqn is %s.') % iqn) return (iqn, port_info[0]) @@ -316,7 +316,7 @@ def _delete_initiator(self, ininame, attempts=2): def terminate_connection(self, volume, connector, **kwargs): """Terminate the map.""" - LOG.debug(_('terminate_connection: volume: %(vol)s host: %(host)s ' + LOG.debug(_('terminate_connection: volume: %(vol)s, host: %(host)s, ' 'connector: %(initiator)s') % {'vol': volume['name'], 'host': connector['host'], @@ -344,7 +344,7 @@ def _remove_iscsi_port(self, hostid, connector): break else: LOG.warn(_('_remove_iscsi_port: iSCSI port was not found ' - 'on host %(hostid)s') % {'hostid': hostid}) + 'on host %(hostid)s.') % {'hostid': hostid}) # Delete host if no initiator added to it. if port_num == 0: @@ -431,8 +431,8 @@ def validate_connector(self, connector): def initialize_connection(self, volume, connector): """Create FC connection between a volume and a host.""" - LOG.debug(_('initialize_connection: volume name: %(vol)s ' - 'host: %(host)s initiator: %(wwn)s') + LOG.debug(_('initialize_connection: volume name: %(vol)s, ' + 'host: %(host)s, initiator: %(wwn)s') % {'vol': volume['name'], 'host': connector['host'], 'wwn': connector['wwpns']}) @@ -540,7 +540,7 @@ def _get_fc_port_ctr(self, port_details): def terminate_connection(self, volume, connector, **kwargs): """Terminate the map.""" - LOG.debug(_('terminate_connection: volume: %(vol)s host: %(host)s ' + LOG.debug(_('terminate_connection: volume: %(vol)s, host: %(host)s, ' 'connector: %(initiator)s') % {'vol': volume['name'], 'host': connector['host'], diff --git a/cinder/volume/drivers/huawei/ssh_common.py b/cinder/volume/drivers/huawei/ssh_common.py index 3de97b2ee5e..e4dae758dc1 100644 --- a/cinder/volume/drivers/huawei/ssh_common.py +++ b/cinder/volume/drivers/huawei/ssh_common.py @@ -64,23 +64,26 @@ def ssh_read(user, channel, cmd, timeout): result = result + channel.recv(8192) except socket.timeout: raise exception.CinderException(_('ssh_read: Read ' - 'SSH timeout')) + 'SSH timeout.')) else: - # Complete CLI response starts with CLI cmd and - # ends with "username:/>". - if result.startswith(cmd) and result.endswith(user + ':/>'): - if not re.search('Welcome', result): + # CLI returns welcome information when first log in. So need to + # deal differently. + if not re.search('Welcome', result): + # Complete CLI response starts with CLI cmd and + # ends with "username:/>". + if result.startswith(cmd) and result.endswith(user + ':/>'): break - # CLI returns welcome information when first log in. - elif re.search(user + ':/>' + cmd, result): + # Some commands need to send 'y'. + elif re.search('(y/n)', result): break - # Some commands need to send 'y'. - elif re.search('(y/n)', result): + # Reach maximum limit of SSH connection. + elif re.search('No response message', result): + msg = _('No response message. Please check system status.') + raise exception.CinderException(msg) + elif (re.search(user + ':/>' + cmd, result) and + result.endswith(user + ':/>')): break - # Reach maximum limit of SSH connection. - elif re.search('No response message', result): - msg = _('No response message. Please check system status.') - raise exception.CinderException(msg) + # Filter the last line: username:/> . result = '\r\n'.join(result.split('\r\n')[:-1]) # Filter welcome information. @@ -104,7 +107,7 @@ def __init__(self, configuration=None): def do_setup(self, context): """Check config file.""" - LOG.debug(_('do_setup.')) + LOG.debug(_('do_setup')) self._check_conf_file() self.login_info = self._get_login_info() @@ -208,7 +211,7 @@ def create_volume(self, volume): """Create a new volume.""" volume_name = self._name_translate(volume['name']) - LOG.debug(_('create_volume: volume name: %s.') % volume_name) + LOG.debug(_('create_volume: volume name: %s') % volume_name) self._update_login_info() if int(volume['size']) == 0: @@ -379,7 +382,7 @@ def _parse_conf_lun_params(self): conf_params['PrefetchTimes'] = prefetch.attrib['Value'].strip() else: LOG.debug(_('_parse_conf_lun_params: Use default prefetch type. ' - 'Prefetch type: Intelligent.')) + 'Prefetch type: Intelligent')) pools_conf = root.findall('LUN/StoragePool') for pool in pools_conf: @@ -492,7 +495,7 @@ def _reset_transport_timeout(self, ssh, time): def delete_volume(self, volume): volume_name = self._name_translate(volume['name']) - LOG.debug(_('delete_volume: volume name: %s.') % volume_name) + LOG.debug(_('delete_volume: volume name: %s') % volume_name) self._update_login_info() volume_id = volume.get('provider_location', None) @@ -530,7 +533,7 @@ def create_volume_from_snapshot(self, volume, snapshot): volume_name = self._name_translate(volume['name']) LOG.debug(_('create_volume_from_snapshot: snapshot ' - 'name: %(snapshot)s, volume name: %(volume)s.') + 'name: %(snapshot)s, volume name: %(volume)s') % {'snapshot': snapshot_name, 'volume': volume_name}) @@ -647,7 +650,7 @@ def create_cloned_volume(self, tgt_volume, src_volume): src_vol_name = self._name_translate(src_volume['name']) tgt_vol_name = self._name_translate(tgt_volume['name']) - LOG.debug(_('create_cloned_volume: src volume: %(src)s ' + LOG.debug(_('create_cloned_volume: src volume: %(src)s, ' 'tgt volume: %(tgt)s') % {'src': src_vol_name, 'tgt': tgt_vol_name}) @@ -694,7 +697,7 @@ def create_snapshot(self, snapshot): snapshot_name = self._name_translate(snapshot['name']) volume_name = self._name_translate(snapshot['volume_name']) - LOG.debug(_('create_snapshot: snapshot name: %(snapshot)s ' + LOG.debug(_('create_snapshot: snapshot name: %(snapshot)s, ' 'volume name: %(volume)s') % {'snapshot': snapshot_name, 'volume': volume_name}) @@ -770,7 +773,7 @@ def delete_snapshot(self, snapshot): snapshot_name = self._name_translate(snapshot['name']) volume_name = self._name_translate(snapshot['volume_name']) - LOG.debug(_('delete_snapshot: snapshot name: %(snapshot)s ' + LOG.debug(_('delete_snapshot: snapshot name: %(snapshot)s, ' 'volume name: %(volume)s') % {'snapshot': snapshot_name, 'volume': volume_name}) @@ -873,7 +876,7 @@ def map_volume(self, host_id, volume_id): 'hostlunid': new_hostlun_id}) out = self._execute_cli(cli_cmd) - msg = ('Failed to map lun %s to host %s. host lun ID: %s' + msg = ('Failed to map LUN %s to host %s. host LUN ID: %s' % (volume_id, host_id, new_hostlun_id)) self._assert_cli_operate_out('map_volume', msg, cli_cmd, out) @@ -981,7 +984,7 @@ def get_lun_details(self, lun_id): return lun_details def change_lun_ctr(self, lun_id, ctr): - LOG.debug(_('change_lun_ctr: Changing LUN %(lun)s ctr to %(ctr)s') + LOG.debug(_('change_lun_ctr: Changing LUN %(lun)s ctr to %(ctr)s.') % {'lun': lun_id, 'ctr': ctr}) cli_cmd = 'chglun -lun %s -c %s' % (lun_id, ctr) @@ -1080,7 +1083,7 @@ def get_volume_stats(self, refresh=False): def _update_volume_stats(self): """Retrieve stats info from volume group.""" - LOG.debug(_("_update_volume_stats: Updating volume stats")) + LOG.debug(_("_update_volume_stats: Updating volume stats.")) data = {} data['vendor_name'] = 'Huawei' data['total_capacity_gb'] = 'infinite' @@ -1144,7 +1147,7 @@ def __init__(self, configuration=None): def do_setup(self, context): """Check config file.""" - LOG.debug(_('do_setup.')) + LOG.debug(_('do_setup')) self._check_conf_file() self.lun_distribution = self._get_lun_ctr_info() @@ -1192,7 +1195,7 @@ def _get_device_type(self): elif re.search('Dorado5100$', line): return 'Dorado5100' else: - LOG.error(_('_get_device_type: The drivers only support' + LOG.error(_('_get_device_type: The driver only supports ' 'Dorado5100 and Dorado 2100 G2 now.')) raise exception.InvalidResults() @@ -1201,7 +1204,7 @@ def _get_lun_ctr_info(self): ctr_info = [0, 0] (c, n) = ((2, 4) if self.device_type == 'Dorado2100 G2' else (3, 5)) for lun in luns: - if lun[n].startswith('OpenStack'): + if lun[n].startswith(VOL_AND_SNAP_NAME_PREFIX): if lun[c] == 'A': ctr_info[0] += 1 else: