From 1c79901d6568e59439d6aca263781ea3bc0f48d2 Mon Sep 17 00:00:00 2001 From: Dennis Marttinen <38858901+twelho@users.noreply.github.com> Date: Thu, 20 Jul 2023 06:31:56 +0000 Subject: [PATCH] Introduce `JUICEFS_IMMUTABLE`, mount `/etc/updatedb.conf` only in mutable environments (#680) * Fix usage of `UpdateDBDirName` * Introduce `JUICEFS_IMMUTABLE`, mount `/etc/updatedb.conf` only in mutable environments In immutable environments, such as Talos Linux, most host directories are read-only. As a result, for example, `FileOrCreate` for the `/etc/updatedb.conf` will fail to create an empty file. This patch introduces `JUICEFS_IMMUTABLE` as a new environment variable for both controller and node instances to handle these kinds of cases that need special attention in immutable environments. --- cmd/controller.go | 9 ++++++++ cmd/node.go | 11 +++++++++ pkg/config/config.go | 1 + pkg/juicefs/mount/builder/common.go | 33 ++++++++++++++++++--------- pkg/juicefs/mount/builder/pod_test.go | 8 +++---- 5 files changed, 47 insertions(+), 15 deletions(-) diff --git a/cmd/controller.go b/cmd/controller.go index 83a14747ac..5266a5e185 100644 --- a/cmd/controller.go +++ b/cmd/controller.go @@ -21,6 +21,7 @@ import ( "fmt" "net/http" "os" + "strconv" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/runtime" @@ -63,6 +64,14 @@ func parseControllerConfig() { config.MountManager = false config.ByProcess = false } + if jfsImmutable := os.Getenv("JUICEFS_IMMUTABLE"); jfsImmutable != "" { + // check if running in an immutable environment + if immutable, err := strconv.ParseBool(jfsImmutable); err == nil { + config.Immutable = immutable + } else { + klog.Errorf("cannot parse JUICEFS_IMMUTABLE: %v", err) + } + } config.NodeName = os.Getenv("NODE_NAME") config.Namespace = os.Getenv("JUICEFS_MOUNT_NAMESPACE") diff --git a/cmd/node.go b/cmd/node.go index 51b4c82a9a..88dba85171 100644 --- a/cmd/node.go +++ b/cmd/node.go @@ -21,6 +21,7 @@ import ( "fmt" "net/http" "os" + "strconv" "time" "k8s.io/klog" @@ -42,12 +43,22 @@ func parseNodeConfig() { return } config.FormatInPod = formatInPod + + if jfsImmutable := os.Getenv("JUICEFS_IMMUTABLE"); jfsImmutable != "" { + if immutable, err := strconv.ParseBool(jfsImmutable); err == nil { + config.Immutable = immutable + } else { + klog.Errorf("cannot parse JUICEFS_IMMUTABLE: %v", err) + } + } + config.NodeName = os.Getenv("NODE_NAME") config.Namespace = os.Getenv("JUICEFS_MOUNT_NAMESPACE") config.PodName = os.Getenv("POD_NAME") config.MountPointPath = os.Getenv("JUICEFS_MOUNT_PATH") config.JFSConfigPath = os.Getenv("JUICEFS_CONFIG_PATH") config.MountLabels = os.Getenv("JUICEFS_MOUNT_LABELS") + config.HostIp = os.Getenv("HOST_IP") config.KubeletPort = os.Getenv("KUBELET_PORT") jfsMountPriorityName := os.Getenv("JUICEFS_MOUNT_PRIORITY_NAME") diff --git a/pkg/config/config.go b/pkg/config/config.go index 6e193b0471..e9bc845e7c 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -31,6 +31,7 @@ var ( Provisioner = false // provisioner in controller MountManager = false // manage mount pod in controller (only in k8s) Webhook = false // inject juicefs client as sidecar in pod (only in k8s) + Immutable = false // csi driver is running in an immutable environment NodeName = "" Namespace = "" diff --git a/pkg/juicefs/mount/builder/common.go b/pkg/juicefs/mount/builder/common.go index 10eff76e6c..afeffb7d9b 100644 --- a/pkg/juicefs/mount/builder/common.go +++ b/pkg/juicefs/mount/builder/common.go @@ -31,6 +31,7 @@ const ( JfsDirName = "jfs-dir" JfsRootDirName = "jfs-root-dir" UpdateDBDirName = "updatedb" + UpdateDBCfgFile = "/etc/updatedb.conf" ) type Builder struct { @@ -92,15 +93,20 @@ func (r *Builder) getVolumes() []corev1.Volume { Path: config.MountPointPath, Type: &dir, }, - }}, { - Name: "updatedb", - VolumeSource: corev1.VolumeSource{ - HostPath: &corev1.HostPathVolumeSource{ - Path: "/etc/updatedb.conf", - Type: &file, - }, }, }} + + if !config.Immutable { + volumes = append(volumes, corev1.Volume{ + Name: UpdateDBDirName, + VolumeSource: corev1.VolumeSource{ + HostPath: &corev1.HostPathVolumeSource{ + Path: UpdateDBCfgFile, + Type: &file, + }, + }}) + } + if r.jfsSetting.FormatCmd != "" { // initContainer will generate xx.conf to share with mount container volumes = append(volumes, corev1.Volume{ @@ -157,11 +163,16 @@ func (r *Builder) getVolumeMounts() []corev1.VolumeMount { Name: JfsDirName, MountPath: config.PodMountBase, MountPropagation: &mp, - }, { - Name: "updatedb", - MountPath: "/etc/updatedb.conf", - MountPropagation: &mp, }} + + if !config.Immutable { + volumeMounts = append(volumeMounts, corev1.VolumeMount{ + Name: UpdateDBDirName, + MountPath: UpdateDBCfgFile, + MountPropagation: &mp, + }) + } + if r.jfsSetting.FormatCmd != "" { // initContainer will generate xx.conf to share with mount container volumeMounts = append(volumeMounts, corev1.VolumeMount{ diff --git a/pkg/juicefs/mount/builder/pod_test.go b/pkg/juicefs/mount/builder/pod_test.go index 0dfad6b30e..40916f4a6a 100644 --- a/pkg/juicefs/mount/builder/pod_test.go +++ b/pkg/juicefs/mount/builder/pod_test.go @@ -75,10 +75,10 @@ var ( }, }, }, { - Name: "updatedb", + Name: UpdateDBDirName, VolumeSource: corev1.VolumeSource{ HostPath: &corev1.HostPathVolumeSource{ - Path: "/etc/updatedb.conf", + Path: UpdateDBCfgFile, Type: &file, }, }, @@ -106,8 +106,8 @@ var ( MountPropagation: &mp, }, { - Name: "updatedb", - MountPath: "/etc/updatedb.conf", + Name: UpdateDBDirName, + MountPath: UpdateDBCfgFile, MountPropagation: &mp, }, },