Try to make booted containers work with GitHub's arm64 runners #150
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
name: build-os | |
on: | |
pull_request: | |
branches: | |
- main | |
paths-ignore: | |
- '**/README.md' | |
push: | |
branches: | |
- main | |
paths-ignore: | |
- '**/README.md' | |
merge_group: | |
workflow_dispatch: | |
jobs: | |
build: | |
name: Test containers | |
strategy: | |
fail-fast: false | |
matrix: | |
os: | |
- ubuntu-22.04 | |
- ubuntu-24.04 | |
- ubuntu-22.04-arm | |
- ubuntu-24.04-arm | |
runs-on: ${{ matrix.os }} | |
steps: | |
- name: Checkout repository | |
uses: actions/checkout@v4 | |
- name: Download and cache base image | |
id: download-base | |
uses: ethanjli/[email protected] | |
with: | |
url: https://downloads.raspberrypi.com/raspios_lite_arm64/images/raspios_lite_arm64-2024-11-19/2024-11-19-raspios-bookworm-arm64-lite.img.xz | |
destination: /tmp/2024-11-19-raspios-bookworm-arm64-lite.img.xz | |
- name: Grow the image | |
id: grow-image | |
uses: ethanjli/[email protected] | |
with: | |
image: ${{ steps.download-base.outputs.destination }} | |
destination: rpi-os-image.img | |
mode: to | |
size: 8G | |
# Run shell commands as root | |
- name: Install and run cowsay | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
run: | | |
apt-get update | |
apt-get install -y cowsay | |
/usr/games/cowsay 'I am running in a light-weight namespace container!' | |
# Run shell commands in a specific shell | |
- name: Run in Python | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
shell: python | |
run: | | |
import platform | |
for word in reversed(['!', platform.python_version(), 'Python', 'in', 'running', 'am', 'I']): | |
print(word, end=' ') | |
# Run a shell with complicated quoting rules | |
- name: Run subshell with complicated quoting rules | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
shell: > | |
sh -c "bash -c \"bash -c 'sh -c {0}'\"" | |
run: | | |
/usr/games/cowsay "I am $USER!" | |
# Run shell commands as the pi user | |
- name: Run script without root permissions | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
user: pi | |
shell: sh | |
run: | | |
sudo apt-get update | |
sudo apt-get install -y figlet | |
figlet -f bubble "I am $USER!" | |
# Run an external script directly, with the shell selected by the shebang line | |
- name: Make a script on the host | |
uses: 1arp/[email protected] | |
with: | |
file: figlet.sh | |
content: | | |
#!/usr/bin/env -S bash -eux | |
figlet -f digital "I am $USER in $SHELL!" | |
- name: Make the script executable | |
run: chmod a+x figlet.sh | |
- name: Run script directly | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
args: --bind "$(pwd)":/run/external | |
user: pi | |
shell: /run/external/figlet.sh | |
# Run shell commands with one or more bind mounts from the host OS | |
- name: Make a bootloader configuration snippet | |
uses: 1arp/[email protected] | |
with: | |
file: boot-config.snippet | |
content: | | |
# Enable support for the RV3028 RTC | |
dtoverlay=i2c-rtc,rv3028,trickle-resistor-ohms=3000,backup-switchover-mode=1 | |
- name: Modify bootloader configuration | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
args: --bind "$(pwd)":/run/external | |
run: | | |
cat /run/external/boot-config.snippet >> /boot/config.txt | |
cp /boot/config.txt /run/external/boot.config | |
- name: Print the bootloader config | |
run: cat boot.config | |
- name: Query installed packages | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
args: --bind "$(pwd)":/run/external | |
run: | | |
#/usr/bin/env bash -x | |
dpkg-query -l | tee > /run/external/installed-packages.txt | |
- name: Upload the bootup timeline to Job Artifacts | |
uses: actions/upload-artifact@v4 | |
with: | |
name: installed-packages-${{ matrix.os }} | |
path: installed-packages.txt | |
if-no-files-found: error | |
overwrite: true | |
# Run shell commands in a booted container | |
# Note: this is code to troubleshoot premature shutdown on arm64 runners | |
- name: Disable unnecessary services | |
uses: ./ | |
# continue-on-error: true | |
with: | |
image: rpi-os-image.img | |
args: --bind "$(pwd)":/run/external | |
run: | | |
systemctl disable sshswitch.service | |
systemctl disable regenerate_ssh_host_keys.service | |
- name: Analyze systemd boot process | |
uses: ./ | |
# continue-on-error: true | |
with: | |
image: rpi-os-image.img | |
args: --bind "$(pwd)":/run/external | |
boot: true | |
run: | | |
while ! systemd-analyze 2>/dev/null; do | |
echo "Waiting for boot to finish..." | |
systemctl list-jobs --no-pager | |
sleep 1 | |
done | |
systemd-analyze critical-chain | cat | |
systemd-analyze blame | cat | |
systemd-analyze plot > /run/external/bootup-timeline.svg | |
echo "Done!" | |
- name: Check logs from previous boot | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
boot: true | |
run: | | |
#/usr/bin/env bash -x | |
journalctl -b-1 --no-pager | |
- name: Upload the bootup timeline to Job Artifacts | |
uses: actions/upload-artifact@v4 | |
if: ${{ ! endsWith(matrix.os, '-arm') }} | |
with: | |
name: bootup-timeline-${{ matrix.os }} | |
path: bootup-timeline.svg | |
if-no-files-found: error | |
overwrite: true | |
# Run shell commands as the pi user in a booted container | |
- name: Run as user in booted container | |
uses: ./ | |
with: | |
image: rpi-os-image.img | |
user: pi | |
boot: true | |
run: | | |
/usr/games/cowsay "I am $USER!" | |
if [ "$USER" != "pi" ]; then | |
exit 666 | |
fi | |
# Check cgroup version | |
- name: Confirm use of cgroup v2 | |
uses: ./ | |
with: | |
# Note: this test should be run on a bookworm image to exercise the required functionality | |
image: rpi-os-image.img | |
boot: true | |
run: | | |
#!/bin/sh -e | |
echo "cgroup v2 mount:" | |
mount | grep cgroup2 | |
# Interact with Docker in an unbooted container | |
- name: Install Docker | |
uses: ./ | |
if: ${{ endsWith(matrix.os, '24.04-arm') }} | |
with: | |
image: rpi-os-image.img | |
run: | | |
export DEBIAN_FRONTEND=noninteractive | |
apt-get update | |
apt-get install -y ca-certificates curl | |
install -m 0755 -d /etc/apt/keyrings | |
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc | |
chmod a+r /etc/apt/keyrings/docker.asc | |
echo \ | |
"deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \ | |
https://download.docker.com/linux/debian \ | |
$(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ | |
> /etc/apt/sources.list.d/docker.list | |
apt-get update | |
apt-get install -y \ | |
docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin | |
- name: Pull a Docker container image | |
uses: ./ | |
if: ${{ endsWith(matrix.os, '24.04-arm') }} | |
with: | |
image: rpi-os-image.img | |
args: --capability=CAP_NET_ADMIN | |
run: | | |
#!/bin/bash -eux | |
/usr/bin/containerd & | |
/usr/bin/dockerd & | |
sleep 10 | |
docker image pull hello-world | |
docker image ls |