github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/controllerutil/volume_util.go (about) 1 /* 2 Copyright (C) 2022-2023 ApeCloud Co., Ltd 3 4 This file is part of KubeBlocks project 5 6 This program is free software: you can redistribute it and/or modify 7 it under the terms of the GNU Affero General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 This program is distributed in the hope that it will be useful 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU Affero General Public License for more details. 15 16 You should have received a copy of the GNU Affero General Public License 17 along with this program. If not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 package controllerutil 21 22 import ( 23 "fmt" 24 "sort" 25 26 "golang.org/x/exp/maps" 27 corev1 "k8s.io/api/core/v1" 28 29 appsv1alpha1 "github.com/1aal/kubeblocks/apis/apps/v1alpha1" 30 ) 31 32 type createVolumeFn func(volumeName string) corev1.Volume 33 type updateVolumeFn func(*corev1.Volume) error 34 35 func findVolumeWithVolumeName(volumes []corev1.Volume, volumeName string) int { 36 for index, itr := range volumes { 37 if itr.Name == volumeName { 38 return index 39 } 40 } 41 return -1 42 } 43 44 func CreateOrUpdateVolume(volumes []corev1.Volume, volumeName string, createFn createVolumeFn, updateFn updateVolumeFn) ([]corev1.Volume, error) { 45 // for update volume 46 if existIndex := findVolumeWithVolumeName(volumes, volumeName); existIndex >= 0 { 47 if updateFn == nil { 48 return volumes, nil 49 } 50 if err := updateFn(&volumes[existIndex]); err != nil { 51 return volumes, err 52 } 53 return volumes, nil 54 } 55 56 // for create volume 57 return append(volumes, createFn(volumeName)), nil 58 } 59 60 func CreateOrUpdatePodVolumes(podSpec *corev1.PodSpec, volumes map[string]appsv1alpha1.ComponentTemplateSpec) error { 61 var ( 62 err error 63 podVolumes = podSpec.Volumes 64 ) 65 // sort the volumes 66 volumeKeys := maps.Keys(volumes) 67 sort.Strings(volumeKeys) 68 // Update PodTemplate Volumes 69 for _, cmName := range volumeKeys { 70 templateSpec := volumes[cmName] 71 if templateSpec.VolumeName == "" { 72 continue 73 } 74 if podVolumes, err = CreateOrUpdateVolume(podVolumes, templateSpec.VolumeName, func(volumeName string) corev1.Volume { 75 return corev1.Volume{ 76 Name: volumeName, 77 VolumeSource: corev1.VolumeSource{ 78 ConfigMap: &corev1.ConfigMapVolumeSource{ 79 LocalObjectReference: corev1.LocalObjectReference{Name: cmName}, 80 DefaultMode: templateSpec.DefaultMode, 81 }, 82 }, 83 } 84 }, func(volume *corev1.Volume) error { 85 configMap := volume.ConfigMap 86 if configMap == nil { 87 return fmt.Errorf("mount volume[%s] requires a ConfigMap: [%+v]", volume.Name, volume) 88 } 89 configMap.Name = cmName 90 return nil 91 }); err != nil { 92 return err 93 } 94 } 95 podSpec.Volumes = podVolumes 96 return nil 97 }