From 125e1efdde0f37e4ab0ce8de930522864eee23f0 Mon Sep 17 00:00:00 2001 From: Afreen Misbah Date: Mon, 2 Sep 2024 14:52:34 +0530 Subject: [PATCH] mgr/dashboard: mgr/dashboard: Select no device by default in EC profile Fixes https://tracker.ceph.com/issues/67853 When EC pools are created with device class specified, the pools are created with just 1 PG and autoscaler does not work. PG autoscaler not working on a cluster where pools have multiple overlapping roots is a known issue, and bug is raised for same :> Issue documented already : https://docs.ceph.com/en/reef/rados/operations/placement-groups/#viewing-pg-scaling-recommendations Also renames "let ceph decide" option to "All devices" in crush rule and ec profile component. Updates unit tests for ec profile modal Signed-off-by: Afreen Misbah (cherry picked from commit 4af51349e5e1d21c200b6bf7db81fa18eb163a61) --- .../crush-rule-form-modal.component.html | 7 ++++--- .../erasure-code-profile-form-modal.component.html | 7 ++++--- ...asure-code-profile-form-modal.component.spec.ts | 1 + .../erasure-code-profile-form-modal.component.ts | 3 ++- .../src/app/shared/api/crush-rule.service.ts | 2 +- .../app/shared/api/erasure-code-profile.service.ts | 3 +-- .../shared/classes/crush.node.selection.class.ts | 14 ++++++++++++-- 7 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html index b3c0089834026..dd199e6ca0a12 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/crush-rule-form-modal/crush-rule-form-modal.component.html @@ -94,8 +94,6 @@
+ + {{tooltips.device_class}} +
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html index 7888fa853e3dd..58f46ae230450 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.html @@ -410,8 +410,6 @@
+ + {{tooltips.crushDeviceClass}} + Available OSDs: {{deviceCount}}
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts index 7d0331dfe54cf..db53e32509575 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.spec.ts @@ -563,6 +563,7 @@ describe('ErasureCodeProfileFormModalComponent', () => { ecpChange('technique', 'cauchy'); formHelper.setMultipleValues(ecp, true); formHelper.setValue('crushFailureDomain', 'osd', true); + formHelper.setValue('crushDeviceClass', 'ssd', true); submittedEcp['crush-failure-domain'] = 'osd'; submittedEcp['crush-device-class'] = 'ssd'; testCreation(); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts index 5982dfe24fb1f..1521ae83f1b20 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/pool/erasure-code-profile-form/erasure-code-profile-form-modal.component.ts @@ -383,7 +383,8 @@ export class ErasureCodeProfileFormModalComponent nodes, this.form.get('crushRoot'), this.form.get('crushFailureDomain'), - this.form.get('crushDeviceClass') + this.form.get('crushDeviceClass'), + false ); this.plugins = plugins; this.names = names; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts index e4e7bb6054045..8354e90381bd6 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/crush-rule.service.ts @@ -13,7 +13,7 @@ export class CrushRuleService { // Copied from /doc/rados/operations/crush-map.rst root: $localize`The name of the node under which data should be placed.`, failure_domain: $localize`The type of CRUSH nodes across which we should separate replicas.`, - device_class: $localize`The device class data should be placed on.` + device_class: $localize`The device class on which to place data.` }; constructor(private http: HttpClient) {} diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts index 988a13de2a936..f61201e3ce3c2 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/erasure-code-profile.service.ts @@ -91,8 +91,7 @@ export class ErasureCodeProfileService { defaults to 1. Using a value greater than one will cause a CRUSH MSR rule to be created. Must be specified if crush-num-failure-domains is specified.`, - crushDeviceClass: $localize`Restrict placement to devices of a specific class - (e.g., ssd or hdd), using the crush device class names in the CRUSH map.`, + crushDeviceClass: $localize`The device class on which to place data.`, directory: $localize`Set the directory name from which the erasure code plugin is loaded.` }; diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts index 34cebbcc8773e..ec8b05232886b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/classes/crush.node.selection.class.ts @@ -19,6 +19,14 @@ export class CrushNodeSelectionClass { failureDomainKeys: string[] = []; devices: string[] = []; deviceCount = 0; + /** + * Handles manual or automatic update of device class. + * + * When set true, the device class form field is automatically + * updated with the first device in the list of devices. + * Otherwise, user manually selects a device class. + */ + autoDeviceUpdate: boolean = true; static searchFailureDomains( nodes: CrushNode[], @@ -120,8 +128,10 @@ export class CrushNodeSelectionClass { nodes: CrushNode[], rootControl: AbstractControl, failureControl: AbstractControl, - deviceControl: AbstractControl + deviceControl: AbstractControl, + autoDeviceUpdate: boolean = true ) { + this.autoDeviceUpdate = autoDeviceUpdate; this.nodes = nodes; this.idTree = CrushNodeSelectionClass.createIdTreeFromNodes(nodes); nodes.forEach((node) => { @@ -208,7 +218,7 @@ export class CrushNodeSelectionClass { this.devices.length === 1 ? this.devices[0] : this.getIncludedCustomValue(this.controls.device, this.devices); - this.silentSet(this.controls.device, device); + if (this.autoDeviceUpdate) this.silentSet(this.controls.device, device); this.onDeviceChange(device); } -- 2.39.5