Skip to content

Commit 421c040

Browse files
committed
Make containerd installation configurable
Signed-off-by: Jan Dubois <[email protected]>
1 parent 079f726 commit 421c040

File tree

9 files changed

+112
-41
lines changed

9 files changed

+112
-41
lines changed

pkg/cidata/cidata.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,11 @@ func GenerateISO9660(isoPath, name string, y *limayaml.LimaYAML) error {
2929
return err
3030
}
3131
args := TemplateArgs{
32-
Name: name,
33-
User: u.Username,
34-
UID: uid,
35-
Provision: y.Provision,
32+
Name: name,
33+
User: u.Username,
34+
UID: uid,
35+
Provision: y.Provision,
36+
Containerd: Containerd{System: *y.Containerd.System, User: *y.Containerd.User},
3637
}
3738
for _, f := range sshutil.DefaultPubKeys() {
3839
args.SSHPubKeys = append(args.SSHPubKeys, f.Content)

pkg/cidata/template.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,18 @@ var (
1818
metaDataTemplate string
1919
)
2020

21+
type Containerd struct {
22+
System bool
23+
User bool
24+
}
2125
type TemplateArgs struct {
2226
Name string // instance name
2327
User string // user name
2428
UID int
2529
SSHPubKeys []string
2630
Mounts []string // abs path, accessible by the User
2731
Provision []limayaml.Provision
32+
Containerd Containerd
2833
}
2934

3035
func ValidateTemplateArgs(args TemplateArgs) error {

pkg/cidata/user-data.TEMPLATE

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ write_files:
2222
#!/bin/bash
2323
set -eux -o pipefail
2424
25+
{{- if .Containerd.User}}
2526
# Enable rootless containers
2627
if [ ! -e "/etc/systemd/system/[email protected]/lima.conf" ]; then
2728
mkdir -p "/etc/systemd/system/[email protected]"
@@ -47,6 +48,7 @@ write_files:
4748
grep -qw "{{.User}}" $f || echo "{{.User}}:100000:65536" >> $f
4849
done
4950
loginctl enable-linger "{{.User}}"
51+
{{- end}}
5052
5153
# Create mount points
5254
{{- range $val := .Mounts}}
@@ -67,23 +69,50 @@ write_files:
6769
# We do not use per-once.
6870
path: /var/lib/cloud/scripts/per-boot/00-base.boot.sh
6971
permissions: '0755'
72+
{{- if or .Mounts .Containerd.User}}
7073
- content: |
7174
#!/bin/bash
7275
set -eux -o pipefail
7376
# Install minimum dependencies
7477
if command -v apt-get 2>&1 >/dev/null; then
7578
export DEBIAN_FRONTEND=noninteractive
7679
apt-get update
77-
apt-get install -y sshfs uidmap
80+
{{- if .Mounts}}
81+
apt-get install -y sshfs
82+
{{- end }}
83+
{{- if .Containerd.User}}
84+
apt-get install -y uidmap
85+
{{- end }}
7886
elif command -v dnf 2>&1 >/dev/null; then
79-
dnf install -y fuse-sshfs shadow-utils
87+
: {{/* make sure the "elif" block is never empty */}}
88+
{{- if .Mounts}}
89+
dnf install -y fuse-sshfs
90+
{{- end}}
91+
{{- if .Containerd.User}}
92+
dnf install -y shadow-utils
93+
{{- end}}
8094
fi
8195
owner: root:root
8296
path: /var/lib/cloud/scripts/per-boot/10-install-packages.boot.sh
8397
permissions: '0755'
98+
{{- end}}
99+
{{- if or .Containerd.System .Containerd.User}}
84100
- content: |
85101
#!/bin/bash
86102
set -eux -o pipefail
103+
if [ ! -x /usr/local/bin/nerdctl ]; then
104+
version="0.8.3"
105+
goarch="amd64"
106+
if [ "$(uname -m )" = "aarch64 "]; then
107+
goarch="arm64"
108+
fi
109+
curl -fsSL https://github.com/containerd/nerdctl/releases/download/v${version}/nerdctl-full-${version}-linux-${goarch}.tar.gz | tar Cxz /usr/local
110+
fi
111+
{{- if .Containerd.System}}
112+
systemctl enable containerd
113+
systemctl start containerd
114+
{{- end}}
115+
{{- if .Containerd.User}}
87116
modprobe tap || true
88117
if [ ! -e "/home/{{.User}}.linux/.config/containerd/config.toml" ]; then
89118
mkdir -p "/home/{{.User}}.linux/.config/containerd"
@@ -95,21 +124,17 @@ write_files:
95124
EOF
96125
chown -R "{{.User}}" "/home/{{.User}}.linux/.config"
97126
fi
98-
if [ ! -x /usr/local/bin/nerdctl ]; then
99-
version="0.8.3"
100-
goarch="amd64"
101-
if [ "$(uname -m )" = "aarch64 "]; then
102-
goarch="arm64"
103-
fi
104-
curl -fsSL https://github.com/containerd/nerdctl/releases/download/v${version}/nerdctl-full-${version}-linux-${goarch}.tar.gz | tar Cxz /usr/local
127+
if [ ! -e "/home/{{.User}}}}.linux/.config/systemd/user/containerd.service" ]; then
105128
until [ -e "/run/user/{{.UID}}/systemd/private" ]; do sleep 3; done
106129
sudo -iu "{{.User}}" "XDG_RUNTIME_DIR=/run/user/{{.UID}}" containerd-rootless-setuptool.sh install
107130
sudo -iu "{{.User}}" "XDG_RUNTIME_DIR=/run/user/{{.UID}}" containerd-rootless-setuptool.sh install-buildkit
108131
sudo -iu "{{.User}}" "XDG_RUNTIME_DIR=/run/user/{{.UID}}" containerd-rootless-setuptool.sh install-stargz
109132
fi
133+
{{- end}}
110134
owner: root:root
111135
path: /var/lib/cloud/scripts/per-boot/20-install-containerd.boot.sh
112136
permissions: '0755'
137+
{{- end}}
113138
{{- if .Provision}}
114139
- content: |
115140
#!/bin/bash

pkg/hostagent/hostagent.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func (a *HostAgent) Run(ctx context.Context) error {
5454
return nil
5555
})
5656
var mErr error
57-
if err := a.waitForRequirements(ctx, "essential", essentialRequirements); err != nil {
57+
if err := a.waitForRequirements(ctx, "essential", a.essentialRequirements()); err != nil {
5858
mErr = multierror.Append(mErr, err)
5959
}
6060
mounts, err := a.setupMounts(ctx)
@@ -71,7 +71,7 @@ func (a *HostAgent) Run(ctx context.Context) error {
7171
return unmountMErr
7272
})
7373
go a.watchGuestAgentEvents(ctx)
74-
if err := a.waitForRequirements(ctx, "optional", optionalRequirements); err != nil {
74+
if err := a.waitForRequirements(ctx, "optional", a.optionalRequirements()); err != nil {
7575
mErr = multierror.Append(mErr, err)
7676
}
7777
return mErr

pkg/hostagent/requirements.go

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,9 @@ type requirement struct {
5454
debugHint string
5555
}
5656

57-
var essentialRequirements = []requirement{
58-
{
57+
func (a *HostAgent) essentialRequirements() []requirement {
58+
req := make([]requirement, 0)
59+
req = append(req, requirement{
5960
description: "ssh",
6061
script: `#!/bin/bash
6162
true
@@ -64,23 +65,25 @@ true
6465
Make sure that the YAML field "ssh.localPort" is not used by other processes on the host.
6566
If any private key under ~/.ssh is protected with a passphrase, you need to have ssh-agent to be running.
6667
`,
67-
},
68-
{
69-
description: "sshfs binary to be installed",
70-
script: `#!/bin/bash
68+
})
69+
if len(a.y.Mounts) > 0 {
70+
req = append(req, requirement{
71+
description: "sshfs binary to be installed",
72+
script: `#!/bin/bash
7173
set -eux -o pipefail
7274
if ! timeout 30s bash -c "until command -v sshfs; do sleep 3; done"; then
7375
echo >&2 "sshfs is not installed yet"
7476
exit 1
7577
fi
7678
`,
77-
debugHint: `The sshfs binary was not installed in the guest.
79+
debugHint: `The sshfs binary was not installed in the guest.
7880
Make sure that you are using an officially supported image.
7981
Also see "/var/log/cloud-init-output.log" in the guest.
8082
A possible workaround is to run "apt-get install sshfs" in the guest.
8183
`,
82-
},
83-
{
84+
})
85+
}
86+
req = append(req, requirement{
8487
description: "the guest agent to be running",
8588
script: `#!/bin/bash
8689
set -eux -o pipefail
@@ -95,22 +98,27 @@ Make sure that you are using an officially supported image.
9598
Also see "/var/log/cloud-init-output.log" in the guest.
9699
A possible workaround is to run "lima-guestagent install-systemd" in the guest.
97100
`,
98-
},
101+
})
102+
return req
99103
}
100104

101-
var optionalRequirements = []requirement{
102-
{
103-
description: "containerd binaries to be installed",
104-
script: `#!/bin/bash
105+
func (a *HostAgent) optionalRequirements() []requirement {
106+
req := make([]requirement, 0)
107+
if *a.y.Containerd.System || *a.y.Containerd.User {
108+
req = append(req, requirement{
109+
description: "containerd binaries to be installed",
110+
script: `#!/bin/bash
105111
set -eux -o pipefail
106112
if ! timeout 30s bash -c "until command -v nerdctl; do sleep 3; done"; then
107113
echo >&2 "nerdctl is not installed yet"
108114
exit 1
109115
fi
110116
`,
111-
debugHint: `The nerdctl binary was not installed in the guest.
117+
debugHint: `The nerdctl binary was not installed in the guest.
112118
Make sure that you are using an officially supported image.
113119
Also see "/var/log/cloud-init-output.log" in the guest.
114120
`,
115-
},
121+
})
122+
}
123+
return req
116124
}

