Skip to content

Commit

Permalink
[Enhancement] Check volume name and mount path when default volume is…
Browse files Browse the repository at this point in the history
… added

Signed-off-by: yandongxiao <[email protected]>
  • Loading branch information
yandongxiao committed Mar 12, 2024
1 parent 65f0bba commit 5551249
Show file tree
Hide file tree
Showing 10 changed files with 77 additions and 31 deletions.
11 changes: 9 additions & 2 deletions helm-charts/charts/kube-starrocks/charts/starrocks/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,9 @@ starrocksFESpec:
# fe storageSpec for persistent metadata.
# Note: Once set, the following fields will not be allowed to be modified.
storageSpec:
# Specifies the name of the volume to mount. If left unspecified, an `emptyDir` volume will be used by default, which
# is ephemeral and data will be lost on pod restart. For persistent storage, it is recommended to specify a volume name.
# For example, using `fe` as the name would be appropriate.
name: ""
# the storageClassName represent the used storageclass name. if not set will use k8s cluster default storageclass.
# you must set name when you set storageClassName
Expand Down Expand Up @@ -433,7 +436,9 @@ starrocksCnSpec:
# specify storageclass name and request size.
# Note: Once set, the following fields will not be allowed to be modified.
storageSpec:
# the name of volume for mount. if not will use emptyDir.
# Specifies the name of the volume to mount. If left unspecified, an `emptyDir` volume will be used by default, which
# is ephemeral and data will be lost on pod restart. For persistent storage, it is recommended to specify a volume name.
# For example, using `cn` as the name would be appropriate.
name: ""
# the storageClassName represent the used storageclass name. if not set will use k8s cluster default storageclass.
# you must set name when you set storageClassName
Expand Down Expand Up @@ -617,7 +622,9 @@ starrocksBeSpec:
# be storageSpec for persistent storage.
# Note: Once set, the following fields will not be allowed to be modified.
storageSpec:
# the name of volume for mount. if not will use emptyDir.
# Specifies the name of the volume to mount. If left unspecified, an `emptyDir` volume will be used by default, which
# is ephemeral and data will be lost on pod restart. For persistent storage, it is recommended to specify a volume name.
# For example, using `be` as the name would be appropriate.
name: ""
# the storageClassName represent the used storageclass name. if not set will use k8s cluster default storageclass.
# you must set name when you set storageClassName
Expand Down
11 changes: 9 additions & 2 deletions helm-charts/charts/kube-starrocks/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,9 @@ starrocks:
# fe storageSpec for persistent metadata.
# Note: Once set, the following fields will not be allowed to be modified.
storageSpec:
# Specifies the name of the volume to mount. If left unspecified, an `emptyDir` volume will be used by default, which
# is ephemeral and data will be lost on pod restart. For persistent storage, it is recommended to specify a volume name.
# For example, using `fe` as the name would be appropriate.
name: ""
# the storageClassName represent the used storageclass name. if not set will use k8s cluster default storageclass.
# you must set name when you set storageClassName
Expand Down Expand Up @@ -530,7 +533,9 @@ starrocks:
# specify storageclass name and request size.
# Note: Once set, the following fields will not be allowed to be modified.
storageSpec:
# the name of volume for mount. if not will use emptyDir.
# Specifies the name of the volume to mount. If left unspecified, an `emptyDir` volume will be used by default, which
# is ephemeral and data will be lost on pod restart. For persistent storage, it is recommended to specify a volume name.
# For example, using `cn` as the name would be appropriate.
name: ""
# the storageClassName represent the used storageclass name. if not set will use k8s cluster default storageclass.
# you must set name when you set storageClassName
Expand Down Expand Up @@ -714,7 +719,9 @@ starrocks:
# be storageSpec for persistent storage.
# Note: Once set, the following fields will not be allowed to be modified.
storageSpec:
# the name of volume for mount. if not will use emptyDir.
# Specifies the name of the volume to mount. If left unspecified, an `emptyDir` volume will be used by default, which
# is ephemeral and data will be lost on pod restart. For persistent storage, it is recommended to specify a volume name.
# For example, using `be` as the name would be appropriate.
name: ""
# the storageClassName represent the used storageclass name. if not set will use k8s cluster default storageclass.
# you must set name when you set storageClassName
Expand Down
22 changes: 21 additions & 1 deletion pkg/apis/starrocks/v1/load_type.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,27 @@ type StarRocksLoadSpec struct {
// +optional
Service *StarRocksService `json:"service,omitempty"`

// StorageVolumes defines the additional storage for meta storage.
// StorageVolumes defines the additional storage for meta or storage.
//
// For FE components
// If the storage volume name is fe-meta or the volume mount path is /opt/starrocks/fe/meta,
// then it will be recognized as storing the configuration of fe meta.
// If the storage volume name is fe-log or the volume mount path is /opt/starrocks/fe/log,
// then it will be recognized as storing the log of fe.
//
// For BE components
// If the storage volume name is be-storage(or be-data) or the volume mount path is /opt/starrocks/be/storage,
// then it will be recognized as storing the data of be.
// If the storage volume name is be-log or the volume mount path is /opt/starrocks/be/log,
// then it will be recognized as storing the log of be.
//
// For CN components
// If the storage volume name is cn-log or the volume mount path is /opt/starrocks/cn/log,
// then it will be recognized as storing the log of cn.
//
// If operator can't find the storage volume name or the volume mount path in the storage volume, it will create
// a default storage volume by using emptyDir.
//
// +optional
StorageVolumes []StorageVolume `json:"storageVolumes,omitempty"`

Expand Down
18 changes: 18 additions & 0 deletions pkg/k8sutils/k8sutils.go
Original file line number Diff line number Diff line change
Expand Up @@ -394,6 +394,24 @@ func GetValueFromSecret(ctx context.Context, k8sClient client.Client, namespace
return string(value), nil
}

func HasVolume(volumes []corev1.Volume, newVolumeName string) bool {
for _, v := range volumes {
if v.Name == newVolumeName {
return true
}
}
return false
}

func HasMountPath(mounts []corev1.VolumeMount, newMountPath string) bool {
for _, v := range mounts {
if v.Name == newMountPath {
return true
}
}
return false
}

func CheckVolumes(volumes []corev1.Volume, mounts []corev1.VolumeMount) error {
// check mount path first
mountPaths := make(map[string]bool)
Expand Down
6 changes: 2 additions & 4 deletions pkg/k8sutils/templates/pod/mount.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ func IsSpecialStorageClass(storageClassName *string) bool {

// MountStorageVolumes parse StorageVolumes from spec and mount them to pod.
// If StorageClassName is EmptyDir, mount an emptyDir volume to pod.
func MountStorageVolumes(spec v1.SpecInterface) ([]corev1.Volume, []corev1.VolumeMount, map[string]bool) {
func MountStorageVolumes(spec v1.SpecInterface) ([]corev1.Volume, []corev1.VolumeMount) {
var volumes []corev1.Volume
var volumeMounts []corev1.VolumeMount
vexist := make(map[string]bool)
for _, sv := range spec.GetStorageVolumes() {
if strings.HasPrefix(sv.StorageSize, "0") {
continue
}
vexist[sv.MountPath] = true
if IsSpecialStorageClass(sv.StorageClassName) {
switch *sv.StorageClassName {
case v1.EmptyDir:
Expand All @@ -37,7 +35,7 @@ func MountStorageVolumes(spec v1.SpecInterface) ([]corev1.Volume, []corev1.Volum
volumes, volumeMounts = MountPersistentVolumeClaim(volumes, volumeMounts, sv.Name, sv.MountPath, sv.SubPath)
}
}
return volumes, volumeMounts, vexist
return volumes, volumeMounts
}

func MountPersistentVolumeClaim(volumes []corev1.Volume, volumeMounts []corev1.VolumeMount,
Expand Down
12 changes: 3 additions & 9 deletions pkg/k8sutils/templates/pod/mount_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ import (
"reflect"
"testing"

v1 "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
corev1 "k8s.io/api/core/v1"

v1 "github.com/StarRocks/starrocks-kubernetes-operator/pkg/apis/starrocks/v1"
)

func TestMountConfigMapInfo(t *testing.T) {
Expand Down Expand Up @@ -211,7 +212,6 @@ func TestMountStorageVolumes(t *testing.T) {
args args
want []corev1.Volume
want1 []corev1.VolumeMount
want2 map[string]bool
}{
{
name: "test mount storage volumes",
Expand Down Expand Up @@ -247,23 +247,17 @@ func TestMountStorageVolumes(t *testing.T) {
MountPath: "/pkg/mounts/volumes1",
},
},
want2: map[string]bool{
"/pkg/mounts/volumes1": true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, got1, got2 := MountStorageVolumes(tt.args.spec)
got, got1 := MountStorageVolumes(tt.args.spec)
if !reflect.DeepEqual(got, tt.want) {
t.Errorf("MountStorageVolumes() got = %v, want %v", got, tt.want)
}
if !reflect.DeepEqual(got1, tt.want1) {
t.Errorf("MountStorageVolumes() got1 = %v, want %v", got1, tt.want1)
}
if !reflect.DeepEqual(got2, tt.want2) {
t.Errorf("MountStorageVolumes() got2 = %v, want %v", got2, tt.want2)
}
})
}
}
Expand Down
14 changes: 8 additions & 6 deletions pkg/subcontrollers/be/be_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const (
_logName = "be-log"
_beConfigPath = "/etc/starrocks/be/conf"
_storageName = "be-storage"
_storageName2 = "be-data" // helm chart use this format
_storagePath = "/opt/starrocks/be/storage"
_envBeConfigPath = "CONFIGMAP_MOUNT_PATH"
)
Expand All @@ -41,14 +42,15 @@ func (be *BeController) buildPodTemplate(src *srapi.StarRocksCluster, config map
metaName := src.Name + "-" + srapi.DEFAULT_BE
beSpec := src.Spec.StarRocksBeSpec

vols, volumeMounts, vexist := pod.MountStorageVolumes(beSpec)
// add default volume about log, if meta not configure.
if _, ok := vexist[_logPath]; !ok {
vols, volumeMounts = pod.MountEmptyDirVolume(vols, volumeMounts, _logName, _logPath, "")
}
if _, ok := vexist[_storagePath]; !ok {
vols, volumeMounts := pod.MountStorageVolumes(beSpec)

if !k8sutils.HasVolume(vols, _storageName) && !k8sutils.HasVolume(vols, _storageName2) &&
!k8sutils.HasMountPath(volumeMounts, _storagePath) {
vols, volumeMounts = pod.MountEmptyDirVolume(vols, volumeMounts, _storageName, _storagePath, "")
}
if !k8sutils.HasVolume(vols, _logName) && !k8sutils.HasMountPath(volumeMounts, _logPath) {
vols, volumeMounts = pod.MountEmptyDirVolume(vols, volumeMounts, _logName, _logPath, "")
}

// mount configmap, secrets to pod if needed
vols, volumeMounts = pod.MountConfigMapInfo(vols, volumeMounts, beSpec.ConfigMapInfo, _beConfigPath)
Expand Down
6 changes: 3 additions & 3 deletions pkg/subcontrollers/cn/cn_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,9 @@ const (
// buildPodTemplate construct the podTemplate for deploy cn.
func (cc *CnController) buildPodTemplate(ctx context.Context, object srobject.StarRocksObject,
cnSpec *srapi.StarRocksCnSpec, config map[string]interface{}) (*corev1.PodTemplateSpec, error) {
vols, volumeMounts, vexist := pod.MountStorageVolumes(cnSpec)
// add default volume about log
if _, ok := vexist[_logPath]; !ok {
vols, volumeMounts := pod.MountStorageVolumes(cnSpec)

if !k8sutils.HasVolume(vols, _logName) && !k8sutils.HasMountPath(volumeMounts, _logPath) {
vols, volumeMounts = pod.MountEmptyDirVolume(vols, volumeMounts, _logName, _logPath, "")
}

Expand Down
6 changes: 3 additions & 3 deletions pkg/subcontrollers/fe/fe_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,12 @@ func (fc *FeController) buildPodTemplate(src *srapi.StarRocksCluster, config map
metaName := src.Name + "-" + srapi.DEFAULT_FE
feSpec := src.Spec.StarRocksFeSpec

vols, volMounts, vexist := pod.MountStorageVolumes(feSpec)
vols, volMounts := pod.MountStorageVolumes(feSpec)
// add default volume about log, meta if not configure.
if _, ok := vexist[_metaPath]; !ok {
if !k8sutils.HasVolume(vols, _metaName) && !k8sutils.HasMountPath(volMounts, _metaPath) {
vols, volMounts = pod.MountEmptyDirVolume(vols, volMounts, _metaName, _metaPath, "")
}
if _, ok := vexist[_logPath]; !ok {
if !k8sutils.HasVolume(vols, _logName) && !k8sutils.HasMountPath(volMounts, _logPath) {
vols, volMounts = pod.MountEmptyDirVolume(vols, volMounts, _logName, _logPath, "")
}

Expand Down
2 changes: 1 addition & 1 deletion pkg/subcontrollers/feproxy/feproxy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ func (controller *FeProxyController) ClearResources(ctx context.Context, src *sr

func (controller *FeProxyController) buildPodTemplate(src *srapi.StarRocksCluster) corev1.PodTemplateSpec {
feProxySpec := src.Spec.StarRocksFeProxySpec
vols, volumeMounts, _ := pod.MountStorageVolumes(feProxySpec)
vols, volumeMounts := pod.MountStorageVolumes(feProxySpec)

vols, volumeMounts = pod.MountConfigMaps(vols, volumeMounts, []srapi.ConfigMapReference{
{
Expand Down

0 comments on commit 5551249

Please sign in to comment.