From f7f0e741e642f509a7af88dd14dd5b5d15a7e40b Mon Sep 17 00:00:00 2001 From: Patrick Nawracay Date: Mon, 27 Aug 2018 15:23:48 +0200 Subject: [PATCH] mgr/dashboard: Clicking on a down OSD raises an error Fixes: http://tracker.ceph.com/issues/24530 Signed-off-by: Patrick Nawracay --- src/pybind/mgr/dashboard/controllers/osd.py | 18 ++++++++- .../osd-details/osd-details.component.html | 7 ++-- .../osd-details/osd-details.component.spec.ts | 40 ++++++++++++++++++- .../osd/osd-details/osd-details.component.ts | 1 + .../osd/osd-list/osd-list.component.html | 10 ++--- .../datatable/table/table.component.scss | 3 ++ 6 files changed, 67 insertions(+), 12 deletions(-) diff --git a/src/pybind/mgr/dashboard/controllers/osd.py b/src/pybind/mgr/dashboard/controllers/osd.py index 3d30df83ed1e4..f734092d6c385 100644 --- a/src/pybind/mgr/dashboard/controllers/osd.py +++ b/src/pybind/mgr/dashboard/controllers/osd.py @@ -4,7 +4,7 @@ from __future__ import absolute_import from . import ApiController, RESTController, UpdatePermission from .. import mgr, logger from ..security import Scope -from ..services.ceph_service import CephService +from ..services.ceph_service import CephService, SendCommandError from ..services.exception import handle_send_command_error from ..tools import str_to_bool @@ -56,7 +56,21 @@ class Osd(RESTController): @handle_send_command_error('osd') def get(self, svc_id): - histogram = CephService.send_command('osd', srv_spec=svc_id, prefix='perf histogram dump') + """ + Returns collected data about an OSD. + + :return: Returns the requested data. The `histogram` key man contain a + string with an error that occurred when the OSD is down. + """ + try: + histogram = CephService.send_command('osd', srv_spec=svc_id, + prefix='perf histogram dump') + except SendCommandError as e: + if 'osd down' in e.message: + histogram = e.message + else: + raise + return { 'osd_map': self.get_osd_map()[svc_id], 'osd_metadata': mgr.get_metadata('osd', svc_id), diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html index c511d54e78c13..d5773faf44631 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.html @@ -17,9 +17,10 @@ -

- Histogram not available -> {{ osd.histogram_failed }} -

+ + Histogram not available: {{ osd.histogram_failed }} + +

Writes

diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts index a8d07224583c4..8146c6d1b3019 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.spec.ts @@ -1,9 +1,13 @@ import { HttpClientModule } from '@angular/common/http'; +import { DebugElement } from '@angular/core'; import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { of } from 'rxjs'; + import { TabsModule } from 'ngx-bootstrap'; import { configureTestBed } from '../../../../../testing/unit-test-helper'; +import { OsdService } from '../../../../shared/api/osd.service'; import { DataTableModule } from '../../../../shared/datatable/datatable.module'; import { CdTableSelection } from '../../../../shared/models/cd-table-selection'; import { SharedModule } from '../../../../shared/shared.module'; @@ -14,6 +18,9 @@ import { OsdDetailsComponent } from './osd-details.component'; describe('OsdDetailsComponent', () => { let component: OsdDetailsComponent; let fixture: ComponentFixture; + let debugElement: DebugElement; + let osdService: OsdService; + let getDetailsSpy; configureTestBed({ imports: [ @@ -23,7 +30,8 @@ describe('OsdDetailsComponent', () => { DataTableModule, SharedModule ], - declarations: [OsdDetailsComponent, OsdPerformanceHistogramComponent] + declarations: [OsdDetailsComponent, OsdPerformanceHistogramComponent], + providers: [OsdService] }); beforeEach(() => { @@ -31,6 +39,10 @@ describe('OsdDetailsComponent', () => { component = fixture.componentInstance; component.selection = new CdTableSelection(); + debugElement = fixture.debugElement; + osdService = debugElement.injector.get(OsdService); + + getDetailsSpy = spyOn(osdService, 'getDetails'); fixture.detectChanges(); }); @@ -38,4 +50,30 @@ describe('OsdDetailsComponent', () => { it('should create', () => { expect(component).toBeTruthy(); }); + + it('should fail creating a histogram', () => { + const detailDataWithoutHistogram = { + osd_map: {}, + osd_metadata: {}, + histogram: 'osd down' + }; + getDetailsSpy.and.returnValue(of(detailDataWithoutHistogram)); + component.osd = { tree: { id: 0 } }; + component.refresh(); + expect(getDetailsSpy).toHaveBeenCalled(); + expect(component.osd.histogram_failed).toBe('osd down'); + }); + + it('should succeed creating a histogram', () => { + const detailDataWithHistogram = { + osd_map: {}, + osd_metdata: {}, + histogram: {} + }; + getDetailsSpy.and.returnValue(of(detailDataWithHistogram)); + component.osd = { tree: { id: 0 } }; + component.refresh(); + expect(getDetailsSpy).toHaveBeenCalled(); + expect(component.osd.histogram_failed).toBe(''); + }); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts index f7b250f2c0618..08bf6e3f00187 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-details/osd-details.component.ts @@ -34,6 +34,7 @@ export class OsdDetailsComponent implements OnChanges { refresh() { this.osdService.getDetails(this.osd.tree.id).subscribe((data: any) => { this.osd.details = data; + this.osd.histogram_failed = ''; if (!_.isObject(data.histogram)) { this.osd.histogram_failed = data.histogram; this.osd.details.histogram = undefined; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html index 6bff31d1f1468..159bda03a2970 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-list/osd-list.component.html @@ -49,13 +49,11 @@ - + - - {{ state }} - , + {{ state }} +   diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss index 5f916eb7fe2c1..05584f5bfe719 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.scss @@ -185,6 +185,9 @@ padding-bottom: 5px; } .datatable-body-row { + .label { + font-size: 0.9em; + } &.clickable:hover .datatable-row-group { background-color: $color-table-hover-row; transition-property: background; -- 2.39.5