Repository: lima-vm/lima
Pull request #564 (2022-01-19 06:21:33)

Make sshfs caching configurable
Requested at https://github.com/lima-vm/lima/pull/556#issuecomment-1016111354, replaces #556.



Patch:
diff --git a/pkg/hostagent/mount.go b/pkg/hostagent/mount.go
index dab0e88e..6621313c 100644
--- a/pkg/hostagent/mount.go
+++ b/pkg/hostagent/mount.go
@@ -42,7 +42,10 @@ func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, e
 		return nil, err
 	}
 	// NOTE: allow_other requires "user_allow_other" in /etc/fuse.conf
-	sshfsOptions := "allow_other,cache=no"
+	sshfsOptions := "allow_other"
+	if !*m.SSHFS.Cache {
+		sshfsOptions = sshfsOptions + ",cache=no"
+	}
 	if *m.SSHFS.FollowSymlinks {
 		sshfsOptions = sshfsOptions + ",follow_symlinks"
 	}
diff --git a/pkg/limayaml/default.yaml b/pkg/limayaml/default.yaml
index 144241d8..4236b6f9 100644
--- a/pkg/limayaml/default.yaml
+++ b/pkg/limayaml/default.yaml
@@ -47,11 +47,15 @@ mounts:
   # Setting `writable` to true is possible, but untested and dangerous.
   # Default: false
   writable: null
-  # SSHFS has an optional flag called 'follow_symlinks'. This allows mounts
-  # to be properly resolved in the guest os and allow for access to the
-  # contents of the symlink. As a result, symlinked files & folders on the Host
-  # system will look and feel like regular files directories in the Guest OS.
   sshfs:
+    # Enabling the SSHFS cache will increase performance of the mounted filesystem, at
+    # the cost of potentially not reflecting changes made on the host in a timely manner.
+    # Default: false
+    cache: null
+    # SSHFS has an optional flag called 'follow_symlinks'. This allows mounts
+    # to be properly resolved in the guest os and allow for access to the
+    # contents of the symlink. As a result, symlinked files & folders on the Host
+    # system will look and feel like regular files directories in the Guest OS.
     # Default: false
     followSymlinks: null
 - location: "/tmp/lima"
diff --git a/pkg/limayaml/defaults.go b/pkg/limayaml/defaults.go
index 2f87b0e7..62818f21 100644
--- a/pkg/limayaml/defaults.go
+++ b/pkg/limayaml/defaults.go
@@ -320,6 +320,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
 	location := make(map[string]int)
 	for _, mount := range append(append(d.Mounts, y.Mounts...), o.Mounts...) {
 		if i, ok := location[mount.Location]; ok {
+			if mount.SSHFS.Cache != nil {
+				mounts[i].SSHFS.Cache = mount.SSHFS.Cache
+			}
 			if mount.SSHFS.FollowSymlinks != nil {
 				mounts[i].SSHFS.FollowSymlinks = mount.SSHFS.FollowSymlinks
 			}
@@ -335,6 +338,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
 
 	for i := range y.Mounts {
 		mount := &y.Mounts[i]
+		if mount.SSHFS.Cache == nil {
+			mount.SSHFS.Cache = pointer.Bool(false)
+		}
 		if mount.SSHFS.FollowSymlinks == nil {
 			mount.SSHFS.FollowSymlinks = pointer.Bool(false)
 		}
diff --git a/pkg/limayaml/limayaml.go b/pkg/limayaml/limayaml.go
index 053c5469..8a478d0b 100644
--- a/pkg/limayaml/limayaml.go
+++ b/pkg/limayaml/limayaml.go
@@ -50,6 +50,7 @@ type Mount struct {
 }
 
 type SSHFS struct {
+	Cache          *bool `yaml:"cache,omitempty" json:"cache,omitempty"`
 	FollowSymlinks *bool `yaml:"followSymlinks,omitempty" json:"followSymlinks,omitempty"`
 }
 


Test patch:
diff --git a/pkg/limayaml/defaults_test.go b/pkg/limayaml/defaults_test.go
index bfe08289..dde8db30 100644
--- a/pkg/limayaml/defaults_test.go
+++ b/pkg/limayaml/defaults_test.go
@@ -120,6 +120,7 @@ func TestFillDefault(t *testing.T) {
 	expect := builtin
 	expect.Mounts = y.Mounts
 	expect.Mounts[0].Writable = pointer.Bool(false)
+	expect.Mounts[0].SSHFS.Cache = pointer.Bool(false)
 	expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
 	// Only missing Mounts field is Writable, and the default value is also the null value: false
 
@@ -243,6 +244,7 @@ func TestFillDefault(t *testing.T) {
 	expect = d
 	// Also verify that archive arch is filled in
 	expect.Containerd.Archives[0].Arch = *d.Arch
+	expect.Mounts[0].SSHFS.Cache = pointer.Bool(false)
 	expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
 
 	y = LimaYAML{}
@@ -314,7 +316,10 @@ func TestFillDefault(t *testing.T) {
 			{
 				Location: "/var/log",
 				Writable: pointer.Bool(true),
-				SSHFS:    SSHFS{FollowSymlinks: pointer.Bool(true)},
+				SSHFS: SSHFS{
+					Cache:          pointer.Bool(true),
+					FollowSymlinks: pointer.Bool(true),
+				},
 			},
 		},
 		Provision: []Provision{
@@ -371,6 +376,7 @@ func TestFillDefault(t *testing.T) {
 	// o.Mounts just makes d.Mounts[0] writable because the Location matches
 	expect.Mounts = append(d.Mounts, y.Mounts...)
 	expect.Mounts[0].Writable = pointer.Bool(true)
+	expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
 	expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(true)
 
 	// o.Networks[1] is overriding the d.Networks[0].Lima entry for the "def0" interface