Skip to content

Commit 8dec2d9

Browse files
alex-mochtonyhutter
authored andcommitted
CI: Add Alpine Linux 3.23 runner to the pipeline (openzfs#18087)
Add an Alpine Linux 3.23 runner to the CI chain to run OpenZFS builds and tests against musl libc. Currently, zfs_send_sparse is killed after 10 minutes on Alpine, causing cascading EBUSY failures in the test suite. With zfs_send_sparse disabled, the ZFS test suite reaches a pass rate of 94.62%. This commit introduces the required Alpine-specific setup and a small set of shell and cloud-init compatibility fixes that also apply to existing Linux runners. The Alpine runner is not enabled by default and is not executed for new pull requests. Sponsored-by: ERNW Research GmbH - https://ernw-research.de/ Signed-off-by: Alexander Moch <amoch@ernw.de> Reviewed-by: Brian Behlendorf <behlendorf1@llnl.gov> Reviewed-by: Tony Hutter <hutter2@llnl.gov> Reviewed-by: Tino Reichardt <milky-zfs@mcmilk.de>
1 parent 8e946b5 commit 8dec2d9

File tree

9 files changed

+121
-20
lines changed

9 files changed

+121
-20
lines changed

.github/workflows/scripts/qemu-2-start.sh

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ case "$OS" in
4343
OSv="almalinux9"
4444
URL="https://repo.almalinux.org/almalinux/10/cloud/x86_64/images/AlmaLinux-10-GenericCloud-latest.x86_64.qcow2"
4545
;;
46+
alpine3-23)
47+
OSNAME="Alpine Linux 3.23.2"
48+
# Alpine Linux v3.22 and v3.23 are unknown to osinfo as of 2025-12-26.
49+
OSv="alpinelinux3.21"
50+
URL="https://dl-cdn.alpinelinux.org/alpine/v3.23/releases/cloud/generic_alpine-3.23.2-x86_64-bios-cloudinit-r0.qcow2"
51+
;;
4652
archlinux)
4753
OSNAME="Archlinux"
4854
URL="https://geo.mirror.pkgbuild.com/images/latest/Arch-Linux-x86_64-cloudimg.qcow2"
@@ -216,13 +222,21 @@ if [ ${OS:0:7} != "freebsd" ]; then
216222
hostname: $OS
217223
218224
users:
219-
- name: root
220-
shell: $BASH
221-
- name: zfs
222-
sudo: ALL=(ALL) NOPASSWD:ALL
223-
shell: $BASH
224-
ssh_authorized_keys:
225-
- $PUBKEY
225+
- name: root
226+
shell: /bin/bash
227+
sudo: ['ALL=(ALL) NOPASSWD:ALL']
228+
- name: zfs
229+
shell: /bin/bash
230+
sudo: ['ALL=(ALL) NOPASSWD:ALL']
231+
ssh_authorized_keys:
232+
- $PUBKEY
233+
# Workaround for Alpine Linux.
234+
lock_passwd: false
235+
passwd: '*'
236+
237+
packages:
238+
- sudo
239+
- bash
226240
227241
growpart:
228242
mode: auto
@@ -305,3 +319,23 @@ else
305319
scp ~/src.txz "root@vm0:/tmp/src.txz"
306320
ssh root@vm0 'tar -C / -zxf /tmp/src.txz'
307321
fi
322+
323+
#
324+
# Config for Alpine Linux similar to FreeBSD.
325+
#
326+
if [ ${OS:0:6} == "alpine" ]; then
327+
while pidof /usr/bin/qemu-system-x86_64 >/dev/null; do
328+
ssh 2>/dev/null zfs@vm0 "uname -a" && break
329+
done
330+
# Enable community and testing repositories.
331+
ssh zfs@vm0 "sudo rm -rf /etc/apk/repositories"
332+
ssh zfs@vm0 "sudo setup-apkrepos -c1"
333+
ssh zfs@vm0 "echo '@testing http://dl-cdn.alpinelinux.org/alpine/edge/testing' | sudo tee -a /etc/apk/repositories"
334+
# Upgrade to edge or latest-stable.
335+
#ssh zfs@vm0 "sudo sed -i 's#/v[0-9]\+\.[0-9]\+/#/edge/#g' /etc/apk/repositories"
336+
#ssh zfs@vm0 "sudo sed -i 's#/v[0-9]\+\.[0-9]\+/#/latest-stable/#g' /etc/apk/repositories"
337+
# Update and upgrade after repository setup.
338+
ssh zfs@vm0 "sudo apk update"
339+
ssh zfs@vm0 "sudo apk add --upgrade apk-tools"
340+
ssh zfs@vm0 "sudo apk upgrade --available"
341+
fi

