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

Reply via email to