diff --git a/api/v1alpha1/juicefsruntime_types.go b/api/v1alpha1/juicefsruntime_types.go index 8098f87140b..042a771acc1 100644 --- a/api/v1alpha1/juicefsruntime_types.go +++ b/api/v1alpha1/juicefsruntime_types.go @@ -96,10 +96,10 @@ type JuiceFSFuseSpec struct { Image string `json:"image,omitempty"` // Image for JuiceFS fuse - ImageTag string `json:"image_tag,omitempty"` + ImageTag string `json:"imageTag,omitempty"` // One of the three policies: `Always`, `IfNotPresent`, `Never` - ImagePullPolicy string `json:"image_pull_policy,omitempty"` + ImagePullPolicy string `json:"imagePullPolicy,omitempty"` // Environment variables that will be used by JuiceFS Fuse Env []corev1.EnvVar `json:"env,omitempty"` @@ -115,7 +115,7 @@ type JuiceFSFuseSpec struct { // NodeSelector is a selector which must be true for the fuse client to fit on a node, // this option only effect when global is enabled // +optional - NodeSelector map[string]string `json:"node_selector,omitempty"` + NodeSelector map[string]string `json:"nodeSelector,omitempty"` // CleanPolicy decides when to clean Juicefs Fuse pods. // Currently Fluid supports two policies: OnDemand and OnRuntimeDeleted diff --git a/charts/fluid/fluid/crds/data.fluid.io_juicefsruntimes.yaml b/charts/fluid/fluid/crds/data.fluid.io_juicefsruntimes.yaml index bab98f00416..15a0199994f 100644 --- a/charts/fluid/fluid/crds/data.fluid.io_juicefsruntimes.yaml +++ b/charts/fluid/fluid/crds/data.fluid.io_juicefsruntimes.yaml @@ -197,14 +197,14 @@ spec: image: description: Image for JuiceFS fuse type: string - image_pull_policy: + imagePullPolicy: description: 'One of the three policies: `Always`, `IfNotPresent`, `Never`' type: string - image_tag: + imageTag: description: Image for JuiceFS fuse type: string - node_selector: + nodeSelector: additionalProperties: type: string description: NodeSelector is a selector which must be true for @@ -1082,6 +1082,11 @@ spec: masterReason: description: Reason for Master's condition transition type: string + mountTime: + description: MountTime represents time last mount happened if Mounttime + is early than master starting time, remount will be required + format: date-time + type: string selector: description: Selector is used for auto-scaling type: string diff --git a/charts/juicefs/templates/fuse/daemonset.yaml b/charts/juicefs/templates/fuse/daemonset.yaml index 6577de7b8b7..8a21d8ef617 100644 --- a/charts/juicefs/templates/fuse/daemonset.yaml +++ b/charts/juicefs/templates/fuse/daemonset.yaml @@ -40,47 +40,6 @@ spec: tolerations: {{ toYaml .Values.tolerations | indent 8 }} {{- end }} - initContainers: - - name: prepare - image: {{ .Values.fuse.image }}:{{ .Values.fuse.imageTag }} - imagePullPolicy: {{ .Values.fuse.imagePullPolicy }} - command: - - sh - - -c - - "sh /root/prepare/prepare-subpath.sh" - securityContext: - privileged: true - env: - {{- if .Values.fuse.envs }} -{{ toYaml .Values.fuse.envs | trim | indent 10 }} - {{- end }} - {{- if .Values.fuse.prepare.metaurlSecret }} - - name: METAURL - valueFrom: - secretKeyRef: - name: {{ .Values.fuse.prepare.metaurlSecret }} - key: metaurl - {{- end }} - {{- if .Values.fuse.prepare.accesskeySecret }} - - name: ACCESS_KEY - valueFrom: - secretKeyRef: - name: {{ .Values.fuse.prepare.accesskeySecret }} - key: access-key - {{- end }} - {{- if .Values.fuse.prepare.secretkeySecret }} - - name: SECRET_KEY - valueFrom: - secretKeyRef: - name: {{ .Values.fuse.prepare.secretkeySecret }} - key: secret-key - {{- end }} - volumeMounts: - - mountPath: /root/.juicefs - mountPropagation: Bidirectional - name: jfs-root-dir - - mountPath: /root/prepare - name: prepare containers: - name: juicefs-fuse image: {{ .Values.fuse.image }}:{{ .Values.fuse.imageTag }} @@ -98,15 +57,34 @@ spec: memory: {{ .Values.fuse.resources.requests.memory }} {{- end }} {{- end }} - {{- if .Values.fuse.command }} - command: ["sh", "-c", "{{ .Values.fuse.command }}"] - {{- end }} + command: ["sh", "/root/script/script.sh"] env: - name: JFS_FOREGROUND value: "1" {{- if .Values.fuse.envs }} {{ toYaml .Values.fuse.envs | trim | indent 10 }} {{- end }} + {{- if .Values.fuse.metaurlSecret }} + - name: METAURL + valueFrom: + secretKeyRef: + name: {{ .Values.fuse.metaurlSecret }} + key: metaurl + {{- end }} + {{- if .Values.fuse.accesskeySecret }} + - name: ACCESS_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.fuse.accesskeySecret }} + key: access-key + {{- end }} + {{- if .Values.fuse.secretkeySecret }} + - name: SECRET_KEY + valueFrom: + secretKeyRef: + name: {{ .Values.fuse.secretkeySecret }} + key: secret-key + {{- end }} readinessProbe: exec: command: @@ -129,19 +107,18 @@ spec: exec: command: ["sh", "-c", "umount {{ .Values.fuse.mountPath }}"] volumeMounts: - - name: jfs-dir + - name: juicefs-fuse-mount mountPath: {{ .Values.fuse.hostMountPath }} mountPropagation: Bidirectional - - mountPath: /root/.juicefs - mountPropagation: Bidirectional - name: jfs-root-dir + - mountPath: /root/script + name: script {{- if .Values.fuse.cacheDir }} - name: cache-dir mountPath: {{ .Values.fuse.cacheDir }} {{- end }} restartPolicy: Always volumes: - - name: jfs-dir + - name: juicefs-fuse-mount hostPath: path: {{ .Values.fuse.hostMountPath }} type: DirectoryOrCreate @@ -151,36 +128,30 @@ spec: path: {{ .Values.fuse.cacheDir }} type: DirectoryOrCreate {{- end }} - - name: jfs-root-dir - emptyDir: {} - - name: prepare + - name: script configMap: - name: {{ template "juicefs.fullname" . }}-prepare + name: {{ template "juicefs.fullname" . }}-script defaultMode: 0777 --- apiVersion: v1 kind: ConfigMap metadata: - name: {{ template "juicefs.fullname" . }}-prepare + name: {{ template "juicefs.fullname" . }}-script labels: app: {{ template "juicefs.name" . }} chart: {{ template "juicefs.chart" . }} release: {{ .Release.Name }} heritage: {{ .Release.Service }} data: - prepare-subpath.sh: | + script.sh: | #!/bin/bash - {{- if and .Values.fuse.prepare.storage .Values.fuse.prepare.bucket .Values.fuse.prepare.accesskeySecret .Values.fuse.prepare.secretkeySecret }} - /usr/local/bin/juicefs format --storage={{ .Values.fuse.prepare.storage }} --bucket={{ .Values.fuse.prepare.bucket }} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${METAURL} {{ .Values.fuse.prepare.name }} + {{- if and .Values.fuse.storage .Values.fuse.bucket .Values.fuse.accesskeySecret .Values.fuse.secretkeySecret }} + /usr/local/bin/juicefs format --storage={{ .Values.fuse.storage }} --bucket={{ .Values.fuse.bucket }} --access-key=${ACCESS_KEY} --secret-key=${SECRET_KEY} ${METAURL} {{ .Values.fuse.name }} {{- else }} - /usr/local/bin/juicefs format ${METAURL} {{ .Values.fuse.prepare.name }} --no-update + /usr/local/bin/juicefs format ${METAURL} {{ .Values.fuse.name }} --no-update {{- end }} - /usr/local/bin/juicefs mount -d ${METAURL} /mnt/jfs - if [ ! -d /mnt/jfs{{ .Values.fuse.prepare.subPath }} ]; then - mkdir /mnt/jfs{{ .Values.fuse.prepare.subPath }} - fi; - umount /mnt/jfs + {{ .Values.fuse.command }} {{- end }} diff --git a/charts/juicefs/values.yaml b/charts/juicefs/values.yaml index e85258e26eb..e85bdccddc2 100644 --- a/charts/juicefs/values.yaml +++ b/charts/juicefs/values.yaml @@ -42,14 +42,13 @@ worker: ## FUSE ## fuse: - prepare: - name: "" - accesskeySecret: "" - secretkeySecret: "" - bucket: "" - metaurlSecret: "" - storage: "" - subPath: "" + name: "" + accesskeySecret: "" + secretkeySecret: "" + bucket: "" + metaurlSecret: "" + storage: "" + subPath: "" criticalPod: false enabled: true image: juicedata/juicefs-csi-driver diff --git a/config/crd/bases/data.fluid.io_juicefsruntimes.yaml b/config/crd/bases/data.fluid.io_juicefsruntimes.yaml index bab98f00416..15a0199994f 100644 --- a/config/crd/bases/data.fluid.io_juicefsruntimes.yaml +++ b/config/crd/bases/data.fluid.io_juicefsruntimes.yaml @@ -197,14 +197,14 @@ spec: image: description: Image for JuiceFS fuse type: string - image_pull_policy: + imagePullPolicy: description: 'One of the three policies: `Always`, `IfNotPresent`, `Never`' type: string - image_tag: + imageTag: description: Image for JuiceFS fuse type: string - node_selector: + nodeSelector: additionalProperties: type: string description: NodeSelector is a selector which must be true for @@ -1082,6 +1082,11 @@ spec: masterReason: description: Reason for Master's condition transition type: string + mountTime: + description: MountTime represents time last mount happened if Mounttime + is early than master starting time, remount will be required + format: date-time + type: string selector: description: Selector is used for auto-scaling type: string diff --git a/pkg/ddc/juicefs/transform_fuse.go b/pkg/ddc/juicefs/transform_fuse.go index eab09177ab2..e2d62b2ea75 100644 --- a/pkg/ddc/juicefs/transform_fuse.go +++ b/pkg/ddc/juicefs/transform_fuse.go @@ -28,23 +28,22 @@ import ( func (j *JuiceFSEngine) transformFuse(runtime *datav1alpha1.JuiceFSRuntime, dataset *datav1alpha1.Dataset, value *JuiceFS) (err error) { value.Fuse = Fuse{} - value.Fuse.Prepare = Prepare{} if len(dataset.Spec.Mounts) <= 0 { return errors.New("do not assign mount point") } mount := dataset.Spec.Mounts[0] - value.Fuse.Prepare.Name = mount.Name + value.Fuse.Name = mount.Name opts := make(map[string]string) source := "" for k, v := range mount.Options { switch k { case JuiceStorage: - value.Fuse.Prepare.Storage = v + value.Fuse.Storage = v continue case JuiceBucket: - value.Fuse.Prepare.Bucket = v + value.Fuse.Bucket = v continue default: opts[k] = v @@ -64,16 +63,16 @@ func (j *JuiceFSEngine) transformFuse(runtime *datav1alpha1.JuiceFSRuntime, data switch key { case JuiceMetaUrl: - value.Fuse.Prepare.MetaUrlSecret = secretKeyRef.Name + value.Fuse.MetaUrlSecret = secretKeyRef.Name v, ok := secret.Data[secretKeyRef.Key] if !ok { return fmt.Errorf("can't get metaurl from secret %s", secret.Name) } source = string(v) case JuiceAccessKey: - value.Fuse.Prepare.AccessKeySecret = secretKeyRef.Name + value.Fuse.AccessKeySecret = secretKeyRef.Name case JuiceSecretKey: - value.Fuse.Prepare.SecretKeySecret = secretKeyRef.Name + value.Fuse.SecretKeySecret = secretKeyRef.Name } } @@ -96,7 +95,7 @@ func (j *JuiceFSEngine) transformFuse(runtime *datav1alpha1.JuiceFSRuntime, data value.Fuse.MountPath = j.getMountPoint() value.Fuse.NodeSelector = map[string]string{} value.Fuse.HostMountPath = j.getHostMountPoint() - value.Fuse.Prepare.SubPath = subPath + value.Fuse.SubPath = subPath value.Fuse.Envs = runtime.Spec.Fuse.Env mountArgs := []string{common.JuiceFSMountPath, source, value.Fuse.MountPath} diff --git a/pkg/ddc/juicefs/type.go b/pkg/ddc/juicefs/type.go index ce927f10ddf..44e68eca85d 100644 --- a/pkg/ddc/juicefs/type.go +++ b/pkg/ddc/juicefs/type.go @@ -47,7 +47,13 @@ type Worker struct { } type Fuse struct { - Prepare Prepare `yaml:"prepare,omitempty"` + SubPath string `yaml:"subPath,omitempty"` + Name string `yaml:"name"` + AccessKeySecret string `yaml:"accesskeySecret,omitempty"` + SecretKeySecret string `yaml:"secretkeySecret,omitempty"` + Bucket string `yaml:"bucket,omitempty"` + MetaUrlSecret string `yaml:"metaurlSecret,omitempty"` + Storage string `yaml:"storage,omitempty"` Image string `yaml:"image,omitempty"` NodeSelector map[string]string `yaml:"nodeSelector,omitempty"` Envs []corev1.EnvVar `yaml:"envs,omitempty"` @@ -63,16 +69,6 @@ type Fuse struct { CriticalPod bool `yaml:"criticalPod,omitempty"` } -type Prepare struct { - SubPath string `yaml:"subPath,omitempty"` - Name string `yaml:"name"` - AccessKeySecret string `yaml:"accesskeySecret,omitempty"` - SecretKeySecret string `yaml:"secretkeySecret,omitempty"` - Bucket string `yaml:"bucket,omitempty"` - MetaUrlSecret string `yaml:"metaurlSecret,omitempty"` - Storage string `yaml:"storage,omitempty"` -} - type TieredStore struct { Path string `yaml:"path,omitempty"` Quota string `yaml:"quota,omitempty"` diff --git a/pkg/scripts/poststart/check_fuse.go b/pkg/scripts/poststart/check_fuse.go index 5e161f1bd4e..c9297ea01e9 100644 --- a/pkg/scripts/poststart/check_fuse.go +++ b/pkg/scripts/poststart/check_fuse.go @@ -88,7 +88,7 @@ func (f *ScriptGeneratorForFuse) BuildConfigmap(ownerReference metav1.OwnerRefer } func (f *ScriptGeneratorForFuse) getConfigmapName() string { - return f.name + "-" + f.mountType + "-" + configMapName + return f.name + "-" + strings.ToLower(f.mountType) + "-" + configMapName } func (f *ScriptGeneratorForFuse) GetPostStartCommand() (handler *corev1.Handler) { diff --git a/pkg/scripts/poststart/check_fuse_test.go b/pkg/scripts/poststart/check_fuse_test.go new file mode 100644 index 00000000000..63dae81ac3d --- /dev/null +++ b/pkg/scripts/poststart/check_fuse_test.go @@ -0,0 +1,90 @@ +/* + Copyright 2022 The Fluid Authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package poststart + +import ( + "github.com/fluid-cloudnative/fluid/pkg/common" + "testing" +) + +func TestScriptGeneratorForFuse_getConfigmapName(t *testing.T) { + type fields struct { + name string + namespace string + mountPath string + mountType string + } + tests := []struct { + name string + fields fields + want string + }{ + { + name: "test-alluxio", + fields: fields{ + name: "test", + namespace: "default", + mountPath: "/dev", + mountType: common.ALLUXIO_MOUNT_TYPE, + }, + want: "test-" + common.ALLUXIO_MOUNT_TYPE + "-" + configMapName, + }, + { + name: "test-jindo", + fields: fields{ + name: "test", + namespace: "default", + mountPath: "/dev", + mountType: common.JindoMountType, + }, + want: "test-" + common.JindoMountType + "-" + configMapName, + }, + { + name: "test-juicefs", + fields: fields{ + name: "test", + namespace: "default", + mountPath: "/dev", + mountType: common.JuiceFSMountType, + }, + want: "test-juicefs-" + configMapName, + }, + { + name: "test-goosefs", + fields: fields{ + name: "test", + namespace: "default", + mountPath: "/dev", + mountType: common.GooseFSMountType, + }, + want: "test-" + common.GooseFSMountType + "-" + configMapName, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + f := &ScriptGeneratorForFuse{ + name: tt.fields.name, + namespace: tt.fields.namespace, + mountPath: tt.fields.mountPath, + mountType: tt.fields.mountType, + } + if got := f.getConfigmapName(); got != tt.want { + t.Errorf("getConfigmapName() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/pkg/utils/kubeclient/volume_mount.go b/pkg/utils/kubeclient/volume_mount.go index c37158ee5a9..18e25f32c0e 100644 --- a/pkg/utils/kubeclient/volume_mount.go +++ b/pkg/utils/kubeclient/volume_mount.go @@ -76,19 +76,16 @@ func GetFuseMountInContainer(mountType string, container corev1.Container) (volu common.ALLUXIO_MOUNT_TYPE: common.ALLUXIO_CHART, common.ALLUXIO_RUNTIME: common.ALLUXIO_CHART, common.GooseFSMountType: common.GooseFSChart, + common.JuiceFSMountType: common.JuiceFSChart, + common.JuiceFSRuntime: common.JuiceFSChart, } volumeMountName := "" - switch mountType { - case common.JuiceFSMountType, common.JuiceFSRuntime: - volumeMountName = "jfs-dir" - default: - if prefix, found := kv[mountType]; found { - volumeMountName = prefix + "-fuse-mount" - } else { - err = fmt.Errorf("failed to find the prefix by mountType %s", mountType) - return - } + if prefix, found := kv[mountType]; found { + volumeMountName = prefix + "-fuse-mount" + } else { + err = fmt.Errorf("failed to find the prefix by mountType %s", mountType) + return } for _, vm := range container.VolumeMounts { diff --git a/pkg/utils/kubeclient/volume_mount_test.go b/pkg/utils/kubeclient/volume_mount_test.go index 2ba35b590fc..f26719d7951 100644 --- a/pkg/utils/kubeclient/volume_mount_test.go +++ b/pkg/utils/kubeclient/volume_mount_test.go @@ -64,7 +64,7 @@ func TestGetFuseMountInContainer(t *testing.T) { container: corev1.Container{ VolumeMounts: []corev1.VolumeMount{ { - Name: "jfs-dir", + Name: "juicefs-fuse-mount", MountPath: "/runtime_mnt/jfs", }, },