From 5c3b2d74aeb3a4bd58e151b08fc76f6cf70bba9c Mon Sep 17 00:00:00 2001 From: Afreen Date: Tue, 13 Feb 2024 15:56:09 +0530 Subject: [PATCH] mgr/dashboard: Handle errors for /api/osd/settings Fixes https://tracker.ceph.com/issues/62089 issue: ===== /api/osd/settings returns "TypeError: string indices must be integers" sometimes. The result is coming from `osd dump` command which instead of returning an object returns an error message which then displays error on dashboard. fix: ==== Added a try-catch block to handle error and updated frontend code to handle those Signed-off-by: Afreen (cherry picked from commit 518bff9c7ed6f6756aff8aa8013c48a5bfdd7b32) --- src/pybind/mgr/dashboard/controllers/osd.py | 15 ++++-- .../dashboard-pie/dashboard-pie.component.ts | 49 ++++++++++--------- .../ceph/dashboard/health/health.component.ts | 7 ++- .../usage-bar/usage-bar.component.html | 2 +- 4 files changed, 44 insertions(+), 29 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/osd.py b/src/pybind/mgr/dashboard/controllers/osd.py index f6f8ce1f58a8a..c9d1417720005 100644 --- a/src/pybind/mgr/dashboard/controllers/osd.py +++ b/src/pybind/mgr/dashboard/controllers/osd.py @@ -168,11 +168,18 @@ class Osd(RESTController): @RESTController.Collection('GET', version=APIVersion.EXPERIMENTAL) @ReadPermission def settings(self): - result = CephService.send_command('mon', 'osd dump') - return { - 'nearfull_ratio': result['nearfull_ratio'], - 'full_ratio': result['full_ratio'] + data = { + 'nearfull_ratio': -1, + 'full_ratio': -1 } + try: + result = CephService.send_command('mon', 'osd dump') + data['nearfull_ratio'] = result['nearfull_ratio'] + data['full_ratio'] = result['full_ratio'] + except TypeError: + logger.error( + 'Error setting nearfull_ratio and full_ratio:', exc_info=True) + return data def _get_operational_status(self, osd_id: int, removing_osd_ids: Optional[List[int]]): if removing_osd_ids is None: diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard-pie/dashboard-pie.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard-pie/dashboard-pie.component.ts index 4680fb850a144..b0c253c33e9d8 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard-pie/dashboard-pie.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard-v3/dashboard-pie/dashboard-pie.component.ts @@ -59,7 +59,7 @@ export class DashboardPieComponent implements OnChanges, OnInit { constructor(private cssHelper: CssHelper, private dimlessBinary: DimlessBinaryPipe) { this.chartConfig = { chartType: 'doughnut', - labels: ['', '', ''], + labels: [], dataset: [ { label: null, @@ -97,19 +97,20 @@ export class DashboardPieComponent implements OnChanges, OnInit { fillStyle: chart.data.datasets[1].backgroundColor[0], strokeStyle: chart.data.datasets[1].backgroundColor[0] }; - labels[1] = { - text: $localize`Warning: ${chart.data.datasets[0].data[0]}%`, - fillStyle: chart.data.datasets[0].backgroundColor[1], - strokeStyle: chart.data.datasets[0].backgroundColor[1] - }; - labels[2] = { - text: $localize`Danger: ${ - chart.data.datasets[0].data[0] + chart.data.datasets[0].data[1] - }%`, - fillStyle: chart.data.datasets[0].backgroundColor[2], - strokeStyle: chart.data.datasets[0].backgroundColor[2] - }; - + if (chart.data.datasets[0].data?.length) { + labels[1] = { + text: $localize`Warning: ${chart.data.datasets[0].data[0]}%`, + fillStyle: chart.data.datasets[0].backgroundColor[1], + strokeStyle: chart.data.datasets[0].backgroundColor[1] + }; + labels[2] = { + text: $localize`Danger: ${ + chart.data.datasets[0].data[0] + chart.data.datasets[0].data[1] + }%`, + fillStyle: chart.data.datasets[0].backgroundColor[2], + strokeStyle: chart.data.datasets[0].backgroundColor[2] + }; + } return labels; } } @@ -158,19 +159,24 @@ export class DashboardPieComponent implements OnChanges, OnInit { const fullRatioPercent = this.highThreshold * 100; const percentAvailable = this.calcPercentage(data.max - data.current, data.max); const percentUsed = this.calcPercentage(data.current, data.max); - if (percentUsed >= fullRatioPercent) { + + if (fullRatioPercent >= 0 && percentUsed >= fullRatioPercent) { this.color = 'chart-color-red'; - } else if (percentUsed >= nearFullRatioPercent) { + } else if (nearFullRatioPercent >= 0 && percentUsed >= nearFullRatioPercent) { this.color = 'chart-color-yellow'; } else { this.color = 'chart-color-blue'; } - chart.dataset[0].data = [ - Math.round(nearFullRatioPercent), - Math.round(Math.abs(nearFullRatioPercent - fullRatioPercent)), - Math.round(100 - fullRatioPercent) - ]; + if (fullRatioPercent >= 0 && nearFullRatioPercent >= 0) { + chart.dataset[0].data = [ + Math.round(nearFullRatioPercent), + Math.round(Math.abs(nearFullRatioPercent - fullRatioPercent)), + Math.round(100 - fullRatioPercent) + ]; + } else { + chart.dataset[1].backgroundColor[1] = this.cssHelper.propertyValue('chart-color-light-gray'); + } chart.dataset[1].data = [ percentUsed, @@ -178,7 +184,6 @@ export class DashboardPieComponent implements OnChanges, OnInit { this.dimlessBinary.transform(data.current) ]; chart.dataset[1].backgroundColor[0] = this.cssHelper.propertyValue(this.color); - chart.dataset[0].label = [`${percentUsed}%\nof ${this.dimlessBinary.transform(data.max)}`]; } diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts index 8210a4c810371..722886d447753 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/dashboard/health/health.component.ts @@ -164,9 +164,12 @@ export class HealthComponent implements OnInit, OnDestroy { data.df.stats.total_bytes ); - if (percentUsed / 100 >= this.osdSettings.nearfull_ratio) { + const nearfullRatio = this.osdSettings.nearfull_ratio; + const fullRatio = this.osdSettings.nearfull_ratio; + + if (nearfullRatio >= 0 && percentUsed / 100 >= nearfullRatio) { this.color = 'chart-color-red'; - } else if (percentUsed / 100 >= this.osdSettings.full_ratio) { + } else if (fullRatio >= 0 && percentUsed / 100 >= fullRatio) { this.color = 'chart-color-yellow'; } else { this.color = 'chart-color-blue'; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html index e7d7b17f0791c..9a0a3398a3c05 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/usage-bar/usage-bar.component.html @@ -29,7 +29,7 @@ data-placement="left" [ngbTooltip]="usageTooltipTpl">