diff --git a/.github/workflows/scripts/qemu-3-deps-vm.sh b/.github/workflows/scripts/qemu-3-deps-vm.sh index b74303791715..b10bd4da323c 100755 --- a/.github/workflows/scripts/qemu-3-deps-vm.sh +++ b/.github/workflows/scripts/qemu-3-deps-vm.sh @@ -1,236 +1,262 @@ #!/usr/bin/env bash ###################################################################### # 3) install dependencies for compiling and loading # # $1: OS name (like 'fedora41') +# $2: (optional) Experimental Fedora kernel version, like "6.14" to +# install instead of Fedora defaults. ###################################################################### set -eu function archlinux() { echo "##[group]Running pacman -Syu" sudo btrfs filesystem resize max / sudo pacman -Syu --noconfirm echo "##[endgroup]" echo "##[group]Install Development Tools" sudo pacman -Sy --noconfirm base-devel bc cpio cryptsetup dhclient dkms \ fakeroot fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils \ parted pax perf python-packaging python-setuptools qemu-guest-agent ksh \ samba sysstat rng-tools rsync wget xxhash echo "##[endgroup]" } function debian() { export DEBIAN_FRONTEND="noninteractive" echo "##[group]Running apt-get update+upgrade" sudo apt-get update -y sudo apt-get upgrade -y echo "##[endgroup]" echo "##[group]Install Development Tools" sudo apt-get install -y \ acl alien attr autoconf bc cpio cryptsetup curl dbench dh-python dkms \ fakeroot fio gdb gdebi git ksh lcov isc-dhcp-client jq libacl1-dev \ libaio-dev libattr1-dev libblkid-dev libcurl4-openssl-dev libdevmapper-dev \ libelf-dev libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev \ libtool libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \ lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \ python3-cffi python3-dev python3-distlib python3-packaging \ python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \ rsync samba sysstat uuid-dev watchdog wget xfslibs-dev xxhash zlib1g-dev echo "##[endgroup]" } function freebsd() { export ASSUME_ALWAYS_YES="YES" echo "##[group]Install Development Tools" sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \ gdb gettext gettext-runtime git gmake gsed jq ksh93 lcov libtool lscpu \ pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash sudo pkg install -xy \ '^samba4[[:digit:]]+$' \ '^py3[[:digit:]]+-cffi$' \ '^py3[[:digit:]]+-sysctl$' \ '^py3[[:digit:]]+-setuptools$' \ '^py3[[:digit:]]+-packaging$' echo "##[endgroup]" } # common packages for: almalinux, centos, redhat function rhel() { echo "##[group]Running dnf update" echo "max_parallel_downloads=10" | sudo -E tee -a /etc/dnf/dnf.conf sudo dnf clean all sudo dnf update -y --setopt=fastestmirror=1 --refresh echo "##[endgroup]" echo "##[group]Install Development Tools" # Alma wants "Development Tools", Fedora 41 wants "development-tools" if ! sudo dnf group install -y "Development Tools" ; then echo "Trying 'development-tools' instead of 'Development Tools'" sudo dnf group install -y development-tools fi sudo dnf install -y \ acl attr bc bzip2 cryptsetup curl dbench dkms elfutils-libelf-devel fio \ gdb git jq kernel-rpm-macros ksh libacl-devel libaio-devel \ libargon2-devel libattr-devel libblkid-devel libcurl-devel libffi-devel \ ncompress libselinux-devel libtirpc-devel libtool libudev-devel \ libuuid-devel lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester \ parted perf python3 python3-cffi python3-devel python3-packaging \ kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \ rpm-build rsync samba sysstat systemd watchdog wget xfsprogs-devel xxhash \ zlib-devel echo "##[endgroup]" } function tumbleweed() { echo "##[group]Running zypper is TODO!" sleep 23456 echo "##[endgroup]" } +# $1: Kernel version to install (like '6.14rc7') +function install_fedora_experimental_kernel { + + our_version="$1" + sudo dnf -y copr enable @kernel-vanilla/stable + sudo dnf -y copr enable @kernel-vanilla/mainline + all="$(sudo dnf list --showduplicates kernel-*)" + echo "Available versions:" + echo "$all" + + # You can have a bunch of minor variants of the version we want '6.14'. + # Pick the newest variant (sorted by version number). + specific_version=$(echo "$all" | grep $our_version | awk '{print $2}' | sort -V | tail -n 1) + list="$(echo "$all" | grep $specific_version | grep -Ev 'kernel-rt|kernel-selftests|kernel-debuginfo' | sed 's/.x86_64//g' | awk '{print $1"-"$2}')" + sudo dnf install -y $list + sudo dnf -y copr disable @kernel-vanilla/stable + sudo dnf -y copr disable @kernel-vanilla/mainline +} + # Install dependencies case "$1" in almalinux8) echo "##[group]Enable epel and powertools repositories" sudo dnf config-manager -y --set-enabled powertools sudo dnf install -y epel-release echo "##[endgroup]" rhel echo "##[group]Install kernel-abi-whitelists" sudo dnf install -y kernel-abi-whitelists echo "##[endgroup]" ;; almalinux9|centos-stream9|centos-stream10) echo "##[group]Enable epel and crb repositories" sudo dnf config-manager -y --set-enabled crb sudo dnf install -y epel-release echo "##[endgroup]" rhel echo "##[group]Install kernel-abi-stablelists" sudo dnf install -y kernel-abi-stablelists echo "##[endgroup]" ;; archlinux) archlinux ;; debian*) echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections debian echo "##[group]Install Debian specific" sudo apt-get install -yq linux-perf dh-sequence-dkms echo "##[endgroup]" ;; fedora*) rhel sudo dnf install -y libunwind-devel # Fedora 42+ moves /usr/bin/script from 'util-linux' to 'util-linux-script' sudo dnf install -y util-linux-script || true + + # Optional: Install an experimental kernel ($2 = kernel version) + if [ -n "${2:-}" ] ; then + install_fedora_experimental_kernel "$2" + fi ;; freebsd*) freebsd ;; tumbleweed) tumbleweed ;; ubuntu*) debian echo "##[group]Install Ubuntu specific" sudo apt-get install -yq linux-tools-common libtirpc-dev \ linux-modules-extra-$(uname -r) if [ "$1" != "ubuntu20" ]; then sudo apt-get install -yq dh-sequence-dkms fi echo "##[endgroup]" echo "##[group]Delete Ubuntu OpenZFS modules" for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done echo "##[endgroup]" ;; esac # This script is used for checkstyle + zloop deps also. # Install only the needed packages and exit - when used this way. test -z "${ONLY_DEPS:-}" || exit 0 # Start services echo "##[group]Enable services" case "$1" in freebsd*) # add virtio things echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf for i in balloon blk console random scsi; do echo "virtio_${i}_load=\"YES\"" | sudo -E tee -a /boot/loader.conf done echo "fdescfs /dev/fd fdescfs rw 0 0" | sudo -E tee -a /etc/fstab sudo -E mount /dev/fd sudo -E touch /etc/zfs/exports sudo -E sysrc mountd_flags="/etc/zfs/exports" echo '[global]' | sudo -E tee /usr/local/etc/smb4.conf >/dev/null sudo -E service nfsd enable sudo -E service qemu-guest-agent enable sudo -E service samba_server enable ;; debian*|ubuntu*) sudo -E systemctl enable nfs-kernel-server sudo -E systemctl enable qemu-guest-agent sudo -E systemctl enable smbd ;; *) # All other linux distros sudo -E systemctl enable nfs-server sudo -E systemctl enable qemu-guest-agent sudo -E systemctl enable smb ;; esac echo "##[endgroup]" # Setup Kernel cmdline CMDLINE="console=tty0 console=ttyS0,115200n8" CMDLINE="$CMDLINE selinux=0" CMDLINE="$CMDLINE random.trust_cpu=on" CMDLINE="$CMDLINE no_timer_check" case "$1" in almalinux*|centos*|fedora*) GRUB_CFG="/boot/grub2/grub.cfg" GRUB_MKCONFIG="grub2-mkconfig" CMDLINE="$CMDLINE biosdevname=0 net.ifnames=0" echo 'GRUB_SERIAL_COMMAND="serial --speed=115200"' \ | sudo tee -a /etc/default/grub >/dev/null ;; ubuntu24) GRUB_CFG="/boot/grub/grub.cfg" GRUB_MKCONFIG="grub-mkconfig" echo 'GRUB_DISABLE_OS_PROBER="false"' \ | sudo tee -a /etc/default/grub >/dev/null ;; *) GRUB_CFG="/boot/grub/grub.cfg" GRUB_MKCONFIG="grub-mkconfig" ;; esac case "$1" in archlinux|freebsd*) true ;; *) echo "##[group]Edit kernel cmdline" sudo sed -i -e '/^GRUB_CMDLINE_LINUX/d' /etc/default/grub || true echo "GRUB_CMDLINE_LINUX=\"$CMDLINE\"" \ | sudo tee -a /etc/default/grub >/dev/null sudo $GRUB_MKCONFIG -o $GRUB_CFG echo "##[endgroup]" ;; esac # reset cloud-init configuration and poweroff sudo cloud-init clean --logs sleep 2 && sudo poweroff & exit 0 diff --git a/.github/workflows/scripts/qemu-3-deps.sh b/.github/workflows/scripts/qemu-3-deps.sh index 184aed85b4e5..267ae4ad3c7b 100755 --- a/.github/workflows/scripts/qemu-3-deps.sh +++ b/.github/workflows/scripts/qemu-3-deps.sh @@ -1,15 +1,28 @@ ###################################################################### # 3) Wait for VM to boot from previous step and launch dependencies # script on it. # # $1: OS name (like 'fedora41') +# $2: (optional) Experimental kernel version to install on fedora, +# like "6.14". ###################################################################### .github/workflows/scripts/qemu-wait-for-vm.sh vm0 + +# SPECIAL CASE: +# +# If the user passed in an experimental kernel version to test on Fedora, +# we need to update the kernel version in zfs's META file to allow the +# build to happen. We update our local copy of META here, since we know +# it will be rsync'd up in the next step. +if [ -n "${2:-}" ] ; then + sed -i -E 's/Linux-Maximum: .+/Linux-Maximum: 99.99/g' META +fi + scp .github/workflows/scripts/qemu-3-deps-vm.sh zfs@vm0:qemu-3-deps-vm.sh PID=`pidof /usr/bin/qemu-system-x86_64` -ssh zfs@vm0 '$HOME/qemu-3-deps-vm.sh' $1 +ssh zfs@vm0 '$HOME/qemu-3-deps-vm.sh' "$@" # wait for poweroff to succeed tail --pid=$PID -f /dev/null sleep 5 # avoid this: "error: Domain is already active" rm -f $HOME/.ssh/known_hosts diff --git a/.github/workflows/zfs-qemu.yml b/.github/workflows/zfs-qemu.yml index d4578e40ad90..eb4616220092 100644 --- a/.github/workflows/zfs-qemu.yml +++ b/.github/workflows/zfs-qemu.yml @@ -1,180 +1,193 @@ name: zfs-qemu on: push: pull_request: workflow_dispatch: inputs: include_stream9: type: boolean required: false default: false description: 'Test on CentOS 9 stream' include_stream10: type: boolean required: false default: false description: 'Test on CentOS 10 stream' + fedora_kernel_ver: + type: string + required: false + default: "" + description: "(optional) Experimental kernel version to install on Fedora (like '6.14' or '6.13.3-0.rc3')" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: test-config: name: Setup runs-on: ubuntu-24.04 outputs: test_os: ${{ steps.os.outputs.os }} ci_type: ${{ steps.os.outputs.ci_type }} steps: - uses: actions/checkout@v4 with: fetch-depth: 0 - name: Generate OS config and CI type id: os run: | FULL_OS='["almalinux8", "almalinux9", "debian11", "debian12", "fedora40", "fedora41", "fedora42", "freebsd13-4r", "freebsd14-2s", "freebsd15-0c", "ubuntu20", "ubuntu22", "ubuntu24"]' QUICK_OS='["almalinux8", "almalinux9", "debian12", "fedora42", "freebsd14-2r", "ubuntu24"]' # determine CI type when running on PR ci_type="full" if ${{ github.event_name == 'pull_request' }}; then head=${{ github.event.pull_request.head.sha }} base=${{ github.event.pull_request.base.sha }} ci_type=$(python3 .github/workflows/scripts/generate-ci-type.py $head $base) fi if [ "$ci_type" == "quick" ]; then os_selection="$QUICK_OS" else os_selection="$FULL_OS" fi - os_json=$(echo ${os_selection} | jq -c) + + if [ ${{ github.event.inputs.fedora_kernel_ver }} != "" ] ; then + # They specified a custom kernel version for Fedora. Use only + # Fedora runners. + os_json=$(echo ${os_selection} | jq -c '[.[] | select(startswith("fedora"))]') + else + # Normal case + os_json=$(echo ${os_selection} | jq -c) + fi # Add optional runners if [ "${{ github.event.inputs.include_stream9 }}" == 'true' ]; then os_json=$(echo $os_json | jq -c '. += ["centos-stream9"]') fi if [ "${{ github.event.inputs.include_stream10 }}" == 'true' ]; then os_json=$(echo $os_json | jq -c '. += ["centos-stream10"]') fi echo $os_json echo "os=$os_json" >> $GITHUB_OUTPUT echo "ci_type=$ci_type" >> $GITHUB_OUTPUT qemu-vm: name: qemu-x86 needs: [ test-config ] strategy: fail-fast: false matrix: # rhl: almalinux8, almalinux9, centos-stream9, fedora40, fedora41 # debian: debian11, debian12, ubuntu20, ubuntu22, ubuntu24 # misc: archlinux, tumbleweed # FreeBSD variants of 2024-12: # FreeBSD Release: freebsd13-4r, freebsd14-2r # FreeBSD Stable: freebsd13-4s, freebsd14-2s # FreeBSD Current: freebsd15-0c os: ${{ fromJson(needs.test-config.outputs.test_os) }} runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - name: Setup QEMU timeout-minutes: 10 run: .github/workflows/scripts/qemu-1-setup.sh - name: Start build machine timeout-minutes: 10 run: .github/workflows/scripts/qemu-2-start.sh ${{ matrix.os }} - name: Install dependencies timeout-minutes: 20 - run: .github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }} + run: .github/workflows/scripts/qemu-3-deps.sh ${{ matrix.os }} ${{ github.event.inputs.fedora_kernel_ver }} - name: Build modules timeout-minutes: 30 run: .github/workflows/scripts/qemu-4-build.sh --poweroff --enable-debug ${{ matrix.os }} - name: Setup testing machines timeout-minutes: 5 run: .github/workflows/scripts/qemu-5-setup.sh - name: Run tests timeout-minutes: 270 run: .github/workflows/scripts/qemu-6-tests.sh env: CI_TYPE: ${{ needs.test-config.outputs.ci_type }} - name: Prepare artifacts if: always() timeout-minutes: 10 run: .github/workflows/scripts/qemu-7-prepare.sh - uses: actions/upload-artifact@v4 id: artifact-upload if: always() with: name: Logs-functional-${{ matrix.os }} path: /tmp/qemu-${{ matrix.os }}.tar if-no-files-found: ignore - name: Test Summary if: always() run: .github/workflows/scripts/qemu-8-summary.sh '${{ steps.artifact-upload.outputs.artifact-url }}' cleanup: if: always() name: Cleanup runs-on: ubuntu-latest needs: [ qemu-vm ] steps: - uses: actions/checkout@v4 with: ref: ${{ github.event.pull_request.head.sha }} - uses: actions/download-artifact@v4 - name: Generating summary run: .github/workflows/scripts/qemu-9-summary-page.sh - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 2 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 3 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 4 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 5 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 6 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 7 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 8 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 9 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 10 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 11 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 12 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 13 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 14 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 15 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 16 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 17 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 18 - name: Generating summary... run: .github/workflows/scripts/qemu-9-summary-page.sh 19 - uses: actions/upload-artifact@v4 with: name: Summary Files path: out-*