-
Notifications
You must be signed in to change notification settings - Fork 5.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mgr/dashboard: CRUSH map viewer #24766
Conversation
I would prefer not to include jquery. |
@tspmelo Ok, I will try, and give the implementation as soon as possible. |
@votdev Yeah, I think so, for the perfect display, I will implement it as soon as possible. |
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.scss
Outdated
Show resolved
Hide resolved
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
Outdated
Show resolved
Hide resolved
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
Outdated
Show resolved
Hide resolved
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts
Show resolved
Hide resolved
return { value: 'No nodes!' }; | ||
} | ||
|
||
for (let i = nodesLength - 1; i > -1; i--) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about using forEach
instead?
for (let i = nodesLength - 1; i > -1; i--) { | |
cephNodes.reverse().forEach((node) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your suggestion is better, I have modified it.
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
Show resolved
Hide resolved
@LenzGr Thanks for your suggestion, and I have modified code in terms of your comments, including: changing the location to display the metadata, replacing the "crush weight" information with the "status" information of osds. |
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
Show resolved
Hide resolved
src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.ts
Show resolved
Hide resolved
return treeNodeMap[rootNodeId]; | ||
} | ||
|
||
private generateNode(node: any, treeNodeMap) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm would rename it to generateNodeLeaf
or generateTreeLeaf
as you are not generating a node.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, I will check it and find a better name for it.
@LenzGr @familyuu I would prefer something like this: I would prefer to have the table inside the crush panel, otherwise it seems to separate things. |
Thank you!
OK, thanks for the explanation. I'm fine with keeping the current order for now, it it's too involved to sort it.
I agree, this is a good start. Would you mind changing the layout as suggested by @tspmelo in #24766 (comment) and adding a few tests as requested? From a functionality POV, this would be a good first step (a "CRUSH map viewer") to get merged. |
|
||
const children: any[] = []; | ||
if (node.children) { | ||
node.children.forEach((childId) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How about sorting the children by ID, using node.children.sort()
?
node.children.forEach((childId) => { | |
node.children.sort().forEach((childId) => { |
}; | ||
const data = { osd_map }; | ||
spyOn(dashboardService, 'getHealth').and.returnValue(of(data)); | ||
fixture.detectChanges(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, I looked through your tests and refactored and extend them a bit, hopefully you will like my suggestion, to minimize the preparation per test.
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts
index 3395120b72..704416c47e 100644
--- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts
+++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/crushmap/crushmap.component.spec.ts
@@ -16,6 +16,7 @@ describe('CrushmapComponent', () => {
let component: CrushmapComponent;
let fixture: ComponentFixture<CrushmapComponent>;
let debugElement: DebugElement;
+
configureTestBed({
imports: [HttpClientTestingModule, TreeModule, TabsModule.forRoot(), SharedModule],
declarations: [CrushmapComponent],
@@ -38,33 +39,52 @@ describe('CrushmapComponent', () => {
expect(span.textContent).toContain(component.panelTitle);
});
- it('should display "No nodes!" if ceph tree nodes is empty array', () => {
- const dashboardService = debugElement.injector.get(DashboardService);
- const osd_map = { tree: {} };
- const data = { osd_map };
- const getHealthSpy = spyOn(dashboardService, 'getHealth');
- getHealthSpy.and.returnValue(of(data));
- fixture.detectChanges();
+ describe('tests tree', () => {
+ let dashboardService: DashboardService;
- expect(getHealthSpy).toHaveBeenCalled();
- expect(component.tree.value).toEqual('No nodes!');
- });
-
- it('should has correct tree data structure after transform the metadata', () => {
- const dashboardService = debugElement.injector.get(DashboardService);
- const osd_map = {
- tree: {
- nodes: [
- { children: [-1], type: 'root', name: 'Root', id: 1 },
- { children: [-2], type: 'host', name: 'Host', id: -1 },
- { status: 'up', type: 'osd', name: 'Osd', id: -2 }
- ]
- }
+ const prepareGetHealth = (nodes: object[]) => {
+ spyOn(dashboardService, 'getHealth').and.returnValue(
+ of({ osd_map: { tree: { nodes: nodes } } })
+ );
+ fixture.detectChanges();
};
- const data = { osd_map };
- spyOn(dashboardService, 'getHealth').and.returnValue(of(data));
- fixture.detectChanges();
- expect(component.tree.children[0].children[0].value).toBe('Osd (osd)--up');
+ beforeEach(() => {
+ dashboardService = debugElement.injector.get(DashboardService);
+ });
+
+ it('should display "No nodes!" if ceph tree nodes is empty array', () => {
+ prepareGetHealth([]);
+ expect(dashboardService.getHealth).toHaveBeenCalled();
+ expect(component.tree.value).toEqual('No nodes!');
+ });
+
+ describe('with data', () => {
+ beforeEach(() => {
+ prepareGetHealth([
+ { children: [-2], type: 'root', name: 'default', id: -1 },
+ { children: [1, 0, 2], type: 'host', name: 'my-host', id: -2 },
+ { status: 'up', type: 'osd', name: 'osd.0', id: 0 },
+ { status: 'down', type: 'osd', name: 'osd.1', id: 1 },
+ { status: 'up', type: 'osd', name: 'osd.2', id: 2 }
+ ]);
+ });
+
+ it('has a tree structure deriving from root', () => {
+ expect(component.tree.value).toBe('default (root)');
+ });
+
+ it('has a tree structure with one host child with 3 children', () => {
+ expect(component.tree.children.length).toBe(1);
+ expect(component.tree.children[0].value).toBe('my-host (host)');
+ expect(component.tree.children[0].children.length).toBe(3);
+ });
+
+ it('has sorted all host children by id', () => {
+ expect(component.tree.children[0].children[0].value).toBe('osd.0 (osd)--up');
+ expect(component.tree.children[0].children[1].value).toBe('osd.1 (osd)--down');
+ expect(component.tree.children[0].children[2].value).toBe('osd.2 (osd)--up');
+ });
+ });
});
});
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for your suggestion. Actually, I am not good at write tests, so, just forgive my poor test cases, and I have modified the code as you suggested, thanks again for your advise.
Thank you, looks good to me. Can you please amend the git commit message to match the title and description of this PR and to include a reference to the tracker issue?
|
This is something we can not fix in the Swimlane ngx datatable. We have many tables (e.g. in the details tables) in the UI with the same behaviour. |
Ok, no problem. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM :-)
|
||
let value: string = node.name + ' (' + node.type + ')'; | ||
if (node.status) { | ||
value += '--' + node.status; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this a special Ceph convention? What about ods.1 (osd) - up
or ods.1 (osd) [up]
? Using colors might be the best solution in my opinion.
Sorry to be such a pain, @familyuu - but the git commit message is still not in the correct format :/ Can you please amend it so it also contains a reference to the tracker issue?
|
|
Looks good to me @votdev - thanks for the suggestion. @familyuu are you fine with including this suggestion? Please let's focus on getting the existing implementation reviewed and merged and refrain from making additional visual/functionality improvements in this PR; let's open new PRs for additional changes/enhancements instead. Thanks! |
To get the PR merged asap i've created a separate PR with my suggestions. |
Fixes: http://tracker.ceph.com/issues/35684 Signed-off-by: familyuu <guodan1@lenovo.com>
Oh, it looks like I misunderstood some of the things you talked about, I modified the git commit message and it looks right now. I am sorry for my carelessness. |
Sounds like I don't need to add code about this topic to my PR. Thank you very much for your advice that make me more capable of developing better apps. I think I have learned a lot of skills in this progress. |
Nothing to be sorry about! Thanks a lot for addressing all of the suggestions and for your contribution! Much appreciated. |
mgr/dashboard: Add CRUSH map viewer
Fixes: http://tracker.ceph.com/issues/35684
Signed-off-by: familyuu guodan1@lenovo.com