diff --git a/setup.sh b/setup.sh index 159e37f..00199b4 100644 --- a/setup.sh +++ b/setup.sh @@ -24,11 +24,17 @@ declare zpool_name zfs_arch_dataset_name zpool_name='zpool' zfs_arch_dataset_name='archlinux' +declare -A partition_types +partition_types[gpt_zfs]='6a85cf4d-1dd2-11b2-99a6-080020736631' +partition_types[gpt_efi]='c12a7328-f81f-11d2-ba4b-00a0c93ec93b' +partition_types[mbr_zfs]='0xbf' +partition_types[mbr_boot]='0x83' + # https://unix.stackexchange.com/a/48550 set -E trap '[ "$?" -ne 77 ] || exit 77' ERR -declare zpool_drive efi_drive +declare zpool_drive efi_drive part_schema function we_are_changerooted () { if [ "$(stat -c '%d:%i' '/')" != "$(stat -c '%d:%i' '/proc/1/root/.')" ]; then @@ -38,23 +44,51 @@ function we_are_changerooted () { fi } -function no_kernel_update_in_iso () { +function uefi_or_bios () { #1.1 + local part_count_linux part_count_efi + # Select disks with at least one partition. Among them count how many + # with the given partition type code we have. + part_count_linux="$(get_partitions | jq --raw-output '[.[][] | select(.children | length > 0) | .children[] | select(.parttype=="'"${partition_types[mbr_boot]}"'") | .path] | length')" + part_count_efi="$(get_partitions | jq --raw-output '[.[][] | select(.children | length > 0) | .children[] | select(.parttype=="'"${partition_types[gpt_efi]}"'") | .path] | length')" + if [[ "${part_count_linux}" -eq '1' ]] && [[ "${part_count_efi}" -eq '0' ]]; then + part_schema='mbr' + >&3 printf -- '%s\n' \ + 'Treating this as an MBR/legacy BIOS machine ...' + elif [[ "${part_count_linux}" -eq '0' ]] && [[ "${part_count_efi}" -eq '1' ]]; then + part_schema='gpt' + >&3 printf -- '%s\n' \ + 'Treating this as a GPT/UEFI machine ...' + else + >&3 printf -- '%s\n' \ + 'We are seeing partitions as follows:' \ + '- Partition type code '"${partition_types[mbr_boot]}"': '"${part_count_linux}" \ + '- Partition type code '"${partition_types[gpt_efi]}"': '"${part_count_efi}" \ + '' \ + 'We are instead expecting either 1 and 0 indicating a legacy' \ + 'BIOS setup or 0 and 1 indicating UEFI. '"${part_count_linux}"' and '"${part_count_efi}"' is' \ + 'neither. Cowardly exiting ...' + exit 77 + fi +} + +function no_kernel_update_in_iso () { + #1.2 sed -ri -e 's'$'\x1''#(IgnorePkg)[^\r\n\f]+'$'\x1''\1 = linux linux-headers'$'\x1''g' /etc/pacman.conf } function set_ntp () { - #1.2 + #1.3 timedatectl set-ntp true } function resize_cow_space () { - #1.3 + #1.4 mount -o remount,size='50%' /run/archiso/cowspace } function update_pacman_db () { - #1.4 + #1.5 printf -- '%s\n' 'Refreshing mirror list ...' systemctl start reflector # In an ISO and for the minimal number of packages we need we do not @@ -63,13 +97,13 @@ function update_pacman_db () { } function install_pkgs () { - #1.5 + #1.6 printf -- '%s\n' 'Installing packages ...' pacman -S --needed --noconfirm "${@}" } function install_zfs () { - #1.6 + #1.7 declare reset_colors='\033[0m' curl -s 'https://raw.githubusercontent.com/eoli3n/archiso-zfs/master/init' | bash printf -- "${reset_colors}" @@ -256,7 +290,7 @@ function export_pool () { } function setup_zpool () { - #1.7 + #1.8 local drive_by_id zpool_drive="$(select_part 'zfs')" drive_by_id="$(get_drive_id "${zpool_drive}")" @@ -276,7 +310,7 @@ function setup_zpool () { } function mount_system () { - #1.8 + #1.9 zfs mount "${zpool_name}"'/root/'"${zfs_arch_dataset_name}" zfs mount -a @@ -289,7 +323,7 @@ function mount_system () { } function copy_zpool_cache () { - #1.9 + #1.10 mkdir -p '/mnt/etc/zfs' zpool set 'cachefile=/etc/zfs/'"${zpool_name}"'.cache' "${zpool_name}" } @@ -309,7 +343,7 @@ function pacman_dont_check_space () { } function install_archlinux () { - #1.10 + #1.11 pacman_dl_parallel pacman_dont_check_space pacstrap /mnt \ @@ -336,7 +370,7 @@ function install_archlinux () { } function gen_fstab () { - #1.11 + #1.12 genfstab -U /mnt | grep -v "${zpool_name}" | tr -s '\n' | sed -r -e 's/\/mnt//' -e '/./,$!d' > '/mnt/etc/fstab' } @@ -349,7 +383,7 @@ EOF } function set_hostname () { - #1.12 + #1.13 declare new_hostname install_pkgs 'pwgen' new_hostname="$(pwgen --no-numerals --no-capitalize --ambiguous 8)" @@ -358,7 +392,7 @@ function set_hostname () { } function set_locale () { - #1.13 + #1.14 printf -- '%s\n' \ 'KEYMAP=de-latin1' \ 'FONT=Lat2-Terminus16' \ @@ -369,7 +403,7 @@ function set_locale () { } function add_zfs_hook_to_initramfs () { - #1.14 + #1.15 # Add zfs hook, remove fsck hook from initramfs. sed -ri \ -e 's'$'\x1''(HOOKS=)(.*?[\(| ])(filesystems)([\)| ][^\r\n\f]*)'$'\x1''\1\2zfs \3\4'$'\x1''g' \ @@ -384,7 +418,7 @@ function add_zfs_hook_to_initramfs () { } function set_initramfs_build_list () { - #1.15 + #1.16 # No need to build fallback initramfs, our new fallback is ZFS snapshots sed -ri \ -e '/^#/d' \ @@ -398,7 +432,7 @@ function set_initramfs_build_list () { } function add_zfs_files_to_new_os () { - #1.16 + #1.17 for zfs_file in '/etc/hostid' '/etc/zfs/zpool.cache' $([[ ! "${ARCHZBM_ZFSPROPS_NO_ENCRYPTION}" ]] && printf -- '%s' '/etc/zfs/'"${zpool_name}"'.key'); do rsync -av --itemize-changes {'','/mnt'}"${zfs_file}" done @@ -571,7 +605,11 @@ Kernel: CommandLine: ro loglevel=0 zbm.import_policy=hostid Prefix: vmlinuz EOF -# Up here maybe 'ro quiet' instead of 'ro' +# Up here maybe 'ro quiet' instead of 'ro'. This is ZFSBootMenu's kernel +# command line. + + # Assign cmdline for final kernel start. This is our Arch Linx kernel + # command line. zfs set org.zfsbootmenu:commandline='rw nowatchdog rd.vconsole.keymap=de-latin1' "${zpool_name}"'/root/'"${zfs_arch_dataset_name}" } @@ -752,22 +790,23 @@ function main () { if we_are_changerooted; then install_os_in_chroot #2.2 else - no_kernel_update_in_iso #1.1 - set_ntp #1.2 - resize_cow_space #1.3 - update_pacman_db #1.4 - install_pkgs 'jq' #1.5 - install_zfs #1.6 - setup_zpool #1.7 - mount_system #1.8 - copy_zpool_cache #1.9 - install_archlinux #1.10 - gen_fstab #1.11 - set_hostname #1.12 - set_locale #1.13 - add_zfs_hook_to_initramfs #1.14 - set_initramfs_build_list #1.15 - add_zfs_files_to_new_os #1.16 + uefi_or_bios #1.1 + no_kernel_update_in_iso #1.2 + set_ntp #1.3 + resize_cow_space #1.4 + update_pacman_db #1.5 + install_pkgs 'jq' #1.6 + install_zfs #1.7 + setup_zpool #1.8 + mount_system #1.9 + copy_zpool_cache #1.10 + install_archlinux #1.11 + gen_fstab #1.12 + set_hostname #1.13 + set_locale #1.14 + add_zfs_hook_to_initramfs #1.15 + set_initramfs_build_list #1.16 + add_zfs_files_to_new_os #1.17 enter_chroot #2.1 # We're done in chroot finalize_os_setup #3.1