xref: /freebsd/sys/contrib/openzfs/.github/workflows/scripts/qemu-3-deps-vm.sh (revision 34f9f5680c9d5d5138e427ba3aeab0138cec3882)
1#!/usr/bin/env bash
2
3######################################################################
4# 3) install dependencies for compiling and loading
5#
6# qemu-3-deps-vm.sh [--poweroff] OS_NAME [FEDORA_VERSION]
7#
8# --poweroff: Power off the VM after installing dependencies
9# OS_NAME: OS name (like 'fedora41')
10# FEDORA_VERSION: (optional) Experimental Fedora kernel version, like "6.14" to
11#     install instead of Fedora defaults.
12######################################################################
13
14set -eu
15
16function alpine() {
17  echo "##[group]Install Development Tools"
18  sudo apk add \
19    acl alpine-sdk attr autoconf automake bash build-base clang22 coreutils \
20    cpio cryptsetup curl curl-dev dhcpcd diffutils eudev eudev-dev eudev-libs \
21    findutils fio gawk gdb gettext-dev git grep jq libaio libaio-dev \
22    libcap-utils libcurl libtirpc-dev libtool libunwind libunwind-dev \
23    linux-headers linux-tools linux-stable linux-stable-dev lsscsi m4 make \
24    nfs-utils openssl-dev parted pax procps py3-cffi py3-distlib py3-packaging \
25    py3-setuptools python3 python3-dev qemu-guest-agent rng-tools rsync samba \
26    samba-server sed strace sysstat tzdata util-linux util-linux-dev wget \
27    words xfsprogs xxhash zlib-dev pamtester@testing
28  echo "##[endgroup]"
29
30  echo "##[group]Switch to eudev"
31  sudo setup-devd udev
32  echo "##[endgroup]"
33
34  echo "##[group]Boot the -stable kernel instead of -virt"
35  # -virt has CONFIG_SCSI_DEBUG disabled, which several ZTS tests
36  # (zpool_expand, zpool_reopen, fault/auto_*, ...) need to simulate
37  # disks that support expand/fault-injection scenarios real static
38  # disks can't easily provide.  -stable has it enabled.  This takes
39  # effect on the VM's next boot, which happens naturally when this
40  # deps step powers off and qemu-prepare-for-build.sh starts the VM
41  # back up for the build step -- no explicit reboot needed here.
42  sudo sed -i 's/^default=virt$/default=stable/' /etc/update-extlinux.conf
43  sudo update-extlinux
44  echo "##[endgroup]"
45
46  echo "##[group]Install ksh93 from Source"
47  # Build the actively-maintained "1.0" branch instead of the
48  # default "dev" branch for a reproducible, stable build.
49  git clone --depth 1 --branch 1.0 https://github.com/ksh93/ksh.git /tmp/ksh
50  cd /tmp/ksh
51  ./bin/package make
52  sudo ./bin/package install /
53  echo "##[endgroup]"
54}
55
56function archlinux() {
57  echo "##[group]Running pacman -Syu"
58  sudo btrfs filesystem resize max /
59  sudo pacman -Syu --noconfirm
60  echo "##[endgroup]"
61
62  echo "##[group]Install Development Tools"
63  sudo pacman -Sy --noconfirm base-devel bc cpio cryptsetup dhclient dkms \
64    fakeroot fio gdb inetutils jq less linux linux-headers lsscsi nfs-utils \
65    parted pax perf python-packaging python-setuptools qemu-guest-agent ksh \
66    samba strace sysstat rng-tools rsync wget xxhash
67  echo "##[endgroup]"
68}
69
70function debian() {
71  export DEBIAN_FRONTEND="noninteractive"
72
73  echo "##[group]Wait for cloud-init to finish"
74  cloud-init status --wait
75  echo "##[endgroup]"
76
77  echo "##[group]Running apt-get update+upgrade"
78  sudo sed -i '/[[:alpha:]]-backports/d' /etc/apt/sources.list
79  sudo apt-get update -y
80  sudo apt-get upgrade -y
81  echo "##[endgroup]"
82
83  echo "##[group]Install Development Tools"
84  sudo apt-get install -y \
85    acl alien attr autoconf bc cpio cryptsetup curl dbench dh-python dkms \
86    fakeroot fio gdb gdebi git ksh lcov isc-dhcp-client jq libacl1-dev \
87    libaio-dev libattr1-dev libblkid-dev libcurl4-openssl-dev libdevmapper-dev \
88    libelf-dev libffi-dev libmount-dev libpam0g-dev libselinux-dev libssl-dev \
89    libtool libtool-bin libudev-dev libunwind-dev linux-headers-$(uname -r) \
90    lsscsi nfs-kernel-server pamtester parted python3 python3-all-dev \
91    python3-cffi python3-dev python3-distlib python3-packaging libtirpc-dev \
92    python3-setuptools python3-sphinx qemu-guest-agent rng-tools rpm2cpio \
93    rsync samba strace sysstat uuid-dev watchdog wget xfslibs-dev xxhash \
94    zlib1g-dev
95  echo "##[endgroup]"
96}
97
98function freebsd() {
99  export ASSUME_ALWAYS_YES="YES"
100
101  echo "##[group]Install Development Tools"
102  sudo pkg install -y autoconf automake autotools base64 checkbashisms fio \
103    gdb gettext gettext-runtime git gmake gsed jq ksh lcov libtool lscpu \
104    pkgconf python python3 pamtester pamtester qemu-guest-agent rsync xxhash
105  sudo pkg install -xy \
106    '^samba4[[:digit:]]+$' \
107    '^py3[[:digit:]]+-cffi$' \
108    '^py3[[:digit:]]+-sysctl$' \
109    '^py3[[:digit:]]+-setuptools$' \
110    '^py3[[:digit:]]+-packaging$'
111  echo "##[endgroup]"
112}
113
114# common packages for: almalinux, centos, redhat
115function rhel() {
116  echo "##[group]Running dnf update"
117  echo "max_parallel_downloads=10" | sudo -E tee -a /etc/dnf/dnf.conf
118  sudo dnf clean all
119  sudo dnf update -y --setopt=fastestmirror=1 --refresh
120  echo "##[endgroup]"
121
122  echo "##[group]Install Development Tools"
123
124  # Alma wants "Development Tools", Fedora 41 wants "development-tools"
125  if ! sudo dnf group install -y "Development Tools" ; then
126    echo "Trying 'development-tools' instead of 'Development Tools'"
127    sudo dnf group install -y development-tools
128  fi
129
130  sudo dnf install -y \
131    acl attr bc bzip2 cryptsetup curl dbench dkms elfutils-libelf-devel fio \
132    gdb git jq kernel-rpm-macros ksh libacl-devel libaio-devel \
133    libargon2-devel libattr-devel libblkid-devel libcurl-devel libffi-devel \
134    ncompress libselinux-devel libtirpc-devel libtool libudev-devel \
135    libuuid-devel lsscsi mdadm nfs-utils openssl-devel pam-devel pamtester \
136    parted perf python3 python3-cffi python3-devel python3-packaging \
137    kernel-devel python3-setuptools qemu-guest-agent rng-tools rpcgen \
138    rpm-build rsync samba strace sysstat systemd watchdog wget xfsprogs-devel \
139    xxhash zlib-devel
140
141  # These are needed for building Lustre.  We only install these on EL VMs since
142  # we don't plan to test build Lustre on other platforms.
143  sudo dnf install -y libnl3-devel libyaml-devel libmount-devel
144
145  echo "##[endgroup]"
146}
147
148function tumbleweed() {
149  echo "##[group]Running zypper is TODO!"
150  sleep 23456
151  echo "##[endgroup]"
152}
153
154# $1: Kernel version to install (like '6.14rc7')
155function install_fedora_experimental_kernel {
156
157  our_version="$1"
158  sudo dnf -y copr enable @kernel-vanilla/stable
159  sudo dnf -y copr enable @kernel-vanilla/mainline
160  all="$(sudo dnf list --showduplicates kernel-* python3-perf* perf* bpftool*)"
161  echo "Available versions:"
162  echo "$all"
163
164  # You can have a bunch of minor variants of the version we want '6.14'.
165  # Pick the newest variant (sorted by version number).
166  specific_version=$(echo "$all" | grep $our_version | awk '{print $2}' | sort -V | tail -n 1)
167  list="$(echo "$all" | grep $specific_version | grep -Ev 'kernel-rt|kernel-selftests|kernel-debuginfo' | sed 's/.x86_64//g' | awk '{print $1"-"$2}')"
168  sudo dnf install -y $list
169  sudo dnf -y copr disable @kernel-vanilla/stable
170  sudo dnf -y copr disable @kernel-vanilla/mainline
171}
172
173POWEROFF=""
174if [ "$1" == "--poweroff" ] ; then
175        POWEROFF=1
176        shift
177fi
178
179# Install dependencies
180case "$1" in
181  almalinux8)
182    echo "##[group]Enable epel and powertools repositories"
183    sudo dnf config-manager -y --set-enabled powertools
184    sudo dnf install -y epel-release
185    echo "##[endgroup]"
186    rhel
187    echo "##[group]Install kernel-abi-whitelists"
188    sudo dnf install -y kernel-abi-whitelists
189    echo "##[endgroup]"
190    ;;
191  almalinux9|almalinux10|centos-stream9|centos-stream10)
192    echo "##[group]Enable epel and crb repositories"
193    sudo dnf config-manager -y --set-enabled crb
194    sudo dnf install -y epel-release
195    echo "##[endgroup]"
196    rhel
197    echo "##[group]Install kernel-abi-stablelists"
198    sudo dnf install -y kernel-abi-stablelists
199    echo "##[endgroup]"
200    ;;
201  alpine*)
202    alpine
203    ;;
204  archlinux)
205    archlinux
206    ;;
207  debian*)
208    echo 'debconf debconf/frontend select Noninteractive' | sudo debconf-set-selections
209    debian
210    echo "##[group]Install Debian specific"
211    sudo apt-get install -yq linux-perf dh-sequence-dkms
212    echo "##[endgroup]"
213    ;;
214  fedora*)
215    rhel
216    sudo dnf install -y libunwind-devel
217
218    # Fedora 42+ moves /usr/bin/script from 'util-linux' to 'util-linux-script'
219    sudo dnf install -y util-linux-script || true
220
221    # Optional: Install an experimental kernel ($2 = kernel version)
222    if [ -n "${2:-}" ] ; then
223      install_fedora_experimental_kernel "$2"
224    fi
225    ;;
226  freebsd*)
227    freebsd
228    ;;
229  tumbleweed)
230    tumbleweed
231    ;;
232  ubuntu22|ubuntu24)
233    debian
234    echo "##[group]Install Ubuntu specific"
235    sudo apt-get install -yq linux-tools-common libtirpc-dev \
236      linux-modules-extra-$(uname -r)
237    sudo apt-get install -yq dh-sequence-dkms
238
239    # Need 'build-essential' explicitly for ARM builder
240    # https://github.com/actions/runner-images/issues/9946
241    sudo apt-get install -yq build-essential
242
243    echo "##[endgroup]"
244    echo "##[group]Delete Ubuntu OpenZFS modules"
245    for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
246    echo "##[endgroup]"
247    ;;
248  ubuntu26)
249    debian
250    echo "##[group]Install Ubuntu specific"
251    # Skip linux-modules-extra which is already installed
252    sudo apt-get install -yq linux-tools-common
253    sudo apt-get install -yq libtirpc-dev
254    sudo apt-get install -yq dh-sequence-dkms
255
256    # Need 'build-essential' explicitly for ARM builder
257    # https://github.com/actions/runner-images/issues/9946
258    sudo apt-get install -yq build-essential
259
260    # Replace sudo-rs with sudo for now because the Rust version
261    # does not support -E to preserve the entire environment
262    sudo update-alternatives --set sudo /usr/bin/sudo.ws
263
264    echo "##[endgroup]"
265    echo "##[group]Delete Ubuntu OpenZFS modules"
266    for i in $(find /lib/modules -name zfs -type d); do sudo rm -rvf $i; done
267    echo "##[endgroup]"
268    ;;
269esac
270
271# This script is used for checkstyle + zloop deps also.
272# Install only the needed packages and exit - when used this way.
273test -z "${ONLY_DEPS:-}" || exit 0
274
275# Start services
276echo "##[group]Enable services"
277case "$1" in
278  alpine*)
279    sudo -E rc-update add qemu-guest-agent
280    sudo -E rc-update add nfs
281    sudo -E rc-update add samba
282    sudo -E rc-update add dhcpcd
283    # Remove services related to cloud-init.
284    sudo -E rc-update del cloud-init-local boot
285    sudo -E rc-update del cloud-init default
286    sudo -E rc-update del cloud-final default
287    sudo -E rc-update del cloud-config default
288    ;;
289  freebsd*)
290    # add virtio things
291    echo 'virtio_load="YES"' | sudo -E tee -a /boot/loader.conf
292    for i in balloon blk console random scsi; do
293      echo "virtio_${i}_load=\"YES\"" | sudo -E tee -a /boot/loader.conf
294    done
295    echo "fdescfs /dev/fd fdescfs rw 0 0" | sudo -E tee -a /etc/fstab
296    sudo -E mount /dev/fd
297    sudo -E touch /etc/zfs/exports
298    sudo -E sysrc mountd_flags="/etc/zfs/exports"
299    echo '[global]' | sudo -E tee /usr/local/etc/smb4.conf >/dev/null
300    sudo -E service nfsd enable
301    sudo -E service qemu-guest-agent enable
302    sudo -E service samba_server enable
303    ;;
304  debian*|ubuntu*)
305    sudo -E systemctl enable nfs-kernel-server
306    sudo -E systemctl enable smbd
307
308    # enable usershares (disabled by default on ubuntu 26.04)
309    sudo -E sed -i '/usershare max shares/s/^#//' /etc/samba/smb.conf
310
311    # add systemd drop-in to allow the service to be enabled
312    sudo -E mkdir -p /etc/systemd/system/qemu-guest-agent.service.d/
313    sudo -E tee /etc/systemd/system/qemu-guest-agent.service.d/override.conf <<EOF
314[Install]
315WantedBy=multi-user.target
316EOF
317    sudo -E systemctl daemon-reload
318    sudo -E systemctl enable qemu-guest-agent
319    ;;
320  *)
321    # All other linux distros
322    sudo -E systemctl enable nfs-server
323    sudo -E systemctl enable qemu-guest-agent
324    sudo -E systemctl enable smb
325    ;;
326esac
327echo "##[endgroup]"
328
329# Setup Kernel cmdline
330CMDLINE="console=tty0 console=ttyS0,115200n8"
331CMDLINE="$CMDLINE selinux=0"
332CMDLINE="$CMDLINE random.trust_cpu=on"
333CMDLINE="$CMDLINE no_timer_check"
334case "$1" in
335  almalinux*|centos*|fedora*)
336    GRUB_CFG="/boot/grub2/grub.cfg"
337    GRUB_MKCONFIG="grub2-mkconfig"
338    CMDLINE="$CMDLINE biosdevname=0 net.ifnames=0"
339    echo 'GRUB_SERIAL_COMMAND="serial --speed=115200"' \
340      | sudo tee -a /etc/default/grub >/dev/null
341    # Force GRUB itself onto the serial console.  These VMs have no display,
342    # and without this grub2-mkconfig can emit 'terminal_output gfxterm',
343    # which leaves GRUB stuck before the kernel starts on a headless VM.
344    sudo sed -i -e '/^GRUB_TERMINAL_INPUT/d' -e '/^GRUB_TERMINAL_OUTPUT/d' /etc/default/grub
345    echo 'GRUB_TERMINAL_INPUT="serial console"' | sudo tee -a /etc/default/grub >/dev/null
346    echo 'GRUB_TERMINAL_OUTPUT="serial console"' | sudo tee -a /etc/default/grub >/dev/null
347    ;;
348  ubuntu24|ubuntu26)
349    GRUB_CFG="/boot/grub/grub.cfg"
350    GRUB_MKCONFIG="grub-mkconfig"
351    echo 'GRUB_DISABLE_OS_PROBER="false"' \
352      | sudo tee -a /etc/default/grub >/dev/null
353    ;;
354  *)
355    GRUB_CFG="/boot/grub/grub.cfg"
356    GRUB_MKCONFIG="grub-mkconfig"
357    ;;
358esac
359
360case "$1" in
361  alpine*|archlinux|freebsd*)
362    true
363    ;;
364  *)
365    echo "##[group]Edit kernel cmdline"
366    sudo sed -i -e '/^GRUB_CMDLINE_LINUX/d' /etc/default/grub || true
367    echo "GRUB_CMDLINE_LINUX=\"$CMDLINE\"" \
368      | sudo tee -a /etc/default/grub >/dev/null
369    sudo $GRUB_MKCONFIG -o $GRUB_CFG
370    echo "##[endgroup]"
371    ;;
372esac
373
374# reset cloud-init configuration and poweroff
375sudo cloud-init clean --logs
376if [ "$POWEROFF" == "1" ] ; then
377        sleep 2 && sudo poweroff &
378fi
379exit 0
380