Skip to content

Commit a140d81

Browse files
committed
artifacts: use common functions for docker-popular
Simplify the docker-popular rootfs building using common functions. Define a new file `setup-minimal.sh` that is responsible for the image-specific setups. Also, use squashfs for test-popular-containers tests, as there is no specific reason for them to be ext4. Signed-off-by: James Curtis <jxcurtis@amazon.co.uk>
1 parent cf50eec commit a140d81

File tree

4 files changed

+93
-74
lines changed

4 files changed

+93
-74
lines changed

.buildkite/pipeline_docker_popular.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@
1515
pipeline.build_group_per_arch(
1616
"rootfs-build",
1717
[
18-
"sudo yum install -y systemd-container",
18+
"sudo yum install -y squashfs-tools docker",
19+
"sudo tools/devtool sh 'tools/test-popular-containers/build_rootfs.sh'",
1920
"cd tools/test-popular-containers",
20-
"sudo ./build_rootfs.sh",
21-
f'tar czf "{ROOTFS_TAR}" *.ext4 *.id_rsa',
21+
f'tar czf "{ROOTFS_TAR}" *.squashfs *.id_rsa',
2222
f'buildkite-agent artifact upload "{ROOTFS_TAR}"',
2323
],
2424
depends_on_build=False,

tools/test-popular-containers/build_rootfs.sh

Lines changed: 27 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,78 +8,36 @@ set -x
88

99
cd $(dirname $0)
1010
TOPDIR=$(git rev-parse --show-cdup)
11+
source "$TOPDIR/tools/functions"
1112

12-
function make_rootfs {
13-
local LABEL=$1
14-
local rootfs=$LABEL
15-
local IMG=$LABEL.ext4
16-
mkdir $LABEL
17-
ctr image pull public.ecr.aws/docker/library/$LABEL
18-
ctr image mount --rw public.ecr.aws/docker/library/$LABEL $LABEL
19-
MNT_SIZE=$(du -sb $LABEL |cut -f1)
20-
SIZE=$(( $MNT_SIZE + 512 * 2**20 ))
13+
# Get the executing uid and gid for `chown` and `chgrp`
14+
USER_UID=$(stat -c '%u' "$TOPDIR")
15+
USER_GID=$(stat -c '%g' "$TOPDIR")
2116

22-
# Generate key for ssh access from host
23-
if [ ! -s id_rsa ]; then
24-
ssh-keygen -f id_rsa -N ""
25-
fi
26-
cp id_rsa $rootfs.id_rsa
27-
chmod a+r $rootfs.id_rsa
2817

29-
truncate -s "$SIZE" "$IMG"
30-
mkfs.ext4 -F "$IMG" -d $LABEL
31-
ctr image unmount $LABEL
32-
rmdir $LABEL
18+
OVERLAY_DIR="$TOPDIR/resources/overlay"
19+
SETUP_SCRIPT="setup-minimal.sh"
20+
OUTPUT_DIR=$PWD
3321

34-
mkdir mnt
35-
mount $IMG mnt
36-
install -d -m 0600 "mnt/root/.ssh/"
37-
cp -v id_rsa.pub "mnt/root/.ssh/authorized_keys"
38-
cp -rvf $TOPDIR/resources/overlay/* mnt
39-
SYSINIT=mnt/etc/systemd/system/sysinit.target.wants
40-
mkdir -pv $SYSINIT
41-
ln -svf /etc/systemd/system/fcnet.service $SYSINIT/fcnet.service
42-
mkdir mnt/etc/local.d
43-
cp -v fcnet.start mnt/etc/local.d
44-
umount -l mnt
45-
rmdir mnt
22+
IMAGES=(amazonlinux:2023 alpine:latest ubuntu:22.04 ubuntu:24.04 ubuntu:25.04 ubuntu:latest)
4623

47-
# --timezone=off parameter is needed to prevent systemd-nspawn from
48-
# bind-mounting /etc/timezone, which causes a file conflict in Ubuntu 24.04
49-
systemd-nspawn --timezone=off --pipe -i $IMG /bin/sh <<EOF
50-
set -x
51-
. /etc/os-release
52-
case \$ID in
53-
ubuntu)
54-
export DEBIAN_FRONTEND=noninteractive
55-
apt update
56-
apt install -y openssh-server iproute2 udev
57-
;;
58-
alpine)
59-
apk add openssh openrc
60-
rc-update add sshd
61-
rc-update add local default
62-
echo "ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100" >>/etc/inittab
63-
;;
64-
amzn)
65-
dnf update
66-
dnf install -y openssh-server iproute passwd systemd-udev
67-
# re-do this
68-
ln -svf /etc/systemd/system/fcnet.service /etc/systemd/system/sysinit.target.wants/fcnet.service
69-
rm -fv /etc/systemd/system/getty.target.wants/getty@tty1.service
70-
;;
71-
esac
72-
passwd -d root
73-
EOF
74-
}
24+
# Generate SSH key for access from host
25+
if [ ! -s id_rsa ]; then
26+
ssh-keygen -f id_rsa -N ""
27+
fi
28+
29+
# install rootfs dependencies
30+
apt update
31+
apt install -y busybox-static cpio curl docker.io tree
32+
prepare_docker
33+
34+
for img in "${IMAGES[@]}"; do
35+
build_rootfs "$img" "$OUTPUT_DIR" "$OVERLAY_DIR" "$SETUP_SCRIPT"
36+
37+
rootfs_name="${img//:/-}"
38+
cp id_rsa "$rootfs_name.id_rsa"
39+
chmod a+r "$rootfs_name.id_rsa"
7540

76-
# FIXME: The AL image build procedure is known for keeping changing the ext4 file
77-
# even after the systemd-nspawn command exits, for unknown reason, causing
78-
# the subsequent tar command to fail. Placing it first as a mitigation gives it
79-
# more time to converge to a stable state.
80-
make_rootfs amazonlinux:2023
81-
make_rootfs alpine:latest
82-
make_rootfs ubuntu:22.04
83-
make_rootfs ubuntu:24.04
84-
make_rootfs ubuntu:25.04
85-
make_rootfs ubuntu:latest
41+
chown "$USER_UID" "$rootfs_name.squashfs" "$rootfs_name.id_rsa"
42+
chgrp "$USER_GID" "$rootfs_name.squashfs" "$rootfs_name.id_rsa"
43+
done
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#!/bin/sh
2+
# Copyright 2025 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
# Minimal rootfs setup: just enough to boot with SSH and networking.
6+
# Runs inside a Docker container via build_rootfs().
7+
8+
set -eux
9+
10+
. /etc/os-release
11+
# On Ubuntu, installing openssh-server automatically sets up required SSH keys for the server.
12+
# AL2023 and Alpine do not do this, so we should setup keys manually via `ssh-keygen`.
13+
# Alpine additionally requires /var/empty to be present for sshd to start properly.
14+
case $ID in
15+
ubuntu)
16+
export DEBIAN_FRONTEND=noninteractive
17+
apt update
18+
apt install -y openssh-server iproute2 udev
19+
;;
20+
amzn)
21+
dnf install -y openssh-server iproute systemd-udev passwd tar
22+
ssh-keygen -A
23+
;;
24+
alpine)
25+
apk add openssh openrc tar
26+
mkdir -p /var/empty
27+
ssh-keygen -A
28+
rc-update add sshd
29+
rc-update add local default
30+
echo "ttyS0::respawn:/sbin/getty -L ttyS0 115200 vt100" >>/etc/inittab
31+
;;
32+
esac
33+
34+
passwd -d root
35+
36+
# Install SSH public key if available
37+
if [ -f /work/id_rsa.pub ]; then
38+
install -d -m 0700 /root/.ssh
39+
cp /work/id_rsa.pub /root/.ssh/authorized_keys
40+
chmod 0600 /root/.ssh/authorized_keys
41+
fi
42+
43+
if [ -d /etc/systemd/system ]; then
44+
# Enable fcnet for systemd-based images
45+
mkdir -pv /etc/systemd/system/sysinit.target.wants
46+
ln -svf /etc/systemd/system/fcnet.service /etc/systemd/system/sysinit.target.wants/fcnet.service
47+
cp -v fcnet.start /etc/local.d
48+
49+
# The serial getty service hooks up the login prompt to the kernel console
50+
# at ttyS0 (where Firecracker connects its serial console). We'll set it up
51+
# for autologin to avoid the login prompt.
52+
for console in ttyS0; do
53+
mkdir "/etc/systemd/system/serial-getty@$console.service.d/"
54+
cat <<'EOF' > "/etc/systemd/system/serial-getty@$console.service.d/override.conf"
55+
[Service]
56+
# systemd requires this empty ExecStart line to override
57+
ExecStart=
58+
ExecStart=-/sbin/agetty --autologin root -o '-p -- \\u' --keep-baud 115200,38400,9600 %I dumb
59+
EOF
60+
done
61+
fi

tools/test-popular-containers/test-docker-rootfs.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# pylint:disable=invalid-name
66

77
"""
8-
Test all the ext4 rootfs in the current directory
8+
Test all the squashfs rootfs in the current directory
99
"""
1010

1111
import os
@@ -29,7 +29,7 @@
2929
vmfcty = MicroVMFactory(DEFAULT_BINARY_DIR)
3030
# (may take a while to compile Firecracker...)
3131

32-
for rootfs in Path(".").glob("*.ext4"):
32+
for rootfs in Path(".").glob("*.squashfs"):
3333
print(f">>>> Testing {rootfs}")
3434
uvm = vmfcty.build(kernel, rootfs)
3535
uvm.spawn()

0 commit comments

Comments
 (0)