-
Notifications
You must be signed in to change notification settings - Fork 11
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #54 from containers/bootc
Add support for running bootc bootable containers
- Loading branch information
Showing
26 changed files
with
741 additions
and
191 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
{ | ||
"ociVersion": "1.0.0", | ||
"process": { | ||
"terminal": true, | ||
"user": { "uid": 0, "gid": 0 }, | ||
"args": ["/output/entrypoint.sh", "<IMAGE_NAME>"], | ||
"env": [ | ||
"PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin", | ||
"TERM=xterm" | ||
], | ||
"cwd": "/", | ||
"capabilities": { | ||
"bounding": [], | ||
"effective": [], | ||
"inheritable": [], | ||
"permitted": [], | ||
"ambient": [] | ||
}, | ||
"rlimits": [ | ||
{ | ||
"type": "RLIMIT_NOFILE", | ||
"hard": 262144, | ||
"soft": 262144 | ||
} | ||
], | ||
"noNewPrivileges": true | ||
}, | ||
"root": { | ||
"path": "<ORIGINAL_ROOT>", | ||
"readonly": false | ||
}, | ||
"hostname": "bootc-install", | ||
"mounts": [ | ||
{ | ||
"type": "bind", | ||
"source": "<PRIV_DIR>/root/crun-vm/bootc", | ||
"destination": "/output", | ||
"options": ["bind", "rprivate", "rw"] | ||
}, | ||
{ | ||
"destination": "/proc", | ||
"type": "proc", | ||
"source": "proc" | ||
}, | ||
{ | ||
"destination": "/dev/pts", | ||
"type": "devpts", | ||
"source": "devpts", | ||
"options": [ | ||
"nosuid", | ||
"noexec", | ||
"newinstance", | ||
"ptmxmode=0666", | ||
"mode=0620", | ||
"gid=5" | ||
] | ||
} | ||
], | ||
"linux": { | ||
"namespaces": [ | ||
{ "type": "pid" }, | ||
{ "type": "network" }, | ||
{ "type": "ipc" }, | ||
{ "type": "uts" }, | ||
{ "type": "cgroup" }, | ||
{ "type": "mount" } | ||
], | ||
"maskedPaths": [ | ||
"/proc/acpi", | ||
"/proc/asound", | ||
"/proc/kcore", | ||
"/proc/keys", | ||
"/proc/latency_stats", | ||
"/proc/timer_list", | ||
"/proc/timer_stats", | ||
"/proc/sched_debug", | ||
"/sys/firmware", | ||
"/proc/scsi" | ||
], | ||
"readonlyPaths": [ | ||
"/proc/bus", | ||
"/proc/fs", | ||
"/proc/irq", | ||
"/proc/sys", | ||
"/proc/sysrq-trigger" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
#!/bin/sh | ||
# SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
set -e | ||
|
||
image_name=$1 | ||
|
||
# monkey-patch loopdev partition detection, given we're not running systemd | ||
# (bootc runs `udevadm settle` as a way to wait until loopdev partitions are | ||
# detected; we hijack that call and use partx to set up the partition devices) | ||
|
||
original_udevadm=$( which udevadm ) | ||
|
||
mkdir -p /output/bin | ||
|
||
cat >/output/bin/udevadm <<EOF | ||
#!/bin/sh | ||
${original_udevadm@Q} "\$@" && partx --add /dev/loop0 | ||
EOF | ||
|
||
chmod +x /output/bin/udevadm | ||
|
||
# default to an xfs root file system if there is no bootc config (some images | ||
# don't currently provide any, for instance quay.io/fedora/fedora-bootc:40) | ||
|
||
if ! find /usr/lib/bootc/install -mindepth 1 -maxdepth 1 | read; then | ||
# /usr/lib/bootc/install is empty | ||
|
||
cat >/usr/lib/bootc/install/00-crun-vm.toml <<-EOF | ||
[install.filesystem.root] | ||
type = "xfs" | ||
EOF | ||
|
||
fi | ||
|
||
# build disk image using bootc-install | ||
|
||
# TODO: `bootc install to-disk` currently fails when using docker-archive. Fix | ||
# the underlying issue to avoid this skopeo-copy command. | ||
skopeo copy --quiet \ | ||
docker-archive:/output/image.docker-archive \ | ||
oci-archive:/output/image.oci-archive | ||
|
||
rm /output/image.docker-archive | ||
|
||
PATH=/output/bin:$PATH bootc install to-disk \ | ||
--source-imgref oci-archive:/output/image.oci-archive \ | ||
--target-imgref "$image_name" \ | ||
--skip-fetch-check \ | ||
--generic-image \ | ||
--via-loopback \ | ||
--karg console=tty0 \ | ||
--karg console=ttyS0 \ | ||
--karg selinux=0 \ | ||
/output/image.raw | ||
|
||
# communicate success by creating a file, since krun always exits successfully | ||
|
||
touch /output/bootc-install-success |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,139 @@ | ||
#!/bin/bash | ||
# SPDX-License-Identifier: GPL-2.0-or-later | ||
|
||
set -o errexit -o pipefail -o nounset | ||
|
||
engine=$1 | ||
container_id=$2 | ||
original_root=$3 | ||
priv_dir=$4 | ||
disk_size=$5 | ||
|
||
__step() { | ||
printf "\033[36m%s\033[0m\n" "$*" | ||
} | ||
|
||
bootc_dir=$priv_dir/root/crun-vm/bootc | ||
|
||
mkfifo "$bootc_dir/progress" | ||
exec > "$bootc_dir/progress" 2>&1 | ||
|
||
# this blocks here until the named pipe above is opened by entrypoint.sh | ||
|
||
# get info about the container *image* | ||
|
||
image_info=$( | ||
"$engine" container inspect \ | ||
--format '{{.Config.Image}}'$'\t''{{.Image}}' \ | ||
"$container_id" | ||
) | ||
|
||
image_name=$( cut -f1 <<< "$image_info" ) | ||
# image_name=${image_name#sha256:} | ||
|
||
image_id=$( cut -f2 <<< "$image_info" ) | ||
|
||
# determine disk size | ||
|
||
if [[ -z "$disk_size" ]]; then | ||
container_image_size=$( | ||
"$engine" image inspect --format '{{.VirtualSize}}' "$image_id" | ||
) | ||
|
||
# use double the container image size to allow for in-place updates | ||
disk_size=$(( container_image_size * 2 )) | ||
|
||
# round up to 1 MiB | ||
alignment=$(( 2**20 )) | ||
disk_size=$(( (disk_size + alignment - 1) / alignment * alignment )) | ||
fi | ||
|
||
truncate --size "$disk_size" "$bootc_dir/image.raw" | ||
disk_size=$( stat --format %s "$bootc_dir/image.raw" ) | ||
|
||
# check if VM image is cached | ||
|
||
container_name=crun-vm-$container_id | ||
|
||
cache_image_labels=( | ||
"crun-vm.from=$image_id" | ||
"crun-vm.size=$disk_size" | ||
) | ||
|
||
cache_image_id=$( | ||
"$engine" images \ | ||
"${cache_image_labels[@]/#/--filter=label=}" \ | ||
--format '{{.ID}}' --no-trunc | ||
) | ||
|
||
if [[ -n "$cache_image_id" ]]; then | ||
|
||
# retrieve VM image from cached containerdisk | ||
|
||
__step "Retrieving cached VM image..." | ||
|
||
trap '"$engine" rm --force "$container_name" >/dev/null 2>&1 || true' EXIT | ||
|
||
"$engine" create --quiet --name "$container_name" "$cache_image_id" </dev/null >/dev/null | ||
"$engine" export "$container_name" | tar -C "$bootc_dir" -x image.qcow2 | ||
"$engine" rm "$container_name" >/dev/null 2>&1 | ||
|
||
trap '' EXIT | ||
|
||
else | ||
|
||
__step "Converting $image_name into a VM image..." | ||
|
||
# save container *image* as an archive | ||
|
||
echo -n 'Preparing container image...' | ||
|
||
"$engine" save --output "$bootc_dir/image.docker-archive" "$image_id" </dev/null 2>&1 \ | ||
| sed -u 's/.*/./' \ | ||
| stdbuf -o0 tr -d '\n' | ||
|
||
echo | ||
|
||
# adjust krun config | ||
|
||
__sed() { | ||
sed -i "s|$1|$2|" "$bootc_dir/config.json" | ||
} | ||
|
||
__sed "<IMAGE_NAME>" "$image_name" | ||
__sed "<ORIGINAL_ROOT>" "$original_root" | ||
__sed "<PRIV_DIR>" "$priv_dir" | ||
|
||
# run bootc-install under krun | ||
|
||
trap 'krun delete --force "$container_name" >/dev/null 2>&1 || true' EXIT | ||
krun run --config "$bootc_dir/config.json" "$container_name" </dev/ptmx | ||
trap '' EXIT | ||
|
||
[[ -e "$bootc_dir/bootc-install-success" ]] | ||
|
||
# convert image to qcow2 to get a lower file size | ||
|
||
qemu-img convert -f raw -O qcow2 "$bootc_dir/image.raw" "$bootc_dir/image.qcow2" | ||
|
||
# cache VM image file as containerdisk | ||
|
||
__step "Caching VM image as a containerdisk..." | ||
|
||
id=$( | ||
"$engine" build --quiet --file - "${cache_image_labels[@]/#/--label=}" "$bootc_dir" <<-'EOF' | ||
FROM scratch | ||
COPY image.qcow2 / | ||
ENTRYPOINT ["no-entrypoint"] | ||
EOF | ||
) | ||
|
||
echo "Stored as untagged container image with ID $id" | ||
|
||
fi | ||
|
||
rm "$bootc_dir/image.raw" | ||
|
||
__step "Booting VM..." | ||
|
||
touch "$bootc_dir/success" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,6 +11,7 @@ prepare: | |
- cargo | ||
- coreutils | ||
- crun | ||
- crun-krun | ||
- docker | ||
- genisoimage | ||
- grep | ||
|
Oops, something went wrong.