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