#!/usr/bin/bash # vim:ft=sh:fdm=marker:fmr={,} # archlabs installer library script file # this file is not meant to be run directly # sourcing this file in a non bash shell is not advised # shellcheck disable=2154,2153,2046 # set -n readonly SYS_MEM="$(awk '/MemTotal/ {print int($2 / 1024)"M"}' /proc/meminfo)" readonly SALT="$(tr -dc 'a-zA-Z0-9' < /dev/urandom | fold -w 32 | head -n 1)" readonly LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if($1) print $1 " -"}' /etc/locale.gen)" readonly CMAPS="$(find /usr/share/kbd/keymaps -name '*.map.gz' | awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " -"}')" mount_install_partitions() { # prepare partition list PARTS for dialog lvm_detect unmount_install_partitions find_partitions 'part|lvm|crypt' || return 1 # remove boot partition from dialog list if we auto partitioned one [[ $BOOT_PART != "" ]] && decr_count "$BOOT_PART" select_root_partition || return 1 if [[ $BOOT_PART ]]; then infobox "$_PrepMount" "\nUsing boot partition: $BOOT_PART\n" 1 elif [[ $SYS == "UEFI" ]]; then select_efi_partition || { BOOT_PART=""; return 1; } elif (( COUNT > 0 )); then select_boot_partition || { BOOT_PART=""; return 1; } fi select_boot_setup || { BOOTLDR=""; return 1; } select_swap || return 1 select_extra_partitions || return 1 return 0 } unmount_install_partitions() { swapoff -a umount -R $MNT # >/dev/null 2>&1 } select_swap() { # Ask user to select partition or create swapfile tput civis if ! SWAP_PART="$(dialog --backtitle "$BT" --cr-wrap --stdout --title " $_SelSwpSetup " \ --menu "$_SelSwpBody" 0 0 0 "$_SelSwpNone" "-" "$_SelSwpFile" "$SYS_MEM" $PARTS)" || [[ $SWAP_PART == "$_SelSwpNone" ]]; then SWAP_PART=""; return 0 fi if [[ $SWAP_PART == "$_SelSwpFile" ]]; then tput cnorm if ! SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "$SYS_MEM")"; then SWAP_PART=""; SWAP_SIZE=""; return 0 fi while ! [[ ${SWAP_SIZE:0:1} =~ [1-9] && ${SWAP_SIZE: -1} =~ (M|G) ]]; do msgbox "$_SelSwpSetup Error" "\n$_SelSwpErr $SWAP_SIZE\n" if ! SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "$SYS_MEM")"; then SWAP_PART=""; SWAP_SIZE=""; break; return 0 fi done enable_swap "$MNT/swapfile" SWAP_PART="/swapfile" else enable_swap "$SWAP_PART" decr_count "$SWAP_PART" SWAP_SIZE="$(lsblk -lno SIZE $SWAP_PART)" fi return 0 } select_mountpoint() { tput cnorm if ! EXTRA_MNT="$(getinput "$_PrepMount $part" "$_ExtPartBody1 /home /var\n" "/")"; then return 1 fi # bad mountpoint if [[ ${EXTRA_MNT:0:1} != "/" || ${#EXTRA_MNT} -le 1 || $EXTRA_MNT =~ \ |\' ]]; then msgbox "$_ErrTitle" "$_ExtErrBody" select_mountpoint || return 1 fi return 0 } select_boot_setup() { # choose bootloader and mountpoint (if needed) tput civis if ! BOOTLDR="$(dialog --cr-wrap --stdout --backtitle "$BT" \ --title " $_PrepMount " --menu "$_MntBootBody" 0 0 0 ${BOOTLDRS[$SYS]})"; then return 1 fi # grub on BIOS needs an install device, NOT partition eg. /dev/sda if [[ $SYS == 'BIOS' && $BOOTLDR == 'grub' && $BOOT_DEVICE == "" ]]; then select_device 'boot' || return 1 fi if [[ $BOOTLDR == 'systemd-boot' ]]; then FILES[9]="/boot/loader/entries/$DIST.conf" elif [[ $BOOTLDR == 'syslinux' ]]; then if [[ $SYS == 'BIOS' ]]; then FILES[9]="/boot/syslinux/syslinux.cfg" if ! BCMDS[$BOOTLDR]="$(dialog --cr-wrap --stdout --backtitle "$BT" \ --title " $_InstSysTitle " --menu "$_InstSysBody" 0 0 0 \ "syslinux-install_update -iam" "Install to MBR (Master Boot Record)" \ "syslinux-install_update -i" "Install to root partition (/)")"; then return 1 fi else FILES[9]="/boot/EFI/syslinux/syslinux.cfg" BCMDS[syslinux]="efibootmgr -c -d $BOOT_DEVICE -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST" fi else export FILES[9]="/etc/default/grub" if [[ $SYS == 'UEFI' ]]; then local ttype="i386-efi" [[ $IS_64BIT == true ]] && ttype='x86_64-efi' BCMDS[grub]+=" --target=$ttype --bootloader-id=$DIST" else BCMDS[grub]+=" --target=i386-pc $BOOT_DEVICE" fi BCMDS[grub]+=" && grub-mkconfig -o /boot/grub/grub.cfg" fi if [[ $BOOT_PART != "" ]]; then infobox "$_PrepMount" "\nSetting up for the bootloader and mounting the boot partition.\n" 1 setup_boot_device mount_partition "$BOOT_PART" "${BMNTS[$SYS-$BOOTLDR]}" || { src /usr/share/archlabs/installer/lib/boot.sh ; return 1; } export SEPERATE_BOOT=true fi return 0 } select_mount_opts() { local part="$1" local fs="$2" local title="${fs^} Mount Options" local opts opts="${FS_OPTS[$fs]}" ssd "$part" && opts=$(sed 's/discard - off/discard - on/' <<< "$opts") tput civis if ! MNT_OPTS="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $title " \ --checklist "$_MntBody" 0 0 0 $opts | sed 's/ /,/g; $s/,$//')"; then return 1 fi if ! yesno "$title" "$_MntConfBody $MNT_OPTS\n"; then select_mount_opts "$part" "$fs" || return 1 fi return 0 } select_filesystem() { local part="$1" local cur_fs str cur_fs="$(lsblk -lno FSTYPE $part)" str="$([[ $cur_fs && $part != "$ROOT_PART" ]] && printf "\nExisting Filesystem: %s" "$cur_fs")" tput civis local fs fs="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_FSTitle: $part " \ --menu "\nSelect which filesystem you want to use for $part\n\nPartition Name: ${part}${str}$_FSBody" 0 0 0 \ $([[ $cur_fs && $part != "$ROOT_PART" ]] && printf "%s" "$_Skip -") \ "ext4" "${FS_CMDS[ext4]}" "ext3" "${FS_CMDS[ext3]}" \ "ext2" "${FS_CMDS[ext2]}" "vfat" "${FS_CMDS[vfat]}" \ "ntfs" "${FS_CMDS[ntfs]}" "f2fs" "${FS_CMDS[f2fs]}" \ "jfs" "${FS_CMDS[jfs]}" "nilfs2" "${FS_CMDS[nilfs2]}" \ "reiserfs" "${FS_CMDS[reiserfs]}" "xfs" "${FS_CMDS[xfs]}")" [[ $fs == "$_Skip" ]] && return 0 || { [[ $fs == "" ]] && return 1; } if yesno "$_FSTitle" "\nFormat $part as $fs?\n"; then format $part $fs else select_filesystem $part || return 1 fi return 0 } select_efi_partition() { tput civis if (( COUNT == 1 )); then BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" infobox "$_PrepMount" "$_OnlyOne for EFI: $BOOT_PART\n" 1 else if ! BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \ --title " $_PrepMount " --menu "$_SelUefiBody" 0 0 0 $PARTS)"; then return 1 fi fi if grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then local msg="$_FormUefiBody $BOOT_PART $_FormUefiBody2" yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Do Not Format" "no" && format "$BOOT_PART" "vfat" else format "$BOOT_PART" "vfat" fi return 0 } select_boot_partition() { tput civis if ! BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepMount " \ --menu "$_SelBiosBody" 0 0 0 "$_Skip" "-" $PARTS)" || [[ $BOOT_PART == "$_Skip" ]]; then BOOT_PART="" else if grep -q 'ext[34]' <<< "$(fsck -N "$BOOT_PART")"; then local msg="$_FormBiosBody $BOOT_PART $_FormUefiBody2" yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Skip Formatting" "no" && format "$BOOT_PART" "ext4" else format "$BOOT_PART" "ext4" fi fi return 0 } select_root_partition() { # if we used LUKS and no LVM or LUKS+LVM remove the relevant partition labels from the list if [[ $LUKS && ! $LVM ]]; then ROOT_PART="/dev/mapper/$LUKS_NAME" decr_count "$LUKS_PART" elif [[ $LVM ]]; then [[ $LUKS ]] && decr_count "$LUKS_PART" for part in $(printf "%s" "$GROUP_PARTS"); do decr_count "$part"; done ROOT_PART="" fi if [[ $COUNT -eq 1 && ! $ROOT_PART ]]; then ROOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" infobox "$_PrepMount" "$_OnlyOne for root (/): $ROOT_PART\n" 1 elif [[ ! $ROOT_PART || $LVM ]]; then tput civis if ! ROOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \ --title " $_PrepMount " --menu "$_SelRootBody" 0 0 0 $PARTS)"; then return 1 fi else local msg="\nUsing${LUKS} root partition:" # $LUKS might just be an empty string infobox "$_PrepMount" "$msg $ROOT_PART\n" 1 fi select_filesystem "$ROOT_PART" || { ROOT_PART=""; return 1; } mount_partition "$ROOT_PART" || { ROOT_PART=""; return 1; } return 0 } select_extra_partitions() { while (( COUNT > 0 )); do tput civis local part if ! part="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepMount " \ --menu "$_ExtPartBody" 0 0 0 "$_Done" "-" $PARTS)" || [[ $part == "$_Done" ]]; then break fi # choose what filesystem and get the mountpoint select_filesystem "$part" || { break; return 1; } select_mountpoint || { break; return 1; } # mount it mount_partition "$part" "$EXTRA_MNT" || { break; return 1; } EXTRA_MNTS="$EXTRA_MNTS $part: $EXTRA_MNT" # if the mountpoint was /usr add 'usr' to MKINIT_HOOKS [[ $EXTRA_MNT == "/usr" && $MKINIT_HOOKS != *usr* ]] && MKINIT_HOOKS="usr $MKINIT_HOOKS" done return 0 }