Skip to content

Add support for ignition to cidata, for CoreOS #2139

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

Closed
wants to merge 9 commits into from
Closed
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 executed
pkg/cidata/cidata.TEMPLATE.d/ignition.yaml

rules:
indentation:
indent-sequences: false
Expand Down
3 changes: 3 additions & 0 deletions examples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@ Distro:
- [`ubuntu-lts`](./ubuntu-lts.yaml): Ubuntu LTS (same as `ubuntu.yaml` but pinned to an LTS version)
- [`deprecated/centos-7`](./deprecated/centos-7.yaml): [deprecated] CentOS Linux 7
- [`experimental/gentoo`](./experimental/gentoo.yaml): [experimental] Gentoo
- [`experimental/fedora-coreos`](./experimental/fedora-coreos.yaml): [experimental] Fedora CoreOS
- [`experimental/flatcar`](experimental/flatcar.yaml): [experimental] Flatcar Container Linux
- [`experimental/opensuse-tumbleweed`](./experimental/opensuse-tumbleweed.yaml): [experimental] openSUSE Tumbleweed
- [`experimental/microos`](experimental/microos.yaml): [experimental] openSUSE Tumbleweed MicroOS

Container engines:
- [`apptainer`](./apptainer.yaml): Apptainer
Expand Down
15 changes: 15 additions & 0 deletions examples/experimental/fedora-coreos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# This example requires Lima v0.15.1 or later.
# <https://fedoraproject.org/coreos/download/>

images:
- location: "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/39.20231204.3.3/x86_64/fedora-coreos-39.20231204.3.3-qemu.x86_64.qcow2.xz"
arch: "x86_64"
digest: "sha256:df4b55402472dcabe7f19e9215193643e5e34513d20afea6f1d7326ab5b3c239"
- location: "https://builds.coreos.fedoraproject.org/prod/streams/stable/builds/39.20231204.3.3/aarch64/fedora-coreos-39.20231204.3.3-qemu.aarch64.qcow2.xz"
arch: "aarch64"
digest: "sha256:df4b55402472dcabe7f19e9215193643e5e34513d20afea6f1d7326ab5b3c239"

# The guest home directory can not be changed with CoreOS currently.
mounts:
- location: "/tmp/lima"
writable: true
21 changes: 21 additions & 0 deletions examples/experimental/flatcar.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# # This example requires Lima v0.15.1 or later.
# <https://www.flatcar.org/releases#stable-release>

images:
- location: "https://stable.release.flatcar-linux.net/amd64-usr/3602.2.3/flatcar_production_qemu_uefi_image.img.bz2"
arch: "x86_64"
digest: "sha512:88d58a5db4a6de69cc146c867378a5ef192f9f5b9e831d7fcce598874fd60500bf1486e3764d22f89cf3442ff729363eb72b07668337e4c45611fbdf65ad6526"
- location: "https://stable.release.flatcar-linux.net/arm64-usr/3602.2.3/flatcar_production_qemu_uefi_image.img.bz2"
arch: "aarch64"
digest: "sha512:5e0bd2ac81f6fa5bb0360e1741af97db9bca4fc91f31ce006faf61b4c7c9a194f5af06ac71f6368d402018006e3a13b1b6ffbdc23dacdaff4a5ab49f1c8a6e98"

# The /usr/local prefix is read-only under Flatcar Container Linux.
guestInstallPrefix: /opt

# The guest home directory can not be changed with CoreOS currently.
mounts:
- location: "/tmp/lima"
writable: true

# There is no support for FUSE or sshfs in Flatcar Container Linux.
mountType: "9p"
12 changes: 12 additions & 0 deletions examples/experimental/microos.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# This example requires Lima v0.15.1 or later.
images:
# Hint: run `limactl prune` to invalidate the cache
- location: https://download.opensuse.org/tumbleweed/appliances/openSUSE-MicroOS.x86_64-OpenStack-Cloud.qcow2
arch: "x86_64"
- location: https://download.opensuse.org/ports/aarch64/tumbleweed/appliances/openSUSE-MicroOS.aarch64-OpenStack-Cloud.qcow2
arch: "aarch64"