.github/workflows/scripts/qemu-3-deps-vm.sh

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,32 @@
1010

1111
set -eu
1212

13+
function alpine() {
14+
echo "##[group]Install Development Tools"
15+
sudo apk add \
16+
acl alpine-sdk attr autoconf automake bash build-base clang21 coreutils \
17+
cpio cryptsetup curl curl-dev dhcpcd eudev eudev-dev eudev-libs findutils \
18+
fio gawk gdb gettext-dev git grep jq libaio libaio-dev libcurl \
19+
libtirpc-dev libtool libunwind libunwind-dev linux-headers linux-tools \
20+
linux-virt linux-virt-dev lsscsi m4 make nfs-utils openssl-dev parted \
21+
pax procps py3-cffi py3-distlib py3-packaging py3-setuptools python3 \
22+
python3-dev qemu-guest-agent rng-tools rsync samba samba-server sed \
23+
strace sysstat util-linux util-linux-dev wget words xfsprogs xxhash \
24+
zlib-dev pamtester@testing
25+
echo "##[endgroup]"
26+
27+
echo "##[group]Switch to eudev"
28+
sudo setup-devd udev
29+
echo "##[endgroup]"
30+
31+
echo "##[group]Install ksh93 from Source"
32+
git clone --depth 1 https://github.com/ksh93/ksh.git /tmp/ksh
33+
cd /tmp/ksh
34+
./bin/package make
35+
sudo ./bin/package install /
36+
echo "##[endgroup]"
37+
}
38+
1339
function archlinux() {
1440
echo "##[group]Running pacman -Syu"
1541
sudo btrfs filesystem resize max /
@@ -27,6 +53,10 @@ function archlinux() {
2753
function debian() {
2854
export DEBIAN_FRONTEND="noninteractive"
2955

56+
echo "##[group]Wait for cloud-init to finish"
57+
cloud-init status --wait
58+
echo "##[endgroup]"
59+
3060
echo "##[group]Running apt-get update+upgrade"
3161
sudo sed -i '/[[:alpha:]]-backports/d' /etc/apt/sources.list
3262
sudo apt-get update -y
@@ -140,6 +170,9 @@ case "$1" in
140170
sudo dnf install -y kernel-abi-stablelists
141171
echo "##[endgroup]"
142172
;;
173+
alpine*)
174+
alpine
175+
;;
143176
archlinux)
144177
archlinux
145178
;;
@@ -188,6 +221,16 @@ test -z "${ONLY_DEPS:-}" || exit 0
188221
# Start services
189222
echo "##[group]Enable services"
190223
case "$1" in
224+
alpine*)
225+
sudo -E rc-update add qemu-guest-agent
226+
sudo -E rc-update add nfs
227+
sudo -E rc-update add samba
228+
sudo -E rc-update add dhcpcd
229+
# Remove services related to cloud-init.
230+
sudo -E rc-update del cloud-init default
231+
sudo -E rc-update del cloud-final default
232+
sudo -E rc-update del cloud-config default
233+
;;
191234
freebsd*)
192235
# add virtio things
193236
echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
@@ -243,7 +286,7 @@ case "$1" in
243286
esac
244287

245288
case "$1" in
246-
archlinux|freebsd*)
289+
alpine*|archlinux|freebsd*)
247290
true
248291
;;
249292
*)

