diff --git a/pkg/config/config.go b/pkg/config/config.go index bd3201081f..f510c0c43a 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -98,10 +98,10 @@ const ( InjectSidecarDisable = "disable" + injectSidecar // config in pv - mountPodCpuLimitKey = "juicefs/mount-cpu-limit" - mountPodMemLimitKey = "juicefs/mount-memory-limit" - mountPodCpuRequestKey = "juicefs/mount-cpu-request" - mountPodMemRequestKey = "juicefs/mount-memory-request" + MountPodCpuLimitKey = "juicefs/mount-cpu-limit" + MountPodMemLimitKey = "juicefs/mount-memory-limit" + MountPodCpuRequestKey = "juicefs/mount-cpu-request" + MountPodMemRequestKey = "juicefs/mount-memory-request" mountPodLabelKey = "juicefs/mount-labels" mountPodAnnotationKey = "juicefs/mount-annotations" mountPodServiceAccount = "juicefs/mount-service-account" @@ -116,10 +116,10 @@ const ( DeleteDelayAtKey = "juicefs-delete-at" // default value - defaultMountPodCpuLimit = "2000m" - defaultMountPodMemLimit = "5Gi" - defaultMountPodCpuRequest = "1000m" - defaultMountPodMemRequest = "1Gi" + DefaultMountPodCpuLimit = "2000m" + DefaultMountPodMemLimit = "5Gi" + DefaultMountPodCpuRequest = "1000m" + DefaultMountPodMemRequest = "1Gi" ) var PodLocks [1024]sync.Mutex diff --git a/pkg/config/setting.go b/pkg/config/setting.go index 7d80ad00f4..a4f1dcd01b 100644 --- a/pkg/config/setting.go +++ b/pkg/config/setting.go @@ -281,10 +281,10 @@ func ParseSetting(secrets, volCtx map[string]string, options []string, usePod bo jfsSetting.SubPath = volCtx["subPath"] } - cpuLimit := volCtx[mountPodCpuLimitKey] - memoryLimit := volCtx[mountPodMemLimitKey] - cpuRequest := volCtx[mountPodCpuRequestKey] - memoryRequest := volCtx[mountPodMemRequestKey] + cpuLimit := volCtx[MountPodCpuLimitKey] + memoryLimit := volCtx[MountPodMemLimitKey] + cpuRequest := volCtx[MountPodCpuRequestKey] + memoryRequest := volCtx[MountPodMemRequestKey] jfsSetting.Resources, err = parsePodResources(cpuLimit, memoryLimit, cpuRequest, memoryRequest) if err != nil { klog.Errorf("Parse resource error: %v", err) @@ -436,10 +436,10 @@ func parsePodResources(cpuLimit, memoryLimit, cpuRequest, memoryRequest string) podLimit := map[corev1.ResourceName]resource.Quantity{} podRequest := map[corev1.ResourceName]resource.Quantity{} // set default value - podLimit[corev1.ResourceCPU] = resource.MustParse(defaultMountPodCpuLimit) - podLimit[corev1.ResourceMemory] = resource.MustParse(defaultMountPodMemLimit) - podRequest[corev1.ResourceCPU] = resource.MustParse(defaultMountPodCpuRequest) - podRequest[corev1.ResourceMemory] = resource.MustParse(defaultMountPodMemRequest) + podLimit[corev1.ResourceCPU] = resource.MustParse(DefaultMountPodCpuLimit) + podLimit[corev1.ResourceMemory] = resource.MustParse(DefaultMountPodMemLimit) + podRequest[corev1.ResourceCPU] = resource.MustParse(DefaultMountPodCpuRequest) + podRequest[corev1.ResourceMemory] = resource.MustParse(DefaultMountPodMemRequest) var err error if cpuLimit != "" { if podLimit[corev1.ResourceCPU], err = resource.ParseQuantity(cpuLimit); err != nil { @@ -470,12 +470,12 @@ func parsePodResources(cpuLimit, memoryLimit, cpuRequest, memoryRequest string) func getDefaultResource() corev1.ResourceRequirements { return corev1.ResourceRequirements{ Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(defaultMountPodCpuLimit), - corev1.ResourceMemory: resource.MustParse(defaultMountPodMemLimit), + corev1.ResourceCPU: resource.MustParse(DefaultMountPodCpuLimit), + corev1.ResourceMemory: resource.MustParse(DefaultMountPodMemLimit), }, Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(defaultMountPodCpuRequest), - corev1.ResourceMemory: resource.MustParse(defaultMountPodMemRequest), + corev1.ResourceCPU: resource.MustParse(DefaultMountPodCpuRequest), + corev1.ResourceMemory: resource.MustParse(DefaultMountPodMemRequest), }, } } diff --git a/pkg/config/setting_test.go b/pkg/config/setting_test.go index 9c56614c7b..a1f9e727ae 100644 --- a/pkg/config/setting_test.go +++ b/pkg/config/setting_test.go @@ -49,12 +49,12 @@ func TestParseSecret(t *testing.T) { } defaultResource := corev1.ResourceRequirements{ Limits: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(defaultMountPodCpuLimit), - corev1.ResourceMemory: resource.MustParse(defaultMountPodMemLimit), + corev1.ResourceCPU: resource.MustParse(DefaultMountPodCpuLimit), + corev1.ResourceMemory: resource.MustParse(DefaultMountPodMemLimit), }, Requests: corev1.ResourceList{ - corev1.ResourceCPU: resource.MustParse(defaultMountPodCpuRequest), - corev1.ResourceMemory: resource.MustParse(defaultMountPodMemRequest), + corev1.ResourceCPU: resource.MustParse(DefaultMountPodCpuRequest), + corev1.ResourceMemory: resource.MustParse(DefaultMountPodMemRequest), }, } @@ -166,7 +166,7 @@ func TestParseSecret(t *testing.T) { name: "test-cpu-limit", args: args{ secrets: map[string]string{"name": "test", "storage": "s3"}, - volCtx: map[string]string{mountPodCpuLimitKey: "1"}, + volCtx: map[string]string{MountPodCpuLimitKey: "1"}, usePod: true, }, want: &JfsSetting{ @@ -182,7 +182,7 @@ func TestParseSecret(t *testing.T) { Resources: corev1.ResourceRequirements{ Limits: map[corev1.ResourceName]resource.Quantity{ corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse(defaultMountPodMemLimit), + corev1.ResourceMemory: resource.MustParse(DefaultMountPodMemLimit), }, Requests: defaultResource.Requests, }, @@ -199,7 +199,7 @@ func TestParseSecret(t *testing.T) { name: "test-mem-limit", args: args{ secrets: map[string]string{"name": "test", "storage": "s3"}, - volCtx: map[string]string{mountPodMemLimitKey: "1G"}, + volCtx: map[string]string{MountPodMemLimitKey: "1G"}, usePod: true, }, want: &JfsSetting{ @@ -215,7 +215,7 @@ func TestParseSecret(t *testing.T) { Resources: corev1.ResourceRequirements{ Limits: map[corev1.ResourceName]resource.Quantity{ corev1.ResourceMemory: resource.MustParse("1G"), - corev1.ResourceCPU: resource.MustParse(defaultMountPodCpuLimit), + corev1.ResourceCPU: resource.MustParse(DefaultMountPodCpuLimit), }, Requests: defaultResource.Requests, }, @@ -232,7 +232,7 @@ func TestParseSecret(t *testing.T) { name: "test-mem-request", args: args{ secrets: map[string]string{"name": "test", "storage": "s3"}, - volCtx: map[string]string{mountPodMemRequestKey: "1G"}, + volCtx: map[string]string{MountPodMemRequestKey: "1G"}, usePod: true, }, want: &JfsSetting{ @@ -248,7 +248,7 @@ func TestParseSecret(t *testing.T) { Resources: corev1.ResourceRequirements{ Requests: map[corev1.ResourceName]resource.Quantity{ corev1.ResourceMemory: resource.MustParse("1G"), - corev1.ResourceCPU: resource.MustParse(defaultMountPodCpuRequest), + corev1.ResourceCPU: resource.MustParse(DefaultMountPodCpuRequest), }, Limits: defaultResource.Limits, }, @@ -265,7 +265,7 @@ func TestParseSecret(t *testing.T) { name: "test-cpu-request", args: args{ secrets: map[string]string{"name": "test"}, - volCtx: map[string]string{mountPodCpuRequestKey: "1"}, + volCtx: map[string]string{MountPodCpuRequestKey: "1"}, }, want: &JfsSetting{ Name: "test", @@ -278,7 +278,7 @@ func TestParseSecret(t *testing.T) { Resources: corev1.ResourceRequirements{ Requests: map[corev1.ResourceName]resource.Quantity{ corev1.ResourceCPU: resource.MustParse("1"), - corev1.ResourceMemory: resource.MustParse(defaultMountPodMemRequest), + corev1.ResourceMemory: resource.MustParse(DefaultMountPodMemRequest), }, Limits: defaultResource.Limits, }, diff --git a/pkg/juicefs/juicefs.go b/pkg/juicefs/juicefs.go index c1ab38b793..9d2ec96d64 100644 --- a/pkg/juicefs/juicefs.go +++ b/pkg/juicefs/juicefs.go @@ -35,6 +35,7 @@ import ( "google.golang.org/grpc/status" corev1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/fields" "k8s.io/klog" @@ -336,7 +337,7 @@ func (j *juicefs) JfsMount(ctx context.Context, volumeID string, target string, // Settings get all jfs settings and generate format/auth command func (j *juicefs) Settings(ctx context.Context, volumeID string, secrets, volCtx map[string]string, options []string) (*config.JfsSetting, error) { - mountOptions, err := j.validOptions(volumeID, options) + mountOptions, err := j.validOptions(volumeID, options, volCtx) if err != nil { return nil, err } @@ -491,7 +492,7 @@ func (j *juicefs) validTarget(target string) error { return nil } -func (j *juicefs) validOptions(volumeId string, options []string) ([]string, error) { +func (j *juicefs) validOptions(volumeId string, options []string, volCtx map[string]string) ([]string, error) { mountOptions := []string{} for _, option := range options { mountOption := strings.TrimSpace(option) @@ -505,6 +506,28 @@ func (j *juicefs) validOptions(volumeId string, options []string) ([]string, err if mountOption == "writeback" { klog.Warningf("writeback is not suitable in CSI, please do not use it. volumeId: %s", volumeId) } + if len(ops) == 2 && ops[0] == "buffer-size" { + rs := volCtx[config.MountPodMemLimitKey] + if rs == "" { + rs = config.DefaultMountPodMemLimit + } + memLimit, err := resource.ParseQuantity(rs) + if err != nil { + return []string{}, fmt.Errorf("invalid memory limit: %s", volCtx[config.MountPodMemLimitKey]) + } + memLimitByte := memLimit.Value() + + // buffer-size is in MiB, turn to byte + bufSize, err := strconv.Atoi(ops[1]) + if err != nil { + return []string{}, fmt.Errorf("invalid mount option: %s", mountOption) + } + bufferSize := int64(bufSize) << 20 + + if bufferSize > memLimitByte { + return []string{}, fmt.Errorf("buffer-size %s MiB is greater than pod memory limit %s", ops[1], memLimit.String()) + } + } mountOptions = append(mountOptions, mountOption) } return mountOptions, nil diff --git a/pkg/juicefs/juicefs_test.go b/pkg/juicefs/juicefs_test.go index f510b807e0..744cc069b7 100644 --- a/pkg/juicefs/juicefs_test.go +++ b/pkg/juicefs/juicefs_test.go @@ -1209,6 +1209,7 @@ func Test_juicefs_validOptions(t *testing.T) { type args struct { volumeId string options []string + volCtx map[string]string } tests := []struct { name string @@ -1252,11 +1253,23 @@ func Test_juicefs_validOptions(t *testing.T) { want: []string{}, wantErr: true, }, + { + name: "test-buffersize", + args: args{ + volumeId: "test", + options: []string{"buffer-size=1024"}, + volCtx: map[string]string{ + config.MountPodMemLimitKey: "1Mi", + }, + }, + want: []string{}, + wantErr: true, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { j := &juicefs{} - got, err := j.validOptions(tt.args.volumeId, tt.args.options) + got, err := j.validOptions(tt.args.volumeId, tt.args.options, tt.args.volCtx) if (err != nil) != tt.wantErr { t.Errorf("validOptions() error = %v, wantErr %v", err, tt.wantErr) return