From d0fe5ce52a2611b2d8171a9f8a593b0349ab9dbc Mon Sep 17 00:00:00 2001 From: Patrick Nawracay Date: Tue, 18 Jun 2019 14:00:15 +0200 Subject: [PATCH] mgr/dashboard: Add backwards compatibility to interlock of `fast-diff` and `object-map` Fixes: http://tracker.ceph.com/issues/39451 Signed-off-by: Patrick Nawracay --- .../block/rbd-form/rbd-form.component.spec.ts | 57 +++++++++++++++++++ .../ceph/block/rbd-form/rbd-form.component.ts | 28 +++++++++ 2 files changed, 85 insertions(+) diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts index 39a0125cd27..6dc1b891231 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.spec.ts @@ -125,6 +125,63 @@ describe('RbdFormComponent', () => { ]); }); + describe('test edit form flags', () => { + const prepare = (pool: string, image: string, enabledFeatures: string[]): void => { + const rbdService = TestBed.get(RbdService); + spyOn(rbdService, 'get').and.returnValue( + of({ + name: image, + pool_name: pool, + features_name: enabledFeatures + }) + ); + spyOn(rbdService, 'defaultFeatures').and.returnValue(of(defaultFeatures)); + component.router = { url: `/block/rbd/edit/${pool}/${image}` } as Router; + fixture.detectChanges(); + [ + deepFlatten, + layering, + exclusiveLock, + objectMap, + journaling, + fastDiff + ] = getFeatureNativeElements(); + }; + + it('should have the interlock feature for flags disabled, if one feature is not set', () => { + prepare('rbd', 'foobar', ['deep-flatten', 'exclusive-lock', 'layering', 'object-map']); + + expect(objectMap.disabled).toBe(false); + expect(fastDiff.disabled).toBe(false); + + expect(objectMap.checked).toBe(true); + expect(fastDiff.checked).toBe(false); + + fastDiff.click(); + fastDiff.click(); + + expect(objectMap.checked).toBe(true); // Shall not be disabled by `fast-diff`! + }); + + it('should not disable object-map when fast-diff is unchecked', () => { + prepare('rbd', 'foobar', ['deep-flatten', 'exclusive-lock', 'layering', 'object-map']); + + fastDiff.click(); + fastDiff.click(); + + expect(objectMap.checked).toBe(true); // Shall not be disabled by `fast-diff`! + }); + + it('should not enable fast-diff when object-map is checked', () => { + prepare('rbd', 'foobar', ['deep-flatten', 'exclusive-lock', 'layering', 'object-map']); + + objectMap.click(); + objectMap.click(); + + expect(fastDiff.checked).toBe(false); // Shall not be disabled by `fast-diff`! + }); + }); + describe('test create form flags', () => { beforeEach(() => { const rbdService = TestBed.get(RbdService); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts index 0e82e8f6200..ba22359761f 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-form/rbd-form.component.ts @@ -385,6 +385,34 @@ export class RbdFormComponent implements OnInit { } interlockCheck(key, checked) { + // Adds a compatibility layer for Ceph cluster where the feature interlock of features hasn't + // been implemented yet. It disables the feature interlock for images which only have one of + // both interlocked features (at the time of this writing: object-map and fast-diff) enabled. + const feature = this.featuresList.find((f) => f.key === key); + if (this.response) { + // Ignore `create` page + const hasInterlockedFeature = feature.interlockedWith != null; + const dependentInterlockedFeature = this.featuresList.find( + (f) => f.interlockedWith === feature.key + ); + const isOriginFeatureEnabled = !!this.response.features_name.find((e) => e === feature.key); // in this case: fast-diff + if (hasInterlockedFeature) { + const isLinkedEnabled = !!this.response.features_name.find( + (e) => e === feature.interlockedWith + ); // depends: object-map + if (isOriginFeatureEnabled !== isLinkedEnabled) { + return; // Ignore incompatible setting because it's from a previous cluster version + } + } else if (dependentInterlockedFeature) { + const isOtherInterlockedFeatureEnabled = !!this.response.features_name.find( + (e) => e === dependentInterlockedFeature.key + ); + if (isOtherInterlockedFeatureEnabled !== isOriginFeatureEnabled) { + return; // Ignore incompatible setting because it's from a previous cluster version + } + } + } + if (checked) { _.filter(this.features, (f) => f.interlockedWith === key).forEach((f) => this.rbdForm.get(f.key).setValue(true, { emitEvent: false }) -- 2.39.5