]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
mgr/dashboard: Gracefully handle client/target info not found
authorRicardo Marques <rimarques@suse.com>
Wed, 11 Sep 2019 17:42:44 +0000 (18:42 +0100)
committerRicardo Marques <rimarques@suse.com>
Thu, 26 Sep 2019 13:03:40 +0000 (14:03 +0100)
Fixes: https://tracker.ceph.com/issues/41779
Signed-off-by: Ricardo Marques <rimarques@suse.com>
(cherry picked from commit d01835fb8cf24f6ccd6e50f529ac44077b11d3de)

Conflicts:
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts

Conflicts caused by https://github.com/ceph/ceph/pull/27376

src/pybind/mgr/dashboard/controllers/iscsi.py
src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts

index 8d7a8e72a4d9a9933efe45351889568268971c1d..15cfd750069becf61b8e6bb79131e146e222e9ea 100644 (file)
@@ -718,19 +718,36 @@ class IscsiTarget(RESTController):
         }
         return target
 
+    @staticmethod
+    def _is_executing(target_iqn):
+        executing_tasks, _ = TaskManager.list()
+        for t in executing_tasks:
+            if t.name.startswith('iscsi/target') and t.metadata.get('target_iqn') == target_iqn:
+                return True
+        return False
+
     @staticmethod
     def _set_info(target):
         if not target['portals']:
             return
         target_iqn = target['target_iqn']
+        # During task execution, additional info is not available
+        if IscsiTarget._is_executing(target_iqn):
+            return
         gateway_name = target['portals'][0]['host']
-        target_info = IscsiClient.instance(gateway_name=gateway_name).get_targetinfo(target_iqn)
-        target['info'] = target_info
-        for client in target['clients']:
-            client_iqn = client['client_iqn']
-            client_info = IscsiClient.instance(gateway_name=gateway_name).get_clientinfo(
-                target_iqn, client_iqn)
-            client['info'] = client_info
+        try:
+            target_info = IscsiClient.instance(gateway_name=gateway_name).get_targetinfo(
+                target_iqn)
+            target['info'] = target_info
+            for client in target['clients']:
+                client_iqn = client['client_iqn']
+                client_info = IscsiClient.instance(gateway_name=gateway_name).get_clientinfo(
+                    target_iqn, client_iqn)
+                client['info'] = client_info
+        except RequestException as e:
+            # Target/Client has been removed in the meanwhile (e.g. using gwcli)
+            if e.status_code != 404:
+                raise e
 
     @staticmethod
     def _sorted_portals(portals):
index b4e482a8fa5a6a531be2a54e658239810b2bbeb5..fa5c2c267be9f95f9f335d729059c62de448e2ef 100644 (file)
@@ -78,7 +78,9 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit {
 
     const cssClasses = {
       target: {
-        expanded: 'fa fa-fw fa-bullseye fa-lg'
+        expanded: this.selectedItem.cdExecuting
+          ? 'fa fa-fw fa-spinner fa-spin fa-lg'
+          : 'fa fa-fw fa-bullseye fa-lg'
       },
       initiators: {
         expanded: 'fa fa-fw fa-user fa-lg',
@@ -120,11 +122,13 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit {
     const clients = [];
     _.forEach(this.selectedItem.clients, (client) => {
       const client_metadata = _.cloneDeep(client.auth);
-      _.extend(client_metadata, client.info);
-      delete client_metadata['state'];
-      _.forEach(Object.keys(client.info.state), (state) => {
-        client_metadata[state.toLowerCase()] = client.info.state[state];
-      });
+      if (client.info) {
+        _.extend(client_metadata, client.info);
+        delete client_metadata['state'];
+        _.forEach(Object.keys(client.info.state), (state) => {
+          client_metadata[state.toLowerCase()] = client.info.state[state];
+        });
+      }
       this.metadata['client_' + client.client_iqn] = client_metadata;
 
       const luns = [];
@@ -138,9 +142,13 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit {
         });
       });
 
+      let status = '';
+      if (client.info) {
+        status = Object.keys(client.info.state).includes('LOGGED_IN') ? 'logged_in' : 'logged_out';
+      }
       clients.push({
         value: client.client_iqn,
-        status: Object.keys(client.info.state).includes('LOGGED_IN') ? 'logged_in' : 'logged_out',
+        status: status,
         id: 'client_' + client.client_iqn,
         children: luns
       });