From ac857e2c2eac01ba3bcc4d1addeaccd782bae9bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Fri, 5 Apr 2024 20:36:40 +0200 Subject: [PATCH 1/8] refactor: create TemplateArgs in a helper function MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anders F Björklund --- pkg/cidata/cidata.go | 41 ++++++++++++++++++++++--------------- pkg/cidata/template.go | 4 ++-- pkg/cidata/template_test.go | 4 ++-- 3 files changed, 29 insertions(+), 20 deletions(-) diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 80d8d6ad953..7004e6144d4 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -111,17 +111,17 @@ func setupEnv(instConfigEnv map[string]string, propagateProxyEnv bool, slirpGate return env, nil } -func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) error { +func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) (*TemplateArgs, error) { if err := limayaml.Validate(instConfig, false); err != nil { - return err + return nil, err } u, err := osutil.LimaUser(true) if err != nil { - return err + return nil, err } uid, err := strconv.Atoi(u.Uid) if err != nil { - return err + return nil, err } args := TemplateArgs{ Name: name, @@ -150,14 +150,14 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS usernetName := instConfig.Networks[firstUsernetIndex].Lima subnet, err = usernet.Subnet(usernetName) if err != nil { - return err + return nil, err } args.SlirpGateway = usernet.GatewayIP(subnet) args.SlirpDNS = usernet.GatewayIP(subnet) } else { subnet, _, err = net.ParseCIDR(networks.SlirpNetwork) if err != nil { - return err + return nil, err } args.SlirpGateway = usernet.GatewayIP(subnet) if *instConfig.VMType == limayaml.VZ { @@ -173,10 +173,10 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS pubKeys, err := sshutil.DefaultPubKeys(*instConfig.SSH.LoadDotSSHPubKeys) if err != nil { - return err + return nil, err } if len(pubKeys) == 0 { - return errors.New("no SSH key was found, run `ssh-keygen`") + return nil, errors.New("no SSH key was found, run `ssh-keygen`") } for _, f := range pubKeys { args.SSHPubKeys = append(args.SSHPubKeys, f.Content) @@ -193,17 +193,17 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS } hostHome, err := localpathutil.Expand("~") if err != nil { - return err + return nil, err } for i, f := range instConfig.Mounts { tag := fmt.Sprintf("mount%d", i) location, err := localpathutil.Expand(f.Location) if err != nil { - return err + return nil, err } mountPoint, err := localpathutil.Expand(f.MountPoint) if err != nil { - return err + return nil, err } options := "defaults" switch fstype { @@ -217,7 +217,7 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS options += fmt.Sprintf(",version=%s", *f.NineP.ProtocolVersion) msize, err := units.RAMInBytes(*f.NineP.Msize) if err != nil { - return fmt.Errorf("failed to parse msize for %q: %w", location, err) + return nil, fmt.Errorf("failed to parse msize for %q: %w", location, err) } options += fmt.Sprintf(",msize=%d", msize) options += fmt.Sprintf(",cache=%s", *f.NineP.Cache) @@ -268,7 +268,7 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS args.Env, err = setupEnv(instConfig.Env, *instConfig.PropagateProxyEnv, args.SlirpGateway) if err != nil { - return err + return nil, err } switch { @@ -285,7 +285,7 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS default: args.DNSAddresses, err = osutil.DNSAddresses() if err != nil { - return err + return nil, err } } @@ -294,12 +294,12 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS for _, path := range instConfig.CACertificates.Files { expanded, err := localpathutil.Expand(path) if err != nil { - return err + return nil, err } content, err := os.ReadFile(expanded) if err != nil { - return err + return nil, err } cert := getCert(string(content)) @@ -319,6 +319,15 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS } } + return &args, nil +} + +func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) error { + args, err := templateArgs(instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, nerdctlArchive, vsockPort, virtioPort) + if err != nil { + return err + } + if err := ValidateTemplateArgs(args); err != nil { return err } diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index 2a18ba43862..0afb116af01 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -89,7 +89,7 @@ type TemplateArgs struct { TimeZone string } -func ValidateTemplateArgs(args TemplateArgs) error { +func ValidateTemplateArgs(args *TemplateArgs) error { if err := identifiers.Validate(args.Name); err != nil { return err } @@ -120,7 +120,7 @@ func ValidateTemplateArgs(args TemplateArgs) error { return nil } -func ExecuteTemplate(args TemplateArgs) ([]iso9660util.Entry, error) { +func ExecuteTemplate(args *TemplateArgs) ([]iso9660util.Entry, error) { if err := ValidateTemplateArgs(args); err != nil { return nil, err } diff --git a/pkg/cidata/template_test.go b/pkg/cidata/template_test.go index a8ae1cc895d..be5be5f0622 100644 --- a/pkg/cidata/template_test.go +++ b/pkg/cidata/template_test.go @@ -11,7 +11,7 @@ import ( var defaultRemoveDefaults = false func TestTemplate(t *testing.T) { - args := TemplateArgs{ + args := &TemplateArgs{ Name: "default", User: "foo", UID: 501, @@ -46,7 +46,7 @@ func TestTemplate(t *testing.T) { } func TestTemplate9p(t *testing.T) { - args := TemplateArgs{ + args := &TemplateArgs{ Name: "default", User: "foo", UID: 501, From a39d704311ebe0eb7d3bd9c6c90f2d2c9860c7a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 6 Apr 2024 10:19:52 +0200 Subject: [PATCH 2/8] trivial: remove unused parameter from helper MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anders F Björklund --- pkg/cidata/cidata.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 7004e6144d4..56fbd84bdb0 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -111,7 +111,7 @@ func setupEnv(instConfigEnv map[string]string, propagateProxyEnv bool, slirpGate return env, nil } -func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) (*TemplateArgs, error) { +func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort, vsockPort int, virtioPort string) (*TemplateArgs, error) { if err := limayaml.Validate(instConfig, false); err != nil { return nil, err } @@ -323,7 +323,7 @@ func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLoc } func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) error { - args, err := templateArgs(instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, nerdctlArchive, vsockPort, virtioPort) + args, err := templateArgs(instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort) if err != nil { return err } From ef78bb6b3a45ef4ff2f57d5a8e90632234545d19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Fri, 5 Apr 2024 20:39:10 +0200 Subject: [PATCH 3/8] Generate cloud-config outside of cidata.iso too MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This does not include any mounts, networks, nor boot scripts. It is assumed that "reverse-sshfs" is being used, for mounts. It also does not include lima-guestagent, nerdctl-full.tgz, or any of the provisioning scripts that are in the cidata... Signed-off-by: Anders F Björklund --- .yamllint | 4 ++ pkg/cidata/cidata.go | 18 ++++++ pkg/cidata/cloud-config.yaml | 62 +++++++++++++++++++ pkg/cidata/template.go | 10 +++ pkg/cidata/template_test.go | 19 ++++++ pkg/instance/create.go | 4 ++ pkg/store/filenames/filenames.go | 1 + .../content/en/docs/dev/internals/_index.md | 1 + 8 files changed, 119 insertions(+) create mode 100644 pkg/cidata/cloud-config.yaml diff --git a/.yamllint b/.yamllint index a7c8c3f9e00..dae683c8f61 100644 --- a/.yamllint +++ b/.yamllint @@ -2,6 +2,10 @@ extends: default +ignore: | + # this is a yaml template, needs to be executed + pkg/cidata/cloud-config.yaml + rules: indentation: indent-sequences: false diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 56fbd84bdb0..fb4c61810db 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -322,6 +322,24 @@ func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLoc return &args, nil } +func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) error { + args, err := templateArgs(instDir, name, instConfig, 0, 0, 0, "") + if err != nil { + return err + } + + if err := ValidateTemplateArgs(args); err != nil { + return err + } + + config, err := ExpandTemplate(args) + if err != nil { + return err + } + + return os.WriteFile(filepath.Join(instDir, filenames.CloudConfig), config, 0o444) +} + func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) error { args, err := templateArgs(instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort) if err != nil { diff --git a/pkg/cidata/cloud-config.yaml b/pkg/cidata/cloud-config.yaml new file mode 100644 index 00000000000..a3bbed9c933 --- /dev/null +++ b/pkg/cidata/cloud-config.yaml @@ -0,0 +1,62 @@ +#cloud-config +# vim:syntax=yaml + +growpart: + mode: auto + devices: ['/'] + +{{- if .UpgradePackages }} +package_update: true +package_upgrade: true +package_reboot_if_required: true +{{- end }} + +{{- if or (eq .MountType "9p") (eq .MountType "virtiofs") }} +{{- if .Mounts }} +# mounts are not included here +{{- end }} +{{- end }} + +{{- if .TimeZone }} +timezone: {{.TimeZone}} +{{- end }} + +users: + - name: "{{.User}}" + uid: "{{.UID}}" + homedir: "{{.Home}}" + shell: /bin/bash + sudo: ALL=(ALL) NOPASSWD:ALL + lock_passwd: true + ssh-authorized-keys: + {{- range $val := .SSHPubKeys }} + - {{ printf "%q" $val }} + {{- end }} + +{{- if .DNSAddresses }} +# resolv_conf is not included here +{{- end }} + +{{ with .CACerts }} +ca_certs: + remove_defaults: {{ .RemoveDefaults }} + {{- if .Trusted}} + trusted: + {{- range $cert := .Trusted }} + - | + {{- range $line := $cert.Lines }} + {{ $line }} + {{- end }} + {{- end }} + {{- end }} +{{- end }} + +{{- if .BootCmds }} +bootcmd: + {{- range $cmd := $.BootCmds }} +- | + {{- range $line := $cmd.Lines }} + {{ $line }} + {{- end }} + {{- end }} +{{- end }} diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index 0afb116af01..07315416787 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -20,6 +20,9 @@ var templateFS embed.FS const templateFSRoot = "cidata.TEMPLATE.d" +//go:embed cloud-config.yaml +var cloudConfigYaml string + type CACerts struct { RemoveDefaults *bool Trusted []Cert @@ -120,6 +123,13 @@ func ValidateTemplateArgs(args *TemplateArgs) error { return nil } +func ExpandTemplate(args *TemplateArgs) ([]byte, error) { + if err := ValidateTemplateArgs(args); err != nil { + return nil, err + } + return textutil.ExecuteTemplate(cloudConfigYaml, args) +} + func ExecuteTemplate(args *TemplateArgs) ([]iso9660util.Entry, error) { if err := ValidateTemplateArgs(args); err != nil { return nil, err diff --git a/pkg/cidata/template_test.go b/pkg/cidata/template_test.go index be5be5f0622..9ca337f7d16 100644 --- a/pkg/cidata/template_test.go +++ b/pkg/cidata/template_test.go @@ -10,6 +10,25 @@ import ( var defaultRemoveDefaults = false +func TestConfig(t *testing.T) { + args := &TemplateArgs{ + Name: "default", + User: "foo", + UID: 501, + Home: "/home/foo.linux", + SSHPubKeys: []string{ + "ssh-rsa dummy foo@example.com", + }, + MountType: "reverse-sshfs", + CACerts: CACerts{ + RemoveDefaults: &defaultRemoveDefaults, + }, + } + config, err := ExpandTemplate(args) + assert.NilError(t, err) + t.Log(string(config)) +} + func TestTemplate(t *testing.T) { args := &TemplateArgs{ Name: "default", diff --git a/pkg/instance/create.go b/pkg/instance/create.go index f8678cb45cc..6a3f91d1c01 100644 --- a/pkg/instance/create.go +++ b/pkg/instance/create.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" + "github.com/lima-vm/lima/pkg/cidata" "github.com/lima-vm/lima/pkg/driver" "github.com/lima-vm/lima/pkg/driverutil" "github.com/lima-vm/lima/pkg/limayaml" @@ -60,6 +61,9 @@ func Create(ctx context.Context, instName string, instConfig []byte, saveBrokenY if err := os.WriteFile(filePath, instConfig, 0o644); err != nil { return nil, err } + if err := cidata.GenerateCloudConfig(instDir, instName, loadedInstConfig); err != nil { + return nil, err + } if err := os.WriteFile(filepath.Join(instDir, filenames.LimaVersion), []byte(version.Version), 0o444); err != nil { return nil, err } diff --git a/pkg/store/filenames/filenames.go b/pkg/store/filenames/filenames.go index f07300a6674..18e589b0753 100644 --- a/pkg/store/filenames/filenames.go +++ b/pkg/store/filenames/filenames.go @@ -30,6 +30,7 @@ const ( LimaVersion = "lima-version" // Lima version used to create instance CIDataISO = "cidata.iso" CIDataISODir = "cidata" + CloudConfig = "cloud-config.yaml" BaseDisk = "basedisk" DiffDisk = "diffdisk" Kernel = "kernel" diff --git a/website/content/en/docs/dev/internals/_index.md b/website/content/en/docs/dev/internals/_index.md index 03d94eaf03f..b71ce546ab7 100644 --- a/website/content/en/docs/dev/internals/_index.md +++ b/website/content/en/docs/dev/internals/_index.md @@ -37,6 +37,7 @@ Metadata: - `protected`: empty file, used by `limactl protect` cloud-init: +- `cloud-config.yaml`: cloud-init configuration, for reference only. - `cidata.iso`: cloud-init ISO9660 image. See [`cidata.iso`](#cidataiso). Ansible: From 844b37863b22f1fe0bd9f2d5f3f088aee07149b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Sat, 6 Apr 2024 11:13:16 +0200 Subject: [PATCH 4/8] trivial: rename functions for documentation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anders F Björklund --- pkg/cidata/cidata.go | 4 ++-- pkg/cidata/template.go | 4 ++-- pkg/cidata/template_test.go | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index fb4c61810db..e852746442d 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -332,7 +332,7 @@ func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) er return err } - config, err := ExpandTemplate(args) + config, err := ExecuteTemplateCloudConfig(args) if err != nil { return err } @@ -350,7 +350,7 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS return err } - layout, err := ExecuteTemplate(args) + layout, err := ExecuteTemplateCIDataISO(args) if err != nil { return err } diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index 07315416787..c69a391ff27 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -123,14 +123,14 @@ func ValidateTemplateArgs(args *TemplateArgs) error { return nil } -func ExpandTemplate(args *TemplateArgs) ([]byte, error) { +func ExecuteTemplateCloudConfig(args *TemplateArgs) ([]byte, error) { if err := ValidateTemplateArgs(args); err != nil { return nil, err } return textutil.ExecuteTemplate(cloudConfigYaml, args) } -func ExecuteTemplate(args *TemplateArgs) ([]iso9660util.Entry, error) { +func ExecuteTemplateCIDataISO(args *TemplateArgs) ([]iso9660util.Entry, error) { if err := ValidateTemplateArgs(args); err != nil { return nil, err } diff --git a/pkg/cidata/template_test.go b/pkg/cidata/template_test.go index 9ca337f7d16..60038132e41 100644 --- a/pkg/cidata/template_test.go +++ b/pkg/cidata/template_test.go @@ -24,7 +24,7 @@ func TestConfig(t *testing.T) { RemoveDefaults: &defaultRemoveDefaults, }, } - config, err := ExpandTemplate(args) + config, err := ExecuteTemplateCloudConfig(args) assert.NilError(t, err) t.Log(string(config)) } @@ -48,7 +48,7 @@ func TestTemplate(t *testing.T) { Trusted: []Cert{}, }, } - layout, err := ExecuteTemplate(args) + layout, err := ExecuteTemplateCIDataISO(args) assert.NilError(t, err) for _, f := range layout { t.Logf("=== %q ===", f.Path) @@ -82,7 +82,7 @@ func TestTemplate9p(t *testing.T) { RemoveDefaults: &defaultRemoveDefaults, }, } - layout, err := ExecuteTemplate(args) + layout, err := ExecuteTemplateCIDataISO(args) assert.NilError(t, err) for _, f := range layout { t.Logf("=== %q ===", f.Path) From ad2ec08224a8ebe2b931c6676f0d820f5a5ca717 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 9 Apr 2024 17:38:47 +0200 Subject: [PATCH 5/8] Regenerate the cloud-config.yaml on start MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit It was already generated by "create", but it might have changed since. So make sure that it is updated by "start". It is up to the user if they already used this file, and if so they need to update the file for the next boot too. Signed-off-by: Anders F Björklund --- pkg/hostagent/hostagent.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pkg/hostagent/hostagent.go b/pkg/hostagent/hostagent.go index 1125cfb9dbc..0c260b13e64 100644 --- a/pkg/hostagent/hostagent.go +++ b/pkg/hostagent/hostagent.go @@ -133,6 +133,9 @@ func New(instName string, stdout io.Writer, signalCh chan os.Signal, opts ...Opt virtioPort = "" // filenames.VirtioPort } + if err := cidata.GenerateCloudConfig(inst.Dir, instName, inst.Config); err != nil { + return nil, err + } if err := cidata.GenerateISO9660(inst.Dir, instName, inst.Config, udpDNSLocalPort, tcpDNSLocalPort, o.nerdctlArchive, vSockPort, virtioPort); err != nil { return nil, err } From d73926c77286a6105caa90c8de9e984ba49c1018 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Tue, 14 May 2024 12:34:02 +0200 Subject: [PATCH 6/8] Remove empty ca_certs from cloud-config.yaml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Since it is a pointer, it is always true (non-nil). And structs are always true, so they can't be tested. Signed-off-by: Anders F Björklund --- pkg/cidata/cidata.TEMPLATE.d/user-data | 4 ++++ pkg/cidata/cidata.go | 6 ++++++ pkg/cidata/cloud-config.yaml | 2 ++ pkg/cidata/template.go | 3 --- pkg/cidata/template_test.go | 18 ++++++++++++++++++ 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/pkg/cidata/cidata.TEMPLATE.d/user-data b/pkg/cidata/cidata.TEMPLATE.d/user-data index 5bbd994030c..8108938b11f 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/user-data +++ b/pkg/cidata/cidata.TEMPLATE.d/user-data @@ -66,9 +66,12 @@ resolv_conf: {{- end }} {{- end }} +{{- if or .CACerts.RemoveDefaults .CACerts.Trusted }} {{ with .CACerts }} ca_certs: + {{- if .RemoveDefaults }} remove_defaults: {{ .RemoveDefaults }} + {{- end }} {{- if .Trusted}} trusted: {{- range $cert := .Trusted }} @@ -76,6 +79,7 @@ ca_certs: {{- range $line := $cert.Lines }} {{ $line }} {{- end }} + {{- end }} {{- end }} {{- end }} {{- end }} diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index e852746442d..088454bb3da 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -311,6 +311,12 @@ func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLoc args.CACerts.Trusted = append(args.CACerts.Trusted, cert) } + // Remove empty caCerts (default values) from configuration yaml + if !*args.CACerts.RemoveDefaults && len(args.CACerts.Trusted) == 0 { + args.CACerts.RemoveDefaults = nil + args.CACerts.Trusted = nil + } + args.BootCmds = getBootCmds(instConfig.Provision) for _, f := range instConfig.Provision { diff --git a/pkg/cidata/cloud-config.yaml b/pkg/cidata/cloud-config.yaml index a3bbed9c933..8658b3586b5 100644 --- a/pkg/cidata/cloud-config.yaml +++ b/pkg/cidata/cloud-config.yaml @@ -37,6 +37,7 @@ users: # resolv_conf is not included here {{- end }} +{{- if .CACerts.RemoveDefaults }} {{ with .CACerts }} ca_certs: remove_defaults: {{ .RemoveDefaults }} @@ -50,6 +51,7 @@ ca_certs: {{- end }} {{- end }} {{- end }} +{{- end }} {{- if .BootCmds }} bootcmd: diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index c69a391ff27..b370b24369a 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -117,9 +117,6 @@ func ValidateTemplateArgs(args *TemplateArgs) error { return fmt.Errorf("field mounts[%d] must be absolute, got %q", i, f) } } - if args.CACerts.RemoveDefaults == nil { - return errors.New("field CACerts.RemoveDefaults must be set") - } return nil } diff --git a/pkg/cidata/template_test.go b/pkg/cidata/template_test.go index 60038132e41..35c3623e991 100644 --- a/pkg/cidata/template_test.go +++ b/pkg/cidata/template_test.go @@ -11,6 +11,23 @@ import ( var defaultRemoveDefaults = false func TestConfig(t *testing.T) { + args := &TemplateArgs{ + Name: "default", + User: "foo", + UID: 501, + Home: "/home/foo.linux", + SSHPubKeys: []string{ + "ssh-rsa dummy foo@example.com", + }, + MountType: "reverse-sshfs", + } + config, err := ExecuteTemplateCloudConfig(args) + assert.NilError(t, err) + t.Log(string(config)) + assert.Assert(t, !strings.Contains(string(config), "ca_certs:")) +} + +func TestConfigCACerts(t *testing.T) { args := &TemplateArgs{ Name: "default", User: "foo", @@ -27,6 +44,7 @@ func TestConfig(t *testing.T) { config, err := ExecuteTemplateCloudConfig(args) assert.NilError(t, err) t.Log(string(config)) + assert.Assert(t, strings.Contains(string(config), "ca_certs:")) } func TestTemplate(t *testing.T) { From 62727a9e8f493435199ca20b2e553e80f77e0ecf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Mon, 1 Jul 2024 12:44:13 +0200 Subject: [PATCH 7/8] Use the same template for cloud-config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anders F Björklund --- pkg/cidata/cidata.TEMPLATE.d/user-data | 2 + pkg/cidata/cidata.go | 12 +++-- pkg/cidata/cloud-config.yaml | 65 +------------------------- pkg/cidata/template.go | 11 +++-- 4 files changed, 20 insertions(+), 70 deletions(-) mode change 100644 => 120000 pkg/cidata/cloud-config.yaml diff --git a/pkg/cidata/cidata.TEMPLATE.d/user-data b/pkg/cidata/cidata.TEMPLATE.d/user-data index 8108938b11f..d98d03591d8 100644 --- a/pkg/cidata/cidata.TEMPLATE.d/user-data +++ b/pkg/cidata/cidata.TEMPLATE.d/user-data @@ -39,6 +39,7 @@ users: - {{ printf "%q" $val }} {{- end }} +{{- if .BootScripts }} write_files: - content: | #!/bin/sh @@ -52,6 +53,7 @@ write_files: owner: root:root path: /var/lib/cloud/scripts/per-boot/00-lima.boot.sh permissions: '0755' +{{- end }} {{- if .DNSAddresses }} # This has no effect on systems using systemd-resolved, but is used diff --git a/pkg/cidata/cidata.go b/pkg/cidata/cidata.go index 088454bb3da..722c1a6c947 100644 --- a/pkg/cidata/cidata.go +++ b/pkg/cidata/cidata.go @@ -111,7 +111,7 @@ func setupEnv(instConfigEnv map[string]string, propagateProxyEnv bool, slirpGate return env, nil } -func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort, vsockPort int, virtioPort string) (*TemplateArgs, error) { +func templateArgs(bootScripts bool, instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort, vsockPort int, virtioPort string) (*TemplateArgs, error) { if err := limayaml.Validate(instConfig, false); err != nil { return nil, err } @@ -124,6 +124,7 @@ func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLoc return nil, err } args := TemplateArgs{ + BootScripts: bootScripts, Name: name, User: u.Username, UID: uid, @@ -329,10 +330,14 @@ func templateArgs(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLoc } func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) error { - args, err := templateArgs(instDir, name, instConfig, 0, 0, 0, "") + args, err := templateArgs(false, instDir, name, instConfig, 0, 0, 0, "") if err != nil { return err } + // mounts are not included here + args.Mounts = nil + // resolv_conf is not included here + args.DNSAddresses = nil if err := ValidateTemplateArgs(args); err != nil { return err @@ -343,11 +348,12 @@ func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) er return err } + os.RemoveAll(filepath.Join(instDir, filenames.CloudConfig)) // delete existing return os.WriteFile(filepath.Join(instDir, filenames.CloudConfig), config, 0o444) } func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNSLocalPort, tcpDNSLocalPort int, nerdctlArchive string, vsockPort int, virtioPort string) error { - args, err := templateArgs(instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort) + args, err := templateArgs(true, instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort) if err != nil { return err } diff --git a/pkg/cidata/cloud-config.yaml b/pkg/cidata/cloud-config.yaml deleted file mode 100644 index 8658b3586b5..00000000000 --- a/pkg/cidata/cloud-config.yaml +++ /dev/null @@ -1,64 +0,0 @@ -#cloud-config -# vim:syntax=yaml - -growpart: - mode: auto - devices: ['/'] - -{{- if .UpgradePackages }} -package_update: true -package_upgrade: true -package_reboot_if_required: true -{{- end }} - -{{- if or (eq .MountType "9p") (eq .MountType "virtiofs") }} -{{- if .Mounts }} -# mounts are not included here -{{- end }} -{{- end }} - -{{- if .TimeZone }} -timezone: {{.TimeZone}} -{{- end }} - -users: - - name: "{{.User}}" - uid: "{{.UID}}" - homedir: "{{.Home}}" - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - lock_passwd: true - ssh-authorized-keys: - {{- range $val := .SSHPubKeys }} - - {{ printf "%q" $val }} - {{- end }} - -{{- if .DNSAddresses }} -# resolv_conf is not included here -{{- end }} - -{{- if .CACerts.RemoveDefaults }} -{{ with .CACerts }} -ca_certs: - remove_defaults: {{ .RemoveDefaults }} - {{- if .Trusted}} - trusted: - {{- range $cert := .Trusted }} - - | - {{- range $line := $cert.Lines }} - {{ $line }} - {{- end }} - {{- end }} - {{- end }} -{{- end }} -{{- end }} - -{{- if .BootCmds }} -bootcmd: - {{- range $cmd := $.BootCmds }} -- | - {{- range $line := $cmd.Lines }} - {{ $line }} - {{- end }} - {{- end }} -{{- end }} diff --git a/pkg/cidata/cloud-config.yaml b/pkg/cidata/cloud-config.yaml new file mode 120000 index 00000000000..4bec8830e5f --- /dev/null +++ b/pkg/cidata/cloud-config.yaml @@ -0,0 +1 @@ +cidata.TEMPLATE.d/user-data \ No newline at end of file diff --git a/pkg/cidata/template.go b/pkg/cidata/template.go index b370b24369a..60abc16a961 100644 --- a/pkg/cidata/template.go +++ b/pkg/cidata/template.go @@ -20,9 +20,6 @@ var templateFS embed.FS const templateFSRoot = "cidata.TEMPLATE.d" -//go:embed cloud-config.yaml -var cloudConfigYaml string - type CACerts struct { RemoveDefaults *bool Trusted []Cert @@ -78,6 +75,7 @@ type TemplateArgs struct { TCPDNSLocalPort int Env map[string]string Param map[string]string + BootScripts bool DNSAddresses []string CACerts CACerts HostHomeMountPoint string @@ -124,6 +122,13 @@ func ExecuteTemplateCloudConfig(args *TemplateArgs) ([]byte, error) { if err := ValidateTemplateArgs(args); err != nil { return nil, err } + + userData, err := templateFS.ReadFile(path.Join(templateFSRoot, "user-data")) + if err != nil { + return nil, err + } + + cloudConfigYaml := string(userData) return textutil.ExecuteTemplate(cloudConfigYaml, args) } From 4b3a0fafa50d5644cba1d1b3e85d41fa851d5c62 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Anders=20F=20Bj=C3=B6rklund?= Date: Wed, 9 Oct 2024 09:09:47 +0200 Subject: [PATCH 8/8] Regenerate the cloud-config.yaml on reset MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Anders F Björklund --- cmd/limactl/factory-reset.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/limactl/factory-reset.go b/cmd/limactl/factory-reset.go index 9e98f501639..c13a450fd2c 100644 --- a/cmd/limactl/factory-reset.go +++ b/cmd/limactl/factory-reset.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" + "github.com/lima-vm/lima/pkg/cidata" "github.com/lima-vm/lima/pkg/instance" "github.com/lima-vm/lima/pkg/store" "github.com/lima-vm/lima/pkg/store/filenames" @@ -63,6 +64,11 @@ func factoryResetAction(_ *cobra.Command, args []string) error { } } } + // Regenerate the cloud-config.yaml, to reflect any changes to the global _config + if err := cidata.GenerateCloudConfig(inst.Dir, instName, inst.Config); err != nil { + logrus.Error(err) + } + logrus.Infof("Instance %q has been factory reset", instName) return nil }