#!/bin/bash # vim: softtabstop=2 shiftwidth=2 expandtab YAML=0 GENZBM=0 IMAGE=0 CONFD=0 DRACUT=0 MKINITCPIO=0 SIZE="5G" POOL_PREFIX="ztest" DISTROS=() # Dictionary for random pool names, provided by words-en dictfile="/usr/share/dict/words" usage() { cat <> "${TESTDIR}/dracut.conf.d/zfsbootmenu.conf" fi if ((DRACUT)) ; then if [ ! -d /usr/lib/dracut ]; then echo "ERROR: missing /usr/lib/dracut" exit 1 fi DRACUTBIN="$(command -v dracut)" if [ ! -x "${DRACUTBIN}" ]; then echo "ERROR: missing dracut script" exit 1 fi if [ ! -d "${TESTDIR}/dracut" ]; then echo "Creating local dracut tree" cp -a /usr/lib/dracut "${TESTDIR}" cp "${DRACUTBIN}" "${TESTDIR}/dracut" fi # Make sure the zfsbootmenu module is a link to the repo version _dracut_mods="${TESTDIR}/dracut/modules.d" test -d "${_dracut_mods}" && rm -rf "${_dracut_mods}/90zfsbootmenu" ln -s "$(realpath -e ../dracut)" "${_dracut_mods}/90zfsbootmenu" fi if ((MKINITCPIO)) ; then cat << EOF > "${TESTDIR}/mkinitcpio.conf" for snippet in $( realpath -e "${TESTDIR}" )/mkinitcpio.d/*.conf ; do source \${snippet} done EOF MKINITCPIOD="${TESTDIR}/mkinitcpio.d" mkdir -p "${MKINITCPIOD}" cat << EOF > "${MKINITCPIOD}/base.conf" MODULES=() BINARIES=() FILEs=() HOOKS=(base udev autodetect modconf block filesystems keyboard) COMPRESSION="cat" EOF cat << EOF > "${MKINITCPIOD}/modroot.conf" zfsbootmenu_module_root="$( realpath -e ../zfsbootmenu )" EOF fi if ((GENZBM)) ; then rm -f "${TESTDIR}/generate-zbm" ln -s "$(realpath -e ../bin/generate-zbm)" "${TESTDIR}/generate-zbm" fi # Setup a local config file if ((YAML)) ; then echo "Configuring local.yaml" yamlconf="${TESTDIR}/local.yaml" STUBS="$(realpath -e stubs)" cp ../etc/zfsbootmenu/config.yaml "${yamlconf}" yq-go eval ".Components.ImageDir = \"${TESTDIR}\"" -i "${yamlconf}" yq-go eval ".Components.Versions = false" -i "${yamlconf}" yq-go eval ".EFI.ImageDir = \"${TESTDIR}\"" -i "${yamlconf}" yq-go eval ".EFI.Versions = false" -i "${yamlconf}" yq-go eval ".EFI.Stub = \"${STUBS}/linuxx64.efi.stub\"" -i "${yamlconf}" yq-go eval ".Global.ManageImages = true" -i "${yamlconf}" yq-go eval ".Global.DracutConfDir = \"${TESTDIR}/dracut.conf.d\"" -i "${yamlconf}" yq-go eval ".Global.PreHooksDir = \"${TESTDIR}/generate-zbm.pre.d\"" -i "${yamlconf}" yq-go eval ".Global.PostHooksDir = \"${TESTDIR}/generate-zbm.post.d\"" -i "${yamlconf}" yq-go eval ".Global.InitCPIOConfig = \"${TESTDIR}/mkinitcpio.conf\"" -i "${yamlconf}" yq-go eval ".Global.InitCPIOHookDirs = [ \"$( realpath -e ../initcpio )\",\"/usr/lib/initcpio\" ]" -i "${yamlconf}" yq-go eval ".Global.DracutFlags = [ \"--local\" ]" -i "${yamlconf}" yq-go eval "del(.Global.BootMountPoint)" -i "${yamlconf}" yq-go eval -P -C "${yamlconf}" fi # seed our initial pool name attempt if ((RANDOM_NAME)); then POOL_NAME="$( random_name )" else POOL_NAME="${POOL_PREFIX}" idx=0 fi while [ -z "${EXISTING_POOL}" ]; do # Check that a file doesn't exist with this name, or that # a currently-imported pool doesn't have this name if [ ! -r "${TESTDIR}/${POOL_NAME}-pool.img" ] \ && ! zpool list -o name -H "${POOL_NAME}" >/dev/null 2>&1 then break fi # Generate a new random name / bump the index if ((RANDOM_NAME)); then POOL_NAME="$( random_name )" else idx=$(( idx + 1 )) POOL_NAME="$( printf "${POOL_PREFIX}-%02d" "${idx}" )" fi done echo "Generated pool name: ${POOL_NAME}" if ((INCLUDE_KEYS)); then # ssh-keygen expects to dump into ${PREFIX}/etc/ssh mkdir -p ./keys/etc/ssh # Generate any missing keys ssh-keygen -A -f ./keys # Copy authorized keys for convenience if [ -r "${HOME}/.ssh/authorized_keys" ] && [ ! -r ./keys/authorized_keys ]; then cp "${HOME}/.ssh/authorized_keys" ./keys/ fi fi # Create image(s) for each specified distro if ((IMAGE)); then for DISTRO in "${DISTROS[@]}"; do IMAGE_SCRIPT="./helpers/image-${DISTRO}.sh" if [ ! -x "${IMAGE_SCRIPT}" ]; then IMAGE_SCRIPT="./helpers/image.sh" fi if command -v doas >/dev/null 2>&1; then SUDO=doas elif command -v sudo >/dev/null 2>&1; then SUDO=sudo else echo "ERROR: unable to elevate user privileges, install sudo or doas" exit 1 fi "${SUDO}" unshare --fork --pid --mount env \ ENCRYPT="${ENCRYPT}" \ LEGACY_POOL="${LEGACY_POOL}" \ EXISTING_POOL="${EXISTING_POOL}" \ PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin" \ "${IMAGE_SCRIPT}" "${TESTDIR}" "${SIZE}" "${DISTRO}" "${POOL_NAME}" # All subsequent distros use the same pool EXISTING_POOL=1 done fi