.github/workflows/scripts/qemu-5-setup.sh

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,13 +58,21 @@ for ((i=1; i<=VMs; i++)); do
5858
fqdn: vm$i
5959
6060
users:
61-
- name: root
62-
shell: $BASH
63-
- name: zfs
64-
sudo: ALL=(ALL) NOPASSWD:ALL
65-
shell: $BASH
66-
ssh_authorized_keys:
67-
- $PUBKEY
61+
- name: root
62+
shell: /bin/bash
63+
sudo: ['ALL=(ALL) NOPASSWD:ALL']
64+
- name: zfs
65+
shell: /bin/bash
66+
sudo: ['ALL=(ALL) NOPASSWD:ALL']
67+
ssh_authorized_keys:
68+
- $PUBKEY
69+
# Workaround for Alpine Linux.
70+
lock_passwd: false
71+
passwd: '*'
72+
73+
packages:
74+
- sudo
75+
- bash
6876
6977
growpart:
7078
mode: auto

.github/workflows/scripts/qemu-6-tests.sh

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,18 @@ case "$1" in
9595
;;
9696
esac
9797

98-
# enable io_uring on el9/el10
98+
# Distribution-specific settings.
9999
case "$1" in
100100
almalinux9|almalinux10|centos-stream*)
101+
# Enable io_uring on Enterprise Linux 9 and 10.
101102
sudo sysctl kernel.io_uring_disabled=0 > /dev/null
102103
;;
104+
alpine*)
105+
# Ensure `/etc/zfs/zpool.cache` exists.
106+
sudo mkdir -p /etc/zfs
107+
sudo touch /etc/zfs/zpool.cache
108+
sudo chmod 644 /etc/zfs/zpool.cache
109+
;;
103110
esac
104111

105112
# run functional testings and save exitcode

.github/workflows/zfs-qemu.yml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ on:
1010
required: false
1111
default: ""
1212
description: "(optional) Experimental kernel version to install on Fedora (like '6.14' or '6.13.3-0.rc3')"
13+
specific_os:
14+
type: string
15+
required: false
16+
default: ""
17+
description: "(optional) Only run on this specific OS (like 'fedora42' or 'alpine3-23')"
1318

1419
concurrency:
1520
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
@@ -58,6 +63,9 @@ jobs:
5863
# They specified a custom kernel version for Fedora.
5964
# Use only Fedora runners.
6065
os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]')
66+
elif ${{ github.event.inputs.specific_os != '' }}; then
67+
# Use only the specified runner.
68+
os_json=$(jq -cn --arg os "${{ github.event.inputs.specific_os }}" '[ $os ]')
6169
else
6270
# Normal case
6371
os_json=$(echo ${os_selection} | jq -c)

tests/zfs-tests/callbacks/zfs_dbgmsg.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ echo "================================================================="
2626
sudo tail -n $lines /proc/spl/kstat/zfs/dbgmsg
2727

2828
# reset dbgmsg
29-
sudo bash -c "echo > /proc/spl/kstat/zfs/dbgmsg"
29+
sudo sh -c "echo > /proc/spl/kstat/zfs/dbgmsg"
3030

3131
echo "================================================================="
3232
echo " End of zfs_dbgmsg log"

tests/zfs-tests/callbacks/zfs_mmp.ksh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ for f in /proc/spl/kstat/zfs/*/multihost; do
3131
echo "================================================================="
3232

3333
sudo tail -n $lines $f
34-
sudo bash -c "echo > $f"
34+
sudo sh -c "echo > $f"
3535
done
3636

3737
echo "================================================================="

tests/zfs-tests/include/libtest.shlib

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ function default_cleanup_noexit
559559
# Here, we loop through the pools we're allowed to
560560
# destroy, only destroying them if it's safe to do
561561
# so.
562-
while [ ! -z ${ALL_POOLS} ]
562+
while [ -n "${ALL_POOLS}" ]
563563
do
564564
for pool in ${ALL_POOLS}
565565
do

tests/zfs-tests/tests/functional/mount/mount_loopback.ksh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ function do_test
7979
imgfile=$1
8080
log_note "Running test on $imgfile"
8181
log_must losetup -f $imgfile
82-
DEV=$(losetup --associated $imgfile | grep -Eo '^/dev/loop[0-9]+')
82+
# Alpine Linux loop devices appear as `/dev/loop/N` instead of `/dev/loopN`.
83+
DEV=$(losetup --associated $imgfile | grep -Eo '^/dev/loop/?[0-9]+')
8384
log_must mkfs.xfs $DEV
8485
mkdir $TEST_BASE_DIR/mnt
8586
log_must mount $DEV $TEST_BASE_DIR/mnt

0 commit comments

Comments
 (0)