pkg/limayaml/default.TEMPLATE.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,16 @@ video:
5858
# Default: "none"
5959
display: "none"
6060

61+
containerd:
62+
# Enable system-wide containerd (systemctl enable containerd)
63+
# Default: false
64+
system: false
65+
# Enable user-scoped containerd (systemctl --user enable containerd)
66+
# Default: true
67+
user: true
68+
69+
# Provisioning scripts need to be idempotent because they might be called
70+
# multiple times, e.g. when the host VM is being restarted.
6171
# provision:
6272
# # `system` is executed with the root privilege
6373
# - mode: system
@@ -74,3 +84,4 @@ video:
7484
# cat <<EOF > ~/.vimrc
7585
# set number
7686
# EOF
87+

pkg/limayaml/defaults.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ func FillDefault(y *LimaYAML) {
2828
provision.Mode = ProvisionModeSystem
2929
}
3030
}
31+
if y.Containerd.System == nil {
32+
y.Containerd.System = &[]bool{false}[0]
33+
}
34+
if y.Containerd.User == nil {
35+
y.Containerd.User = &[]bool{true}[0]
36+
}
3137
}
3238

3339
func resolveArch(s string) Arch {

pkg/limayaml/limayaml.go

Lines changed: 16 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
package limayaml
22

33
type LimaYAML struct {
4-
Arch Arch `yaml:"arch,omitempty"`
5-
Images []Image `yaml:"images"` // REQUIRED
6-
CPUs int `yaml:"cpus,omitempty"`
7-
Memory string `yaml:"memory,omitempty"` // go-units.RAMInBytes
8-
Disk string `yaml:"disk,omitempty"` // go-units.RAMInBytes
9-
Mounts []Mount `yaml:"mounts,omitempty"`
10-
SSH SSH `yaml:"ssh,omitempty"` // REQUIRED (FIXME)
11-
Firmware Firmware `yaml:"firmware,omitempty"`
12-
Video Video `yaml:"video,omitempty"`
13-
Provision []Provision `yaml:"provision,omitempty"`
4+
Arch Arch `yaml:"arch,omitempty"`
5+
Images []Image `yaml:"images"` // REQUIRED
6+
CPUs int `yaml:"cpus,omitempty"`
7+
Memory string `yaml:"memory,omitempty"` // go-units.RAMInBytes
8+
Disk string `yaml:"disk,omitempty"` // go-units.RAMInBytes
9+
Mounts []Mount `yaml:"mounts,omitempty"`
10+
SSH SSH `yaml:"ssh,omitempty"` // REQUIRED (FIXME)
11+
Firmware Firmware `yaml:"firmware,omitempty"`
12+
Video Video `yaml:"video,omitempty"`
13+
Provision []Provision `yaml:"provision,omitempty"`
14+
Containerd Containerd `yaml:"containerd,omitempty"`
1415
}
1516

1617
type Arch = string
@@ -56,3 +57,8 @@ type Provision struct {
5657
Mode ProvisionMode `yaml:"mode"` // default: "system"
5758
Script string `yaml:"script"`
5859
}
60+
61+
type Containerd struct {
62+
System *bool `yaml:"system,omitempty"`
63+
User *bool `yaml:"user,omitempty"`
64+
}

pkg/limayaml/validate.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,5 +103,14 @@ func ValidateRaw(y LimaYAML) error {
103103

104104
// y.Firmware.LegacyBIOS is ignored for aarch64, but not a fatal error.
105105

106+
for i, p := range y.Provision {
107+
switch p.Mode {
108+
case ProvisionModeSystem, ProvisionModeUser:
109+
default:
110+
return errors.Errorf("field `provision[%d].mode` must be either %q or %q",
111+
i, ProvisionModeSystem, ProvisionModeUser)
112+
}
113+
}
114+
106115
return nil
107116
}

0 commit comments

Comments
 (0)