diff --git a/.github/workflows/scripts/qemu-4-build-vm.sh b/.github/workflows/scripts/qemu-4-build-vm.sh index 17e976ebcc39..2807d9e77127 100755 --- a/.github/workflows/scripts/qemu-4-build-vm.sh +++ b/.github/workflows/scripts/qemu-4-build-vm.sh @@ -1,379 +1,396 @@ #!/usr/bin/env bash ###################################################################### # 4) configure and build openzfs modules. This is run on the VMs. # # Usage: # -# qemu-4-build-vm.sh OS [--enable-debug][--dkms][--poweroff] -# [--release][--repo][--tarball] +# qemu-4-build-vm.sh OS [--enable-debug][--dkms][--patch-level NUM] +# [--poweroff][--release][--repo][--tarball] # # OS: OS name like 'fedora41' # --enable-debug: Build RPMs with '--enable-debug' (for testing) # --dkms: Build DKMS RPMs as well +# --patch-level NUM: Use a custom patch level number for packages. # --poweroff: Power-off the VM after building # --release Build zfs-release*.rpm as well # --repo After building everything, copy RPMs into /tmp/repo # in the ZFS RPM repository file structure. Also # copy tarballs if they were built. # --tarball: Also build a tarball of ZFS source ###################################################################### ENABLE_DEBUG="" DKMS="" +PATCH_LEVEL="" POWEROFF="" RELEASE="" REPO="" TARBALL="" while [[ $# -gt 0 ]]; do case $1 in --enable-debug) ENABLE_DEBUG=1 shift ;; --dkms) DKMS=1 shift ;; + --patch-level) + PATCH_LEVEL=$2 + shift + shift + ;; --poweroff) POWEROFF=1 shift ;; --release) RELEASE=1 shift ;; --repo) REPO=1 shift ;; --tarball) TARBALL=1 shift ;; *) OS=$1 shift ;; esac done set -eu function run() { LOG="/var/tmp/build-stderr.txt" echo "****************************************************" echo "$(date) ($*)" echo "****************************************************" ($@ || echo $? > /tmp/rv) 3>&1 1>&2 2>&3 | stdbuf -eL -oL tee -a $LOG if [ -f /tmp/rv ]; then RV=$(cat /tmp/rv) echo "****************************************************" echo "exit with value=$RV ($*)" echo "****************************************************" echo 1 > /var/tmp/build-exitcode.txt exit $RV fi } # Look at the RPMs in the current directory and copy/move them to # /tmp/repo, using the directory structure we use for the ZFS RPM repos. # # For example: # /tmp/repo/epel-testing/9.5 # /tmp/repo/epel-testing/9.5/SRPMS # /tmp/repo/epel-testing/9.5/SRPMS/zfs-2.3.99-1.el9.src.rpm # /tmp/repo/epel-testing/9.5/SRPMS/zfs-kmod-2.3.99-1.el9.src.rpm # /tmp/repo/epel-testing/9.5/kmod # /tmp/repo/epel-testing/9.5/kmod/x86_64 # /tmp/repo/epel-testing/9.5/kmod/x86_64/debug # /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/kmod-zfs-debuginfo-2.3.99-1.el9.x86_64.rpm # /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/libnvpair3-debuginfo-2.3.99-1.el9.x86_64.rpm # /tmp/repo/epel-testing/9.5/kmod/x86_64/debug/libuutil3-debuginfo-2.3.99-1.el9.x86_64.rpm # ... function copy_rpms_to_repo { # Pick a RPM to query. It doesn't matter which one - we just want to extract # the 'Build Host' value from it. rpm=$(ls zfs-*.rpm | head -n 1) # Get zfs version '2.2.99' zfs_ver=$(rpm -qpi $rpm | awk '/Version/{print $3}') # Get "2.1" or "2.2" zfs_major=$(echo $zfs_ver | grep -Eo [0-9]+\.[0-9]+) # Get 'almalinux9.5' or 'fedora41' type string build_host=$(rpm -qpi $rpm | awk '/Build Host/{print $4}') # Get '9.5' or '41' OS version os_ver=$(echo $build_host | grep -Eo '[0-9\.]+$') # Our ZFS version and OS name will determine which repo the RPMs # will go in (regular or testing). Fedora always gets the newest # releases, and Alma gets the older releases. case $build_host in almalinux*) case $zfs_major in 2.2) d="epel" ;; *) d="epel-testing" ;; esac ;; fedora*) d="fedora" ;; esac prefix=/tmp/repo dst="$prefix/$d/$os_ver" # Special case: move zfs-release*.rpm out of the way first (if we built them). # This will make filtering the other RPMs easier. mkdir -p $dst mv zfs-release*.rpm $dst || true # Copy source RPMs mkdir -p $dst/SRPMS cp $(ls *.src.rpm) $dst/SRPMS/ if [[ "$build_host" =~ "almalinux" ]] ; then # Copy kmods+userspace mkdir -p $dst/kmod/x86_64/debug cp $(ls *.rpm | grep -Ev 'src.rpm|dkms|debuginfo') $dst/kmod/x86_64 cp *debuginfo*.rpm $dst/kmod/x86_64/debug fi if [ -n "$DKMS" ] ; then # Copy dkms+userspace mkdir -p $dst/x86_64 cp $(ls *.rpm | grep -Ev 'src.rpm|kmod|debuginfo') $dst/x86_64 fi # Copy debug mkdir -p $dst/x86_64/debug cp $(ls *debuginfo*.rpm | grep -v kmod) $dst/x86_64/debug } function freebsd() { extra="${1:-}" export MAKE="gmake" echo "##[group]Autogen.sh" run ./autogen.sh echo "##[endgroup]" echo "##[group]Configure" run ./configure \ --prefix=/usr/local \ --with-libintl-prefix=/usr/local \ --enable-pyzfs \ --enable-debuginfo $extra echo "##[endgroup]" echo "##[group]Build" run gmake -j$(sysctl -n hw.ncpu) echo "##[endgroup]" echo "##[group]Install" run sudo gmake install echo "##[endgroup]" } function linux() { extra="${1:-}" echo "##[group]Autogen.sh" run ./autogen.sh echo "##[endgroup]" echo "##[group]Configure" run ./configure \ --prefix=/usr \ --enable-pyzfs \ --enable-debuginfo $extra echo "##[endgroup]" echo "##[group]Build" run make -j$(nproc) echo "##[endgroup]" echo "##[group]Install" run sudo make install echo "##[endgroup]" } function rpm_build_and_install() { extra="${1:-}" # Build RPMs with XZ compression by default (since gzip decompression is slow) echo "%_binary_payload w7.xzdio" >> ~/.rpmmacros echo "##[group]Autogen.sh" run ./autogen.sh echo "##[endgroup]" + if [ -n "$PATCH_LEVEL" ] ; then + sed -i -E 's/(Release:\s+)1/\1'$PATCH_LEVEL'/g' META + fi + echo "##[group]Configure" run ./configure --enable-debuginfo $extra echo "##[endgroup]" echo "##[group]Build" run make pkg-kmod pkg-utils echo "##[endgroup]" if [ -n "$DKMS" ] ; then echo "##[group]DKMS" make rpm-dkms echo "##[endgroup]" fi if [ -n "$REPO" ] ; then echo "Skipping install since we're only building RPMs and nothing else" else echo "##[group]Install" run sudo dnf -y --nobest install $(ls *.rpm | grep -Ev 'dkms|src.rpm') echo "##[endgroup]" fi # Optionally build the zfs-release.*.rpm if [ -n "$RELEASE" ] ; then echo "##[group]Release" pushd ~ sudo dnf -y install rpm-build || true # Check out a sparse copy of zfsonlinux.github.com.git so we don't get # all the binaries. We just need a few kilobytes of files to build RPMs. git clone --depth 1 --no-checkout \ https://github.com/zfsonlinux/zfsonlinux.github.com.git cd zfsonlinux.github.com git sparse-checkout set zfs-release git checkout cd zfs-release mkdir -p ~/rpmbuild/{BUILDROOT,SPECS,RPMS,SRPMS,SOURCES,BUILD} cp RPM-GPG-KEY-openzfs* *.repo ~/rpmbuild/SOURCES cp zfs-release.spec ~/rpmbuild/SPECS/ rpmbuild -ba ~/rpmbuild/SPECS/zfs-release.spec # ZFS release RPMs are built. Copy them to the ~/zfs directory just to # keep all the RPMs in the same place. cp ~/rpmbuild/RPMS/noarch/*.rpm ~/zfs cp ~/rpmbuild/SRPMS/*.rpm ~/zfs popd rm -fr ~/rpmbuild echo "##[endgroup]" fi if [ -n "$REPO" ] ; then echo "##[group]Repo" copy_rpms_to_repo echo "##[endgroup]" fi } function deb_build_and_install() { extra="${1:-}" echo "##[group]Autogen.sh" run ./autogen.sh echo "##[endgroup]" echo "##[group]Configure" run ./configure \ --prefix=/usr \ --enable-pyzfs \ --enable-debuginfo $extra echo "##[endgroup]" echo "##[group]Build" run make native-deb-kmod native-deb-utils echo "##[endgroup]" echo "##[group]Install" # Do kmod install. Note that when you build the native debs, the # packages themselves are placed in parent directory '../' rather than # in the source directory like the rpms are. run sudo apt-get -y install $(find ../ | grep -E '\.deb$' \ | grep -Ev 'dkms|dracut') echo "##[endgroup]" } function build_tarball { if [ -n "$REPO" ] ; then ./autogen.sh ./configure --with-config=srpm make dist mkdir -p /tmp/repo/releases # The tarball name is based off of 'Version' field in the META file. mv *.tar.gz /tmp/repo/releases/ fi } # Debug: show kernel cmdline if [ -f /proc/cmdline ] ; then cat /proc/cmdline || true fi # Set our hostname to our OS name and version number. Specifically, we set the # major and minor number so that when we query the Build Host field in the RPMs # we build, we can see what specific version of Fedora/Almalinux we were using # to build them. This is helpful for matching up KMOD versions. # # Examples: # # rhel8.10 # almalinux9.5 # fedora42 source /etc/os-release -sudo hostname "$ID$VERSION_ID" + if which hostnamectl &> /dev/null ; then + # Fedora 42+ use hostnamectl + sudo hostnamectl set-hostname "$ID$VERSION_ID" + sudo hostnamectl set-hostname --pretty "$ID$VERSION_ID" +else + sudo hostname "$ID$VERSION_ID" +fi # save some sysinfo uname -a > /var/tmp/uname.txt cd $HOME/zfs export PATH="$PATH:/sbin:/usr/sbin:/usr/local/sbin" extra="" if [ -n "$ENABLE_DEBUG" ] ; then extra="--enable-debug" fi # build case "$OS" in freebsd*) freebsd "$extra" ;; alma*|centos*) rpm_build_and_install "--with-spec=redhat $extra" ;; fedora*) rpm_build_and_install "$extra" # Historically, we've always built the release tarballs on Fedora, since # there was one instance long ago where we built them on CentOS 7, and they # didn't work correctly for everyone. if [ -n "$TARBALL" ] ; then build_tarball fi ;; debian*|ubuntu*) deb_build_and_install "$extra" ;; *) linux "$extra" ;; esac # building the zfs module was ok echo 0 > /var/tmp/build-exitcode.txt # reset cloud-init configuration and poweroff if [ -n "$POWEROFF" ] ; then sudo cloud-init clean --logs sync && sleep 2 && sudo poweroff & fi exit 0 diff --git a/.github/workflows/zfs-qemu-packages.yml b/.github/workflows/zfs-qemu-packages.yml index 5b5afe746859..d8a95954fe1a 100644 --- a/.github/workflows/zfs-qemu-packages.yml +++ b/.github/workflows/zfs-qemu-packages.yml @@ -1,140 +1,151 @@ # This workflow is used to build and test RPM packages. It is a # 'workflow_dispatch' workflow, which means it gets run manually. # # The workflow has a dropdown menu with two options: # # Build RPMs - Build release RPMs and tarballs and put them into an artifact # ZIP file. The directory structure used in the ZIP file mirrors # the ZFS yum repo. # # Test repo - Test install the ZFS RPMs from the ZFS repo. On EL distos, this # will do a DKMS and KMOD test install from both the regular and # testing repos. On Fedora, it will do a DKMS install from the # regular repo. All test install results will be displayed in the # Summary page. Note that the workflow provides an optional text # text box where you can specify the full URL to an alternate repo. # If left blank, it will install from the default repo from the # zfs-release RPM (http://download.zfsonlinux.org). # # Most users will never need to use this workflow. It will be used primary by # ZFS admins for building and testing releases. # name: zfs-qemu-packages on: workflow_dispatch: inputs: test_type: type: choice required: false default: "Build RPMs" description: "Build RPMs or test the repo?" options: - "Build RPMs" - "Test repo" + patch_level: + type: string + required: false + default: "" + description: "(optional) patch level number" repo_url: type: string required: false default: "" description: "(optional) repo URL (blank: use http://download.zfsonlinux.org)" concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true jobs: zfs-qemu-packages-jobs: name: qemu-VMs strategy: fail-fast: false matrix: os: ['almalinux8', 'almalinux9', 'almalinux10', 'fedora41', 'fedora42'] 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 }} - name: Build modules or Test repo timeout-minutes: 30 run: | set -e if [ "${{ github.event.inputs.test_type }}" == "Test repo" ] ; then # Bring VM back up and copy over zfs source .github/workflows/scripts/qemu-prepare-for-build.sh mkdir -p /tmp/repo ssh zfs@vm0 '$HOME/zfs/.github/workflows/scripts/qemu-test-repo-vm.sh' ${{ github.event.inputs.repo_url }} else - .github/workflows/scripts/qemu-4-build.sh --repo --release --dkms --tarball ${{ matrix.os }} + EXTRA="" + if [ -n "${{ github.event.inputs.patch_level }}" ] ; then + EXTRA="--patch-level ${{ github.event.inputs.patch_level }}" + fi + + .github/workflows/scripts/qemu-4-build.sh $EXTRA \ + --repo --release --dkms --tarball ${{ matrix.os }} fi - name: Prepare artifacts if: always() timeout-minutes: 10 run: | rsync -a zfs@vm0:/tmp/repo /tmp || true .github/workflows/scripts/replace-dupes-with-symlinks.sh /tmp/repo tar -cf ${{ matrix.os }}-repo.tar -C /tmp repo - uses: actions/upload-artifact@v4 id: artifact-upload if: always() with: name: ${{ matrix.os }}-repo path: ${{ matrix.os }}-repo.tar compression-level: 0 retention-days: 2 if-no-files-found: ignore combine_repos: if: always() needs: [zfs-qemu-packages-jobs] name: "Results" runs-on: ubuntu-latest steps: - uses: actions/download-artifact@v4 id: artifact-download if: always() - name: Test Summary if: always() run: | for i in $(find . -type f -iname "*.tar") ; do tar -xf $i -C /tmp done tar -cf all-repo.tar -C /tmp repo # If we're installing from a repo, print out the summary of the versions # that got installed using Markdown. if [ "${{ github.event.inputs.test_type }}" == "Test repo" ] ; then cd /tmp/repo for i in $(ls *.txt) ; do nicename="$(echo $i | sed 's/.txt//g; s/-/ /g')" echo "### $nicename" >> $GITHUB_STEP_SUMMARY echo "|repo|RPM|URL|" >> $GITHUB_STEP_SUMMARY echo "|:---|:---|:---|" >> $GITHUB_STEP_SUMMARY awk '{print "|"$1"|"$2"|"$3"|"}' $i >> $GITHUB_STEP_SUMMARY done fi - uses: actions/upload-artifact@v4 id: artifact-upload2 if: always() with: name: all-repo path: all-repo.tar compression-level: 0 retention-days: 5 if-no-files-found: ignore