Skip to content

Commit c5eb9ac

Browse files
authored
Merge pull request #3339 from jandubois/no-tilde-mountpoint
Do tilde-expansion only once in FillDefaults()
2 parents 7ceb9a0 + 6ef40ed commit c5eb9ac

File tree

8 files changed

+46
-67
lines changed

8 files changed

+46
-67
lines changed

pkg/cidata/cidata.go

+4-12
Original file line numberDiff line numberDiff line change
@@ -201,14 +201,6 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
201201
}
202202
for i, f := range instConfig.Mounts {
203203
tag := fmt.Sprintf("mount%d", i)
204-
location, err := localpathutil.Expand(f.Location)
205-
if err != nil {
206-
return nil, err
207-
}
208-
mountPoint, err := localpathutil.Expand(*f.MountPoint)
209-
if err != nil {
210-
return nil, err
211-
}
212204
options := "defaults"
213205
switch fstype {
214206
case "9p", "virtiofs":
@@ -221,17 +213,17 @@ func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.L
221213
options += fmt.Sprintf(",version=%s", *f.NineP.ProtocolVersion)
222214
msize, err := units.RAMInBytes(*f.NineP.Msize)
223215
if err != nil {
224-
return nil, fmt.Errorf("failed to parse msize for %q: %w", location, err)
216+
return nil, fmt.Errorf("failed to parse msize for %q: %w", f.Location, err)
225217
}
226218
options += fmt.Sprintf(",msize=%d", msize)
227219
options += fmt.Sprintf(",cache=%s", *f.NineP.Cache)
228220
}
229221
// don't fail the boot, if virtfs is not available
230222
options += ",nofail"
231223
}
232-
args.Mounts = append(args.Mounts, Mount{Tag: tag, MountPoint: mountPoint, Type: fstype, Options: options})
233-
if location == hostHome {
234-
args.HostHomeMountPoint = mountPoint
224+
args.Mounts = append(args.Mounts, Mount{Tag: tag, MountPoint: *f.MountPoint, Type: fstype, Options: options})
225+
if f.Location == hostHome {
226+
args.HostHomeMountPoint = *f.MountPoint
235227
}
236228
}
237229

pkg/hostagent/inotify.go

