@@ -20,8 +20,10 @@ import (
2020
2121 "github.com/pingcap/tidb-operator/api/v2/core/v1alpha1"
2222 "github.com/pingcap/tidb-operator/pkg/client"
23+ "github.com/pingcap/tidb-operator/pkg/overlay"
2324 "github.com/pingcap/tidb-operator/pkg/runtime"
2425 "github.com/pingcap/tidb-operator/pkg/runtime/scope"
26+ "github.com/pingcap/tidb-operator/pkg/utils/k8s"
2527 maputil "github.com/pingcap/tidb-operator/pkg/utils/map"
2628)
2729
@@ -201,3 +203,101 @@ func IsOffline[
201203](f F ) bool {
202204 return scope.From [S ](f ).IsOffline ()
203205}
206+
207+ func Volumes [
208+ S scope.Instance [F , T ],
209+ F client.Object ,
210+ T runtime.Instance ,
211+ ](f F ) []v1alpha1.Volume {
212+ return scope.From [S ](f ).Volumes ()
213+ }
214+
215+ func PVCOverlay [
216+ S scope.Instance [F , T ],
217+ F client.Object ,
218+ T runtime.Instance ,
219+ ](f F ) []v1alpha1.NamedPersistentVolumeClaimOverlay {
220+ return scope.From [S ](f ).PVCOverlay ()
221+ }
222+
223+ func PVCs [
224+ S scope.Instance [F , T ],
225+ F client.Object ,
226+ T runtime.Instance ,
227+ ](cluster * v1alpha1.Cluster , obj F , ps ... PVCPatch ) []* corev1.PersistentVolumeClaim {
228+ vols := Volumes [S ](obj )
229+ var pvcs []* corev1.PersistentVolumeClaim
230+ nameToIndex := map [string ]int {}
231+ for i := range vols {
232+ vol := & vols [i ]
233+ nameToIndex [vol .Name ] = i
234+ pvc := & corev1.PersistentVolumeClaim {
235+ ObjectMeta : metav1.ObjectMeta {
236+ Name : persistentVolumeClaimName (PodName [S ](obj ), vol .Name ),
237+ Namespace : obj .GetNamespace (),
238+ Labels : PersistentVolumeClaimLabels [S ](obj , vol .Name ),
239+ OwnerReferences : []metav1.OwnerReference {
240+ * metav1 .NewControllerRef (obj , scope .GVK [S ]()),
241+ },
242+ },
243+ Spec : corev1.PersistentVolumeClaimSpec {
244+ AccessModes : []corev1.PersistentVolumeAccessMode {
245+ corev1 .ReadWriteOnce ,
246+ },
247+ Resources : corev1.VolumeResourceRequirements {
248+ Requests : corev1.ResourceList {
249+ corev1 .ResourceStorage : vol .Storage ,
250+ },
251+ },
252+ StorageClassName : vol .StorageClassName ,
253+ },
254+ }
255+
256+ for _ , p := range ps {
257+ p .Patch (vol , pvc )
258+ }
259+
260+ pvcs = append (pvcs , pvc )
261+ }
262+
263+ pvcOverlays := PVCOverlay [S ](obj )
264+
265+ for _ , o := range pvcOverlays {
266+ index , ok := nameToIndex [o .Name ]
267+ if ! ok {
268+ // TODO(liubo02): it should be validated
269+ panic ("vol name" + o .Name + "doesn't exist" )
270+ }
271+
272+ overlay .OverlayPersistentVolumeClaim (pvcs [index ], & o .PersistentVolumeClaim )
273+ }
274+
275+ return pvcs
276+ }
277+
278+ type PVCPatch interface {
279+ Patch (vol * v1alpha1.Volume , pvc * corev1.PersistentVolumeClaim )
280+ }
281+
282+ type PVCPatchFunc func (vol * v1alpha1.Volume , pvc * corev1.PersistentVolumeClaim )
283+
284+ func (f PVCPatchFunc ) Patch (vol * v1alpha1.Volume , pvc * corev1.PersistentVolumeClaim ) {
285+ f (vol , pvc )
286+ }
287+
288+ func EnableVAC (enable bool ) PVCPatch {
289+ return PVCPatchFunc (func (vol * v1alpha1.Volume , pvc * corev1.PersistentVolumeClaim ) {
290+ if enable {
291+ pvc .Spec .VolumeAttributesClassName = vol .VolumeAttributesClassName
292+ }
293+ })
294+ }
295+
296+ func WithLegacyK8sAppLabels () PVCPatch {
297+ return PVCPatchFunc (func (_ * v1alpha1.Volume , pvc * corev1.PersistentVolumeClaim ) {
298+ pvc .Labels = maputil .MergeTo (pvc .Labels , k8s .LabelsK8sApp (
299+ pvc .Labels [v1alpha1 .LabelKeyCluster ],
300+ pvc .Labels [v1alpha1 .LabelKeyComponent ],
301+ ))
302+ })
303+ }
0 commit comments