Skip to content

Commit 44454dd

Browse files
authored
Merge pull request #867 from chancez/configure_mount_locations
Support configuring mount locations within guests
2 parents 96b5d17 + d3df001 commit 44454dd

File tree

11 files changed

+53
-31
lines changed

11 files changed

+53
-31
lines changed

examples/default.yaml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ disk: null
4444
# 🔵 This file: Mount the home as read-only, /tmp/lima as writable
4545
mounts:
4646
- location: "~"
47+
# Configure the mountPoint inside the guest.
48+
# 🟢 Builtin default: value of location
49+
mountPoint: null
4750
# CAUTION: `writable` SHOULD be false for the home directory.
4851
# Setting `writable` to true is possible, but untested and dangerous.
4952
# 🟢 Builtin default: false

pkg/cidata/cidata.TEMPLATE.d/lima.env

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ LIMA_CIDATA_USER={{ .User }}
33
LIMA_CIDATA_UID={{ .UID }}
44
LIMA_CIDATA_MOUNTS={{ len .Mounts }}
55
{{- range $i, $val := .Mounts}}
6-
LIMA_CIDATA_MOUNTS_{{$i}}_MOUNTPOINT={{$val.Target}}
6+
LIMA_CIDATA_MOUNTS_{{$i}}_MOUNTPOINT={{$val.MountPoint}}
77
{{- end}}
88
LIMA_CIDATA_MOUNTTYPE={{ .MountType }}
99
{{- if .Containerd.User}}

pkg/cidata/cidata.TEMPLATE.d/user-data

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ growpart:
99
{{- if .Mounts }}
1010
mounts:
1111
{{- range $m := $.Mounts}}
12-
- [{{$m.Tag}}, {{$m.Target}}, {{$m.Type}}, "{{$m.Options}}", "0", "0"]
12+
- [{{$m.Tag}}, {{$m.MountPoint}}, {{$m.Type}}, "{{$m.Options}}", "0", "0"]
1313
{{- end }}
1414
{{- end }}
1515
{{- end }}

pkg/cidata/cidata.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,11 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
130130
}
131131
for i, f := range y.Mounts {
132132
tag := fmt.Sprintf("mount%d", i)
133-
expanded, err := localpathutil.Expand(f.Location)
133+
location, err := localpathutil.Expand(f.Location)
134+
if err != nil {
135+
return err
136+
}
137+
mountPoint, err := localpathutil.Expand(f.MountPoint)
134138
if err != nil {
135139
return err
136140
}
@@ -144,14 +148,14 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
144148
options += fmt.Sprintf(",version=%s", *f.NineP.ProtocolVersion)
145149
msize, err := units.RAMInBytes(*f.NineP.Msize)
146150
if err != nil {
147-
return fmt.Errorf("failed to parse msize for %q: %w", expanded, err)
151+
return fmt.Errorf("failed to parse msize for %q: %w", location, err)
148152
}
149153
options += fmt.Sprintf(",msize=%d", msize)
150154
options += fmt.Sprintf(",cache=%s", *f.NineP.Cache)
151155
// don't fail the boot, if virtfs is not available
152156
options += ",nofail"
153157
}
154-
args.Mounts = append(args.Mounts, Mount{Tag: tag, Target: expanded, Type: fstype, Options: options})
158+
args.Mounts = append(args.Mounts, Mount{Tag: tag, MountPoint: mountPoint, Type: fstype, Options: options})
155159
}
156160

