Skip to content

Commit

Permalink
Merge pull request #2271 from afbjorklund/cloud-config
Browse files Browse the repository at this point in the history
Generate cloud-config outside of cidata.iso too
  • Loading branch information
AkihiroSuda authored Oct 15, 2024
2 parents c6b5b31 + 4b3a0fa commit f1babc0
Show file tree
Hide file tree
Showing 11 changed files with 140 additions and 26 deletions.
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 {
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
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 [email protected]",
},
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 [email protected]",
},
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

0 comments on commit f1babc0

Please sign in to comment.