Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Generate cloud-config outside of cidata.iso too #2271

Merged
merged 8 commits into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .yamllint
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
6 changes: 6 additions & 0 deletions cmd/limactl/factory-reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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 {
afbjorklund marked this conversation as resolved.
Show resolved Hide resolved
logrus.Error(err)
}

logrus.Infof("Instance %q has been factory reset", instName)
return nil
}
Expand Down
6 changes: 6 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/user-data
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ users:
- {{ printf "%q" $val }}
{{- end }}

{{- if .BootScripts }}
write_files:
- content: |
#!/bin/sh
Expand All @@ -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
Expand All @@ -66,16 +68,20 @@ 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 }}
- |
{{- range $line := $cert.Lines }}
{{ $line }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
{{- end }}
Expand Down
73 changes: 56 additions & 17 deletions pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,19 +111,20 @@ 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(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 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{
BootScripts: bootScripts,
Name: name,
User: u.Username,
UID: uid,
Expand All @@ -150,14 +151,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 {
Expand All @@ -173,10 +174,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)
Expand All @@ -193,17 +194,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 {
Expand All @@ -217,7 +218,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)
Expand Down Expand Up @@ -268,7 +269,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 {
Expand All @@ -285,7 +286,7 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS
default:
args.DNSAddresses, err = osutil.DNSAddresses()
if err != nil {
return err
return nil, err
}
}

Expand All @@ -294,12 +295,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))
Expand All @@ -311,6 +312,12 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS
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 {
Expand All @@ -319,11 +326,43 @@ func GenerateISO9660(instDir, name string, instConfig *limayaml.LimaYAML, udpDNS
}
}

return &args, nil
}

func GenerateCloudConfig(instDir, name string, instConfig *limayaml.LimaYAML) error {
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
}

config, err := ExecuteTemplateCloudConfig(args)
if err != nil {
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(true, instDir, name, instConfig, udpDNSLocalPort, tcpDNSLocalPort, vsockPort, virtioPort)
if err != nil {
return err
}

if err := ValidateTemplateArgs(args); err != nil {
return err
}

layout, err := ExecuteTemplate(args)
layout, err := ExecuteTemplateCIDataISO(args)
if err != nil {
return err
}
Expand Down
1 change: 1 addition & 0 deletions pkg/cidata/cloud-config.yaml
afbjorklund marked this conversation as resolved.
Show resolved Hide resolved
22 changes: 17 additions & 5 deletions pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ type TemplateArgs struct {
TCPDNSLocalPort int
Env map[string]string
Param map[string]string
BootScripts bool
DNSAddresses []string
CACerts CACerts
HostHomeMountPoint string
Expand All @@ -89,7 +90,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
}
Expand All @@ -114,13 +115,24 @@ 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
}

func ExecuteTemplate(args TemplateArgs) ([]iso9660util.Entry, error) {
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)
}

func ExecuteTemplateCIDataISO(args *TemplateArgs) ([]iso9660util.Entry, error) {
if err := ValidateTemplateArgs(args); err != nil {
return nil, err
}
Expand Down
45 changes: 41 additions & 4 deletions pkg/cidata/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,45 @@ 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",
UID: 501,
Home: "/home/foo.linux",
SSHPubKeys: []string{
"ssh-rsa dummy foo@example.com",
},
MountType: "reverse-sshfs",
CACerts: CACerts{
RemoveDefaults: &defaultRemoveDefaults,
},
}
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) {
args := TemplateArgs{
args := &TemplateArgs{
Name: "default",
User: "foo",
UID: 501,
Expand All @@ -29,7 +66,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)
Expand All @@ -46,7 +83,7 @@ func TestTemplate(t *testing.T) {
}

func TestTemplate9p(t *testing.T) {
args := TemplateArgs{
args := &TemplateArgs{
Name: "default",
User: "foo",
UID: 501,
Expand All @@ -63,7 +100,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)
Expand Down
3 changes: 3 additions & 0 deletions pkg/hostagent/hostagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/instance/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
}
Expand Down
Loading
Loading