OpenShift Data Foundation で Ceph RBD を xfs フォーマットでプロビジョニングする

## TL;DR
* `.spec.managedResources.cephBlockPools.disableStorageClass: true` をセットした後、storageClass の設定を編集する。
* 自己責任でお願いします。

## 背景
ODF を導入後、storageClass `ocs-storagecluster-ceph-rbd` を指定して PVC を発行すると、ext4 でフォーマットされた PV がプロビジョニングされる。storageClass の Manifest から `.parameters."csi.storage.k8s.io/fstype"`の値を確認すると、 `ext4` が設定されている：
```
$ oc get sc ocs-storagecluster-ceph-rbd -o yaml
...
parameters:
  clusterID: openshift-storage
  ...
  csi.storage.k8s.io/fstype: ext4
```

これを `csi.storage.k8s.io/fstype: xfs` に変えたい場合、どうすればいいのだろうか。
通常の Rook-Ceph の場合、storageClass の Manifest を編集し、上記のキーの値を `xfs` にすればよい。しかし ODF では、[ocs-operator](https://github.com/red-hat-storage/ocs-operator/tree/main) の働きによって storageClass の修正が抑制されている。

## 失敗例：単に storageClass の Manifest を修正する
次のようなスクリプト `./fix_sc.sh` を作成し、storageClass `ocs-storagecluster-ceph-rbd` の fstype の値を `xfs` に修正してみる：

```bash:fix_sc.sh
#!/bin/bash

# Create a temp directory
cd $(mktemp -d)

# Extract the storageClass manifest
oc get sc ocs-storagecluster-ceph-rbd -o yaml > ocs-storagecluster-ceph-rbd.yaml

# Fix value: ext4 -> xfs
yq eval '.parameters."csi.storage.k8s.io/fstype" = "xfs"' -i ocs-storagecluster-ceph-rbd.yaml

# Recreate the storageClass
oc delete -f ocs-storagecluster-ceph-rbd.yaml >/dev/null
oc apply -f ocs-storagecluster-ceph-rbd.yaml >/dev/null

# Check the fixed value
fstype=$(oc get sc ocs-storagecluster-ceph-rbd -o yaml | yq '.parameters."csi.storage.k8s.io/fstype"')
echo $fstype
```

スクリプトを実行する：
```
$ ./fix_sc.sh
xfs
```

一瞬、成功したように思われるが、`ocs-operator` の Controller によって直ちに修正されるため、再確認すると `ext4` に戻っている：
```
$ oc get sc ocs-storagecluster-ceph-rbd -o yaml | yq '.parameters."csi.storage.k8s.io/fstype"'
ext4
```

## 解決策
OCS-Operator のコードを見ると、 storageClass は次の箇所で制御している。

https://github.com/red-hat-storage/ocs-operator/blob/cf0f728cb36c8977da784a5d54674a4579a0cf63/controllers/storagecluster/storageclasses.go#L280-L318

該当するコードを引用すると次の通り：
```go:ocs-operator/controllers/storagecluster/storageclasses.go
// newCephBlockPoolStorageClassConfiguration generates configuration options for a Ceph Block Pool StorageClass.
func newCephBlockPoolStorageClassConfiguration(initData *ocsv1.StorageCluster) StorageClassConfiguration {
	persistentVolumeReclaimDelete := corev1.PersistentVolumeReclaimDelete
	allowVolumeExpansion := true
	managementSpec := initData.Spec.ManagedResources.CephBlockPools
	scc := StorageClassConfiguration{
		storageClass: &storagev1.StorageClass{
			ObjectMeta: metav1.ObjectMeta{
				Name: generateNameForCephBlockPoolSC(initData),
				Annotations: map[string]string{
					"description": "Provides RWO Filesystem volumes, and RWO and RWX Block volumes",
				},
			},
			Provisioner:   rbdDriverName,
			ReclaimPolicy: &persistentVolumeReclaimDelete,
			// AllowVolumeExpansion is set to true to enable expansion of OCS backed Volumes
			AllowVolumeExpansion: &allowVolumeExpansion,
			Parameters: map[string]string{
				"clusterID":                 initData.Namespace,
				"pool":                      generateNameForCephBlockPool(initData),
				"imageFeatures":             "layering,deep-flatten,exclusive-lock,object-map,fast-diff",
				"csi.storage.k8s.io/fstype": "ext4",
				"imageFormat":               "2",
				"csi.storage.k8s.io/provisioner-secret-name":            "rook-csi-rbd-provisioner",
				"csi.storage.k8s.io/provisioner-secret-namespace":       initData.Namespace,
				"csi.storage.k8s.io/node-stage-secret-name":             "rook-csi-rbd-node",
				"csi.storage.k8s.io/node-stage-secret-namespace":        initData.Namespace,
				"csi.storage.k8s.io/controller-expand-secret-name":      "rook-csi-rbd-provisioner",
				"csi.storage.k8s.io/controller-expand-secret-namespace": initData.Namespace,
			},
		},
		reconcileStrategy: ReconcileStrategy(managementSpec.ReconcileStrategy),
		disable:           managementSpec.DisableStorageClass,
		isClusterExternal: initData.Spec.ExternalStorage.Enable,
	}
	if initData.Spec.ManagedResources.CephBlockPools.DefaultStorageClass {
		scc.storageClass.Annotations[defaultStorageClassAnnotation] = "true"
	}
	return scc
}
```

`ext4` はハードコーディングされている。この設定を変えようとすること自体、歓迎されていない気もする。

取り急ぎ、`spec.managedResources.cephBlockPools.disableStorageClass` を true にセットすれば無効化できそうである。

コントローラ `ocs-storagecluster` の現在の設定を見る：
```
$ oc get storagecluster ocs-storagecluster -n openshift-storage -o yaml | yq '.spec.managedResources.cephBlockPools'
defaultStorageClass: true
```

次のコマンドで manifest を修正画面を開く：
```
oc edit storagecluster ocs-storagecluster -n openshift-storage
```

`.spec.managedResources.cephBlockPools.disableStorageClass: true` を追加し、設定を保存する。

変更後の設定を確認する：
```
$ oc get storagecluster ocs-storagecluster -n openshift-storage -o yaml | yq '.spec.managedResources.cephBlockPools'
defaultStorageClass: true
disableStorageClass: true
```


改めて、さきほど作成した `fix_sc.sh` を実行する：
```
$ ./fix_sc.sh
xfs
```

しばらく待って storageClass を再確認すると、今度は `xfs` の設定が保たれている：
```
$ oc get sc ocs-storagecluster-ceph-rbd -o yaml | yq '.parameters."csi.storage.k8s.io/fstype"'
xfs
```