Skip to content

Commit 2c3c44a

Browse files
authored
Merge pull request #68 from AkihiroSuda/dev-factor-cidata
cidata: split user-data
2 parents 5fb7526 + e0829e7 commit 2c3c44a

17 files changed

+495
-423
lines changed

Diff for: docs/internal.md

+28-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Metadata:
1717
- `lima.yaml`: the YAML
1818

1919
cloud-init:
20-
- `cidata.iso`: cloud-init ISO9660 image. (`user-data`, `meta-data`, `lima-guestagent.Linux-<ARCH>`)
20+
- `cidata.iso`: cloud-init ISO9660 image. See [`cidata.iso`](#cidata-iso).
2121

2222
disk:
2323
- `basedisk`: the base image
@@ -58,3 +58,30 @@ The directory contains the following files:
5858

5959
- `$LIMA_INSTANCE`: `lima ...` is expanded to `limactl shell ${LIMA_INSTANCE} ...`.
6060
- Default : `default`
61+
62+
## `cidata.iso`
63+
`cidata.iso` contains the following files:
64+
65+
- `user-data`: [Cloud-init user-data](https://cloudinit.readthedocs.io/en/latest/topics/format.html)
66+
- `meta-data`: [Cloud-init meta-data](https://cloudinit.readthedocs.io/en/latest/topics/instancedata.html)
67+
- `lima.env`: the environment variables
68+
- `lima-guestagent`: Lima guest agent binary
69+
- `nerdctl-full.tgz`: [`nerdctl-full-<VERSION>-linux-<ARCH>.tar.gz`](https://github.com/containerd/nerdctl/releases)
70+
- `boot.sh`: Boot script
71+
- `boot/*`: Boot script modules
72+
- `provision.system/*`: Custom provision scripts (system)
73+
- `provision.user/*`: Custom provision scripts (user)
74+
75+
Max file name length = 30
76+
77+
### Volume label
78+
The volume label is "cidata", as defined by [cloud-init NoCloud](https://cloudinit.readthedocs.io/en/latest/topics/datasources/nocloud.html).
79+
80+
### Environment variables
81+
- `LIMA_CIDATA_MNT`: the mount point of the disk. `/mnt/lima-cidata`.
82+
- `LIMA_CIDATA_USER`: the user name string
83+
- `LIMA_CIDATA_UID`: the numeric UID
84+
- `LIMA_CIDATA_MOUNTS`: the number of the Lima mounts
85+
- `LIMA_CIDATA_MOUNTS_%d_MOUNTPOINT`: the N-th mount point of Lima mounts (N=0, 1, ...)
86+
- `LIMA_CIDATA_CONTAINERD_USER`: set to "1" if rootless containerd to be set up
87+
- `LIMA_CIDATA_CONTAINERD_SYSTEM`: set to "1" if system-wide containerd to be set up

Diff for: pkg/cidata/cidata.TEMPLATE.d/boot.sh

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#!/bin/sh
2+
set -eu
3+
4+
INFO(){
5+
echo "LIMA| $*"
6+
}
7+
8+
WARNING(){
9+
echo "LIMA| WARNING: $*"
10+
}
11+
12+
# shellcheck disable=SC2163
13+
while read -r line; do export "$line"; done <"${LIMA_CIDATA_MNT}"/lima.env
14+
15+
CODE=0
16+
17+
for f in "${LIMA_CIDATA_MNT}"/boot/*; do
18+
INFO "Executing $f"
19+
if ! "$f"; then
20+
WARNING "Failed to execute $f"
21+
CODE=1
22+
fi
23+
done
24+
25+
if [ -d "${LIMA_CIDATA_MNT}"/provision.system ]; then
26+
for f in "${LIMA_CIDATA_MNT}"/provision.system/*; do
27+
INFO "Executing $f"
28+
if ! "$f"; then
29+
WARNING "Failed to execute $f"
30+
CODE=1
31+
fi
32+
done
33+
fi
34+
35+
if [ -d "${LIMA_CIDATA_MNT}"/provision.user ]; then
36+
until [ -e "/run/user/${LIMA_CIDATA_UID}}/systemd/private" ]; do sleep 3; done
37+
for f in "${LIMA_CIDATA_MNT}"/provision.user/*; do
38+
INFO "Executing $f (as user ${LIMA_CIDATA_USER})"
39+
if ! sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" "$f"; then
40+
WARNING "Failed to execute $f (as user ${LIMA_CIDATA_USER})"
41+
CODE=1
42+
fi
43+
done
44+
fi
45+
46+
INFO "Exiting with code $CODE"
47+
exit "$CODE"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
#!/bin/sh
2+
# This script pretends that /bin/ash can be used as /bin/bash, so all following
3+
# cloud-init scripts can use `#!/bin/bash` and `set -o pipefail`.
4+
test -f /etc/alpine-release || exit 0
5+
6+
# Redirect bash to ash (built with CONFIG_ASH_BASH_COMPAT) and hope for the best :)
7+
# It does support `set -o pipefail`, but not `[[`.
8+
# /bin/bash can't be a symlink because /bin/ash is a symlink to /bin/busybox
9+
cat >/bin/bash <<'EOF'
10+
#!/bin/sh
11+
exec /bin/ash "$@"
12+
EOF
13+
chmod +x /bin/bash
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#!/bin/bash
2+
set -eux -o pipefail
3+
4+
# Restrict the rest of this script to Alpine until it has been tested with other distros
5+
test -f /etc/alpine-release || exit 0
6+
7+
# Data directories that should be persisted across reboots
8+
DATADIRS="/home /usr/local /etc/containerd /var/lib/containerd"
9+
10+
# When running from RAM try to move persistent data to data-volume
11+
# FIXME: the test for tmpfs mounts is probably Alpine-specific
12+
if [ "$(awk '$2 == "/" {print $3}' /proc/mounts)" == "tmpfs" ]; then
13+
mkdir -p /mnt/data
14+
if [ -e /dev/disk/by-label/data-volume ]; then
15+
mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
16+
else
17+
# Find an unpartitioned disk and create data-volume
18+
DISKS=$(lsblk --list --noheadings --output name,type | awk '$2 == "disk" {print $1}')
19+
for DISK in ${DISKS}; do
20+
IN_USE=false
21+
# Looking for a disk that is not mounted or partitioned
22+
for PART in $(awk '/^\/dev\// {gsub("/dev/", ""); print $1}' /proc/mounts); do
23+
if [ "${DISK}" == "${PART}" -o -e /sys/block/${DISK}/${PART} ]; then
24+
IN_USE=true
25+
break
26+
fi
27+
done
28+
if [ "${IN_USE}" == "false" ]; then
29+
echo 'type=83' | sfdisk --label dos /dev/${DISK}
30+
PART=$(lsblk --list /dev/${DISK} --noheadings --output name,type | awk '$2 == "part" {print $1}')
31+
mkfs.ext4 -L data-volume /dev/${PART}
32+
mount -t ext4 /dev/disk/by-label/data-volume /mnt/data
33+
for DIR in ${DATADIRS}; do
34+
DEST="/mnt/data$(dirname ${DIR})"
35+
mkdir -p ${DIR} ${DEST}
36+
mv ${DIR} ${DEST}
37+
done
38+
break
39+
fi
40+
done
41+
fi
42+
for DIR in ${DATADIRS}; do
43+
if [ -d /mnt/data${DIR} ]; then
44+
[ -e ${DIR} ] && rm -rf ${DIR}
45+
ln -s /mnt/data${DIR} ${DIR}
46+
fi
47+
done
48+
fi

Diff for: pkg/cidata/cidata.TEMPLATE.d/boot/10-alpine-prep.sh

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
#!/bin/bash
2+
set -eux -o pipefail
3+
4+
# This script prepares Alpine for lima; there is nothing in here for other distros
5+
test -f /etc/alpine-release || exit 0
6+
7+
# Configure apk repos
8+
BRANCH=edge
9+
VERSION_ID=$(awk -F= '$1=="VERSION_ID" {print $2}' /etc/os-release)
10+
case ${VERSION_ID} in
11+
*_alpha*|*_beta*) BRANCH=edge;;
12+
*.*.*) BRANCH=v${VERSION_ID%.*};;
13+
esac
14+
15+
for REPO in main community; do
16+
URL="https://dl-cdn.alpinelinux.org/alpine/${BRANCH}/${REPO}"
17+
if ! grep -q "^${URL}$" /etc/apk/repositories; then
18+
echo "${URL}" >> /etc/apk/repositories
19+
fi
20+
done
21+
22+
# Alpine doesn't use PAM so we need to explicitly allow public key auth
23+
usermod -p '*' "${LIMA_CIDATA_USER}"
24+
25+
# Alpine disables TCP forwarding, which is needed by the lima-guestagent
26+
sed -i 's/AllowTcpForwarding no/AllowTcpForwarding yes/g' /etc/ssh/sshd_config
27+
rc-service sshd reload
28+
29+
# Create directory for the lima-guestagent socket (normally done by systemd)
30+
mkdir -p /run/user/${LIMA_CIDATA_UID}
31+
chown "${LIMA_CIDATA_USER}" /run/user/${LIMA_CIDATA_UID}
32+
chmod 700 /run/user/${LIMA_CIDATA_UID}
33+
34+
# Install the openrc lima-guestagent service script
35+
cat >/etc/init.d/lima-guestagent <<'EOF'
36+
#!/sbin/openrc-run
37+
supervisor=supervise-daemon
38+
39+
name="lima-guestagent"
40+
description="Forward ports to the lima-hostagent"
41+
42+
export XDG_RUNTIME_DIR="/run/user/${LIMA_CIDATA_UID}"
43+
command=/usr/local/bin/lima-guestagent
44+
command_args="daemon"
45+
command_background=true
46+
command_user="${LIMA_CIDATA_USER}:${LIMA_CIDATA_USER}"
47+
pidfile="${XDG_RUNTIME_DIR}/lima-guestagent.pid"
48+
EOF
49+
chmod 755 /etc/init.d/lima-guestagent
50+
51+
# mount /sys/fs/cgroup
52+
rc-service cgroups start
53+
54+
# `limactl stop` tells acpid to powerdown
55+
rc-update add acpid
56+
rc-service acpid start
+49
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#!/bin/bash
2+
set -eux -o pipefail
3+
4+
# This script does not work unless systemd is available
5+
command -v systemctl 2>&1 >/dev/null || exit 0
6+
7+
# Set up env
8+
for f in .profile .bashrc; do
9+
if ! grep -q "# Lima BEGIN" "/home/${LIMA_CIDATA_USER}.linux/$f"; then
10+
cat >>"/home/${LIMA_CIDATA_USER}.linux/$f" <<EOF
11+
# Lima BEGIN
12+
# Make sure iptables and mount.fuse3 are available
13+
PATH="$PATH:/usr/sbin:/sbin"
14+
# fuse-overlayfs is the most stable snapshotter for rootless
15+
CONTAINERD_SNAPSHOTTER="fuse-overlayfs"
16+
export PATH CONTAINERD_SNAPSHOTTER
17+
# Lima END
18+
EOF
19+
chown "${LIMA_CIDATA_USER}" "/home/${LIMA_CIDATA_USER}.linux/$f"
20+
fi
21+
done
22+
# Enable cgroup delegation (only meaningful on cgroup v2)
23+
if [ ! -e "/etc/systemd/system/[email protected]/lima.conf" ]; then
24+
mkdir -p "/etc/systemd/system/[email protected]"
25+
cat >"/etc/systemd/system/[email protected]/lima.conf" <<EOF
26+
[Service]
27+
Delegate=yes
28+
EOF
29+
fi
30+
systemctl daemon-reload
31+
32+
# Set up sysctl
33+
sysctl_conf="/etc/sysctl.d/99-lima.conf"
34+
if [ ! -e "${sysctl_conf}" ]; then
35+
if [ -e "/proc/sys/kernel/unprivileged_userns_clone" ]; then
36+
echo "kernel.unprivileged_userns_clone=1" >> "${sysctl_conf}"
37+
fi
38+
echo "net.ipv4.ping_group_range = 0 2147483647" >> "${sysctl_conf}"
39+
echo "net.ipv4.ip_unprivileged_port_start=0" >> "${sysctl_conf}"
40+
sysctl --system
41+
fi
42+
43+
# Set up subuid
44+
for f in /etc/subuid /etc/subgid; do
45+
grep -qw "${LIMA_CIDATA_USER}" $f || echo "${LIMA_CIDATA_USER}:100000:65536" >> $f
46+
done
47+
48+
# Start systemd session
49+
loginctl enable-linger "${LIMA_CIDATA_USER}"
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/bin/sh
2+
set -eux
3+
4+
# Create mount points
5+
# NOTE: Busybox sh does not support `for ((i=0;i<$N;i++))` form
6+
for f in $(seq 0 $((LIMA_CIDATA_MOUNTS - 1))); do
7+
mountpointvar="LIMA_CIDATA_MOUNTS_${f}_MOUNTPOINT"
8+
mountpoint="$(eval echo \$$mountpointvar)"
9+
mkdir -p "${mountpoint}"
10+
chown "${LIMA_CIDATA_USER}" "${mountpoint}"
11+
done
12+
13+
# Install or update the guestagent binary
14+
install -m 755 "${LIMA_CIDATA_MNT}"/lima-guestagent /usr/local/bin/lima-guestagent
15+
16+
# Launch the guestagent service
17+
if [ -f /etc/alpine-release ]; then
18+
rc-update add lima-guestagent default
19+
rc-service lima-guestagent start
20+
else
21+
until [ -e "/run/user/${LIMA_CIDATA_UID}/systemd/private" ]; do sleep 3; done
22+
sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" lima-guestagent install-systemd
23+
fi
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
#!/bin/bash
2+
set -eux -o pipefail
3+
4+
# Install minimum dependencies
5+
if command -v apt-get 2>&1 >/dev/null; then
6+
export DEBIAN_FRONTEND=noninteractive
7+
apt-get update
8+
if [ "${LIMA_CIDATA_MOUNTS}" -gt 0 ]; then
9+
apt-get install -y sshfs
10+
fi
11+
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ] || [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
12+
apt-get install -y iptables
13+
fi
14+
if [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
15+
apt-get install -y uidmap fuse3 dbus-user-session
16+
fi
17+
elif command -v dnf 2>&1 >/dev/null; then
18+
if [ "${LIMA_CIDATA_MOUNTS}" -gt 0 ]; then
19+
dnf install -y fuse-sshfs
20+
fi
21+
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ] || [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
22+
dnf install -y iptables
23+
fi
24+
if [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
25+
dnf install -y shadow-utils fuse3
26+
if [ ! -f /usr/bin/fusermount ]; then
27+
# Workaround for https://github.com/containerd/stargz-snapshotter/issues/340
28+
ln -s fusermount3 /usr/bin/fusermount
29+
fi
30+
fi
31+
elif command -v apk 2>&1 >/dev/null; then
32+
if [ "${LIMA_CIDATA_MOUNTS}" -gt 0 ]; then
33+
if ! command -v sshfs 2>&1 >/dev/null; then
34+
apk update
35+
apk add sshfs
36+
fi
37+
modprobe fuse
38+
fi
39+
fi
40+
# Modify /etc/fuse.conf to allow "-o allow_root"
41+
42+
if [ "${LIMA_CIDATA_MOUNTS}" -gt 0 ]; then
43+
if ! grep -q "^user_allow_other" /etc/fuse.conf ; then
44+
echo "user_allow_other" >> /etc/fuse.conf
45+
fi
46+
fi
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
#!/bin/bash
2+
set -eux -o pipefail
3+
4+
5+
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" != 1 ] && [ "${LIMA_CIDATA_CONTAINERD_USER}" != 1 ]; then
6+
exit 0
7+
fi
8+
9+
# This script does not work unless systemd is available
10+
command -v systemctl 2>&1 >/dev/null || exit 0
11+
12+
if [ ! -x /usr/local/bin/nerdctl ]; then
13+
tar Cxzf /usr/local "${LIMA_CIDATA_MNT}"/nerdctl-full.tgz
14+
fi
15+
16+
if [ "${LIMA_CIDATA_CONTAINERD_SYSTEM}" = 1 ]; then
17+
mkdir -p /etc/containerd
18+
cat >"/etc/containerd/config.toml" <<EOF
19+
version = 2
20+
[proxy_plugins]
21+
[proxy_plugins."stargz"]
22+
type = "snapshot"
23+
address = "/run/containerd-stargz-grpc/containerd-stargz-grpc.sock"
24+
EOF
25+
systemctl enable --now containerd buildkit stargz-snapshotter
26+
fi
27+
28+
if [ "${LIMA_CIDATA_CONTAINERD_USER}" = 1 ]; then
29+
modprobe tap || true
30+
if [ ! -e "/home/${LIMA_CIDATA_USER}.linux/.config/containerd/config.toml" ]; then
31+
mkdir -p "/home/${LIMA_CIDATA_USER}.linux/.config/containerd"
32+
cat >"/home/${LIMA_CIDATA_USER}.linux/.config/containerd/config.toml" <<EOF
33+
version = 2
34+
[proxy_plugins]
35+
[proxy_plugins."fuse-overlayfs"]
36+
type = "snapshot"
37+
address = "/run/user/${LIMA_CIDATA_UID}/containerd-fuse-overlayfs.sock"
38+
[proxy_plugins."stargz"]
39+
type = "snapshot"
40+
address = "/run/user/${LIMA_CIDATA_UID}/containerd-stargz-grpc/containerd-stargz-grpc.sock"
41+
EOF
42+
chown -R "${LIMA_CIDATA_USER}" "/home/${LIMA_CIDATA_USER}.linux/.config"
43+
fi
44+
selinux=
45+
if command -v selinuxenabled 2>&1 >/dev/null && selinuxenabled; then
46+
selinux=1
47+
fi
48+
if [ ! -e "/home/${LIMA_CIDATA_USER}}}.linux/.config/systemd/user/containerd.service" ]; then
49+
until [ -e "/run/user/${LIMA_CIDATA_UID}/systemd/private" ]; do sleep 3; done
50+
if [ -n "$selinux" ]; then
51+
echo "Temporarily disabling SELinux, during installing containerd units"
52+
setenforce 0
53+
fi
54+
sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" systemctl --user enable --now dbus
55+
sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" containerd-rootless-setuptool.sh install
56+
sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" containerd-rootless-setuptool.sh install-buildkit
57+
sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" containerd-rootless-setuptool.sh install-fuse-overlayfs
58+
if ! sudo -iu "${LIMA_CIDATA_USER}" "XDG_RUNTIME_DIR=/run/user/${LIMA_CIDATA_UID}" containerd-rootless-setuptool.sh install-stargz; then
59+
echo >&2 "WARNING: rootless stargz does not seem supported on this host (kernel older than 5.11?)"
60+
fi
61+
if [ -n "$selinux" ]; then
62+
echo "Restoring SELinux"
63+
setenforce 1
64+
fi
65+
fi
66+
fi

0 commit comments

Comments
 (0)