diff --git a/archlabs-installer b/archlabs-installer index e37ee2b..694b07c 100755 --- a/archlabs-installer +++ b/archlabs-installer @@ -7,7 +7,7 @@ # shellcheck disable=SC2086,SC2046 -VER=2.1.33 +VER=2.1.35 # default values { @@ -158,7 +158,7 @@ _part="\nFull device auto partitioning is available for beginners otherwise cfdi _uefi="\nSelect the EFI boot partition (/boot), required for UEFI boot.\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as vfat/fat32 if not already." _bios="\nDo you want to use a separate boot partition? (optional)\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as ext3/4 if not already." _biosluks="\nSelect the boot partition (/boot), required for LUKS.\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as ext3/4 if not already." -_format="is already formatted correctly.\n\nFor a clean install, previously existing partitions should be reformatted, however this removes ALL data (bootloaders) on the partition so choose carefully.\n\nDo you want to reformat the partition?\n" +_format="is already formatted correctly.\n\nFor a clean install, existing partitions should be formatted, however this removes ALL data (bootloaders) on the partition so choose carefully.\n\nDo you want to format the partition?\n" _swapsize="\nEnter the size of the swapfile in megabytes (M) or gigabytes (G).\n\neg. 100M will create a 100 megabyte swapfile, while 10G will create a 10 gigabyte swapfile.\n\nFor ease of use and as an example it is filled in to match the size of your system memory (RAM).\n\nMust be greater than 1, contain only whole numbers, and end with either M or G." _expart="\nYou can now choose any additional partitions you want mounted, you'll be asked for a mountpoint after.\n\nSelect 'done' to finish the mounting step and begin unpacking the base system in the background." _exmnt="\nWhere do you want the partition mounted?\n\nEnsure the name begins with a slash (/).\nExamples include: /usr, /home, /var, etc." @@ -195,7 +195,7 @@ _lvmdelask="\nConfirm deletion of volume group(s) and logical volume(s).\n\nDele # Errors _errexpart="\nCannot mount partition due to a problem with the mountpoint.\n\nEnsure it begins with a slash (/) followed by at least one character.\n" -_errpart="\nYou need create the partition(s) first.\n\n\nBIOS systems require at least one partition (ROOT).\n\nUEFI systems require at least two (ROOT and EFI).\n" +_errpart="\nYou need to create the partition(s) first.\n\n\nBIOS systems require at least one partition (ROOT).\n\nUEFI systems require at least two (ROOT and EFI).\n" _errchoice="\nIf you want to fix the issue yourself use Ctrl-z to pause the installer. From there you can do whatever is needed to resolve the error.\nOnce finished use the 'fg' command to resume the installer, then select 'Continue'.\n" _lukserr="\nA minimum of two partitions are required for encryption:\n\n 1. root (/) - standard or LVM.\n 2. boot (/boot) - standard (unless using LVM on BIOS systems).\n" _lvmerr="\nThere are no viable partitions available to use for LVM, a minimum of one is required.\n\nIf LVM is already in use, deactivating it will allow the partition(s) to be used again.\n" @@ -735,49 +735,22 @@ part_auto() part_find() { - PARTS="" - COUNT=0 local regexp="$1" err='' local s dev size isize model - # string of partitions >= 80M as /TYPE/PART SIZE__FSTYPE - while read -r dev size; do - [[ $dev && $size ]] || continue - s=${size%%__*} - size_t="${s: -1:1}" - isize=${s:0:-1} - isize=${isize%.*} - if [[ $dev = /dev/nvme* ]]; then - model=$(lsblk -lno MODEL "${dev%p[1-9]}") - else - model=$(lsblk -lno MODEL "${dev%[1-9]}") - fi - if ! [[ $size_t == 'K' || ($size_t == 'M' && $isize -lt 80) ]]; then - if [[ $PARTS ]]; then - PARTS+=$'\n'"$dev ${size}__$model" - else - PARTS="$dev ${size}__$model" - fi - (( COUNT++ )) - fi - done < <(lsblk -lno TYPE,PATH,SIZE,FSTYPE,LABEL | - awk "/$regexp/"' && !'"/${IGNORE_DEV:-NONEXX}/"' { - if ($4 == "") { $4 = "unformatted" } - if ($5 == "") { $5 = "unlabeled" } - print $2, $3 "__" $4 "__" $5 - }') + PARTS="$(part_pretty "" "$regexp")" + PART_COUNT=$(wc -l <<< "$PARTS") case "$regexp" in - 'part|lvm|crypt') [[ $COUNT -lt 1 || ($SYS == 'UEFI' && $COUNT -lt 2) ]] && err="$_errpart" ;; - 'part|crypt') (( COUNT < 1 )) && err="$_lvmerr" ;; - 'part|lvm') (( COUNT < 2 )) && err="$_lukserr" ;; + 'part|lvm|crypt') [[ $PART_COUNT -lt 1 || ($SYS == 'UEFI' && $PART_COUNT -lt 2) ]] && err="$_errpart" ;; + 'part|crypt') (( PART_COUNT < 1 )) && err="$_lvmerr" ;; + 'part|lvm') (( PART_COUNT < 2 )) && err="$_lukserr" ;; esac if [[ $err ]]; then - msg "Not Enough Partitions" "$err" 2 + msg "Not Enough Partitions" "$err" 0 return 1 fi - return 0 } @@ -786,10 +759,13 @@ part_swap() local swp="$1" if [[ $swp == "$MNT/swapfile" && $SWAP_S ]]; then + msg "Swap Setup" "\nActivating $SWAP_S swapfile at /swapfile\n" 1 fallocate -l $SWAP_S "$swp" 2> "$ERR" errshow 0 "fallocate -l '$SWAP_S' '$swp'" chmod 600 "$swp" 2> "$ERR" errshow 0 "chmod 600 '$swp'" + else + msg "Swap Setup" "\nActivating swap partition $(part_pretty "$SWAP")\n" 1 fi mkswap "$swp" > /dev/null 2> "$ERR" errshow 0 "mkswap '$swp' > /dev/null" @@ -816,13 +792,45 @@ part_mount() errshow 0 "mount '$part' '$mntpt' > /dev/null" || return 1 fi - msg "Mount Complete" "\nPartition $part mounted at $mntpt\n" 1 + msg "Mount Complete" "\n$(part_pretty "$part") mounted at $mntpt\n" 1 part_countdec "$part" part_cryptlv "$part" return 0 } +part_pretty() +{ + local part="$1" + local regexp="$2" + local s dev size isize model + [[ $regexp == "" ]] && regexp="part|crypt|lvm" + + # invalid block device passed in + [[ $part && ! -b $part ]] && return + + # string of partitions >= 80M + # format: /dev/sda1 447.1G__ext4__unlabeled__Sandisk_SDSSDXP480G + while read -r dev size; do + [[ $dev && $size ]] || continue + s=${size%%__*} + size_t="${s: -1:1}" + isize=${s:0:-1} + isize=${isize%.*} + if [[ $dev = /dev/nvme* ]]; then + model=$(lsblk -lno MODEL "${dev%p[1-9]}") + else + model=$(lsblk -lno MODEL "${dev%[1-9]}") + fi + [[ $size_t == 'K' || ($size_t == 'M' && $isize -lt 80) ]] || printf "%s\n" "$dev ${size}__$model" + done < <(lsblk -lno TYPE,PATH,SIZE,FSTYPE,LABEL $part | + awk "/$regexp/"' && !'"/${IGNORE_DEV:-NONEXX}/"' { + if ($4 == "") { $4 = "unformatted" } + if ($5 == "") { $5 = "unlabeled" } + print $2, $3 "__" $4 "__" $5 + }') +} + part_format() { local part="$1" @@ -830,7 +838,7 @@ part_format() local delay="$3" shift 3 - msg "Format" "\nFormatting $part as $fs\n" 0 + msg "Format" "\nFormatting $(part_pretty "$part") as $fs\n" 0 mkfs.$fs ${FS_CMD_FLAGS[$fs]} "$part" > /dev/null 2> "$ERR" errshow 0 "mkfs.$fs ${FS_CMD_FLAGS[$fs]} '$part' > /dev/null" || return 1 sleep "$delay" @@ -838,13 +846,13 @@ part_format() part_device() { - if [[ $DEV_COUNT -eq 1 && $SYS_DEVS ]]; then - DEVICE="$(awk '{print $1}' <<< "$SYS_DEVS")" + if [[ $DEV_COUNT -eq 1 && $DEVS ]]; then + DEVICE="$(awk '{print $1}' <<< "$DEVS")" elif (( DEV_COUNT > 1 )); then if [[ $1 ]]; then - dlg DEVICE menu "Boot Device" "\nSelect the device to use for bootloader install." $SYS_DEVS + dlg DEVICE menu "Boot Device" "\nSelect the device to use for bootloader install." $DEVS else - dlg DEVICE menu "Select Device" "$_device" $SYS_DEVS + dlg DEVICE menu "Select Device" "$_device" $DEVS fi [[ $DEVICE ]] || return 1 elif [[ $DEV_COUNT -lt 1 && ! $1 ]]; then @@ -916,9 +924,9 @@ part_cryptlv() part_countdec() { for pt; do - if (( COUNT )); then + if (( PART_COUNT )); then PARTS="$(sed "/${pt//\//\\/}/d" <<< "$PARTS")" - (( COUNT-- )) + (( PART_COUNT-- )) fi done } @@ -960,7 +968,7 @@ select_boot() return 0 fi - if (( COUNT )); then + if (( PART_COUNT )); then while read -r dev size; do # walk partition list and skip ones that are too small/big for boot s=${size%%__*} size_t="${s: -1:1}" @@ -983,7 +991,7 @@ select_boot() return 1 ;; 1) - msg "EFI Boot Partition" "\nOnly one partition available that meets size requirements.\n" 1 + msg "EFI Boot Partition" "\nOnly one partition that meets size requirements for boot (/boot).\n" 1 BOOT="$(awk 'NF > 0 {print $1}' <<< "$pts")" ;; *) @@ -1001,7 +1009,7 @@ select_boot() return 1 ;; 1) - msg "Boot Partition" "\nOnly one partition available that meets size requirements.\n" 1 + msg "Boot Partition" "\nOnly one partition that meets size requirements for boot (/boot).\n" 1 BOOT="$(awk 'NF > 0 {print $1}' <<< "$pts")" ;; *) @@ -1024,7 +1032,7 @@ select_boot() local fs fs="$(fsck -N "$BOOT")" if ([[ $SYS == 'BIOS' ]] && grep -q 'ext[34]' <<< "$fs") || ([[ $SYS == 'UEFI' ]] && grep -q 'fat' <<< "$fs"); then - yesno "Format Boot Partition" "\nIMPORTANT: The boot partition $BOOT $_format" "Format $BOOT" "Skip Formatting" 1 || return 0 + yesno "Format Boot Partition" "\nIMPORTANT: $(part_pretty "$BOOT") $_format" "Format" "Don't Format" 1 || return 0 fi case "$SYS" in @@ -1058,7 +1066,7 @@ select_root() done <<< "$PARTS" if (( ptcount == 1 )); then # only one available device - msg "Root Partition (/)" "\nOnly one partition available that meets size requirements.\n" 2 + msg "Root Partition (/)" "\nOnly one that meets size requirements for root (/).\n" 2 ROOT="$(awk 'NF > 0 {print $1}' <<< "$pts")" else local txt="\nSelect the root (/) partition, this is where $DIST will be installed." @@ -1079,7 +1087,7 @@ select_swap() { local pts dev size isize - if (( COUNT )) ; then + if (( PART_COUNT )) ; then while read -r dev size; do # walk partition list and skip ones that are > 64G s=${size%%__*} size_t="${s: -1:1}" @@ -1128,14 +1136,14 @@ select_extra() local part dev size # walk partition list and skip ones that are < 1G - if (( COUNT )); then + if (( PART_COUNT )); then while read -r dev size; do s=${size%%__*} [[ ${s: -1:1} == 'M' ]] && part_countdec "$dev" done <<< "$PARTS" fi - while (( COUNT )); do + while (( PART_COUNT )); do part='' dlg part menu 'Mount Extra' "$_expart" 'done' 'finish mounting step' $PARTS || break if [[ $part == 'done' ]]; then @@ -1148,7 +1156,7 @@ select_extra() fi done - if (( COUNT == 0 )); then + if (( PART_COUNT == 0 )); then msg "Mount Extra" "\nMounting Finished\n\nNo more partitions to mount, returning to main menu.\n" 2 fi return 0 @@ -1164,7 +1172,7 @@ select_mntopts() opts+="$i - off " done - yesno "$title" "\nPerform automatic mount with default options?\n" "Automatic" "Custom" && return 1 + yesno "$title" "\nUse automatic mount with default options?\n" "Automatic" "Custom" && return 1 until [[ $MNT_OPTS ]]; do dlg MNT_OPTS check "$title" "$_mount" $opts [[ $MNT_OPTS ]] || return 1 # no options is auto mount @@ -1178,9 +1186,9 @@ select_filesystem() { local part="$1" local fs='' - local cur + local cur txt cur="$(lsblk -lno FSTYPE "$part" 2> /dev/null)" - local txt="\nSelect which filesystem to use for: $part\n\nDefault: ext4" + txt="\nSelect which filesystem to use for: $(part_pretty "$part")\n\nDefault: ext4" # bail early if the partition was created in part_auto() [[ $cur && $part == "$AUTO_ROOT" ]] && return 0 @@ -1192,7 +1200,7 @@ select_filesystem() dlg fs menu "Filesystem" "$txt" ext4 - ext3 - ext2 - vfat - ntfs - f2fs - jfs - xfs - nilfs2 - reiserfs - || return 1 fi [[ $fs == 'skip' ]] && return 0 - yesno "Filesystem" "\nFormat $part as $fs?\n" || fs='' + yesno "Filesystem" "\nFormat $(part_pretty "$part") as $fs?\n" || fs='' done part_format "$part" "$fs" 0 } @@ -1201,7 +1209,7 @@ select_mountpoint() { EXMNT='' until [[ $EXMNT ]]; do - dlg EXMNT input "Extra Mount $part" "$_exmnt" "/" || return 1 + dlg EXMNT input "Extra Mount $(part_pretty "$part")" "$_exmnt" "/" || return 1 if [[ ${EXMNT:0:1} != "/" || ${#EXMNT} -le 1 || $EXMNT =~ \ |\' || $EXMNTS == *"$EXMNT"* ]]; then msg "Mountpoint Error" "$_errexpart" EXMNT='' @@ -1258,7 +1266,7 @@ install_main() if [[ -e ${MNT}$f ]]; then ${EDITOR:-vim} "${MNT}$f" else - msg "File Missing" "\nThe file(s) selected do not exist:\n\n${MNT}$f\n" + msg "File Missing" "\nOne or more of the files selected do not exist:\n\n${MNT}$f\n" fi done fi @@ -1315,6 +1323,9 @@ install_base() [[ -f /etc/resolv.conf ]] && cp -fv /etc/resolv.conf "$MNT/etc/" [[ -e /etc/NetworkManager/system-connections ]] && cp -rvf /etc/NetworkManager/system-connections "$MNT/etc/NetworkManager/" + # allow members of the wheel group to run commands as root + sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" "$MNT/etc/sudoers" + mkdir -pv "$MNT/etc/default" echo "LANG=$LOCALE" > "$MNT/etc/locale.conf" cp -fv "$MNT/etc/locale.conf" "$MNT/etc/default/locale" @@ -1525,15 +1536,8 @@ install_packages() fi # update and install crucial packages first to avoid issues - chrun "pacman -Syyu --noconfirm" 2> "$ERR" 2>&1 - errshow 1 "chrun 'pacman -Syyu --noconfirm'" - chrun "pacman -S ${BASE_PKGS[*]} ${loginpkg[*]} $NEWSHELL $UCODE $KERNEL --noconfirm --needed" 2> "$ERR" 2>&1 - errshow 1 "chrun 'pacman -S ${BASE_PKGS[*]} ${loginpkg[*]} $NEWSHELL $UCODE $KERNEL --noconfirm --needed'" - if [[ $PACSTRAP != 1 ]]; then - chrun "pacman -S ${ISO_PKGS[*]} --noconfirm --needed" 2> "$ERR" 2>&1 - errshow 1 "chrun 'pacman -S ${ISO_PKGS[*]} --noconfirm --needed'" - chrun "systemctl enable NetworkManager.service" > /tmp/bgout 2>&1 - fi + chrun "pacman -Syyu ${loginpkg[*]} $NEWSHELL $UCODE $KERNEL --noconfirm --needed" 2> "$ERR" 2>&1 + errshow 1 "chrun 'pacman -Syyu ${loginpkg[*]} $NEWSHELL $UCODE $KERNEL --noconfirm --needed'" # reinstalling iputils fixes the network issue for non-root users chrun "pacman -S iputils --noconfirm" @@ -1565,9 +1569,6 @@ install_packages() esac fi - # allow members of the wheel group to run commands as root - sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" "$MNT/etc/sudoers" - return 0 } @@ -1731,10 +1732,11 @@ install_background() PACSTRAP=1 ( install_mirrorlist "/etc/pacman.d/mirrorlist" > /tmp/bgout 2>&1 && - pacstrap /mnt > /tmp/bgout 2>&1 && + pacstrap /mnt ${BASE_PKGS[*]} ${ISO_PKGS[*]} >> /tmp/bgout 2>&1 && cp /etc/pacman.d/mirrorlist "$MNT/etc/pacman.d/mirrorlist" cp /etc/pacman.conf "$MNT/etc/pacman.conf" al_repo "$MNT/etc/pacman.conf" + chrun "systemctl enable NetworkManager.service" >> /tmp/bgout 2>&1 ) & BG_PID=$! else @@ -1743,7 +1745,7 @@ install_background() rsync -a /run/archiso/sfs/airootfs/ "$MNT/" && install_mirrorlist "$MNT/etc/pacman.d/mirrorlist" > /tmp/bgout 2>&1 && al_repo "$MNT/etc/pacman.conf" && - chrun "pacman -Syyu ${BASE_PKGS[*]} --noconfirm --needed" > /tmp/bgout 2>&1 + chrun "pacman -Syyu ${BASE_PKGS[*]} --noconfirm --needed" >> /tmp/bgout 2>&1 ) & BG_PID=$! fi @@ -2118,7 +2120,7 @@ lvm_lv_size() fi fi (( ERR_SIZE )) || break - msg "Invalid Logical Volume Size" "$_lvmerrlvsize" + msg "Invalid Logical Volume Size" "$_lvmerrlvsize" 2 done return $ERR_SIZE @@ -2165,7 +2167,7 @@ lvm_del_all() LVM='' fi else - msg "Delete LVM" "\nNo LVMs to remove...\n" 2 + msg "Delete LVM" "\nNo available LVM to remove...\n" 2 LVM='' fi } @@ -2266,7 +2268,7 @@ luks_open() umount_dir "$MNT" part_find 'part|crypt|lvm' || return 1 - if (( COUNT == 1 )); then + if (( PART_COUNT == 1 )); then LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" else dlg LUKS_PART menu "$_luksopen" "\nSelect which partition to open." $PARTS @@ -2275,10 +2277,11 @@ luks_open() [[ $LUKS_PART ]] || return 1 luks_pass "$_luksopen" || return 1 - msg "$_luksopen" "\nOpening encrypted partition: $LUKS_NAME\n\nUsing device/volume: $LUKS_PART\n" 0 + msg "$_luksopen" "\nOpening encryption: $LUKS_NAME\n\nUsing device/volume: $(part_pretty "$LUKS_PART")\n" 0 cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> "$ERR" errshow 0 "cryptsetup open --type luks '$LUKS_PART' '$LUKS_NAME' <<< '$LUKS_PASS'" || return 1 - LUKS='encrypted'; luks_show + LUKS='encrypted' + luks_show return 0 } @@ -2326,7 +2329,7 @@ luks_setup() if [[ $AUTO_ROOT ]]; then LUKS_PART="$AUTO_ROOT" - elif (( COUNT == 1 )); then + elif (( PART_COUNT == 1 )); then LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" else dlg LUKS_PART menu "$_luksnew" "\nSelect the partition you want to encrypt." $PARTS @@ -2723,18 +2726,13 @@ is_bg_install() system_devices() { IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')" + DEVS="$(lsblk -lno TYPE,PATH,SIZE,MODEL | awk '/disk/ && !'"/${IGNORE_DEV:-NONEXX}/"' {print $2, $3 "__" $4}')" + DEV_COUNT=$(wc -l <<< "$DEVS") - SYS_DEVS="$(lsblk -lno TYPE,PATH,SIZE,MODEL | awk '/disk/ && !'"/${IGNORE_DEV:-NONEXX}/"' {print $2, $3 "__" $4}')" - - if [[ -z $SYS_DEVS ]]; then + if [[ -z $DEVS ]]; then msg "Device Error" "\nNo available devices...\n\nExiting..\n" 2 die 1 fi - - DEV_COUNT=0 - while read -r line; do - [[ "$line" ]] && (( DEV_COUNT++ )) - done <<< "$SYS_DEVS" } system_identify()