mounts:
- location: "~"
- location: "/tmp/lima"
writable: true
96 changes: 96 additions & 0 deletions pkg/cidata/cidata.TEMPLATE.d/ignition.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
variant: fcos
version: 1.4.0
passwd:
users:
- name: "{{.User}}"
groups:
- sudo
ssh_authorized_keys:
{{- range $val := .SSHPubKeys}}
- "{{$val}}"
{{- end}}
storage:
files:
- path: /etc/hostname
mode: 0644
overwrite: true
contents:
inline: "lima-{{.Name}}"
{{- if or (eq .MountType "9p") (eq .MountType "virtiofs") }}
{{- if .Mounts }}
- path: /etc/fstab
mode: 0644
contents:
inline: |
{{- range $m := $.Mounts}}
{{$m.Tag}} {{$m.MountPoint}} {{$m.Type}} {{$m.Options}} 0 0
{{- end }}
{{- end }}
{{- end }}
- path: /etc/fuse.conf
mode: 0644
overwrite: true
contents:
inline: "user_allow_other\n"
systemd:
units:
# Note1: name must systemd-escape path
# Note2: path must not contain symlinks
- name: "var-mnt-lima\\x2dcidata.mount"
enabled: true
contents: |
[Unit]
Before=local-fs.target

[Mount]
What=/dev/disk/by-label/cidata
Where=/var/mnt/lima-cidata
Options=ro,mode=0700,dmode=0700,overriderockperm,exec,uid=0

[Install]
RequiredBy=local-fs.target
- name: lima-ssh-ready.service
enabled: true
contents: |
[Unit]
After=sshd.service

[Service]
Type=oneshot
ExecStart=/bin/cp /mnt/lima-cidata/meta-data /run/lima-ssh-ready

[Install]
RequiredBy=multi-user.target
{{- if or .Containerd.User .Containerd.System }}
- name: lima-install-containerd.service
enabled: true
contents: |
[Service]
Type=oneshot
ExecStart=/bin/sh -c "/usr/bin/tar Cxzf /usr/local /mnt/lima-cidata/nerdctl-full.tgz"

[Install]
RequiredBy=multi-user.target
{{- end}}
- name: lima-install-guestagent.service
enabled: true
contents: |
[Service]
Type=oneshot
ExecStart=/bin/sh -c "install -m 755 /mnt/lima-cidata/lima-guestagent /usr/local/bin/lima-guestagent"
ExecStartPost=/usr/local/bin/lima-guestagent install-systemd

[Install]
RequiredBy=multi-user.target
- name: lima-boot-done.service
enabled: true
contents: |
[Unit]
After=lima-install-guestagent.service

[Service]
Type=oneshot
ExecStart=/bin/cp /mnt/lima-cidata/meta-data /run/lima-boot-done

[Install]
RequiredBy=multi-user.target
7 changes: 6 additions & 1 deletion pkg/cidata/cidata.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,10 +319,15 @@ func GenerateISO9660(instDir, name string, y *limayaml.LimaYAML, udpDNSLocalPort
return err
}

layout, err := ExecuteTemplate(args)
layout, ignition, err := ExecuteTemplate(args)
if err != nil {
return err
}
if ignition != nil {
if err := os.WriteFile(filepath.Join(instDir, filenames.Ignition), ignition, 0o600); err != nil {
return err
}
}