157161
switch *y.MountType {

pkg/cidata/template.go

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,10 @@ type Network struct {
3737
Interface string
3838
}
3939
type Mount struct {
40-
Tag string
41-
Target string // abs path, accessible by the User
42-
Type string
43-
Options string
40+
Tag string
41+
MountPoint string // abs path, accessible by the User
42+
Type string
43+
Options string
4444
}
4545
type TemplateArgs struct {
4646
Name string // instance name
@@ -80,7 +80,7 @@ func ValidateTemplateArgs(args TemplateArgs) error {
8080
return errors.New("field SSHPubKeys must be set")
8181
}
8282
for i, m := range args.Mounts {
83-
f := m.Target
83+
f := m.MountPoint
8484
if !filepath.IsAbs(f) {
8585
return fmt.Errorf("field mounts[%d] must be absolute, got %q", i, f)
8686
}

pkg/cidata/template_test.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ func TestTemplate(t *testing.T) {
1717
"ssh-rsa dummy [email protected]",
1818
},
1919
Mounts: []Mount{
20-
{Target: "/Users/dummy"},
21-
{Target: "/Users/dummy/lima"},
20+
{MountPoint: "/Users/dummy"},
21+
{MountPoint: "/Users/dummy/lima"},
2222
},
2323
MountType: "reverse-sshfs",
2424
}
@@ -45,8 +45,8 @@ func TestTemplate9p(t *testing.T) {
4545
"ssh-rsa dummy [email protected]",
4646
},
4747
Mounts: []Mount{
48-
{Tag: "mount0", Target: "/Users/dummy", Type: "9p", Options: "ro,trans=virtio"},
49-
{Tag: "mount1", Target: "/Users/dummy/lima", Type: "9p", Options: "rw,trans=virtio"},
48+
{Tag: "mount0", MountPoint: "/Users/dummy", Type: "9p", Options: "ro,trans=virtio"},
49+
{Tag: "mount1", MountPoint: "/Users/dummy/lima", Type: "9p", Options: "rw,trans=virtio"},
5050
},
5151
MountType: "9p",
5252
}

pkg/hostagent/mount.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,16 @@ func (a *HostAgent) setupMounts(ctx context.Context) ([]*mount, error) {
3434
}
3535

3636
func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, error) {
37-
expanded, err := localpathutil.Expand(m.Location)
37+
location, err := localpathutil.Expand(m.Location)
3838
if err != nil {
3939
return nil, err
4040
}
41-
if err := os.MkdirAll(expanded, 0755); err != nil {
41+
42+
mountPoint, err := localpathutil.Expand(m.MountPoint)
43+
if err != nil {
44+
return nil, err
45+
}
46+
if err := os.MkdirAll(location, 0755); err != nil {
4247
return nil, err
4348
}
4449
// NOTE: allow_other requires "user_allow_other" in /etc/fuse.conf
@@ -49,34 +54,35 @@ func (a *HostAgent) setupMount(ctx context.Context, m limayaml.Mount) (*mount, e
4954
if *m.SSHFS.FollowSymlinks {
5055
sshfsOptions = sshfsOptions + ",follow_symlinks"
5156
}
52-
logrus.Infof("Mounting %q", expanded)
57+
logrus.Infof("Mounting %q on %q", location, mountPoint)
58+
5359
rsf := &reversesshfs.ReverseSSHFS{
5460
Driver: *m.SSHFS.SFTPDriver,
5561
SSHConfig: a.sshConfig,
56-
LocalPath: expanded,
62+
LocalPath: location,
5763
Host: "127.0.0.1",
5864
Port: a.sshLocalPort,
59-
RemotePath: expanded,
65+
RemotePath: mountPoint,
6066
Readonly: !(*m.Writable),
6167
SSHFSAdditionalArgs: []string{"-o", sshfsOptions},
6268
}
6369
if err := rsf.Prepare(); err != nil {
64-
return nil, fmt.Errorf("failed to prepare reverse sshfs for %q: %w", expanded, err)
70+
return nil, fmt.Errorf("failed to prepare reverse sshfs for %q on %q: %w", location, mountPoint, err)
6571
}
6672
if err := rsf.Start(); err != nil {
67-
logrus.WithError(err).Warnf("failed to mount reverse sshfs for %q, retrying with `-o nonempty`", expanded)
73+
logrus.WithError(err).Warnf("failed to mount reverse sshfs for %q on %q, retrying with `-o nonempty`", location, mountPoint)
6874
// NOTE: nonempty is not supported for libfuse3: https://github.com/canonical/multipass/issues/1381
6975
rsf.SSHFSAdditionalArgs = []string{"-o", "nonempty"}
7076
if err := rsf.Start(); err != nil {
71-
return nil, fmt.Errorf("failed to mount reverse sshfs for %q: %w", expanded, err)
77+
return nil, fmt.Errorf("failed to mount reverse sshfs for %q on %q: %w", location, mountPoint, err)
7278
}
7379
}
7480

7581
res := &mount{
7682
close: func() error {
77-
logrus.Infof("Unmounting %q", expanded)
83+
logrus.Infof("Unmounting %q", location)
7884
if closeErr := rsf.Close(); closeErr != nil {
79-
return fmt.Errorf("failed to unmount reverse sshfs for %q: %w", expanded, err)
85+
return fmt.Errorf("failed to unmount reverse sshfs for %q on %q: %w", location, mountPoint, err)
8086
}
8187
return nil
8288
},

pkg/limayaml/defaults.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
402402
if mount.Writable != nil {
403403
mounts[i].Writable = mount.Writable
404404
}
405+
if mount.MountPoint != "" {
406+
mounts[i].MountPoint = mount.MountPoint
407+
}
405408
} else {
406409
location[mount.Location] = len(mounts)
407410
mounts = append(mounts, mount)
@@ -439,6 +442,9 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
439442
mounts[i].NineP.Cache = pointer.String(Default9pCacheForRO)
440443
}
441444
}
445+
if mount.MountPoint == "" {
446+
mounts[i].MountPoint = mount.Location
447+
}
442448
}
443449

444450
if y.MountType == nil {

pkg/limayaml/defaults_test.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ func TestFillDefault(t *testing.T) {
145145
}
146146

147147
expect.Mounts = y.Mounts
148+
expect.Mounts[0].MountPoint = expect.Mounts[0].Location
148149
expect.Mounts[0].Writable = pointer.Bool(false)
149150
expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
150151
expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
@@ -299,6 +300,7 @@ func TestFillDefault(t *testing.T) {
299300
expect = d
300301
// Also verify that archive arch is filled in
301302
expect.Containerd.Archives[0].Arch = *d.Arch
303+
expect.Mounts[0].MountPoint = expect.Mounts[0].Location
302304
expect.Mounts[0].SSHFS.Cache = pointer.Bool(true)
303305
expect.Mounts[0].SSHFS.FollowSymlinks = pointer.Bool(false)
304306
expect.Mounts[0].SSHFS.SFTPDriver = pointer.String("")

pkg/limayaml/limayaml.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,10 +63,11 @@ type Image struct {
6363
}
6464

6565
type Mount struct {
66-
Location string `yaml:"location" json:"location"` // REQUIRED
67-
Writable *bool `yaml:"writable,omitempty" json:"writable,omitempty"`
68-
SSHFS SSHFS `yaml:"sshfs,omitempty" json:"sshfs,omitempty"`
69-
NineP NineP `yaml:"9p,omitempty" json:"9p,omitempty"`
66+
Location string `yaml:"location" json:"location"` // REQUIRED
67+
MountPoint string `yaml:"mountPoint,omitempty" json:"mountPoint,omitempty"`
68+
Writable *bool `yaml:"writable,omitempty" json:"writable,omitempty"`
69+
SSHFS SSHFS `yaml:"sshfs,omitempty" json:"sshfs,omitempty"`
70+
NineP NineP `yaml:"9p,omitempty" json:"9p,omitempty"`
7071
}
7172

7273
type SFTPDriver = string

0 commit comments

Comments
 (0)