diff --git a/setup.sh b/setup.sh index 6d3391b..5ec2e97 100644 --- a/setup.sh +++ b/setup.sh @@ -18,7 +18,6 @@ exec 3>&1 declare this_script_url this_script_url="${SCRIPT_URL:?}" -postconf_hook="$(dirname "${this_script_url}")"'/zbm_set_new_uefi_boot_entries.sh' declare zpool_name zfs_arch_dataset_name zpool_name='zpool' @@ -658,13 +657,11 @@ function configure_zfsbootmenu () { paru_install 'zfsbootmenu' if [[ "${part_schema}" = 'gpt' ]]; then - mkdir -p '/etc/zfsbootmenu/posthooks.d' cat > '/etc/zfsbootmenu/config.yaml' <&3 echo 'A log message' -# } -# -# var="$(my_func arg_1)" -# -# Here "${var}" will only capture the output of some_command "${1:?}". It -# will not capture 'echo' which will instead show up on our stdout/FD 1. -exec 3>&1 - -# https://unix.stackexchange.com/a/48550 -set -E -trap '[ "$?" -ne 77 ] || exit 77' ERR - -function get_partitions () { - declare partitions_json - partitions_json="$(lsblk --output PATH,PARTTYPE --json --tree)" || return 1 - printf -- '%s' "${partitions_json}" - return 0 -} - -function get_parts () { - local zfs_install_drive - declare parttype parts - parttype="${1:?}" - zfs_install_drive="${2:-}" - case "${parttype}" in - zfs) - parts="$(get_partitions | jq --raw-output '.[][] | select(.children | length > 0) | .children[] | select(.parttype=="6a85cf4d-1dd2-11b2-99a6-080020736631") | .path')" || exit 1 - ;; - efi) - parts="$(get_partitions | jq --raw-output '.[][] | select(.children | length > 0) | select(.path=="'"${zfs_install_drive:?}"'") | .children[] | select(.parttype=="c12a7328-f81f-11d2-ba4b-00a0c93ec93b") | .path')" || exit 1 - ;; - *) - >&3 printf -- '%s\n' 'Unknown partition type '"'"'"${parttype}"'"'"', exiting ...' - exit 77 - ;; - esac - printf -- '%s' "${parts}" - return 0 -} - -function we_have_exactly_one_part () { - local parttype parts_list parts_count - parttype="${1:?}" - parts_list="${2:?}" - parts_count="$(wc -l <<<"${parts_list}")" - if [[ "$(wc -c <<<"${parts_list}")" -gt '1' ]]; then - case "${parts_count}" in - 0) - >&3 printf -- '%s\n' 'No '"${parttype^^}"' partition found. Exiting ...' - exit 77 - ;; - 1) - return 0 - ;; - *) - return 1 - ;; - esac - >&3 printf -- '%s\n' 'Partition list does not look valid. Cowardly exiting ...' - exit 77 - fi -} - -function select_part () { - local parts enriched_parts enriched_parts_count part_number part_type zfs_install_drive - declare part - part_type="${1:?}" # 'efi' or 'zfs' - zfs_install_drive="${2:-}" - if [[ "${zfs_install_drive}" ]]; then - # This is intended to find correct EFI partition - parts="$(get_parts "${part_type}" "${zfs_install_drive}")" - else - parts="$(get_parts "${part_type}")" - fi - - if [[ ! "${parts}" ]]; then - case "${part_type}" in - efi) - part_type_human_readable='EFI system partition (ESP) with partition type code EF00' - ;; - zfs) - part_type_human_readable='ZFS zpool partition with partition type code BF00' - ;; - esac - >&3 printf -- '%s\n' \ - 'It looks as if there is no '"${part_type_human_readable}" \ - 'on any of the disks. Is this a chroot? Exiting ...' - exit 77 - fi - - if we_have_exactly_one_part "${part_type}" "${parts}"; then - part="${parts}" - else - >&3 printf -- '%s\n' 'More than one '"${part_type^^}"' partition to pick for installation. Cowardly exiting ...' - exit 77 - fi - printf -- '%s' "${part}" - return 0 -} - -function get_part_parent () { - local child_partition parent_partition - child_partition="${1:?}" - parent_partition="$(get_partitions | jq --raw-output '.[][] | select(.children | length > 0) | select(.children[].path=="'"${child_partition:?}"'") | .path')" - printf -- '%s' "${parent_partition}" - return 0 -} - -function get_disks_with_one_efipart () { - local disks_with_one_efipart - # Find disks that have exactly one EFI partition and where that EFI - # partition is partition number 1. We expect exactly one disk to meet - # these criteria. Anything else and we bail. - disks_with_one_efipart="$(lsblk --output PATH,PARTTYPE --json --tree | jq --raw-output '.[][] | select(.children | length > 0) | select( any (.children[]; (.path | test("^[^[:digit:]]+1")) and (.parttype=="c12a7328-f81f-11d2-ba4b-00a0c93ec93b")) and ([select(.children[].parttype=="c12a7328-f81f-11d2-ba4b-00a0c93ec93b")] | length == 1) ) | .path')" - if [[ "$(wc -l <<<"${disks_with_one_efipart}")" -eq '1' ]] && [[ "$(wc -c <<<"${disks_with_one_efipart}")" -gt '1' ]]; then - printf -- '%s' "${disks_with_one_efipart}" - return 0 - fi - return 1 -} - -function set_new_uefi_boot_entries () { - declare -a uefi_images - mapfile -t uefi_images < \ - <(find '/efi/EFI/ZBM' -type f -iname '*.efi' -print0 | \ - xargs -0 --no-run-if-empty --max-args '1' stat -c '%Y %n' | \ - sort -V | \ - awk '{print $2}') - zpool_drive="$(select_part 'zfs')" - zfs_parent="$(get_part_parent "${zpool_drive:?}")" - efi_drive="${zfs_parent}" - - if efibootmgr | grep -Piq -- 'ZFSBootMenu'; then - local -a old_uefi_entries - mapfile -t old_uefi_entries < \ - <(efibootmgr | \ - grep -Pio -- '(?<=^Boot)[^\*[:space:]]+(?=\*? ZFSBootMenu)') - for old_uefi_entry in "${old_uefi_entries[@]}"; do - efibootmgr --bootnum "${old_uefi_entry}" --delete-bootnum &>/dev/null && { - >&3 printf -- '%s\n' \ - 'EFI boot entry '"${old_uefi_entry}"' deleted.' - } - done - fi - - if ! efibootmgr | grep -Piq -- 'ZFSBootMenu'; then - local efi_disks_list - efi_disks_list="$(get_disks_with_one_efipart)" - if grep -Piq -- '^'"${efi_drive}"'$' <<<"${efi_disks_list}"; then - for uefi_image in "${uefi_images[@]}"; do - uefi_image_version="$(basename "${uefi_image%%.EFI}")" - uefi_image_inverted="${uefi_image#/efi}" - uefi_image_inverted="${uefi_image_inverted//\//\\}" - efibootmgr --disk "${efi_drive}" \ - --part 1 \ - --create \ - --label 'ZFSBootMenu '"${uefi_image_version}" \ - --loader "${uefi_image_inverted}" &>/dev/null && { - >&3 printf -- '%s\n' \ - 'EFI boot entry ZFSBootMenu '"${uefi_image_version}"' added.' - } - done - fi - fi -} - -set_new_uefi_boot_entries