How to use cli_cmd method in avocado

Best Python code snippet using avocado_python Github


Full Screen

1# vim: tabstop=4 shiftwidth=4 softtabstop=42# Copyright (c) 2012 Huawei Technologies Co., Ltd.3# Copyright (c) 2012 OpenStack LLC.4# All Rights Reserved.5#6# Licensed under the Apache License, Version 2.0 (the "License"); you may7# not use this file except in compliance with the License. You may obtain8# a copy of the License at9#10# Unless required by applicable law or agreed to in writing, software13# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT14# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the15# License for the specific language governing permissions and limitations16# under the License.17"""18Volume driver for HUAWEI T series and Dorado storage systems.19"""20import re21import socket22import time23from oslo.config import cfg24from xml.etree import ElementTree as ET25from cinder import exception26from cinder.openstack.common import excutils27from cinder.openstack.common import log as logging28from cinder import utils29from cinder.volume import driver30LOG = logging.getLogger(__name__)31huawei_opt = [32 cfg.StrOpt('cinder_huawei_conf_file',33 default='/etc/cinder/cinder_huawei_conf.xml',34 help='config data for cinder huawei plugin')]35HOST_GROUP_NAME = 'HostGroup_OpenStack'36HOST_NAME_PREFIX = 'Host_'37HOST_PORT_PREFIX = 'HostPort_'38VOL_AND_SNAP_NAME_FREFIX = 'OpenStack_'39READBUFFERSIZE = 819240class SSHConnection(utils.SSHPool):41 """An SSH connetion class .42 For some reasons, we can not use method ssh_execute defined in utils to43 send CLI commands. Here we define a new class inherited to SSHPool. Use44 method create() to build a new SSH client and use invoke_shell() to start45 an interactive shell session on the storage system.46 """47 def __init__(self, ip, port, login, password, conn_timeout,48 privatekey=None, *args, **kwargs):49 self.ssh = None50 super(SSHConnection, self).__init__(ip, port, conn_timeout, login,51 password, privatekey=None,52 *args, **kwargs)53 def connect(self):54 """Create an SSH client and open an interactive SSH channel."""55 self.ssh = self.create()56 = self.ssh.invoke_shell()57, 800)58 def close(self):59 """Close SSH connection."""60 self.ssh.close()62 def read(self, timeout=None):63 """Read data from SSH channel."""64 result = ''65 user_flg = self.login + ':/>$'66 while True:68 try:69 result = result + except socket.timeout:71 break72 else:73 # If we get the complete result string, then no need to wait74 # until time out.75 if, result) or'(y/n)', result):76 break77 return result78 def send_cmd(self, strcmd, timeout, waitstr=None):79 """Send SSH commands and return results."""80 info = ''81 + '\n')82 result = info = '\r\n'.join(result.split('\r\n')[1:-1])84 return info85class HuaweiISCSIDriver(driver.ISCSIDriver):86 """Huawei T series and Dorado iSCSI volume driver."""87 def __init__(self, *args, **kwargs):88 super(HuaweiISCSIDriver, self).__init__(*args, **kwargs)89 self.configuration.append_config_values(huawei_opt)90 self.device_type = {}91 self.login_info = {}92 self.hostgroup_id = None93 # Flag to tell whether the other controller is available94 # if the current controller can not be connected to.95 self.controller_alterable = True96 def do_setup(self, context):97 """Check config file."""98 LOG.debug(_('do_setup.'))99 self._check_conf_file()100 # Create hostgroup.101 self.login_info = self._get_login_info()102 hostgroup_name = HOST_GROUP_NAME103 self.hostgroup_id = self._find_hostgroup(hostgroup_name)104 if not self.hostgroup_id:105 self._create_hostgroup(hostgroup_name)106 self.hostgroup_id = self._find_hostgroup(hostgroup_name)107 def check_for_setup_error(self):108 """Try to connect with device and get device type."""109 LOG.debug(_('check_for_setup_error.'))110 self.login_info = self._get_login_info()111 self.device_type = self._get_device_type()112 if not self.device_type['type']:113 err_msg = (_('check_for_setup_error: Can not get device type.'))114 LOG.error(err_msg)115 raise exception.VolumeBackendAPIException(data=err_msg)116 LOG.debug(_('check_for_setup_error: Device type is:%(type)s, '117 'version is:%(version)s.')118 % {'type': self.device_type['type'],119 'version': self.device_type['version']})120 # Now only version V1 is supported.121 if self.device_type['version'] != 'V100R':122 err_msg = (_('check_for_setup_error: Product version not right. '123 'Please make sure the product version is V1.'))124 LOG.error(err_msg)125 raise exception.VolumeBackendAPIException(data=err_msg)126 def create_volume(self, volume):127 """Create a new volume."""128 volume_name = self._name_translate(volume['name'])129 LOG.debug(_('create_volume:volume name: %s.') % volume_name)130 self.login_info = self._get_login_info()131 if int(volume['size']) == 0:132 volume_sise = '100M'133 else:134 volume_sise = '%sG' % volume['size']135 self._create_volume(volume_name, volume_sise)136 def delete_volume(self, volume):137 """Delete a volume."""138 volume_name = self._name_translate(volume['name'])139 LOG.debug(_('delete_volume: volume name: %s.') % volume_name)140 self.login_info = self._get_login_info()141 volume_id = self._find_lun(volume_name)142 if volume_id:143 self._delete_volume(volume_name, volume_id)144 else:145 err_msg = (_('delete_volume:No need to delete volume.'146 'Volume %(name)s does not exist.')147 % {'name': volume['name']})148 LOG.error(err_msg)149 def create_export(self, context, volume):150 """Driver entry point to get the export info for a new volume."""151 volume_name = self._name_translate(volume['name'])152 LOG.debug(_('create_export: volume name:%s') % volume['name'])153 lun_id = self._find_lun(volume_name)154 if not lun_id:155 err_msg = (_('create_export:Volume %(name)s does not exist.')156 % {'name': volume_name})157 LOG.error(err_msg)158 raise exception.VolumeBackendAPIException(data=err_msg)159 return {'provider_location': lun_id}160 def ensure_export(self, context, volume):161 """Driver entry point to get the export info for a existing volume."""162 pass163 def remove_export(self, context, volume_id):164 """Driver entry point to remove an export for a volume."""165 pass166 def initialize_connection(self, volume, connector):167 """Map a volume to a host and return target iSCSI information."""168 initiator_name = connector['initiator']169 volume_name = self._name_translate(volume['name'])170 LOG.debug(_('initialize_connection: volume name: %(volume)s. '171 'initiator name: %(ini)s.')172 % {'volume': volume_name,173 'ini': initiator_name})174 host_name = HOST_NAME_PREFIX + str(hash(initiator_name))175 host_id = self._find_host_in_hostgroup(host_name, self.hostgroup_id)176 if not host_id:177 self._add_host(host_name, self.hostgroup_id)178 host_id = self._find_host_in_hostgroup(host_name,179 self.hostgroup_id)180 # Create an initiator.181 added = self._check_initiator(initiator_name)182 if not added:183 self._add_initiator(initiator_name)184 # Add the initiator to host.185 port_name = HOST_PORT_PREFIX + str(hash(initiator_name))186 port_info = initiator_name187 portadded = False188 hostport_info = self._get_hostport_info(host_id)189 if hostport_info:190 for hostport in hostport_info:191 if hostport['info'] == initiator_name:192 portadded = True193 break194 if not portadded:195 self._add_hostport(port_name, host_id, port_info)196 LOG.debug(_('initialize_connection:host name: %(host)s,'197 'initiator name: %(ini)s, '198 'hostport name: %(port)s')199 % {'host': host_name,200 'ini': initiator_name,201 'port': port_name})202 # Get target iSCSI iqn.203 iscsi_conf = self._get_iscsi_info()204 target_ip = None205 for ini in iscsi_conf['Initiator']:206 if ini['Name'] == initiator_name:207 target_ip = ini['TargetIP']208 break209 if not target_ip:210 target_ip = iscsi_conf['DefaultTargetIP']211 target_iqn = self._get_tgt_iqn(target_ip)212 if not target_iqn:213 err_msg = (_('initialize_connection:'214 'Failed to find target iSCSI iqn.'))215 LOG.error(err_msg)216 raise exception.VolumeBackendAPIException(data=err_msg)217 # Map a LUN to a host if not mapped.218 lun_id = self._find_lun(volume_name)219 if not lun_id:220 err_msg = (_('initialize_connection:Failed to find the '221 'given volume. '222 'volume name:%(volume)s.')223 % {'volume': volume_name})224 raise exception.VolumeBackendAPIException(data=err_msg)225 hostlun_id = None226 map_info = self._get_map_info(host_id)227 # Make sure the hostLUN ID starts from 1.228 new_hostlun_id = 1229 new_hostlunid_found = False230 if map_info:231 for map in map_info:232 if map['devlunid'] == lun_id:233 hostlun_id = map['hostlunid']234 break235 elif not new_hostlunid_found:236 if new_hostlun_id < int(map['hostlunid']):237 new_hostlunid_found = True238 else:239 new_hostlun_id = int(map['hostlunid']) + 1240 # The LUN is not mapped to the host.241 if not hostlun_id:242 self._map_lun(lun_id, host_id, new_hostlun_id)243 hostlun_id = self._get_hostlunid(host_id, lun_id)244 # Return iSCSI properties.245 properties = {}246 properties['target_discovered'] = False247 properties['target_portal'] = ('%s:%s' % (target_ip, '3260'))248 properties['target_iqn'] = target_iqn249 properties['target_lun'] = int(hostlun_id)250 properties['volume_id'] = volume['id']251 auth = volume['provider_auth']252 if auth:253 (auth_method, auth_username, auth_secret) = auth.split()254 properties['auth_method'] = auth_method255 properties['auth_username'] = auth_username256 properties['auth_password'] = auth_secret257 return {'driver_volume_type': 'iscsi', 'data': properties}258 def terminate_connection(self, volume, connector, **kwargs):259 """Delete map between a volume and a host."""260 initiator_name = connector['initiator']261 volume_name = self._name_translate(volume['name'])262 LOG.debug(_('terminate_connection:volume name: %(volume)s, '263 'initiator name: %(ini)s.')264 % {'volume': volume_name,265 'ini': initiator_name})266 self.login_info = self._get_login_info()267 host_name = HOST_NAME_PREFIX + str(hash(initiator_name))268 host_id = self._find_host_in_hostgroup(host_name, self.hostgroup_id)269 if not host_id:270 err_msg = (_('terminate_connection:Host does not exist. '271 'Host name:%(host)s.')272 % {'host': host_name})273 LOG.error(err_msg)274 raise exception.VolumeBackendAPIException(data=err_msg)275 # Delete host map.276 lun_id = self._find_lun(volume_name)277 if not lun_id:278 err_msg = (_('terminate_connection:volume does not exist.'279 'volume name:%(volume)s')280 % {'volume': volume_name})281 LOG.error(err_msg)282 raise exception.VolumeBackendAPIException(data=err_msg)283 map_id = None284 mapnum = 0285 map_info = self._get_map_info(host_id)286 if map_info:287 mapnum = len(map_info)288 for map in map_info:289 if map['devlunid'] == lun_id:290 map_id = map['mapid']291 break292 if map_id:293 self._delete_map(map_id)294 mapnum = mapnum - 1295 else:296 LOG.error(_('terminate_connection:No map between host '297 'and volume. Host name:%(hostname)s,'298 'volume name:%(volumename)s.')299 % {'hostname': host_name,300 'volumename': volume_name})301 # Delete host initiator when no LUN mapped to it.302 portnum = 0303 hostportinfo = self._get_hostport_info(host_id)304 if hostportinfo:305 portnum = len(hostportinfo)306 for hostport in hostportinfo:307 if hostport['info'] == initiator_name and mapnum == 0:308 self._delete_hostport(hostport['id'])309 self._delete_initiator(initiator_name)310 portnum = portnum - 1311 break312 else:313 LOG.error(_('terminate_connection:No initiator is added '314 'to the host. Host name:%(hostname)s')315 % {'hostname': host_name})316 # Delete host when no initiator added to it.317 if portnum == 0:318 self._delete_host(host_id)319 def create_snapshot(self, snapshot):320 """Create a snapshot."""321 snapshot_name = self._name_translate(snapshot['name'])322 volume_name = self._name_translate(snapshot['volume_name'])323 LOG.debug(_('create_snapshot:snapshot name:%(snapshot)s, '324 'volume name:%(volume)s.')325 % {'snapshot': snapshot_name,326 'volume': volume_name})327 self.login_info = self._get_login_info()328 if self.device_type['type'] == 'Dorado2100 G2':329 err_msg = (_('create_snapshot:Device does not support snapshot.'))330 LOG.error(err_msg)331 raise exception.VolumeBackendAPIException(data=err_msg)332 if self._is_resource_pool_enough() is False:333 err_msg = (_('create_snapshot:'334 'Resource pool needs 1GB valid size at least.'))335 LOG.error(err_msg)336 raise exception.VolumeBackendAPIException(data=err_msg)337 lun_id = self._find_lun(volume_name)338 if not lun_id:339 err_msg = (_('create_snapshot:Volume does not exist.'340 'Volume name:%(name)s')341 % {'name': volume_name})342 LOG.error(err_msg)343 raise exception.VolumeBackendAPIException(data=err_msg)344 self._create_snapshot(snapshot_name, lun_id)345 snapshot_id = self._find_snapshot(snapshot_name)346 if not snapshot_id:347 err_msg = (_('create_snapshot:Snapshot does not exist.'348 'Snapshot name:%(name)s')349 % {'name': snapshot_name})350 LOG.error(err_msg)351 raise exception.VolumeBackendAPIException(data=err_msg)352 self._active_snapshot(snapshot_id)353 def delete_snapshot(self, snapshot):354 """Delete a snapshot."""355 snapshot_name = self._name_translate(snapshot['name'])356 volume_name = self._name_translate(snapshot['volume_name'])357 LOG.debug(_('delete_snapshot:snapshot name:%(snapshot)s, '358 'volume name:%(volume)s.')359 % {'snapshot': snapshot_name,360 'volume': volume_name})361 self.login_info = self._get_login_info()362 if self.device_type['type'] == 'Dorado2100 G2':363 err_msg = (_('delete_snapshot:Device does not support snapshot.'))364 LOG.error(err_msg)365 raise exception.VolumeBackendAPIException(data=err_msg)366 snapshot_id = self._find_snapshot(snapshot_name)367 if snapshot_id:368 self._disable_snapshot(snapshot_id)369 self._delete_snapshot(snapshot_id)370 else:371 err_msg = (_('delete_snapshot:Snapshot does not exist. '372 'snapshot name:%(snap)s')373 % {'snap': snapshot_name})374 LOG.debug(err_msg)375 def create_volume_from_snapshot(self, volume, snapshot):376 """Create a volume from a snapshot.377 We use LUNcopy to create a new LUN from snapshot.378 """379 snapshot_name = self._name_translate(snapshot['name'])380 volume_name = self._name_translate(volume['name'])381 LOG.debug(_('create_volume_from_snapshot:snapshot '382 'name:%(snapshot)s, '383 'volume name:%(volume)s.')384 % {'snapshot': snapshot_name,385 'volume': volume_name})386 self.login_info = self._get_login_info()387 if self.device_type['type'].find('Dorado') > -1:388 err_msg = (_('create_volume_from_snapshot:Device does '389 'not support create volume from snapshot. '390 'Volume name:%(volume)s, '391 'snapshot name:%(snapshot)s.')392 % {'volume': volume_name,393 'snapshot': snapshot_name})394 LOG.error(err_msg)395 raise exception.VolumeBackendAPIException(data=err_msg)396 snapshot_id = self._find_snapshot(snapshot_name)397 if not snapshot_id:398 err_msg = (_('create_volume_from_snapshot:Snapshot does not exist.'399 'Snapshot name:%(name)s')400 % {'name': snapshot_name})401 LOG.error(err_msg)402 raise exception.VolumeBackendAPIException(data=err_msg)403 # Create a target LUN.404 if int(volume['size']) == 0:405 volume_size = '%sG' % snapshot['volume_size']406 else:407 volume_size = '%sG' % volume['size']408 self._create_volume(volume_name, volume_size)409 volume_id = self._find_lun(volume_name)410 luncopy_name = volume_name411 try:412 self._create_luncopy(luncopy_name, snapshot_id, volume_id)413 luncopy_id = self._find_luncopy(luncopy_name)414 self._start_luncopy(luncopy_id)415 self._wait_for_luncopy(luncopy_name)416 # If LUNcopy failed,we should delete the target volume.417 except Exception:418 with excutils.save_and_reraise_exception():419 self._delete_luncopy(luncopy_id)420 self._delete_volume(volume_name, volume_id)421 self._delete_luncopy(luncopy_id)422 def get_volume_stats(self, refresh=False):423 """Get volume status.424 If 'refresh' is True, run update the stats first.425 """426 if refresh:427 self._update_volume_status()428 return self._stats429 def _check_conf_file(self):430 """Check the config file, make sure the key elements are set."""431 root = self._read_xml()432 try:433 IP1 = root.findtext('Storage/ControllerIP0')434 IP2 = root.findtext('Storage/ControllerIP1')435 username = root.findtext('Storage/UserName')436 pwd = root.findtext('Storage/UserPassword')437 pool = root.findall('LUN/StoragePool')438 isconfwrong = False439 if ((not IP1 and not IP2) or440 (not username) or441 (not pwd) or442 (not pool)):443 isconfwrong = True444 elif not pool[0].attrib['Name']:445 isconfwrong = True446 if isconfwrong is True:447 err_msg = (_('Config file is wrong. '448 'Controler IP, UserName, UserPassword and '449 'StoragePool must be set.'))450 LOG.error(err_msg)451 raise exception.InvalidInput(reason=err_msg)452 except Exception as err:453 LOG.error(_('_check_conf_file: %s') % str(err))454 raise exception.VolumeBackendAPIException(data=err)455 def _read_xml(self):456 """Open xml file."""457 filename = self.configuration.cinder_huawei_conf_file458 try:459 tree = ET.parse(filename)460 root = tree.getroot()461 except Exception as err:462 LOG.error(_('_read_xml:%s') % err)463 raise exception.VolumeBackendAPIException(data=err)464 return root465 def _get_login_info(self):466 """Get login IP, username and password from config file."""467 logininfo = {}468 root = self._read_xml()469 try:470 logininfo['ControllerIP0'] = root.findtext('Storage/ControllerIP0')471 logininfo['ControllerIP1'] = root.findtext('Storage/ControllerIP1')472 logininfo['UserName'] = root.findtext('Storage/UserName')473 logininfo['UserPassword'] = root.findtext('Storage/UserPassword')474 except Exception as err:475 LOG.debug(_('_get_login_info error. %s') % err)476 raise exception.VolumeBackendAPIException(data=err)477 return logininfo478 def _get_lun_set_info(self):479 """Get parameters from config file for creating LUN."""480 # Default LUN set information481 lunsetinfo = {'LUNType': 'Thick',482 'StripUnitSize': '64',483 'WriteType': '1',484 'MirrorSwitch': '1',485 'PrefetchType': '3',486 'PrefetchValue': '0',487 'PrefetchTimes': '0',488 'StoragePool': 'RAID_001'}489 root = self._read_xml()490 try:491 luntype = root.findtext('LUN/LUNType')492 if luntype in ['Thick', 'Thin']:493 lunsetinfo['LUNType'] = luntype494 elif luntype is not '' or luntype is not None:495 err_msg = (_('Config file is wrong. LUNType must be "Thin"'496 ' or "Thick". LUNType:%(type)s')497 % {'type': luntype})498 raise exception.VolumeBackendAPIException(data=err_msg)499 # Here we do not judge whether the parameters are right.500 # CLI will return error responses if the parameters not right.501 stripunitsize = root.findtext('LUN/StripUnitSize')502 if stripunitsize is not '' and stripunitsize is not None:503 lunsetinfo['StripUnitSize'] = stripunitsize504 writetype = root.findtext('LUN/WriteType')505 if writetype is not '' and writetype is not None:506 lunsetinfo['WriteType'] = writetype507 mirrorswitch = root.findtext('LUN/MirrorSwitch')508 if mirrorswitch is not '' and mirrorswitch is not None:509 lunsetinfo['MirrorSwitch'] = mirrorswitch510 if self.device_type['type'] == 'Tseries':511 pooltype = luntype512 prefetch = root.find('LUN/Prefetch')513 if ((prefetch is not None) and514 (prefetch.attrib['Type'] != '')):515 lunsetinfo['PrefetchType'] = prefetch.attrib['Type']516 if lunsetinfo['PrefetchType'] == '1':517 lunsetinfo['PrefetchValue'] = prefetch.attrib['Value']518 elif lunsetinfo['PrefetchType'] == '2':519 lunsetinfo['PrefetchTimes'] = prefetch.attrib['Value']520 else:521 LOG.debug(_('_get_lun_set_info:Use default prefetch type. '522 'Prefetch type:Intelligent.'))523 # No need to set Prefetch type for Dorado.524 elif self.device_type['type'] == 'Dorado5100':525 pooltype = 'Thick'526 elif self.device_type['type'] == 'Dorado2100 G2':527 return lunsetinfo528 poolsinfo = self._find_pool_info(pooltype)529 if not poolsinfo:530 err_msg = (_('_get_lun_set_info:No available pools! '531 'Please check whether storage pool is created.'))532 LOG.error(err_msg)533 raise exception.VolumeBackendAPIException(data=err_msg)534 pools = root.findall('LUN/StoragePool')535 lunsetinfo['StoragePool'] = \536 self._get_maximum_pool(pools, poolsinfo, luntype)537 except Exception as err:538 LOG.error(_('_get_lun_set_info:%s') % err)539 raise exception.VolumeBackendAPIException(data=err)540 return lunsetinfo541 def _find_pool_info(self, pooltype):542 """Return pools information created in storage device."""543 if pooltype == 'Thick':544 cli_cmd = ('showrg')545 else:546 cli_cmd = ('showpool')547 out = self._execute_cli(cli_cmd)548 en = out.split('\r\n')549 if len(en) <= 6:550 return None551 pools_list = []552 for i in range(6, len(en) - 2):553 r = en[i].split()554 pools_list.append(r)555 return pools_list556 def _get_maximum_pool(self, poolinconf, poolindev, luntype):557 """Get the maximum pool from config file.558 According to the given pools' name in config file,559 we select the pool of maximum free capacity.560 """561 maxpoolid = None562 maxpoolsize = 0563 if luntype == 'Thin':564 nameindex = 1565 sizeindex = 4566 else:567 nameindex = 5568 sizeindex = 3569 for pool in poolinconf:570 poolname = pool.attrib['Name']571 for pooldetail in poolindev:572 if pooldetail[nameindex] == poolname:573 if int(float(pooldetail[sizeindex])) > maxpoolsize:574 maxpoolid = pooldetail[0]575 maxpoolsize = int(float(pooldetail[sizeindex]))576 break577 if maxpoolid:578 return maxpoolid579 else:580 err_msg = (_('_get_maximum_pool:maxpoolid is None.'581 'Please check config file and make sure '582 'the "Name" in "StoragePool" is right.'))583 raise exception.VolumeBackendAPIException(data=err_msg)584 def _get_iscsi_info(self):585 """Get iSCSI info from config file."""586 iscsiinfo = {}587 root = self._read_xml()588 try:589 iscsiinfo['DefaultTargetIP'] = \590 root.findtext('iSCSI/DefaultTargetIP')591 initiator_list = []592 for dic in root.findall('iSCSI/Initiator'):593 initiator_list.append(dic.attrib)594 iscsiinfo['Initiator'] = initiator_list595 except Exception as err:596 LOG.error(_('_get_iscsi_info:%s') % str(err))597 return iscsiinfo598 def _execute_cli(self, cmd):599 """Build SSH connection to execute CLI commands.600 If the connection to first controller time out,601 try to connect to the other controller.602 """603 user = self.login_info['UserName']604 pwd = self.login_info['UserPassword']605 while True:606 if self.controller_alterable:607 ip = self.login_info['ControllerIP0']608 else:609 ip = self.login_info['ControllerIP1']610 try:611 ssh = SSHConnection(ip, 22, user, pwd, 30)612 ssh.connect()613 while True:614 out = ssh.send_cmd(cmd, 30)615 if out.find('(y/n)') > -1:616 cmd = 'y'617 else:618 break619 ssh.close()620 except Exception as err:621 if ((not self.controller_alterable) and622 (str(err).find('timed out') > -1)):623 self.controller_alterable = False624 LOG.debug(_('_execute_cli:Connect to controller0 %(ctr0)s'625 ' time out.Try to Connect to controller1 '626 '%(ctr1)s.')627 % {'ctr0': self.login_info['ControllerIP0'],628 'ctr1': self.login_info['ControllerIP1']})629 continue630 else:631 LOG.error(_('_execute_cli:%s') % err)632 raise exception.VolumeBackendAPIException(data=err)633 index = out.find(user + ':/>')634 if index > -1:635 return out[index:]636 else:637 return out638 def _name_translate(self, name):639 """Form new names because of the 32-character limit on names."""640 newname = VOL_AND_SNAP_NAME_FREFIX + str(hash(name))641 LOG.debug(_('_name_translate:Name in cinder: %(old)s, '642 'new name in storage system: %(new)s')643 % {'old': name,644 'new': newname})645 return newname646 def _find_lun(self, name):647 """Get the ID of a LUN with the given LUN name."""648 cli_cmd = ('showlun')649 out = self._execute_cli(cli_cmd)650 en = out.split('\r\n')651 if len(en) <= 6:652 return None653 if 'Dorado2100 G2' == self.device_type['type']:654 d = 2655 elif 'Dorado5100' == self.device_type['type']:656 d = 1657 else:658 d = 0659 for i in range(6, len(en) - 2):660 r = en[i].split()661 if r[6 - d] == name:662 return r[0]663 return None664 def _create_hostgroup(self, hostgroupname):665 """Create a host group."""666 cli_cmd = ('createhostgroup -n %(name)s'667 % {'name': hostgroupname})668 out = self._execute_cli(cli_cmd)669 if not'command operates successfully', out):670 err_msg = (_('_create_hostgroup:Failed to Create hostgroup. '671 'Hostgroup name: %(name)s. '672 'out:%(out)s.')673 % {'name': hostgroupname,674 'out': out})675 LOG.error(err_msg)676 raise exception.VolumeBackendAPIException(data=err_msg)677 def _find_hostgroup(self, groupname):678 """Get the given hostgroup ID."""679 cli_cmd = ('showhostgroup')680 out = self._execute_cli(cli_cmd)681 en = out.split('\r\n')682 if len(en) <= 6:683 return None684 for i in range(6, len(en) - 2):685 r = en[i].split()686 if r[1] == groupname:687 return r[0]688 return None689 def _add_host(self, hostname, hostgroupid):690 """Add a new host."""691 cli_cmd = ('addhost -group %(groupid)s -n %(hostname)s -t 0'692 % {'groupid': hostgroupid,693 'hostname': hostname})694 out = self._execute_cli(cli_cmd)695 if not'command operates successfully', out):696 err_msg = (_('_add_host:Failed to add host to hostgroup.'697 'host name:%(host)s '698 'hostgroup id:%(hostgroup)s '699 'out:%(out)s')700 % {'host': hostname,701 'hostgroup': hostgroupid,702 'out': out})703 LOG.error(err_msg)704 raise exception.VolumeBackendAPIException(data=err_msg)705 def _check_initiator(self, ininame):706 """Check whether the initiator is already added."""707 cli_cmd = ('showiscsiini -ini %(name)s'708 % {'name': ininame})709 out = self._execute_cli(cli_cmd)710 if out.find('Initiator Information') > -1:711 return True712 else:713 return False714 def _add_initiator(self, ininame):715 """Add a new initiator to storage device."""716 cli_cmd = ('addiscsiini -n %(name)s'717 % {'name': ininame})718 out = self._execute_cli(cli_cmd)719 if not'command operates successfully', out):720 err_msg = (_('_add_initiator:Failed to add initiator.'721 'initiator name:%(name)s '722 'out:%(out)s')723 % {'name': ininame,724 'out': out})725 LOG.error(err_msg)726 raise exception.VolumeBackendAPIException(data=err_msg)727 def _delete_initiator(self, ininame):728 """Delete an initiator."""729 cli_cmd = ('deliscsiini -n %(name)s'730 % {'name': ininame})731 out = self._execute_cli(cli_cmd)732 if not'command operates successfully', out):733 err_msg = (_('_delete_initiator:ERROE:Failed to delete initiator.'734 'initiator name:%(name)s '735 'out:%(out)s')736 % {'name': ininame,737 'out': out})738 LOG.error(err_msg)739 def _find_host_in_hostgroup(self, hostname, hostgroupid):740 """Get the given host ID."""741 cli_cmd = ('showhost -group %(groupid)s'742 % {'groupid': hostgroupid})743 out = self._execute_cli(cli_cmd)744 en = out.split('\r\n')745 if len(en) < 6:746 return None747 for i in range(6, len(en) - 2):748 r = en[i].split()749 if r[1] == hostname:750 return r[0]751 return None752 def _get_hostport_info(self, hostid):753 """Get hostports details of the given host."""754 cli_cmd = ('showhostport -host %(hostid)s'755 % {'hostid': hostid})756 out = self._execute_cli(cli_cmd)757 en = out.split('\r\n')758 if len(en) < 6:759 return None760 hostportinfo = []761 list_key = ['id', 'name', 'info', 'type', 'hostid',762 'linkstatus', 'multioathtype']763 for i in range(6, len(en) - 2):764 list_val = en[i].split()765 hostport_dic = dict(map(None, list_key, list_val))766 hostportinfo.append(hostport_dic)767 return hostportinfo768 def _add_hostport(self, portname, hostid, portinfo, multipathtype=0):769 """Add a host port."""770 cli_cmd = ('addhostport -host %(id)s -type 5 '771 '-info %(info)s -n %(name)s -mtype %(mtype)s'772 % {'id': hostid,773 'info': portinfo,774 'name': portname,775 'mtype': multipathtype})776 out = self._execute_cli(cli_cmd)777 if not'command operates successfully', out):778 err_msg = (_('_add_hostport:Failed to add hostport. '779 'port name:%(port)s'780 'port information:%(info)s '781 'host id:%(host)s'782 'out:%(out)s')783 % {'port': portname,784 'info': portinfo,785 'host': hostid,786 'out': out})787 LOG.error(err_msg)788 raise exception.VolumeBackendAPIException(data=err_msg)789 def _delete_hostport(self, portid):790 """Delete a host port."""791 cli_cmd = ('delhostport -force -p %(portid)s'792 % {'portid': portid})793 out = self._execute_cli(cli_cmd)794 if not'command operates successfully', out):795 err_msg = (_('_delete_hostport:Failed to delete host port. '796 'port id:%(portid)s')797 % {'portid': portid})798 LOG.error(err_msg)799 def _get_tgt_iqn(self, iscsiip):800 """Get target iSCSI iqn."""801 LOG.debug(_('_get_tgt_iqn:iSCSI IP is %s.') % iscsiip)802 cli_cmd = ('showiscsitgtname')803 out = self._execute_cli(cli_cmd)804 en = out.split('\r\n')805 if len(en) < 4:806 return None807 index = en[4].find('iqn')808 iqn_prefix = en[4][index:]809 iqn_prefix.strip()810 iscsiip_info = self._get_iscsi_ip_info(iscsiip)811 if iscsiip_info:812 if iscsiip_info['ctrid'] == 'A':813 ctr = '0'814 elif iscsiip_info['ctrid'] == 'B':815 ctr = '1'816 interface = '0' + iscsiip_info['interfaceid']817 port = iscsiip_info['portid'].replace('P', '0')818 iqn_suffix = ctr + '02' + interface + port819 for i in range(0, len(iqn_suffix)):820 if iqn_suffix[i] != '0':821 iqn_suffix = iqn_suffix[i:]822 break823 if self.device_type['type'] == 'Tseries':824 iqn = iqn_prefix + ':' + iqn_suffix + ':' \825 + iscsiip_info['ipaddress']826 elif self.device_type['type'] == "Dorado2100 G2":827 iqn = iqn_prefix + ":" + iscsiip_info['ipaddress'] + "-" \828 + iqn_suffix829 else:830 iqn = iqn_prefix + ':' + iscsiip_info['ipaddress']831 LOG.debug(_('_get_tgt_iqn:iSCSI target iqn is:%s') % iqn)832 return iqn833 else:834 return None835 def _get_iscsi_ip_info(self, iscsiip):836 """Get iSCSI IP infomation of storage device."""837 cli_cmd = ('showiscsiip')838 out = self._execute_cli(cli_cmd)839 en = out.split('\r\n')840 if len(en) < 6:841 return None842 iscsiIPinfo = {}843 for i in range(6, len(en) - 2):844 r = en[i].split()845 if r[3] == iscsiip:846 iscsiIPinfo['ctrid'] = r[0]847 iscsiIPinfo['interfaceid'] = r[1]848 iscsiIPinfo['portid'] = r[2]849 iscsiIPinfo['ipaddress'] = r[3]850 return iscsiIPinfo851 return None852 def _map_lun(self, lunid, hostid, new_hostlun_id):853 """Map a lun to a host.854 Here we give the hostlun ID which starts from 1.855 """856 cli_cmd = ('addhostmap -host %(hostid)s -devlun %(lunid)s'857 '-hostlun %(hostlunid)s'858 % {'hostid': hostid,859 'lunid': lunid,860 'hostlunid': new_hostlun_id})861 out = self._execute_cli(cli_cmd)862 if not'command operates successfully', out):863 err_msg = (_('_map_lun:Failed to add hostmap.'864 'hostid:%(host)s'865 'lunid:%(lun)s'866 'hostlunid:%(hostlunid)s.'867 'out:%(out)s')868 % {'host': hostid,869 'lun': lunid,870 'hostlunid': new_hostlun_id,871 'out': out})872 LOG.error(err_msg)873 raise exception.VolumeBackendAPIException(data=err_msg)874 def _get_hostlunid(self, hostid, lunid):875 """Get the hostLUN ID of a LUN according host ID and LUN ID."""876 mapinfo = self._get_map_info(hostid)877 if mapinfo:878 for map in mapinfo:879 if map['devlunid'] == lunid:880 return map['hostlunid']881 return None882 def _delete_map(self, mapid, attempts=1):883 """Remove the map."""884 cli_cmd = ('delhostmap -force -map %(mapid)s'885 % {'mapid': mapid})886 while attempts >= 0:887 attempts -= 1888 out = self._execute_cli(cli_cmd)889 # We retry to delete host map 10s later if there are890 # IOs accessing the system.891 if'command operates successfully', out):892 break893 else:894 if'there are IOs accessing the system', out):895 time.sleep(10)896 LOG.debug(_('_delete_map:There are IOs accessing '897 'the system. Retry to delete host map. '898 'map id:%(mapid)s')899 % {'mapid': mapid})900 continue901 else:902 err_msg = (_('_delete_map:Failed to delete host map.'903 ' mapid:%(mapid)s '904 'out:%(out)s')905 % {'mapid': mapid,906 'out': out})907 LOG.error(err_msg)908 raise exception.VolumeBackendAPIException(data=err_msg)909 def _delete_host(self, hostid):910 """Delete a host."""911 cli_cmd = ('delhost -force -host %(hostid)s'912 % {'hostid': hostid})913 out = self._execute_cli(cli_cmd)914 if not'command operates successfully', out):915 err_msg = (_('Error: Failed delete host,host id: %(hostid)s.'916 'out:%(out)s')917 % {'hostid': hostid,918 'out': out})919 LOG.error(err_msg)920 raise exception.VolumeBackendAPIException(data=err_msg)921 def _get_map_info(self, hostid):922 """Get map infomation of the given host.923 This method return a map information list. Every item in the list924 is a dictionary. The dictionarie includes three keys: mapid,925 devlunid, hostlunid. These items are sorted by hostlunid value926 from small to large.927 """928 cli_cmd = ('showhostmap -host %(hostid)s'929 % {'hostid': hostid})930 out = self._execute_cli(cli_cmd)931 en = out.split('\r\n')932 if len(en) <= 6:933 return None934 mapinfo = []935 list_tmp = []936 list_key = ['mapid', 'devlunid', 'hostlunid']937 for i in range(6, len(en) - 2):938 list_tmp = en[i].split()939 list_val = [list_tmp[0], list_tmp[2], list_tmp[4]]940 dic = dict(map(None, list_key, list_val))941 inserted = False942 mapinfo_length = len(mapinfo)943 if mapinfo_length == 0:944 mapinfo.append(dic)945 continue946 for index in range(0, mapinfo_length):947 if (int(mapinfo[mapinfo_length - index - 1]['hostlunid']) <948 int(dic['hostlunid'])):949 mapinfo.insert(mapinfo_length - index, dic)950 inserted = True951 break952 if not inserted:953 mapinfo.insert(0, dic)954 return mapinfo955 def _get_device_type(self):956 """Get the storage device type and product version."""957 cli_cmd = ('showsys')958 out = self._execute_cli(cli_cmd)959 en = out.split('\r\n')960 if len(en) <= 6:961 return None962 for line in en:963 if'Device Type', line):964 if'T$', line):965 device_type = 'Tseries'966 elif'Dorado2100 G2$', line):967 device_type = 'Dorado2100 G2'968 elif'Dorado5100$', line):969 device_type = 'Dorado5100'970 else:971 device_type = None972 continue973 if'Product Version', line):974 if'V100R+', line):975 product_version = 'V100R'976 else:977 product_version = None978 break979 r = {'type': device_type, 'version': product_version}980 return r981 def _active_snapshot(self, snapshotid):982 """Active a snapshot."""983 cli_cmd = ('actvsnapshot -snapshot %(snapshotid)s'984 % {'snapshotid': snapshotid})985 out = self._execute_cli(cli_cmd)986 if not'command operates successfully', out):987 err_msg = (_('_active_snapshot:Failed to active snapshot. '988 'snapshot id:%(name)s. '989 'out:%(out)s')990 % {'name': snapshotid,991 'out': out})992 LOG.error(err_msg)993 raise exception.VolumeBackendAPIException(data=err_msg)994 def _disable_snapshot(self, snapshotid):995 """Disable a snapshot."""996 cli_cmd = ('disablesnapshot -snapshot %(snapshotid)s'997 % {'snapshotid': snapshotid})998 out = self._execute_cli(cli_cmd)999 if not'command operates successfully', out):1000 err_msg = (_('_disable_snapshot:Failed to disable snapshot. '1001 'snapshot id:%(id)s. '1002 'out:%(out)s')1003 % {'id': snapshotid,1004 'out': out})1005 LOG.error(err_msg)1006 raise exception.VolumeBackendAPIException(data=err_msg)1007 def _delete_snapshot(self, snapshotid):1008 """Delete a snapshot."""1009 cli_cmd = ('delsnapshot -snapshot %(snapshotid)s'1010 % {'snapshotid': snapshotid})1011 out = self._execute_cli(cli_cmd)1012 if not'command operates successfully', out):1013 err_msg = (_('_delete_snapshot:Failed to delete snapshot. '1014 'snapshot id:%(id)s. '1015 'out:%(out)s')1016 % {'id': snapshotid,1017 'out': out})1018 LOG.error(err_msg)1019 raise exception.VolumeBackendAPIException(data=err_msg)1020 def _create_volume(self, name, size):1021 """Create a new volume with the given name and size."""1022 lunsetinfo = self._get_lun_set_info()1023 cli_cmd = ('createlun -n %(name)s -lunsize %(size)s '1024 '-wrtype %(wrtype)s '1025 % {'name': name,1026 'size': size,1027 'wrtype': lunsetinfo['WriteType']})1028 # If write type is "write through", no need to set mirror switch.1029 if lunsetinfo['WriteType'] != '2':1030 cli_cmd = cli_cmd + ('-mirrorsw %(mirrorsw)s '1031 % {'mirrorsw': lunsetinfo['MirrorSwitch']})1032 # Differences exist between "Thin" and "thick" LUN for CLI commands.1033 luntype = lunsetinfo['LUNType']1034 if luntype == 'Thin':1035 dorado2100g2_luntype = '2'1036 Tseries = ('-pool %(pool)s '1037 % {'pool': lunsetinfo['StoragePool']})1038 else:1039 dorado2100g2_luntype = '3'1040 Tseries = ('-rg %(raidgroup)s -susize %(susize)s '1041 % {'raidgroup': lunsetinfo['StoragePool'],1042 'susize': lunsetinfo['StripUnitSize']})1043 prefetch_value_or_times = ''1044 pretype = '-pretype %s ' % lunsetinfo['PrefetchType']1045 # If constant prefetch, we should set prefetch value.1046 if lunsetinfo['PrefetchType'] == '1':1047 prefetch_value_or_times = '-value %s' % lunsetinfo['PrefetchValue']1048 # If variable prefetch, we should set prefetch mutiple.1049 elif lunsetinfo['PrefetchType'] == '2':1050 prefetch_value_or_times = '-times %s' % lunsetinfo['PrefetchTimes']1051 if self.device_type['type'] == 'Tseries':1052 cli_cmd = cli_cmd + Tseries + pretype + prefetch_value_or_times1053 elif self.device_type['type'] == 'Dorado5100':1054 cli_cmd = cli_cmd + ('-rg %(raidgroup)s -susize %(susize)s'1055 % {'raidgroup': lunsetinfo['StoragePool'],1056 'susize': lunsetinfo['StripUnitSize']})1057 elif self.device_type['type'] == 'Dorado2100 G2':1058 cli_cmd = cli_cmd + ('-type %(type)s'1059 % {'type': dorado2100g2_luntype})1060 out = self._execute_cli(cli_cmd)1061 if not'command operates successfully', out):1062 err_msg = (_('_create_volume:Failed to Create volume. '1063 'volume name:%(name)s. '1064 'out:%(out)s')1065 % {'name': name,1066 'out': out})1067 LOG.error(err_msg)1068 raise exception.VolumeBackendAPIException(data=err_msg)1069 def _delete_volume(self, name, lunid):1070 """Delete a volume."""1071 cli_cmd = ('dellun -force -lun %s' % (lunid))1072 out = self._execute_cli(cli_cmd)1073 if not'command operates successfully', out):1074 err_msg = (_('_delete_volume:Failed to delete volume. '1075 'Volume name:%(name)s '1076 'out:%(out)s')1077 % {'name': name,1078 'out': out})1079 LOG.error(err_msg)1080 raise exception.VolumeBackendAPIException(data=err_msg)1081 def _create_luncopy(self, luncopyname, srclunid, tgtlunid):1082 """Create a LUNcopy."""1083 cli_cmd = ('createluncopy -n %(name)s -l 4 -slun %(srclunid)s '1084 '-tlun %(tgtlunid)s'1085 % {'name': luncopyname,1086 'srclunid': srclunid,1087 'tgtlunid': tgtlunid})1088 out = self._execute_cli(cli_cmd)1089 if not'command operates successfully', out):1090 err_msg = (_('_create_luncopy:Failed to Create LUNcopy. '1091 'LUNcopy name:%(name)s '1092 'out:%(out)s')1093 % {'name': luncopyname,1094 'out': out})1095 LOG.error(err_msg)1096 raise exception.VolumeBackendAPIException(data=err_msg)1097 def _start_luncopy(self, luncopyid):1098 """Starte a LUNcopy."""1099 cli_cmd = ('chgluncopystatus -luncopy %(luncopyid)s -start'1100 % {'luncopyid': luncopyid})1101 out = self._execute_cli(cli_cmd)1102 if not'command operates successfully', out):1103 err_msg = (_('_start_luncopy:Failed to start LUNcopy. '1104 'LUNcopy id:%(luncopyid)s '1105 'out:%(out)s')1106 % {'luncopyid': luncopyid,1107 'out': out})1108 LOG.error(err_msg)1109 raise exception.VolumeBackendAPIException(data=err_msg)1110 def _find_luncopy(self, luncopyname):1111 """Get the given LUNcopy's ID."""1112 cli_cmd = ('showluncopy')1113 out = self._execute_cli(cli_cmd)1114 en = out.split('\r\n')1115 if len(en) <= 6:1116 return None1117 for i in range(6, len(en) - 2):1118 r = en[i].split()1119 if r[0] == luncopyname:1120 luncopyid = r[1]1121 return luncopyid1122 return None1123 def _wait_for_luncopy(self, luncopyname):1124 """Wait for LUNcopy to complete."""1125 while True:1126 luncopy_info = self._get_luncopy_info(luncopyname)1127 if luncopy_info['state'] == 'Complete':1128 break1129 elif luncopy_info['status'] != 'Normal':1130 err_msg = (_('_wait_for_luncopy:LUNcopy status isnot normal. '1131 'LUNcopy name:%(luncopyname)s')1132 % {'luncopyname': luncopyname})1133 LOG.error(err_msg)1134 raise exception.VolumeBackendAPIException(data=err_msg)1135 time.sleep(10)1136 def _get_luncopy_info(self, luncopyname):1137 """Get LUNcopy information."""1138 cli_cmd = ('showluncopy')1139 out = self._execute_cli(cli_cmd)1140 en = out.split('\r\n')1141 if len(en) <= 6:1142 return None1143 luncopyinfo = {}1144 for i in range(6, len(en) - 2):1145 r = en[i].split()1146 if r[0] == luncopyname:1147 luncopyinfo['name'] = r[0]1148 luncopyinfo['id'] = r[1]1149 luncopyinfo['state'] = r[3]1150 luncopyinfo['status'] = r[4]1151 return luncopyinfo1152 return None1153 def _delete_luncopy(self, luncopyid):1154 """Delete a LUNcopy."""1155 cli_cmd = ('delluncopy -luncopy %(id)s'1156 % {'id': luncopyid})1157 out = self._execute_cli(cli_cmd)1158 if not'command operates successfully', out):1159 err_msg = (_('_delete_luncopy:Failed to delete LUNcopy. '1160 'LUNcopy id:%(luncopyid)s '1161 'out:%(out)s')1162 % {'luncopyid': luncopyid,1163 'out': out})1164 LOG.error(err_msg)1165 raise exception.VolumeBackendAPIException(data=err_msg)1166 def _create_snapshot(self, snapshotname, srclunid):1167 """Create a snapshot with snapshot name and source LUN ID."""1168 cli_cmd = ('createsnapshot -lun %(lunid)s -n %(snapname)s'1169 % {'lunid': srclunid,1170 'snapname': snapshotname})1171 out = self._execute_cli(cli_cmd)1172 if not'command operates successfully', out):1173 err_msg = (_('_create_snapshot:Failed to Create snapshot. '1174 'Snapshot name:%(name)s '1175 'out:%(out)s')1176 % {'name': snapshotname,1177 'out': out})1178 LOG.error(err_msg)1179 raise exception.VolumeBackendAPIException(data=err_msg)1180 def _find_snapshot(self, snapshotname):1181 """Get the given snapshot ID."""1182 cli_cmd = ('showsnapshot')1183 out = self._execute_cli(cli_cmd)1184 en = out.split('\r\n')1185 if len(en) <= 6:1186 return None1187 for i in range(6, len(en) - 2):1188 r = en[i].split()1189 if r[0] == snapshotname:1190 return r[1]1191 return None1192 def _is_resource_pool_enough(self):1193 """Check whether resource pools' valid size is more than 1G."""1194 cli_cmd = ('showrespool')1195 out = self._execute_cli(cli_cmd)1196 en = re.split('\r\n', out)1197 if len(en) <= 6:1198 LOG.error(_('_is_resource_pool_enough:Resource pool for snapshot'1199 'not be added.'))1200 return False1201 resource_pools = []1202 list_key = ['pool id', 'size', 'usage', 'valid size',1203 'alarm threshold']1204 for i in range(6, len(en) - 2):1205 list_val = en[i].split()1206 dic = dict(map(None, list_key, list_val))1207 resource_pools.append(dic)1208 for pool in resource_pools:1209 if float(pool['valid size']) < 1024.0:1210 return False1211 return True1212 def _update_volume_status(self):1213 """Retrieve status info from volume group."""1214 LOG.debug(_("Updating volume status"))1215 data = {}1216 backend_name = self.configuration.safe_get('volume_backend_name')1217 data["volume_backend_name"] = backend_name or 'HuaweiISCSIDriver'1218 data['vendor_name'] = 'Huawei'1219 data['driver_version'] = '1.0'1220 data['storage_protocol'] = 'iSCSI'1221 data['total_capacity_gb'] = 'infinite'1222 data['free_capacity_gb'] = self._get_free_capacity()1223 data['reserved_percentage'] = 01224 self._stats = data1225 def _get_free_capacity(self):1226 """Get total free capacity of pools."""1227 self.login_info = self._get_login_info()1228 self.device_type = self._get_device_type()1229 root = self._read_xml()1230 lun_type = root.findtext('LUN/LUNType')1231 if (self.device_type['type'] == 'Dorado5100' or not lun_type):1232 lun_type = 'Thick'1233 elif self.device_type['type'] == 'Dorado2100 G2':1234 lun_type = 'Thin'1235 poolinfo_dev = self._find_pool_info(lun_type)1236 pools_conf = root.findall('LUN/StoragePool')1237 total_free_capacity = 01238 for poolinfo in poolinfo_dev:1239 if self.device_type['type'] == 'Dorado2100 G2':1240 total_free_capacity += float(poolinfo[2])1241 continue1242 for pool in pools_conf:1243 if ((self.device_type['type'] == 'Dorado5100') and1244 (poolinfo[5] == pool.attrib['Name'])):1245 total_free_capacity += float(poolinfo[3])1246 break1247 else:1248 if ((lun_type == 'Thick') and1249 (poolinfo[5] == pool.attrib['Name'])):1250 total_free_capacity += float(poolinfo[3])1251 break1252 elif poolinfo[1] == pool.attrib['Name']:1253 total_free_capacity += float(poolinfo[4])1254 break...

