From 9610407d895b2e2300094bf85e2e8ef7db39dcdf Mon Sep 17 00:00:00 2001 From: Tobias Wolf Date: Mon, 25 Nov 2024 16:45:48 +0100 Subject: [PATCH] file: add support for named mds metadata pool names This commit adds optional support to specify the MDS metadata pool name. It defaults to `-metadata` as current implementation expects but allows customization if needed e.g. if exisiting naming conventions used `_metadata`. Additionally an "preservePoolNames" boolean has been added to indicate that no generated pool names should be used. Signed-off-by: Tobias Wolf (cherry picked from commit 675678fad62807b5d2356e16c399a0251ccb6553) --- .../Shared-Filesystem/ceph-filesystem-crd.md | 8 +++- Documentation/CRDs/specification.md | 34 ++++++++++++-- .../charts/rook-ceph/templates/resources.yaml | 6 +++ deploy/examples/crds.yaml | 6 +++ pkg/apis/ceph.rook.io/v1/types.go | 6 ++- .../disruption/clusterdisruption/pools.go | 2 +- pkg/operator/ceph/file/filesystem.go | 47 +++++++++++++------ pkg/operator/ceph/file/filesystem_test.go | 26 +++++++++- 8 files changed, 111 insertions(+), 24 deletions(-) diff --git a/Documentation/CRDs/Shared-Filesystem/ceph-filesystem-crd.md b/Documentation/CRDs/Shared-Filesystem/ceph-filesystem-crd.md index cc87c6658..157f90181 100644 --- a/Documentation/CRDs/Shared-Filesystem/ceph-filesystem-crd.md +++ b/Documentation/CRDs/Shared-Filesystem/ceph-filesystem-crd.md @@ -111,8 +111,10 @@ Also see an example in the [`storageclass-ec.yaml`](https://github.com/rook/rook The pools allow all of the settings defined in the Pool CRD spec. For more details, see the [Pool CRD](../Block-Storage/ceph-block-pool-crd.md) settings. In the example above, there must be at least three hosts (size 3) and at least eight devices (6 data + 2 coding chunks) in the cluster. * `metadataPool`: The settings used to create the filesystem metadata pool. Must use replication. + * `name`: (optional) Override the default generated name of the metadata pool. * `dataPools`: The settings to create the filesystem data pools. Optionally (and we highly recommend), a pool name can be specified with the `name` field to override the default generated name; see more below. If multiple pools are specified, Rook will add the pools to the filesystem. Assigning users or files to a pool is left as an exercise for the reader with the [CephFS documentation](http://docs.ceph.com/docs/master/cephfs/file-layouts/). The data pools can use replication or erasure coding. If erasure coding pools are specified, the cluster must be running with bluestore enabled on the OSDs. - * `name`: (optional, and highly recommended) Override the default generated name of the pool. The final pool name will consist of the filesystem name and pool name, e.g., `-`. We highly recommend to specify `name` to prevent issues that can arise from modifying the spec in a way that causes Rook to lose the original pool ordering. + * `name`: (optional, and highly recommended) Override the default generated name of the pool. We highly recommend to specify `name` to prevent issues that can arise from modifying the spec in a way that causes Rook to lose the original pool ordering. +* `preservePoolNames`: Preserve pool names as specified. * `preserveFilesystemOnDelete`: If it is set to 'true' the filesystem will remain when the CephFilesystem resource is deleted. This is a security measure to avoid loss of data if the CephFilesystem resource is deleted accidentally. The default value is 'false'. This option @@ -121,6 +123,10 @@ The pools allow all of the settings defined in the Pool CRD spec. For more detai `preserveFilesystemOnDelete`. For backwards compatibility and upgradeability, if this is set to 'true', Rook will treat `preserveFilesystemOnDelete` as being set to 'true'. +### Generated Pool Names + +Both `metadataPool` and `dataPools` support defining names as required. The final pool name will consist of the filesystem name and pool name, e.g., `-` or `-metadata` for `metadataPool`. For more granular configuration you may want to set `preservePoolNames` to `true` in `pools` to disable generation of names. In that case all pool names defined are used as given. + ## Metadata Server Settings The metadata server settings correspond to the MDS daemon settings. diff --git a/Documentation/CRDs/specification.md b/Documentation/CRDs/specification.md index 8bcd2b251..79ceb8b2c 100644 --- a/Documentation/CRDs/specification.md +++ b/Documentation/CRDs/specification.md @@ -1127,8 +1127,8 @@ FilesystemSpec metadataPool
- -PoolSpec + +NamedPoolSpec @@ -1151,6 +1151,18 @@ PoolSpec +preservePoolNames
+ +bool + + + +(Optional) +

Preserve pool names as specified

+ + + + preservePoolsOnDelete
bool @@ -6504,8 +6516,8 @@ FilesystemSnapshotScheduleStatusRetention metadataPool
- -PoolSpec + +NamedPoolSpec @@ -6528,6 +6540,18 @@ PoolSpec +preservePoolNames
+ +bool + + + +(Optional) +

Preserve pool names as specified

+ + + + preservePoolsOnDelete
bool @@ -10999,7 +11023,7 @@ This list allows defining additional StorageClasses on top of default STANDARD s

PoolSpec

-(Appears on:FilesystemSpec, NamedBlockPoolSpec, NamedPoolSpec, ObjectStoreSpec, ObjectZoneSpec) +(Appears on:NamedBlockPoolSpec, NamedPoolSpec, ObjectStoreSpec, ObjectZoneSpec)

PoolSpec represents the spec of ceph pool

diff --git a/deploy/charts/rook-ceph/templates/resources.yaml b/deploy/charts/rook-ceph/templates/resources.yaml index fe8c0fac7..f01a3a1c3 100644 --- a/deploy/charts/rook-ceph/templates/resources.yaml +++ b/deploy/charts/rook-ceph/templates/resources.yaml @@ -7036,6 +7036,9 @@ spec: type: object type: array type: object + name: + description: Name of the pool + type: string parameters: additionalProperties: type: string @@ -8068,6 +8071,9 @@ spec: preserveFilesystemOnDelete: description: Preserve the fs in the cluster on CephFilesystem CR deletion. Setting this to true automatically implies PreservePoolsOnDelete is true. type: boolean + preservePoolNames: + description: Preserve pool names as specified + type: boolean preservePoolsOnDelete: description: Preserve pools on filesystem deletion type: boolean diff --git a/deploy/examples/crds.yaml b/deploy/examples/crds.yaml index 5ce6759b7..cb38b0089 100644 --- a/deploy/examples/crds.yaml +++ b/deploy/examples/crds.yaml @@ -7031,6 +7031,9 @@ spec: type: object type: array type: object + name: + description: Name of the pool + type: string parameters: additionalProperties: type: string @@ -8063,6 +8066,9 @@ spec: preserveFilesystemOnDelete: description: Preserve the fs in the cluster on CephFilesystem CR deletion. Setting this to true automatically implies PreservePoolsOnDelete is true. type: boolean + preservePoolNames: + description: Preserve pool names as specified + type: boolean preservePoolsOnDelete: description: Preserve pools on filesystem deletion type: boolean diff --git a/pkg/apis/ceph.rook.io/v1/types.go b/pkg/apis/ceph.rook.io/v1/types.go index 2a6b6d4bb..7b5b34636 100755 --- a/pkg/apis/ceph.rook.io/v1/types.go +++ b/pkg/apis/ceph.rook.io/v1/types.go @@ -1166,12 +1166,16 @@ type CephFilesystemList struct { type FilesystemSpec struct { // The metadata pool settings // +nullable - MetadataPool PoolSpec `json:"metadataPool"` + MetadataPool NamedPoolSpec `json:"metadataPool"` // The data pool settings, with optional predefined pool name. // +nullable DataPools []NamedPoolSpec `json:"dataPools"` + // Preserve pool names as specified + // +optional + PreservePoolNames bool `json:"preservePoolNames,omitempty"` + // Preserve pools on filesystem deletion // +optional PreservePoolsOnDelete bool `json:"preservePoolsOnDelete,omitempty"` diff --git a/pkg/operator/ceph/disruption/clusterdisruption/pools.go b/pkg/operator/ceph/disruption/clusterdisruption/pools.go index ee0240a94..fe25ad9c3 100644 --- a/pkg/operator/ceph/disruption/clusterdisruption/pools.go +++ b/pkg/operator/ceph/disruption/clusterdisruption/pools.go @@ -52,7 +52,7 @@ func (r *ReconcileClusterDisruption) processPools(request reconcile.Request) (*c } poolCount += len(cephFilesystemList.Items) for _, cephFilesystem := range cephFilesystemList.Items { - poolSpecs = append(poolSpecs, cephFilesystem.Spec.MetadataPool) + poolSpecs = append(poolSpecs, cephFilesystem.Spec.MetadataPool.PoolSpec) for _, pool := range cephFilesystem.Spec.DataPools { poolSpecs = append(poolSpecs, pool.PoolSpec) } diff --git a/pkg/operator/ceph/file/filesystem.go b/pkg/operator/ceph/file/filesystem.go index b8e6b36cf..d7f3cb20a 100644 --- a/pkg/operator/ceph/file/filesystem.go +++ b/pkg/operator/ceph/file/filesystem.go @@ -152,12 +152,13 @@ func validateFilesystem(context *clusterd.Context, clusterInfo *cephclient.Clust } } - if err := cephpool.ValidatePoolSpec(context, clusterInfo, clusterSpec, &f.Spec.MetadataPool); err != nil { + localMetadataPoolSpec := f.Spec.MetadataPool.PoolSpec + if err := cephpool.ValidatePoolSpec(context, clusterInfo, clusterSpec, &localMetadataPoolSpec); err != nil { return errors.Wrap(err, "invalid metadata pool") } for _, p := range f.Spec.DataPools { - localpoolSpec := p.PoolSpec - if err := cephpool.ValidatePoolSpec(context, clusterInfo, clusterSpec, &localpoolSpec); err != nil { + localPoolSpec := p.PoolSpec + if err := cephpool.ValidatePoolSpec(context, clusterInfo, clusterSpec, &localPoolSpec); err != nil { return errors.Wrap(err, "Invalid data pool") } } @@ -190,12 +191,10 @@ func newFS(name, namespace string) *Filesystem { // createOrUpdatePools function sets the sizes for MetadataPool and dataPool func createOrUpdatePools(f *Filesystem, context *clusterd.Context, clusterInfo *cephclient.ClusterInfo, clusterSpec *cephv1.ClusterSpec, spec cephv1.FilesystemSpec) error { - // generating the metadata pool's name - metadataPool := cephv1.NamedPoolSpec{ - Name: GenerateMetaDataPoolName(f.Name), - PoolSpec: spec.MetadataPool, - } + metadataPool := spec.MetadataPool metadataPool.Application = cephfsApplication + metadataPool.Name = generateMetaDataPoolName(f.Name, &spec) + err := cephclient.CreatePool(context, clusterInfo, clusterSpec, &metadataPool) if err != nil { return errors.Wrapf(err, "failed to update metadata pool %q", metadataPool.Name) @@ -264,11 +263,10 @@ func (f *Filesystem) doFilesystemCreate(context *clusterd.Context, clusterInfo * reversedPoolMap[value] = key } - spec.MetadataPool.Application = cephfsApplication - metadataPool := cephv1.NamedPoolSpec{ - Name: GenerateMetaDataPoolName(f.Name), - PoolSpec: spec.MetadataPool, - } + metadataPool := spec.MetadataPool + metadataPool.Application = cephfsApplication + metadataPool.Name = generateMetaDataPoolName(f.Name, &spec) + if _, poolFound := reversedPoolMap[metadataPool.Name]; !poolFound { err = cephclient.CreatePool(context, clusterInfo, clusterSpec, &metadataPool) if err != nil { @@ -320,19 +318,40 @@ func downFilesystem(context *clusterd.Context, clusterInfo *cephclient.ClusterIn // or get predefined name from spec func generateDataPoolNames(f *Filesystem, spec cephv1.FilesystemSpec) []string { var dataPoolNames []string + for i, pool := range spec.DataPools { poolName := "" + if pool.Name == "" { poolName = fmt.Sprintf("%s-%s%d", f.Name, dataPoolSuffix, i) + } else if spec.PreservePoolNames { + poolName = pool.Name } else { poolName = fmt.Sprintf("%s-%s", f.Name, pool.Name) } + dataPoolNames = append(dataPoolNames, poolName) } + return dataPoolNames } // GenerateMetaDataPoolName generates MetaDataPool name by prefixing the filesystem name to the constant metaDataPoolSuffix func GenerateMetaDataPoolName(fsName string) string { - return fmt.Sprintf("%s-%s", fsName, metaDataPoolSuffix) + return generateMetaDataPoolName(fsName, nil) +} + +// GenerateMetaDataPoolName generates MetaDataPool name as specified in FilesystemSpec +func generateMetaDataPoolName(fsName string, spec *cephv1.FilesystemSpec) string { + poolName := "" + + if nil == spec || spec.MetadataPool.Name == "" { + poolName = fmt.Sprintf("%s-%s", fsName, metaDataPoolSuffix) + } else if spec.PreservePoolNames { + poolName = spec.MetadataPool.Name + } else { + poolName = fmt.Sprintf("%s-%s", fsName, spec.MetadataPool.Name) + } + + return poolName } diff --git a/pkg/operator/ceph/file/filesystem_test.go b/pkg/operator/ceph/file/filesystem_test.go index 856add388..1e0637cd6 100644 --- a/pkg/operator/ceph/file/filesystem_test.go +++ b/pkg/operator/ceph/file/filesystem_test.go @@ -63,7 +63,7 @@ func TestValidateSpec(t *testing.T) { // missing metadata pool assert.NotNil(t, validateFilesystem(context, clusterInfo, clusterSpec, fs)) - fs.Spec.MetadataPool = p + fs.Spec.MetadataPool.PoolSpec = p // missing mds count assert.NotNil(t, validateFilesystem(context, clusterInfo, clusterSpec, fs)) @@ -112,6 +112,26 @@ func TestGenerateDataPoolNames(t *testing.T) { assert.Equal(t, expectedNames, names) } +func TestPreservePoolNames(t *testing.T) { + fs := &Filesystem{Name: "fake", Namespace: "fake"} + fsSpec := cephv1.FilesystemSpec{ + DataPools: []cephv1.NamedPoolSpec{ + { + PoolSpec: cephv1.PoolSpec{Replicated: cephv1.ReplicatedSpec{Size: 1, RequireSafeReplicaSize: false}}, + }, + { + Name: "somename", + PoolSpec: cephv1.PoolSpec{Replicated: cephv1.ReplicatedSpec{Size: 1, RequireSafeReplicaSize: false}}, + }, + }, + PreservePoolNames: true, + } + + expectedNames := []string{"fake-data0", "somename"} + names := generateDataPoolNames(fs, fsSpec) + assert.Equal(t, expectedNames, names) +} + func isBasePoolOperation(fsName, command string, args []string) bool { if reflect.DeepEqual(args[0:7], []string{"osd", "pool", "create", fsName + "-metadata", "0", "replicated", fsName + "-metadata"}) { return true @@ -325,7 +345,9 @@ func fsTest(fsName string) cephv1.CephFilesystem { return cephv1.CephFilesystem{ ObjectMeta: metav1.ObjectMeta{Name: fsName, Namespace: "ns"}, Spec: cephv1.FilesystemSpec{ - MetadataPool: cephv1.PoolSpec{Replicated: cephv1.ReplicatedSpec{Size: 1, RequireSafeReplicaSize: false}}, + MetadataPool: cephv1.NamedPoolSpec{ + PoolSpec: cephv1.PoolSpec{Replicated: cephv1.ReplicatedSpec{Size: 1, RequireSafeReplicaSize: false}}, + }, DataPools: []cephv1.NamedPoolSpec{ { PoolSpec: cephv1.PoolSpec{Replicated: cephv1.ReplicatedSpec{Size: 1, RequireSafeReplicaSize: false}},