Skip to content

Commit 536f375

Browse files
authored
Merge pull request #2588 from norio-nomura/support-template-in-mounts
limayaml: support template expansion in `.mounts[].location` and `.mounts[].mountPoint`
2 parents 2eb8b2f + 59e7c0e commit 536f375

File tree

5 files changed

+38
-0
lines changed

5 files changed

+38
-0
lines changed

examples/default.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ memory: null
5050
disk: null
5151

5252
# Expose host directories to the guest, the mount point might be accessible from all UIDs in the guest
53+
# "location" can use these template variables: {{.Home}}, {{.Dir}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}.
54+
# "mountPoint" can use these template variables: {{.Home}}, {{.Name}}, {{.UID}}, {{.User}}, and {{.Param.Key}}
5355
# 🟢 Builtin default: null (Mount nothing)
5456
# 🔵 This file: Mount the home as read-only, /tmp/lima as writable
5557
mounts:

pkg/limayaml/defaults.go

+10
Original file line numberDiff line numberDiff line change
@@ -577,6 +577,16 @@ func FillDefault(y, d, o *LimaYAML, filePath string) {
577577
mounts := make([]Mount, 0, len(d.Mounts)+len(y.Mounts)+len(o.Mounts))
578578
location := make(map[string]int)
579579
for _, mount := range append(append(d.Mounts, y.Mounts...), o.Mounts...) {
580+
if out, err := executeHostTemplate(mount.Location, instDir, y.Param); err == nil {
581+
mount.Location = out.String()
582+
} else {
583+
logrus.WithError(err).Warnf("Couldn't process mount location %q as a template", mount.Location)
584+
}
585+
if out, err := executeGuestTemplate(mount.MountPoint, instDir, y.Param); err == nil {
586+
mount.MountPoint = out.String()
587+
} else {
588+
logrus.WithError(err).Warnf("Couldn't process mount point %q as a template", mount.MountPoint)
589+
}
580590
if i, ok := location[mount.Location]; ok {
581591
if mount.SSHFS.Cache != nil {
582592
mounts[i].SSHFS.Cache = mount.SSHFS.Cache

pkg/limayaml/defaults_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ func TestFillDefault(t *testing.T) {
131131
},
132132
Mounts: []Mount{
133133
{Location: "/tmp"},
134+
{Location: "{{.Dir}}/{{.Param.ONE}}", MountPoint: "/mnt/{{.Param.ONE}}"},
134135
},
135136
MountType: ptr.Of(NINEP),
136137
Provision: []Provision{
@@ -214,6 +215,17 @@ func TestFillDefault(t *testing.T) {
214215
expect.Mounts[0].NineP.Cache = ptr.Of(Default9pCacheForRO)
215216
expect.Mounts[0].Virtiofs.QueueSize = nil
216217
// Only missing Mounts field is Writable, and the default value is also the null value: false
218+
expect.Mounts[1].Location = fmt.Sprintf("%s/%s", instDir, y.Param["ONE"])
219+
expect.Mounts[1].MountPoint = fmt.Sprintf("/mnt/%s", y.Param["ONE"])
220+
expect.Mounts[1].Writable = ptr.Of(false)
221+
expect.Mounts[1].SSHFS.Cache = ptr.Of(true)
222+
expect.Mounts[1].SSHFS.FollowSymlinks = ptr.Of(false)
223+
expect.Mounts[1].SSHFS.SFTPDriver = ptr.Of("")
224+
expect.Mounts[1].NineP.SecurityModel = ptr.Of(Default9pSecurityModel)
225+
expect.Mounts[1].NineP.ProtocolVersion = ptr.Of(Default9pProtocolVersion)
226+
expect.Mounts[1].NineP.Msize = ptr.Of(Default9pMsize)
227+
expect.Mounts[1].NineP.Cache = ptr.Of(Default9pCacheForRO)
228+
expect.Mounts[1].Virtiofs.QueueSize = nil
217229

218230
expect.MountType = ptr.Of(NINEP)
219231

pkg/limayaml/validate.go

+10
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,16 @@ func ValidateParamIsUsed(y *LimaYAML) error {
426426
break
427427
}
428428
}
429+
for _, p := range y.Mounts {
430+
if re.MatchString(p.Location) {
431+
keyIsUsed = true
432+
break
433+
}
434+
if re.MatchString(p.MountPoint) {
435+
keyIsUsed = true
436+
break
437+
}
438+
}
429439
if !keyIsUsed {
430440
return fmt.Errorf("field `param` key %q is not used in any provision, probe, copyToHost, or portForward", key)
431441
}

pkg/limayaml/validate_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ func TestValidateParamIsUsed(t *testing.T) {
3838
assert.Error(t, err, "field `param` key \"name\" is not used in any provision, probe, copyToHost, or portForward")
3939

4040
fieldsUsingParam := []string{
41+
`mounts: [{"location": "/tmp/{{ .Param.name }}"}]`,
42+
`mounts: [{"location": "/tmp", mountPoint: "/tmp/{{ .Param.name }}"}]`,
4143
`provision: [{"script": "echo {{ .Param.name }}"}]`,
4244
`probes: [{"script": "echo {{ .Param.name }}"}]`,
4345
`copyToHost: [{"guest": "/tmp/{{ .Param.name }}", "host": "/tmp"}]`,
@@ -55,6 +57,8 @@ func TestValidateParamIsUsed(t *testing.T) {
5557
rootfulYaml := `param:
5658
rootful: true`
5759
fieldsUsingIfParamRootfulTrue := []string{
60+
`mounts: [{"location": "/tmp/{{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}", "mountPoint": "/tmp"}]`,
61+
`mounts: [{"location": "/tmp", "mountPoint": "/tmp/{{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}"}]`,
5862
`provision: [{"script": "echo {{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}"}]`,
5963
`probes: [{"script": "echo {{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}"}]`,
6064
`copyToHost: [{"guest": "/tmp/{{if eq .Param.rootful \"true\"}}rootful{{else}}rootless{{end}}", "host": "/tmp"}]`,

0 commit comments

Comments
 (0)