Full Screen

Full Screen Github


Full Screen

...89 if os.path.isfile('../../wlantest/wlantest_cli'):90 self.wlantest_cli = '../../wlantest/wlantest_cli'91 else:92 self.wlantest_cli = 'wlantest_cli'93 def cli_cmd(self, params):94 if self.remote_host is not None:95 exe = self.setup_params["wlantest_cli"]96 ret = self.remote_host.execute([exe] + params)97 if ret[0] != 0:98 raise Exception("wlantest_cli failed")99 return ret[1]100 else:101 return subprocess.check_output([self.wlantest_cli] + params)102 def flush(self):103 res = self.cli_cmd(["flush"])104 if "FAIL" in res:105 raise Exception("wlantest_cli flush failed")106 def relog(self):107 res = self.cli_cmd(["relog"])108 if "FAIL" in res:109 raise Exception("wlantest_cli relog failed")110 def add_passphrase(self, passphrase):111 res = self.cli_cmd(["add_passphrase", passphrase])112 if "FAIL" in res:113 raise Exception("wlantest_cli add_passphrase failed")114 def add_wepkey(self, key):115 res = self.cli_cmd(["add_wepkey", key])116 if "FAIL" in res:117 raise Exception("wlantest_cli add_key failed")118 def info_bss(self, field, bssid):119 res = self.cli_cmd(["info_bss", field, bssid])120 if "FAIL" in res:121 raise Exception("Could not get BSS info from wlantest for " + bssid)122 return res123 def get_bss_counter(self, field, bssid):124 try:125 res = self.cli_cmd(["get_bss_counter", field, bssid])126 except Exception, e:127 return 0128 if "FAIL" in res:129 return 0130 return int(res)131 def clear_bss_counters(self, bssid):132 self.cli_cmd(["clear_bss_counters", bssid])133 def info_sta(self, field, bssid, addr):134 res = self.cli_cmd(["info_sta", field, bssid, addr])135 if "FAIL" in res:136 raise Exception("Could not get STA info from wlantest for " + addr)137 return res138 def get_sta_counter(self, field, bssid, addr):139 res = self.cli_cmd(["get_sta_counter", field, bssid, addr])140 if "FAIL" in res:141 raise Exception("wlantest_cli command failed")142 return int(res)143 def clear_sta_counters(self, bssid, addr):144 res = self.cli_cmd(["clear_sta_counters", bssid, addr])145 if "FAIL" in res:146 raise Exception("wlantest_cli command failed")147 def tdls_clear(self, bssid, addr1, addr2):148 self.cli_cmd(["clear_tdls_counters", bssid, addr1, addr2])149 def get_tdls_counter(self, field, bssid, addr1, addr2):150 res = self.cli_cmd(["get_tdls_counter", field, bssid, addr1, addr2])151 if "FAIL" in res:152 raise Exception("wlantest_cli command failed")153 return int(res)154 def require_ap_pmf_mandatory(self, bssid):155 res = self.info_bss("rsn_capab", bssid)156 if "MFPR" not in res:157 raise Exception("AP did not require PMF")158 if "MFPC" not in res:159 raise Exception("AP did not enable PMF")160 res = self.info_bss("key_mgmt", bssid)161 if "PSK-SHA256" not in res:162 raise Exception("AP did not enable SHA256-based AKM for PMF")163 def require_ap_pmf_optional(self, bssid):164 res = self.info_bss("rsn_capab", bssid)165 if "MFPR" in res:166 raise Exception("AP required PMF")167 if "MFPC" not in res:168 raise Exception("AP did not enable PMF")169 def require_ap_no_pmf(self, bssid):170 res = self.info_bss("rsn_capab", bssid)171 if "MFPR" in res:172 raise Exception("AP required PMF")173 if "MFPC" in res:174 raise Exception("AP enabled PMF")175 def require_sta_pmf_mandatory(self, bssid, addr):176 res = self.info_sta("rsn_capab", bssid, addr)177 if "MFPR" not in res:178 raise Exception("STA did not require PMF")179 if "MFPC" not in res:180 raise Exception("STA did not enable PMF")181 def require_sta_pmf(self, bssid, addr):182 res = self.info_sta("rsn_capab", bssid, addr)183 if "MFPC" not in res:184 raise Exception("STA did not enable PMF")185 def require_sta_no_pmf(self, bssid, addr):186 res = self.info_sta("rsn_capab", bssid, addr)187 if "MFPC" in res:188 raise Exception("STA enabled PMF")189 def require_sta_key_mgmt(self, bssid, addr, key_mgmt):190 res = self.info_sta("key_mgmt", bssid, addr)191 if key_mgmt not in res:192 raise Exception("Unexpected STA key_mgmt")193 def get_tx_tid(self, bssid, addr, tid):194 res = self.cli_cmd(["get_tx_tid", bssid, addr, str(tid)])195 if "FAIL" in res:196 raise Exception("wlantest_cli command failed")197 return int(res)198 def get_rx_tid(self, bssid, addr, tid):199 res = self.cli_cmd(["get_rx_tid", bssid, addr, str(tid)])200 if "FAIL" in res:201 raise Exception("wlantest_cli command failed")202 return int(res)203 def get_tid_counters(self, bssid, addr):204 tx = {}205 rx = {}206 for tid in range(0, 17):207 tx[tid] = self.get_tx_tid(bssid, addr, tid)208 rx[tid] = self.get_rx_tid(bssid, addr, tid)...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:


You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run avocado automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?