Repository: lima-vm/lima (2025-08-09T11:56:28Z)

Issue:
Generated cloud-init has a few errors and warnings.
### Description

In limactl version 1.2.1, cloud-init exits with an error. Upon checking, there are a few keys that are outdated (warnings) and an error.


## Error: 
Cloud config schema errors: mounts: None is not of type 'array'.

## Warnings:
users.0.ssh-authorized-keys:  Deprecated in version 18.3. Use **ssh_authorized_keys** instead.
users.0.uid:  Changed in version 22.3. The use of ``string`` type is deprecated. Use an ``integer`` instead.




Discussion:
These warnings are known, but fixing/changing them caused issues with older images...

* https://github.com/lima-vm/lima/issues/2265

Eventually, we should be able to upgrade cloud-config (when those old distributions go EOL)

There should not be any **error**, though. Empty mounts should be skipped over.
The issue was that it was only broken for _some_ mountTypes, not for the "reverse-sshfs" hardcoded in the unit tests...

```
{{- if or .RosettaEnabled (or (eq .MountType "9p") (eq .MountType "virtiofs")) }}
mounts:
  {{- if .RosettaEnabled }}{{/* Mount the rosetta volume before systemd-binfmt.service(8) starts */}}
- [vz-rosetta, /mnt/lima-rosetta, virtiofs, defaults, "0", "0"]
  {{- end }}
  {{- if .Mounts }}
    {{- range $m := $.Mounts}}
- [{{$m.Tag}}, {{$m.MountPoint}}, {{$m.Type}}, "{{$m.Options}}", "0", "0"]
    {{- end }}
  {{- end }}
{{- end }}
```




Patch:
diff --git a/pkg/cidata/cidata.TEMPLATE.d/user-data b/pkg/cidata/cidata.TEMPLATE.d/user-data
index 3842f8d46e9..e2e13045396 100644
--- a/pkg/cidata/cidata.TEMPLATE.d/user-data
+++ b/pkg/cidata/cidata.TEMPLATE.d/user-data
@@ -11,7 +11,7 @@ package_upgrade: true
 package_reboot_if_required: true
 {{- end }}
 
-{{- if or .RosettaEnabled (or (eq .MountType "9p") (eq .MountType "virtiofs")) }}
+{{- if or .RosettaEnabled (and .Mounts (or (eq .MountType "9p") (eq .MountType "virtiofs"))) }}
 mounts:
   {{- if .RosettaEnabled }}{{/* Mount the rosetta volume before systemd-binfmt.service(8) starts */}}
 - [vz-rosetta, /mnt/lima-rosetta, virtiofs, defaults, "0", "0"]


Test patch:
diff --git a/pkg/cidata/template_test.go b/pkg/cidata/template_test.go
index 31f7b2df77d..fc2482b91f9 100644
--- a/pkg/cidata/template_test.go
+++ b/pkg/cidata/template_test.go
@@ -30,6 +30,7 @@ func TestConfig(t *testing.T) {
 	assert.NilError(t, err)
 	t.Log(string(config))
 	assert.Assert(t, !strings.Contains(string(config), "ca_certs:"))
+	assert.Assert(t, !strings.Contains(string(config), "mounts:"))
 }
 
 func TestConfigCACerts(t *testing.T) {
@@ -54,6 +55,51 @@ func TestConfigCACerts(t *testing.T) {
 	assert.Assert(t, strings.Contains(string(config), "ca_certs:"))
 }
 
+var defaultMounts = []Mount{
+	{MountPoint: "/home/foo.linux", Tag: "mount0", Type: "virtiofs", Options: "ro"},
+	{MountPoint: "/tmp/lima", Tag: "mount1", Type: "virtiofs"},
+}
+
+func TestConfigMounts(t *testing.T) {
+	args := &TemplateArgs{
+		Name:    "default",
+		User:    "foo",
+		UID:     501,
+		Comment: "Foo",
+		Home:    "/home/foo.linux",
+		Shell:   "/bin/bash",
+		SSHPubKeys: []string{
+			"ssh-rsa dummy foo@example.com",
+		},
+		MountType: "virtiofs", // override
+		Mounts:    defaultMounts,
+	}
+	config, err := ExecuteTemplateCloudConfig(args)
+	assert.NilError(t, err)
+	t.Log(string(config))
+	assert.Assert(t, strings.Contains(string(config), "mounts:"))
+}
+
+func TestConfigMountsNone(t *testing.T) {
+	args := &TemplateArgs{
+		Name:    "default",
+		User:    "foo",
+		UID:     501,
+		Comment: "Foo",
+		Home:    "/home/foo.linux",
+		Shell:   "/bin/bash",
+		SSHPubKeys: []string{
+			"ssh-rsa dummy foo@example.com",
+		},
+		MountType: "virtiofs", // override
+		Mounts:    []Mount{},
+	}
+	config, err := ExecuteTemplateCloudConfig(args)
+	assert.NilError(t, err)
+	t.Log(string(config))
+	assert.Assert(t, !strings.Contains(string(config), "mounts:"))
+}
+
 func TestTemplate(t *testing.T) {
 	args := &TemplateArgs{
 		Name:  "default",