for i, f := range y.Provision {
switch f.Mode {
Expand Down
45 changes: 36 additions & 9 deletions pkg/cidata/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
"errors"
"fmt"
"io/fs"
"os/exec"
"path"

"github.com/lima-vm/lima/pkg/iso9660util"

"github.com/containerd/containerd/identifiers"
"github.com/lima-vm/lima/pkg/textutil"
"github.com/sirupsen/logrus"
)

//go:embed cidata.TEMPLATE.d
Expand Down Expand Up @@ -114,28 +116,47 @@ func ValidateTemplateArgs(args TemplateArgs) error {
return nil
}

func ExecuteTemplate(args TemplateArgs) ([]iso9660util.Entry, error) {
if err := ValidateTemplateArgs(args); err != nil {
func executeButane(yaml []byte) ([]byte, error) {
butane, err := exec.LookPath("butane")
if err != nil {
logrus.Debug("butane not found in PATH, skipping ignition")
return nil, err
}
var stdout, stderr bytes.Buffer
cmd := exec.Command(butane, "--strict")
cmd.Stdin = bytes.NewReader(yaml)
cmd.Stdout = &stdout
cmd.Stderr = &stderr
if err := cmd.Run(); err != nil {
logrus.Warnf("%v %s: %s %s", cmd, yaml, err, stderr.String())
return nil, err
}
return stdout.Bytes(), nil
}

func ExecuteTemplate(args TemplateArgs) ([]iso9660util.Entry, []byte, error) {
if err := ValidateTemplateArgs(args); err != nil {
return nil, nil, err
}

fsys, err := fs.Sub(templateFS, templateFSRoot)
if err != nil {
return nil, err
return nil, nil, err
}

var layout []iso9660util.Entry
walkFn := func(path string, d fs.DirEntry, walkErr error) error {
var ignition []byte
walkFn := func(p string, d fs.DirEntry, walkErr error) error {
if walkErr != nil {
return walkErr
}
if d.IsDir() {
return nil
}
if !d.Type().IsRegular() {
return fmt.Errorf("got non-regular file %q", path)
return fmt.Errorf("got non-regular file %q", p)
}
templateB, err := fs.ReadFile(fsys, path)
templateB, err := fs.ReadFile(fsys, p)
if err != nil {
return err
}
Expand All @@ -144,15 +165,21 @@ func ExecuteTemplate(args TemplateArgs) ([]iso9660util.Entry, error) {
return err
}
layout = append(layout, iso9660util.Entry{
Path: path,
Path: p,
Reader: bytes.NewReader(b),
})
if path.Base(p) == "ignition.yaml" {
ign, err := executeButane([]byte(b))
if err == nil {
ignition = ign
}
}
return nil
}

if err := fs.WalkDir(fsys, ".", walkFn); err != nil {
return nil, err
return nil, nil, err
}

return layout, nil
return layout, ignition, nil
}
4 changes: 2 additions & 2 deletions pkg/cidata/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestTemplate(t *testing.T) {
},
MountType: "reverse-sshfs",
}
layout, err := ExecuteTemplate(args)
layout, _, err := ExecuteTemplate(args)
assert.NilError(t, err)
for _, f := range layout {
t.Logf("=== %q ===", f.Path)
Expand Down Expand Up @@ -52,7 +52,7 @@ func TestTemplate9p(t *testing.T) {
},
MountType: "9p",
}
layout, err := ExecuteTemplate(args)
layout, _, err := ExecuteTemplate(args)
assert.NilError(t, err)
for _, f := range layout {
t.Logf("=== %q ===", f.Path)
Expand Down
7 changes: 7 additions & 0 deletions pkg/qemu/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -674,6 +674,13 @@ func Cmdline(cfg Config) (exe string, args []string, err error) {
"-device", "virtio-scsi-pci,id=scsi0",
"-device", "scsi-cd,bus=scsi0.0,drive=cdrom0")

// ignition
ignition := filepath.Join(cfg.InstanceDir, filenames.Ignition)
if _, err := os.Stat(ignition); err == nil {
args = append(args,
"-fw_cfg", "name=opt/com.coreos/config,file="+ignition)
}

// Kernel
kernel := filepath.Join(cfg.InstanceDir, filenames.Kernel)
kernelCmdline := filepath.Join(cfg.InstanceDir, filenames.KernelCmdline)
Expand Down
1 change: 1 addition & 0 deletions pkg/store/filenames/filenames.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const (
LimaVersion = "lima-version" // Lima version used to create instance
CIDataISO = "cidata.iso"
CIDataISODir = "cidata"
Ignition = "config.ign"
BaseDisk = "basedisk"
DiffDisk = "diffdisk"
Kernel = "kernel"
Expand Down