From a38d8a4264f43ed28441826a32e716fb17ade38c Mon Sep 17 00:00:00 2001 From: Weiwei Date: Mon, 31 Jul 2023 15:07:19 +0800 Subject: [PATCH] support hostpath for mount pod (#703) --- Makefile | 1 - pkg/config/config.go | 1 + pkg/config/setting.go | 12 +++++++ pkg/config/setting_test.go | 25 ++++++++++++++ pkg/juicefs/mount/builder/pod.go | 31 +++++++++++++++++ pkg/juicefs/mount/builder/pod_test.go | 50 +++++++++++++++++++++++++++ pkg/juicefs/mount/pod_mount_test.go | 2 +- 7 files changed, 120 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 3109dfe8b6..77c7ca1821 100644 --- a/Makefile +++ b/Makefile @@ -132,7 +132,6 @@ uninstall: yaml # build dev image .PHONY: image-dev image-dev: juicefs-csi-driver - docker pull $(IMAGE):nightly docker build --build-arg TARGETARCH=$(TARGETARCH) -t $(IMAGE):$(DEV_TAG) -f docker/dev.Dockerfile bin # push dev image diff --git a/pkg/config/config.go b/pkg/config/config.go index e9bc845e7c..199cb7454f 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -109,6 +109,7 @@ const ( deleteDelay = "juicefs/mount-delete-delay" cleanCache = "juicefs/clean-cache" cachePVC = "juicefs/mount-cache-pvc" + mountPodHostPath = "juicefs/host-path" // DeleteDelayTimeKey mount pod annotation DeleteDelayTimeKey = "juicefs-delete-delay" diff --git a/pkg/config/setting.go b/pkg/config/setting.go index 503a9ea212..7d80ad00f4 100644 --- a/pkg/config/setting.go +++ b/pkg/config/setting.go @@ -66,6 +66,7 @@ type JfsSetting struct { MountPodAnnotations map[string]string `json:"mount_pod_annotations"` DeletedDelay string `json:"deleted_delay"` CleanCache bool `json:"clean_cache"` + HostPath []string `json:"host_path"` ServiceAccountName string Resources corev1.ResourceRequirements @@ -322,6 +323,17 @@ func ParseSetting(secrets, volCtx map[string]string, options []string, usePod bo } jfsSetting.MountPodAnnotations = annos } + + var hostPaths []string + if volCtx[mountPodHostPath] != "" { + for _, v := range strings.Split(volCtx[mountPodHostPath], ",") { + p := strings.TrimSpace(v) + if p != "" { + hostPaths = append(hostPaths, strings.TrimSpace(v)) + } + } + jfsSetting.HostPath = hostPaths + } } if len(labels) != 0 { jfsSetting.MountPodLabels = labels diff --git a/pkg/config/setting_test.go b/pkg/config/setting_test.go index e5b0e318e3..9c56614c7b 100644 --- a/pkg/config/setting_test.go +++ b/pkg/config/setting_test.go @@ -600,6 +600,31 @@ func TestParseSecret(t *testing.T) { }, wantErr: false, }, + { + name: "specify host path", + args: args{ + secrets: map[string]string{"name": "test"}, + volCtx: map[string]string{mountPodHostPath: "/abc"}, + }, + want: &JfsSetting{ + Name: "test", + Source: "test", + Configs: map[string]string{}, + Envs: map[string]string{}, + Options: []string{}, + CacheDirs: []string{"/var/jfsCache"}, + Resources: defaultResource, + Attr: PodAttr{ + JFSConfigPath: JFSConfigPath, + Image: "juicedata/mount:ee-nightly", + MountPointPath: MountPointPath, + JFSMountPriorityName: JFSMountPriorityName, + }, + CachePVCs: []CachePVC{}, + HostPath: []string{"/abc"}, + }, + wantErr: false, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/juicefs/mount/builder/pod.go b/pkg/juicefs/mount/builder/pod.go index 3ae157099a..f742f7a1e5 100644 --- a/pkg/juicefs/mount/builder/pod.go +++ b/pkg/juicefs/mount/builder/pod.go @@ -45,6 +45,11 @@ func (r *Builder) NewMountPod(podName string) *corev1.Pod { pod.Spec.Volumes = append(pod.Spec.Volumes, cacheVolumes...) pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, cacheVolumeMounts...) + // add mount path host path volume + mountVolumes, mountVolumeMounts := r.genHostPathVolumes() + pod.Spec.Volumes = append(pod.Spec.Volumes, mountVolumes...) + pod.Spec.Containers[0].VolumeMounts = append(pod.Spec.Containers[0].VolumeMounts, mountVolumeMounts...) + pod.Name = podName pod.Spec.ServiceAccountName = r.jfsSetting.ServiceAccountName controllerutil.AddFinalizer(pod, config.Finalizer) @@ -153,6 +158,32 @@ func (r *Builder) getCacheDirVolumes(mountPropagation corev1.MountPropagationMod return cacheVolumes, cacheVolumeMounts } +func (r *Builder) genHostPathVolumes() (volumes []corev1.Volume, volumeMounts []corev1.VolumeMount) { + volumes = []corev1.Volume{} + volumeMounts = []corev1.VolumeMount{} + if len(r.jfsSetting.HostPath) == 0 { + return + } + mountPropagation := corev1.MountPropagationBidirectional + for idx, hostPath := range r.jfsSetting.HostPath { + name := fmt.Sprintf("hostpath-%d", idx) + volumes = append(volumes, corev1.Volume{ + Name: name, + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: hostPath, + }, + }, + }) + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: name, + MountPath: hostPath, + MountPropagation: &mountPropagation, + }) + } + return +} + func (r *Builder) getCommand() string { cmd := "" options := r.jfsSetting.Options diff --git a/pkg/juicefs/mount/builder/pod_test.go b/pkg/juicefs/mount/builder/pod_test.go index 40916f4a6a..afd844853a 100644 --- a/pkg/juicefs/mount/builder/pod_test.go +++ b/pkg/juicefs/mount/builder/pod_test.go @@ -19,6 +19,7 @@ package builder import ( "encoding/json" "fmt" + "reflect" "testing" corev1 "k8s.io/api/core/v1" @@ -497,3 +498,52 @@ func TestPodMount_getMetricsPort(t *testing.T) { }) } } + +func TestBuilder_genHostPathVolumes(t *testing.T) { + mountPropagation := corev1.MountPropagationBidirectional + type fields struct { + jfsSetting *config.JfsSetting + } + tests := []struct { + name string + fields fields + wantVolumes []corev1.Volume + wantVolumeMounts []corev1.VolumeMount + }{ + { + name: "test", + fields: fields{ + jfsSetting: &config.JfsSetting{ + HostPath: []string{"/tmp"}, + }, + }, + wantVolumes: []corev1.Volume{{ + Name: "hostpath-0", + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: "/tmp", + }, + }, + }}, + wantVolumeMounts: []corev1.VolumeMount{{ + Name: "hostpath-0", + MountPath: "/tmp", + MountPropagation: &mountPropagation, + }}, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + r := &Builder{ + jfsSetting: tt.fields.jfsSetting, + } + gotVolumes, gotVolumeMounts := r.genHostPathVolumes() + if !reflect.DeepEqual(gotVolumes, tt.wantVolumes) { + t.Errorf("genHostPathVolumes() gotVolumes = %v, want %v", gotVolumes, tt.wantVolumes) + } + if !reflect.DeepEqual(gotVolumeMounts, tt.wantVolumeMounts) { + t.Errorf("genHostPathVolumes() gotVolumeMounts = %v, want %v", gotVolumeMounts, tt.wantVolumeMounts) + } + }) + } +} diff --git a/pkg/juicefs/mount/pod_mount_test.go b/pkg/juicefs/mount/pod_mount_test.go index 8128772757..c799e573f6 100644 --- a/pkg/juicefs/mount/pod_mount_test.go +++ b/pkg/juicefs/mount/pod_mount_test.go @@ -807,7 +807,7 @@ func TestGenHashOfSetting(t *testing.T) { Name: "test", }, }, - want: "551d22f6ec39a4b5e281d577fb45ad978935abb4e96ea1544ef52173b25131d", + want: "49483cb6b1f74f8e7c6a55dc596f921254216ec8f17e43ff70e2077e8f1f49f", wantErr: false, }, }