file: add support for named mds metadata pool names

This commit adds optional support to specify the MDS metadata pool name. It defaults to `<fsName>-metadata` as current implementation expects but allows customization if needed e.g. if exisiting naming conventions used `<fsName>_metadata`. Additionally an "preservePoolNames" boolean has been added to indicate that no generated pool names should be used.

Signed-off-by: Tobias Wolf <wolf@b1-systems.de>
(cherry picked from commit 675678fad6)
This commit is contained in:
Tobias Wolf authored and Travis Nielsen committed 2024-12-09 14:23:46 -07:00
1 parent fdc8d66f88
commit 9610407d89
8 files changed
+111 -24

No files matched your search

@@ -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., `<fsName>-<poolName>`. 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., `<fsName>-<poolName>` or `<fsName>-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.
+29 -5
View File
@@ -1127,8 +1127,8 @@ FilesystemSpec
<td>
<code>metadataPool</code><br/>
<em>
<a href="#ceph.rook.io/v1.PoolSpec">
PoolSpec
<a href="#ceph.rook.io/v1.NamedPoolSpec">
NamedPoolSpec
</a>
</em>
</td>
@@ -1151,6 +1151,18 @@ PoolSpec
</tr>
<tr>
<td>
<code>preservePoolNames</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Preserve pool names as specified</p>
</td>
</tr>
<tr>
<td>
<code>preservePoolsOnDelete</code><br/>
<em>
bool
@@ -6504,8 +6516,8 @@ FilesystemSnapshotScheduleStatusRetention
<td>
<code>metadataPool</code><br/>
<em>
<a href="#ceph.rook.io/v1.PoolSpec">
PoolSpec
<a href="#ceph.rook.io/v1.NamedPoolSpec">
NamedPoolSpec
</a>
</em>
</td>
@@ -6528,6 +6540,18 @@ PoolSpec
</tr>
<tr>
<td>
<code>preservePoolNames</code><br/>
<em>
bool
</em>
</td>
<td>
<em>(Optional)</em>
<p>Preserve pool names as specified</p>
</td>
</tr>
<tr>
<td>
<code>preservePoolsOnDelete</code><br/>
<em>
bool
@@ -10999,7 +11023,7 @@ This list allows defining additional StorageClasses on top of default STANDARD s
<h3 id="ceph.rook.io/v1.PoolSpec">PoolSpec
</h3>
<p>
(<em>Appears on:</em><a href="#ceph.rook.io/v1.FilesystemSpec">FilesystemSpec</a>, <a href="#ceph.rook.io/v1.NamedBlockPoolSpec">NamedBlockPoolSpec</a>, <a href="#ceph.rook.io/v1.NamedPoolSpec">NamedPoolSpec</a>, <a href="#ceph.rook.io/v1.ObjectStoreSpec">ObjectStoreSpec</a>, <a href="#ceph.rook.io/v1.ObjectZoneSpec">ObjectZoneSpec</a>)
(<em>Appears on:</em><a href="#ceph.rook.io/v1.NamedBlockPoolSpec">NamedBlockPoolSpec</a>, <a href="#ceph.rook.io/v1.NamedPoolSpec">NamedPoolSpec</a>, <a href="#ceph.rook.io/v1.ObjectStoreSpec">ObjectStoreSpec</a>, <a href="#ceph.rook.io/v1.ObjectZoneSpec">ObjectZoneSpec</a>)
</p>
<div>
<p>PoolSpec represents the spec of ceph pool</p>
@@ -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
+6
View File
@@ -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
+5 -1
View File
@@ -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"`
@@ -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)
}
+33 -14
View File
@@ -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
}
+24 -2
View File
@@ -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}},