+5-10
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import (
1111
"strings"
1212

1313
guestagentapi "github.com/lima-vm/lima/pkg/guestagent/api"
14-
"github.com/lima-vm/lima/pkg/localpathutil"
1514
"github.com/rjeczalik/notify"
1615
"github.com/sirupsen/logrus"
1716
"google.golang.org/protobuf/types/known/timestamppb"
@@ -74,20 +73,16 @@ func (a *HostAgent) setupWatchers(events chan notify.EventInfo) error {
7473
if !*m.Writable {
7574
continue
7675
}
77-
location, err := localpathutil.Expand(m.Location)
76+
symlink, err := filepath.EvalSymlinks(m.Location)
7877
if err != nil {
7978
return err
8079
}
81-
symlink, err := filepath.EvalSymlinks(location)
82-
if err != nil {
83-
return err
84-
}
85-
if location != symlink {
86-
mountSymlinks[symlink] = location
80+
if m.Location != symlink {
81+
mountSymlinks[symlink] = m.Location
8782
}
8883

89-
logrus.Infof("enable inotify for writable mount: %s", location)
90-
err = notify.Watch(path.Join(location, "..."), events, GetNotifyEvent())
84+
logrus.Infof("enable inotify for writable mount: %s", m.Location)
85+
err = notify.Watch(path.Join(m.Location, "..."), events, GetNotifyEvent())
9186
if err != nil {
9287
return err
9388
}

pkg/hostagent/mount.go

+10-20
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import (
99
"os"
1010

1111
"github.com/lima-vm/lima/pkg/limayaml"
12-
"github.com/lima-vm/lima/pkg/localpathutil"
1312
"github.com/lima-vm/sshocker/pkg/reversesshfs"
1413
"github.com/sirupsen/logrus"
1514
)
@@ -35,16 +34,7 @@ func (a *HostAgent) setupMounts() ([]*mount, error) {
3534
}
3635

3736
func (a *HostAgent) setupMount(m limayaml.Mount) (*mount, error) {
38-
location, err := localpathutil.Expand(m.Location)
39-
if err != nil {
40-
return nil, err
41-
}
42-
43-
mountPoint, err := localpathutil.Expand(*m.MountPoint)
44-
if err != nil {
45-
return nil, err
46-
}
47-
if err := os.MkdirAll(location, 0o755); err != nil {
37+
if err := os.MkdirAll(m.Location, 0o755); err != nil {
4838
return nil, err
4939
}
5040
// NOTE: allow_other requires "user_allow_other" in /etc/fuse.conf
@@ -55,35 +45,35 @@ func (a *HostAgent) setupMount(m limayaml.Mount) (*mount, error) {
5545
if *m.SSHFS.FollowSymlinks {
5646
sshfsOptions += ",follow_symlinks"
5747
}
58-
logrus.Infof("Mounting %q on %q", location, mountPoint)
48+
logrus.Infof("Mounting %q on %q", m.Location, *m.MountPoint)
5949

6050
rsf := &reversesshfs.ReverseSSHFS{
6151
Driver: *m.SSHFS.SFTPDriver,
6252
SSHConfig: a.sshConfig,
63-
LocalPath: location,
53+
LocalPath: m.Location,
6454
Host: "127.0.0.1",
6555
Port: a.sshLocalPort,
66-
RemotePath: mountPoint,
56+
RemotePath: *m.MountPoint,
6757
Readonly: !(*m.Writable),
6858
SSHFSAdditionalArgs: []string{"-o", sshfsOptions},
6959
}
7060
if err := rsf.Prepare(); err != nil {
71-
return nil, fmt.Errorf("failed to prepare reverse sshfs for %q on %q: %w", location, mountPoint, err)
61+
return nil, fmt.Errorf("failed to prepare reverse sshfs for %q on %q: %w", m.Location, *m.MountPoint, err)
7262
}
7363
if err := rsf.Start(); err != nil {
74-
logrus.WithError(err).Warnf("failed to mount reverse sshfs for %q on %q, retrying with `-o nonempty`", location, mountPoint)
64+
logrus.WithError(err).Warnf("failed to mount reverse sshfs for %q on %q, retrying with `-o nonempty`", m.Location, *m.MountPoint)
7565
// NOTE: nonempty is not supported for libfuse3: https://github.com/canonical/multipass/issues/1381
7666
rsf.SSHFSAdditionalArgs = []string{"-o", "nonempty"}
7767
if err := rsf.Start(); err != nil {
78-
return nil, fmt.Errorf("failed to mount reverse sshfs for %q on %q: %w", location, mountPoint, err)
68+
return nil, fmt.Errorf("failed to mount reverse sshfs for %q on %q: %w", m.Location, *m.MountPoint, err)
7969
}
8070
}
8171

8272
res := &mount{
8373
close: func() error {
84-
logrus.Infof("Unmounting %q", location)
85-
if closeErr := rsf.Close(); closeErr != nil {
86-
return fmt.Errorf("failed to unmount reverse sshfs for %q on %q: %w", location, mountPoint, err)
74+
logrus.Infof("Unmounting %q", m.Location)
75+
if err := rsf.Close(); err != nil {
76+
return fmt.Errorf("failed to unmount reverse sshfs for %q on %q: %w", m.Location, *m.MountPoint, err)
8777
}
8878
return nil
8979
},

pkg/limayaml/defaults.go

+7-1
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"golang.org/x/sys/cpu"
3030

3131
"github.com/lima-vm/lima/pkg/identifierutil"
32+
"github.com/lima-vm/lima/pkg/localpathutil"
3233
. "github.com/lima-vm/lima/pkg/must"
3334
"github.com/lima-vm/lima/pkg/networks"
3435
"github.com/lima-vm/lima/pkg/osutil"
@@ -822,8 +823,13 @@ func FillDefault(y, d, o *LimaYAML, filePath string, warn bool) {
822823
mounts[i].NineP.Cache = ptr.Of(Default9pCacheForRO)
823824
}
824825
}
826+
if location, err := localpathutil.Expand(mount.Location); err == nil {
827+
mounts[i].Location = location
828+
} else {
829+
logrus.WithError(err).Warnf("Couldn't expand location %q", mount.Location)
830+
}
825831
if mount.MountPoint == nil {
826-
mounts[i].MountPoint = ptr.Of(mount.Location)
832+
mounts[i].MountPoint = ptr.Of(mounts[i].Location)
827833
}
828834
}
829835

pkg/limayaml/defaults_test.go

+9-4
Original file line numberDiff line numberDiff line change
@@ -146,7 +146,9 @@ func TestFillDefault(t *testing.T) {
146146
},
147147
},
148148
Mounts: []Mount{
149-
{Location: "/tmp"},
149+
// Location will be passed through localpathutil.Expand() which will normalize the name
150+
// (add a drive letter). So we must start with a valid local path to match it again later.
151+
{Location: filepath.Clean(os.TempDir())},
150152
{Location: "{{.Dir}}/{{.Param.ONE}}", MountPoint: ptr.Of("/mnt/{{.Param.ONE}}")},
151153
},
152154
MountType: ptr.Of(NINEP),
@@ -231,7 +233,7 @@ func TestFillDefault(t *testing.T) {
231233
expect.Mounts[0].NineP.Cache = ptr.Of(Default9pCacheForRO)
232234
expect.Mounts[0].Virtiofs.QueueSize = nil
233235
// Only missing Mounts field is Writable, and the default value is also the null value: false
234-
expect.Mounts[1].Location = fmt.Sprintf("%s/%s", instDir, y.Param["ONE"])
236+
expect.Mounts[1].Location = filepath.Join(instDir, y.Param["ONE"])
235237
expect.Mounts[1].MountPoint = ptr.Of(fmt.Sprintf("/mnt/%s", y.Param["ONE"]))
236238
expect.Mounts[1].Writable = ptr.Of(false)
237239
expect.Mounts[1].SSHFS.Cache = ptr.Of(true)
@@ -321,6 +323,9 @@ func TestFillDefault(t *testing.T) {
321323
// User-provided defaults should override any builtin defaults
322324

323325
// Choose values that are different from the "builtin" defaults
326+
327+
// Calling filepath.Abs() to add a drive letter on Windows
328+
varLog, _ := filepath.Abs("/var/log")
324329
d = LimaYAML{
325330
VMType: ptr.Of("vz"),
326331
OS: ptr.Of("unknown"),
@@ -385,7 +390,7 @@ func TestFillDefault(t *testing.T) {
385390

386391
Mounts: []Mount{
387392
{
388-
Location: "/var/log",
393+
Location: varLog,
389394
Writable: ptr.Of(false),
390395
},
391396
},
@@ -593,7 +598,7 @@ func TestFillDefault(t *testing.T) {
593598

594599
Mounts: []Mount{
595600
{
596-
Location: "/var/log",
601+
Location: varLog,
597602
Writable: ptr.Of(true),
598603
SSHFS: SSHFS{
599604
Cache: ptr.Of(false),

pkg/limayaml/validate.go

+5
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ func Validate(y *LimaYAML, warn bool) error {
155155
return fmt.Errorf("field `mounts[%d].location` must be an absolute path, got %q",
156156
i, f.Location)
157157
}
158+
// f.Location has already been expanded in FillDefaults(), but that function cannot return errors.
158159
loc, err := localpathutil.Expand(f.Location)
159160
if err != nil {
160161
return fmt.Errorf("field `mounts[%d].location` refers to an unexpandable path: %q: %w", i, f.Location, err)
@@ -175,6 +176,10 @@ func Validate(y *LimaYAML, warn bool) error {
175176
case *y.User.Home:
176177
return fmt.Errorf("field `mounts[%d].mountPoint` is the reserved internal home directory %q", i, *y.User.Home)
177178
}
179+
// There is no tilde-expansion for guest filenames
180+
if strings.HasPrefix(*f.MountPoint, "~") {
181+
return fmt.Errorf("field `mounts[%d].mountPoint` must not start with \"~\"", i)
182+
}
178183

179184
if _, err := units.RAMInBytes(*f.NineP.Msize); err != nil {
180185
return fmt.Errorf("field `msize` has an invalid value: %w", err)

pkg/qemu/qemu.go

+3-12
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ import (
3131
"github.com/lima-vm/lima/pkg/fileutils"
3232
"github.com/lima-vm/lima/pkg/iso9660util"
3333
"github.com/lima-vm/lima/pkg/limayaml"
34-
"github.com/lima-vm/lima/pkg/localpathutil"
3534
"github.com/lima-vm/lima/pkg/networks"
3635
"github.com/lima-vm/lima/pkg/qemu/imgutil"
3736
"github.com/lima-vm/lima/pkg/store"
@@ -935,19 +934,15 @@ func Cmdline(ctx context.Context, cfg Config) (exe string, args []string, err er
935934
if *y.MountType == limayaml.NINEP || *y.MountType == limayaml.VIRTIOFS {
936935
for i, f := range y.Mounts {
937936
tag := fmt.Sprintf("mount%d", i)
938-
location, err := localpathutil.Expand(f.Location)
939-
if err != nil {
940-
return "", nil, err
941-
}
942-
if err := os.MkdirAll(location, 0o755); err != nil {
937+
if err := os.MkdirAll(f.Location, 0o755); err != nil {
943938
return "", nil, err
944939
}
945940

946941
switch *y.MountType {
947942
case limayaml.NINEP:
948943
options := "local"
949944
options += fmt.Sprintf(",mount_tag=%s", tag)
950-
options += fmt.Sprintf(",path=%s", location)
945+
options += fmt.Sprintf(",path=%s", f.Location)
951946
options += fmt.Sprintf(",security_model=%s", *f.NineP.SecurityModel)
952947
if !*f.Writable {
953948
options += ",readonly"
@@ -1067,10 +1062,6 @@ func FindVirtiofsd(qemuExe string) (string, error) {
10671062

10681063
func VirtiofsdCmdline(cfg Config, mountIndex int) ([]string, error) {
10691064
mount := cfg.LimaYAML.Mounts[mountIndex]
1070-
location, err := localpathutil.Expand(mount.Location)
1071-
if err != nil {
1072-
return nil, err
1073-
}
10741065

10751066
vhostSock := filepath.Join(cfg.InstanceDir, fmt.Sprintf(filenames.VhostSock, mountIndex))
10761067
// qemu_driver has to wait for the socket to appear, so make sure any old ones are removed here.
@@ -1080,7 +1071,7 @@ func VirtiofsdCmdline(cfg Config, mountIndex int) ([]string, error) {
10801071

10811072
return []string{
10821073
"--socket-path", vhostSock,
1083-
"--shared-dir", location,
1074+
"--shared-dir", mount.Location,
10841075
}, nil
10851076
}
10861077

pkg/vz/vm_darwin.go

+3-8
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
"github.com/lima-vm/lima/pkg/driver"
2626
"github.com/lima-vm/lima/pkg/iso9660util"
2727
"github.com/lima-vm/lima/pkg/limayaml"
28-
"github.com/lima-vm/lima/pkg/localpathutil"
2928
"github.com/lima-vm/lima/pkg/nativeimgutil"
3029
"github.com/lima-vm/lima/pkg/networks"
3130
"github.com/lima-vm/lima/pkg/networks/usernet"
@@ -548,18 +547,14 @@ func attachFolderMounts(driver *driver.BaseDriver, vmConfig *vz.VirtualMachineCo
548547
var mounts []vz.DirectorySharingDeviceConfiguration
549548
if *driver.Instance.Config.MountType == limayaml.VIRTIOFS {
550549
for i, mount := range driver.Instance.Config.Mounts {
551-
expandedPath, err := localpathutil.Expand(mount.Location)
552-
if err != nil {
553-
return err
554-
}
555-
if _, err := os.Stat(expandedPath); errors.Is(err, os.ErrNotExist) {
556-
err := os.MkdirAll(expandedPath, 0o750)
550+
if _, err := os.Stat(mount.Location); errors.Is(err, os.ErrNotExist) {
551+
err := os.MkdirAll(mount.Location, 0o750)
557552
if err != nil {
558553
return err
559554
}
560555
}
561556

562-
directory, err := vz.NewSharedDirectory(expandedPath, !*mount.Writable)
557+
directory, err := vz.NewSharedDirectory(mount.Location, !*mount.Writable)
563558
if err != nil {
564559
return err
565560
}

0 commit comments

Comments
 (0)