From: Ricardo Marques Date: Wed, 11 Sep 2019 17:42:44 +0000 (+0100) Subject: mgr/dashboard: Gracefully handle client/target info not found X-Git-Tag: v15.1.0~1439^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=d01835fb8cf24f6ccd6e50f529ac44077b11d3de;p=ceph-ci.git mgr/dashboard: Gracefully handle client/target info not found Fixes: https://tracker.ceph.com/issues/41779 Signed-off-by: Ricardo Marques --- diff --git a/src/pybind/mgr/dashboard/controllers/iscsi.py b/src/pybind/mgr/dashboard/controllers/iscsi.py index 57f518721af..88baee92097 100644 --- a/src/pybind/mgr/dashboard/controllers/iscsi.py +++ b/src/pybind/mgr/dashboard/controllers/iscsi.py @@ -708,19 +708,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): diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts index a87e5f24122..73af8e927ce 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-details/iscsi-target-details.component.ts @@ -78,7 +78,12 @@ export class IscsiTargetDetailsComponent implements OnChanges, OnInit { this.metadata = { root: this.selectedItem.target_controls }; const cssClasses = { target: { - expanded: _.join([Icons.large, Icons.bullseye], ' ') + expanded: _.join( + this.selectedItem.cdExecuting + ? [Icons.large, Icons.spinner, Icons.spin] + : [Icons.large, Icons.bullseye], + ' ' + ) }, initiators: { expanded: _.join([Icons.large, Icons.user], ' '), @@ -120,11 +125,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 +145,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 });