Sandro Bonazzola has uploaded a new change for review. Change subject: packaging: setup: iscsi: add multiple lun per target support ......................................................................
packaging: setup: iscsi: add multiple lun per target support Add support for multiple lun on the same target. It allows to choose the lun to be used when more than one is available on the target. Change-Id: I0b00cc09754a8b95bc1497e0f769ae2a9c64f1b5 Bug-Url: https://bugzilla.redhat.com/1125315 Signed-off-by: Sandro Bonazzola <sbona...@redhat.com> --- M src/ovirt_hosted_engine_setup/constants.py M src/plugins/ovirt-hosted-engine-setup/storage/iscsi.py 2 files changed, 116 insertions(+), 32 deletions(-) git pull ssh://gerrit.ovirt.org:29418/ovirt-hosted-engine-setup refs/changes/98/31398/1 diff --git a/src/ovirt_hosted_engine_setup/constants.py b/src/ovirt_hosted_engine_setup/constants.py index 2b471d8..8cdf91c 100644 --- a/src/ovirt_hosted_engine_setup/constants.py +++ b/src/ovirt_hosted_engine_setup/constants.py @@ -500,6 +500,14 @@ def ISCSI_TARGET(self): return 'OVEHOSTED_STORAGE/iSCSITargetName' + @ohostedattrs( + answerfile=True, + summary=True, + description=_('iSCSI LUN ID'), + ) + def ISCSI_LUN_ID(self): + return 'OVEHOSTED_STORAGE/iSCSILunId' + ISCSI_PASSWORD = 'OVEHOSTED_STORAGE/iSCSIPortalPassword' @ohostedattrs( diff --git a/src/plugins/ovirt-hosted-engine-setup/storage/iscsi.py b/src/plugins/ovirt-hosted-engine-setup/storage/iscsi.py index 264bf9e..a6f2e13 100644 --- a/src/plugins/ovirt-hosted-engine-setup/storage/iscsi.py +++ b/src/plugins/ovirt-hosted-engine-setup/storage/iscsi.py @@ -158,25 +158,69 @@ return password def _customize_target(self, values, default): - valid = False - while not valid: - target = self.environment[ohostedcons.StorageEnv.ISCSI_TARGET] - if target is None: - self._interactive = True - target = self.dialog.queryString( - name='OVEHOSTED_STORAGE_ISCSI_TARGET', - note=_( - 'Please specify the target name ' - '(@VALUES@) [@DEFAULT@]: ' - ), - prompt=True, - caseSensitive=True, - default=default, - validValues=values, - ) - self._validate_domain(target) - valid = True - self.environment[ohostedcons.StorageEnv.ISCSI_TARGET] = target + target = self.environment[ohostedcons.StorageEnv.ISCSI_TARGET] + if target is None: + self._interactive = True + target = self.dialog.queryString( + name='OVEHOSTED_STORAGE_ISCSI_TARGET', + note=_( + 'Please specify the target name ' + '(@VALUES@) [@DEFAULT@]: ' + ), + prompt=True, + caseSensitive=True, + default=default, + validValues=values, + ) + return target + + def _customize_lun(self, target): + available_luns = self._iscsi_get_lun_list( + ip=self.environment[ohostedcons.StorageEnv.ISCSI_IP_ADDR], + port=self.environment[ohostedcons.StorageEnv.ISCSI_PORT], + user=self.environment[ohostedcons.StorageEnv.ISCSI_USER], + password=self.environment[ohostedcons.StorageEnv.ISCSI_PASSWORD], + iqn=target, + ) + lun_list = '' + lun_data = {} + default = None + for entry in available_luns: + for pathstatus in entry['pathstatus']: + lun_data[pathstatus['lun']] = pathstatus['physdev'] + values = lun_data.keys() + values.sort() + for lunid in values: + lun_list += '\t {lunid} - {physdev}\n'.format( + lunid=lunid, + physdev=lun_data[lunid], + ) + self.dialog.note( + _( + 'The following luns have been found on the requested target:\n' + '{lun_list}' + ).format( + lun_list=lun_list, + ) + ) + if len(values) > 0: + values.sort() + default = values[0] + lun = self.environment[ohostedcons.StorageEnv.ISCSI_LUN_ID] + if lun is None: + self._interactive = True + lun = self.dialog.queryString( + name='OVEHOSTED_STORAGE_ISCSI_LUN', + note=_( + 'Please specify the lun id ' + '(@VALUES@) [@DEFAULT@]: ' + ), + prompt=True, + caseSensitive=True, + default=default, + validValues=values, + ) + return str(lun) def _iscsi_discovery(self, address, port, user, password): targets = self.serv.s.discoverSendTargets( @@ -192,11 +236,11 @@ raise RuntimeError(targets['status']['message']) return targets['targets'] - def _iscsi_get_device(self, ip, port, user, password, iqn): + def _iscsi_get_lun_list(self, ip, port, user, password, iqn): retry = self._MAXRETRY - iscsi_device = None - while iscsi_device is None and retry > 0: - # check if the device is already known to VDSM + iscsi_lun_list = [] + iqn_found = False + while not iqn_found and retry > 0: devices = self.serv.s.getDeviceList( ohostedcons.VDSMConstants.ISCSI_DOMAIN ) @@ -206,9 +250,9 @@ for device in devices['devList']: for path in device['pathlist']: if path['iqn'] == iqn: - iscsi_device = device - retry = -1 - if iscsi_device is None: + iscsi_lun_list.append(device) + iqn_found = True + if not iqn_found: self.logger.info('Discovering iSCSI node') self._iscsi_discovery( ip, @@ -236,15 +280,26 @@ raise RuntimeError(devices['status']['message']) retry -= 1 time.sleep(self._RETRY_DELAY) - return iscsi_device + return iscsi_lun_list - def _validate_domain(self, target): + def _iscsi_get_device(self, ip, port, user, password, iqn, lun): + available_luns = self._iscsi_get_lun_list( + ip, port, user, password, iqn + ) + for iscsi_device in available_luns: + for pathstatus in iscsi_device['pathstatus']: + if pathstatus['lun'] == lun: + return iscsi_device + return None + + def _validate_domain(self, target, lun): device = self._iscsi_get_device( ip=self.environment[ohostedcons.StorageEnv.ISCSI_IP_ADDR], port=self.environment[ohostedcons.StorageEnv.ISCSI_PORT], user=self.environment[ohostedcons.StorageEnv.ISCSI_USER], password=self.environment[ohostedcons.StorageEnv.ISCSI_PASSWORD], iqn=target, + lun=lun ) if device is None: raise RuntimeError( @@ -321,6 +376,10 @@ None ) self.environment.setdefault( + ohostedcons.StorageEnv.ISCSI_LUN_ID, + None + ) + self.environment.setdefault( ohostedcons.StorageEnv.VG_UUID, None ) @@ -343,10 +402,13 @@ def _customization(self): self.serv = self.environment[ohostedcons.VDSMEnv.VDS_CLI] valid_access = False + valid_lun = False address = None port = None user = None password = None + target = None + lun = None valid_targets = [] while not valid_access: address = self._customize_ip_address() @@ -373,10 +435,23 @@ self.environment[ohostedcons.StorageEnv.ISCSI_USER] = user self.environment[ohostedcons.StorageEnv.ISCSI_PASSWORD] = password - self._customize_target( - values=valid_targets, - default=valid_targets[0] - ) + while not valid_lun: + target = self._customize_target( + values=valid_targets, + default=valid_targets[0] + ) + lun = self._customize_lun(target) + try: + self._validate_domain(target, lun) + valid_lun = True + except Exception as e: + self.logger.debug('exception', exc_info=True) + self.logger.error(e) + if not self._interactive: + raise RuntimeError(_('Cannot access iSCSI LUN')) + + self.environment[ohostedcons.StorageEnv.ISCSI_TARGET] = target + self.environment[ohostedcons.StorageEnv.ISCSI_LUN_ID] = lun @plugin.event( stage=plugin.Stages.STAGE_MISC, @@ -399,6 +474,7 @@ user=self.environment[ohostedcons.StorageEnv.ISCSI_USER], password=self.environment[ohostedcons.StorageEnv.ISCSI_PASSWORD], iqn=self.environment[ohostedcons.StorageEnv.ISCSI_TARGET], + lun=self.environment[ohostedcons.StorageEnv.ISCSI_LUN_ID], ) if self.environment[ohostedcons.StorageEnv.VG_UUID] is None: -- To view, visit http://gerrit.ovirt.org/31398 To unsubscribe, visit http://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I0b00cc09754a8b95bc1497e0f769ae2a9c64f1b5 Gerrit-PatchSet: 1 Gerrit-Project: ovirt-hosted-engine-setup Gerrit-Branch: master Gerrit-Owner: Sandro Bonazzola <sbona...@redhat.com> _______________________________________________ Engine-patches mailing list Engine-patches@ovirt.org http://lists.ovirt.org/mailman/listinfo/engine-patches