diff --git a/source/archlabs-installer b/source/archlabs-installer index 5a85a96..6e510ca 100755 --- a/source/archlabs-installer +++ b/source/archlabs-installer @@ -15,18 +15,22 @@ # immutable variables { readonly DIST="Archlabs" # Linux distributor -readonly VER="1.6.39" # Installer version +readonly VER="1.6.41" # Installer version readonly LIVE="liveuser" # Live session user readonly TRN="/usr/share/archlabs-installer" # Translation path readonly MNT="/mnt/install" # Install mountpoint readonly ERR="/tmp/errlog" # Built-in error log # create a regex string of all usb devices on the system -for dev in $(lsblk -lno NAME,TRAN | awk '/usb/ {print $1}'); do USB_DEVS="${dev}$([[ $USB_DEVS ]] && echo -n "|$USB_DEVS")"; done +for dev in $(lsblk -lno NAME,TRAN | awk '/usb/ {print $1}'); do + USB_DEVS="${dev}$([[ $USB_DEVS ]] && echo -n "|$USB_DEVS")" +done # determine which device was used for booting to ignore later during partition select -readonly IGNORE_DEV="$(lsblk -lno NAME,TYPE,TRAN,MOUNTPOINT | awk "/$USB_DEVS/"' && /\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')" -readonly SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE,TRAN | awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')" +readonly IGNORE_DEV="$(lsblk -lno NAME,TYPE,TRAN,MOUNTPOINT | + awk "/$USB_DEVS/"' && /\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')" +readonly SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE,TRAN | + awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')" readonly LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if($1) print $1 " -"}' /etc/locale.gen)" readonly SYS_MEM=$(grep 'MemTotal' /proc/meminfo | awk '{print int($2 / 1024)}') readonly DEV_COUNT="$(wc -l <<< "$SYS_DEVS")" @@ -40,9 +44,11 @@ for zone in America Australia Asia Atlantic Africa Europe Indian Pacific Arctic done readonly SUBZONES # make it read only -for t in st termite xterm; do - hash $t >/dev/null 2>&1 && { readonly TERM_CMD="$t"; break; } -done +if [[ $TERM != 'linux' ]]; then + for t in st termite xterm; do + hash $t >/dev/null 2>&1 && { readonly TERM_CMD="$t"; break; } + done +fi # static string of keymap codes and respective language readonly KEYMAPS="us English cm English gb English au English gh English za English @@ -60,14 +66,13 @@ lv Latvian md Moldavian mao Maori by Belarusian me Montenegrin mk Macedonian kh az Azerbaijani" declare -Agr BOOT_MNTS=( -[UEFI-grub]="/boot/efi" [UEFI-systemd-boot]="/boot" -[BIOS-grub]="/boot" [BIOS-syslinux]="/boot" +[UEFI-grub]="/boot/efi" [UEFI-systemd-boot]="/boot" [BIOS-grub]="/boot" +[BIOS-syslinux]="/boot" [UEFI-syslinux]="/boot" ) # static list of bootloaders & boot partition mountpoints stored as the system type (BIOS or UEFI) -declare -Agr BOOTLOADERS=( -[UEFI]="grub ${BOOT_MNTS[UEFI-grub]} systemd-boot ${BOOT_MNTS[UEFI-systemd-boot]}" -[BIOS]="grub ${BOOT_MNTS[BIOS-grub]} syslinux ${BOOT_MNTS[BIOS-syslinux]}" +declare -Agr BOOTLOADERS=([BIOS]="grub ${BOOT_MNTS[BIOS-grub]} syslinux ${BOOT_MNTS[BIOS-syslinux]}" +[UEFI]="grub ${BOOT_MNTS[UEFI-grub]} systemd-boot ${BOOT_MNTS[UEFI-systemd-boot]} syslinux ${BOOT_MNTS[UEFI-syslinux]}" ) # static mkfs commands for each filesystem offered @@ -78,8 +83,7 @@ declare -Agr FS_CMDS=( ) # static filesystem mount options -declare -Agr FS_OPTS=( -[vfat]="" [ntfs]="" [ext2]="" [ext3]="" +declare -Agr FS_OPTS=([vfat]="" [ntfs]="" [ext2]="" [ext3]="" [ext4]="dealloc - off discard - off nofail - off noacl - off relatime - off noatime - off nobarrier - off nodelalloc - off" [jfs]="discard - off errors=continue - off errors=panic - off nointegrity - off" [reiserfs]="acl - off nolog - off notail - off replayonly - off user_xattr - off" @@ -98,7 +102,6 @@ luks_variable_init() { declare -g LUKS_PASS="" declare -g LUKS_UUID="" declare -g LUKS_DEV="" - declare -g MKINIT_HOOKS="shutdown" declare -g SEPERATE_BOOT=0 } @@ -113,21 +116,18 @@ initialize_variables() { declare -g BOOT_PART="" declare -g BOOTLOADER="" declare -g EXTRA_MNT="" - declare -g SWAP_FILE="none" + declare -g SWAP="none" declare -g SWAP_SIZE="${SYS_MEM}M" declare -g KERNEL="linux" - declare -g NEWUSER="" declare -g USER_PASS="" declare -g ROOT_PASS="" - declare -g LOGIN_WM="" declare -g LOGIN_TYPE="" declare -g INSTALL_WMS="" declare -g WM_PACKAGES="" declare -g EXTRA_PACKAGES="" declare -g REMOVE_PKGS="" - declare -g CURRENT_MENU="main" declare -g MENU_HIGHLIGHT=0 declare -g EDITOR_CHOICE="" @@ -135,22 +135,13 @@ initialize_variables() { # boolean checks declare -g AUTOLOGIN=false - declare -g FIRST_PREP=false - declare -g FIRST_CONFIG=false - declare -g UNPACKED_BASE=false - declare -g SET_ROOT_PASSWD=false - declare -g TIMEZONE_SET=false - declare -g DONE_UPDATE=false - declare -g BOOT_DONE=false - declare -g FULL_DONE=false - declare -g CONFIRM_DONE=false # Commands used to install each bootloader. # NOTE: syslinux and grub in particular can/will change during runtime declare -Ag BOOT_CMDS=( [syslinux]="syslinux-install_update -iam" - [grub]="grub-install --bootloader-id=$DIST --recheck --force" - [systemd-boot]="bootctl --path=/boot install" + [grub]="grub-install --recheck --force" + [systemd-boot]="bootctl --path=${BOOT_MNTS[UEFI-systemd-boot]} install" ) # files able to be reviewed when finishing install @@ -169,7 +160,7 @@ initialize_variables() { } ###################################################################### -## Utility and Check Functions ## +## Utility Functions ## ###################################################################### chroot_cmd() { @@ -215,7 +206,7 @@ select_language() { "9" "Magyar (hu_HU)" "10" "Chinese (zh_CN)") source $TRN/english.trans 2>/dev/null - FONT="ter-i16n" + declare -g FONT="ter-i16n" case $lang in 1) LOC="en_US.UTF-8" ;; @@ -228,22 +219,23 @@ select_language() { 8) source $TRN/dutch.trans 2>/dev/null && LOC="nl_NL.UTF-8" ;; 9) source $TRN/hungarian.trans 2>/dev/null && LOC="hu_HU.UTF-8" FONT="lat2-16" ;; 10) source $TRN/chinese.trans 2>/dev/null && LOC="zh_CN.UTF-8" ;; - *) clear; tput cnorm - pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail" - exit 0 + *) die 0 esac sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen - [[ $LOC != "en_US.UTF-8" ]] && sed -i "s/#${LOC}/${LOC}/" /etc/locale.gen - locale-gen >/dev/null 2>&1 - setfont $FONT >/dev/null 2>&1 - export LANG="$LOC" + if [[ $LOC != "en_US.UTF-8" ]]; then + sed -i "s/#${LOC}/${LOC}/" /etc/locale.gen + locale-gen >/dev/null 2>&1 + setfont $FONT >/dev/null 2>&1 + export LANG="$LOC" + fi + return 0 } identify_system() { if grep -qi 'apple' /sys/class/dmi/id/sys_vendor; then - modprobe -r -q efivars || true + modprobe -r -q efivars else modprobe -q efivarfs fi @@ -259,32 +251,26 @@ identify_system() { } check_requirements() { - declare -g HAS_NETWORK=false - + local err=0 if [[ $(whoami) != "root" ]]; then - infobox "$_ErrTitle" "$_NotRoot\n$_Exit"; clear; tput cnorm - pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail" - exit 1 - elif ! (ping -c 1 archlabslinux.com || ping -c 1 google.com || ping -c 1 bitbucket.org || ping -c 1 github.com || ping -c 1 sourceforge.net) >/dev/null 2>&1; then - - if [[ $(systemctl is-active NetworkManager) == "active" ]] && hash nmtui >/dev/null 2>&1;then - tput civis; nmtui + infobox "$_ErrTitle" "$_NotRoot\n$_Exit" + err=1 + elif ! grep -qw 'lm' /proc/cpuinfo; then + infobox "$_ErrTitle" "\nSystem does not meet the minimum requirements, CPU must be x86_64 capable.\n$_Exit" + err=1 + elif ! (ping -c 1 archlinux.org || ping -c 1 archlabslinux.com || ping -c 1 google.com || ping -c 1 bitbucket.org || ping -c 1 github.com || ping -c 1 sourceforge.net) >/dev/null 2>&1; then + ([[ $(systemctl is-active NetworkManager) == "active" ]] && hash nmtui >/dev/null 2>&1) && { tput civis; nmtui; } + if ! (ping -c 1 archlinux.org || ping -c 1 archlabslinux.com || ping -c 1 google.com || ping -c 1 bitbucket.org || ping -c 1 github.com || ping -c 1 sourceforge.net) >/dev/null 2>&1; then + infobox "$_ErrTitle" "$_NoNetwork\n$_Exit" + err=1 fi - - if (ping -c 1 archlabslinux.com || ping -c 1 google.com || ping -c 1 bitbucket.org || ping -c 1 github.com || ping -c 1 sourceforge.net) >/dev/null 2>&1; then - HAS_NETWORK=true - else - infobox "$_ErrTitle" "$_NoNetwork\nYou may experience issues without one...\n" - fi - else - HAS_NETWORK=true fi - return 0 + [[ $err -eq 1 ]] && die 1 || return 0 } check_for_errors() { - # if the last process exited normally then we can bail + # return if the last process exited normally (( $? == 0 )) && return 0 local command="$1" @@ -292,26 +278,13 @@ check_for_errors() { # get error message from logfile and attempt to format slightly better for humans # strip any non-printable characters, escape sequences, and other known messy text - local err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")" + local err + err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")" + [[ $err != "" ]] && msgbox "$_ErrTitle" "$msg\n\nWith the following error message:\n\n$err" + msg="$([[ $err == "" ]] && echo -n "$msg")\n$_ErrChoice" + yesno "$_ErrTitle" "$msg" "Exit & Shutdown" "Ignore & Continue" && die 'shutdown' - if [[ $err != "" ]]; then - msgbox "$_ErrTitle" "$msg\n\nWith the following error message:\n\n$err" - fi - - if yesno "$_ErrTitle" "$msg\n$_ErrChoice" "Wipe Install" "Manual Fix" "no"; then - for d in $MNT/?*; do - if ! grep -q "boot" <<< "$d"; then - rm -rf "$d" 2>/dev/null - fi - done - unmount_partitions - - [[ -e $ERR ]] && rm -rf $ERR - initialize_variables - luks_variable_init - fi - - return 1 + return 0 } check_parts_are_mounted() { @@ -339,10 +312,11 @@ msgbox() { } infobox() { + local time="$3" local bt="${BT:-$DIST Installer - (x86_64)}" tput civis dialog --cr-wrap --backtitle "$bt" --title " $1 " --infobox "$2\n" 0 0 - sleep 2 + sleep ${time:-2} } yesno() { @@ -362,15 +336,23 @@ yesno() { } wrap_up() { - if yesno "$_CloseInst" "$1" "$2" "$3"; then - unmount_partitions - [[ -e $ERR ]] && rm -rf $ERR - pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail" - tput cnorm - clear - [[ $4 == "reboot" ]] && reboot - exit 0 - fi + yesno "$_CloseInst" "$1" "$2" "$3" || return 0 + [[ $4 == "reboot" ]] && die 'reboot' || die 0 +} + +die() { + tput cnorm + unmount_partitions + pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail" + [[ $1 =~ [0-9] ]] && exit $1 || systemctl $1 +} + +oneshot() { + local func="$1" + [[ -e /tmp/.ai.$func ]] && return 0 + $1 || return 1 + touch "/tmp/.ai.$func" + return 0 } ###################################################################### @@ -378,157 +360,77 @@ wrap_up() { ###################################################################### set_keymap() { - local map tput civis - map="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepLayout " \ + declare -g KEYMAP + KEYMAP="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepLayout " \ --menu "$_XMapBody" 20 70 12 $KEYMAPS)" - [[ $? != 0 || $map == "" ]] && return 1 + [[ $? != 0 || $KEYMAP == "" ]] && return 1 - cat >/tmp/00-keyboard.conf </tmp/keyboard </dev/null 2>&1 - echo -e "KEYMAP=$map\nFONT=$FONT" >/tmp/vconsole.conf return 0 } set_locale() { - local locale tput civis - locale="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ + declare -g LOCALE + LOCALE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ --title "$_ConfLocale" --menu "$_LocaleBody" 25 70 12 $LOCALES)" - [[ $? != 0 || $locale == "" ]] && return 1 - - infobox "$_ConfLocale" "$_GenLocale $locale\n" - - sed -i "s/#en_US.UTF-8/en_US.UTF-8/g; s/#${locale}/${locale}/g" $MNT/etc/locale.gen - sed -i "s/en_US.UTF-8/${locale}/g" $MNT/etc/locale.conf - cp -f $MNT/etc/locale.conf $MNT/etc/default/locale - - chroot_cmd "locale-gen" >/dev/null 2>$ERR - check_for_errors 'locale-gen' || return 1 - - set_timezone + [[ $? != 0 || $LOCALE == "" ]] && return 1 + return 0 } set_timezone() { tput civis - - local zone - zone="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ + declare -g ZONE + ZONE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ --title " $_TimeZTitle " --menu "$_TimeZBody" 20 70 10 America - Australia - \ Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica -)" - local subzone - subzone="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ - --title " $_TimeZTitle " --menu "$_TimeSubZBody" 20 70 12 ${SUBZONES[$zone]})" + declare -g SUBZONE + SUBZONE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ + --title " $_TimeZTitle " --menu "$_TimeSubZBody" 20 70 12 ${SUBZONES[$ZONE]})" - if yesno "$_TimeZTitle" "$_TimeZQ $zone/$subzone?\n"; then - chroot_cmd "ln -sf /usr/share/zoneinfo/$zone/$subzone /etc/localtime" 2>$ERR - check_for_errors "ln -sf /usr/share/zoneinfo/$zone/$subzone /etc/localtime" || return 1 + if yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n"; then + return 0 else - set_timezone || return 1 + set_timezone fi - - TIMEZONE_SET=true - set_hwclock } set_hwclock() { chroot_cmd "hwclock --systohc --utc" - if [[ $? != 0 ]]; then - chroot_cmd "hwclock --systohc --utc --directisa" - [[ $? != 0 ]] && infobox "$_ErrTitle" "\nHwclock setup attempts failed.\n\nContinuing anyway.\n" - fi + [[ $? != 0 ]] && chroot_cmd "hwclock --systohc --utc --directisa" return 0 } set_hostname() { tput cnorm - local hostname - hostname="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")" - [[ $? != 0 || $hostname == "" ]] && return 1 - - echo "$hostname" > $MNT/etc/hostname - cat > $MNT/etc/hosts << EOF -127.0.0.1 localhost -127.0.1.1 $hostname -::1 localhost ip6-localhost ip6-loopback -ff02::1 ip6-allnodes -ff02::2 ip6-allrouters -EOF + declare -g HOSTNAME + HOSTNAME="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")" + [[ $? != 0 || $HOSTNAME == "" ]] && return 1 + return 0 } create_user() { - if [[ $AUTOLOGIN == true && $LOGIN_TYPE == 'lightdm' ]]; then - local groups="rfkill,wheel,autologin,nopasswdlogin,network,lp,storage,power,video,audio,lp" - else - local groups="rfkill,wheel,autologin,network,lp,storage,power,video,audio,lp" - fi - - NEWUSER="" - user_input_values "$NEWUSER" || return 1 - - if [[ $SET_ROOT_PASSWD != true ]]; then - infobox "$_ConfRoot" "\nSetting root password\n" - chroot_cmd "echo 'root:$ROOT_PASS' | chpasswd" 2>$ERR - check_for_errors "chpasswd root" || return 1 - SET_ROOT_PASSWD=true - fi - - infobox "$_ConfUser" "$_UserSetBody" - - if [[ -e $MNT/home/$LIVE ]]; then - # for first user created, swap the live user account - swap_livuser - chroot_cmd "mv -f /home/$LIVE /home/$NEWUSER" 2>$ERR - check_for_errors "mv -f /home/$LIVE /home/$NEWUSER" || return 1 - chroot_cmd "usermod -aG $groups $NEWUSER" 2>$ERR - check_for_errors "usermod -aG $groups $NEWUSER" || return 1 - else - # create new user account - chroot_cmd "useradd $NEWUSER -m -g users -G $groups -s /bin/zsh" 2>$ERR - check_for_errors "useradd $NEWUSER -m -g users -G $groups -s /bin/zsh" || return 1 - chroot_cmd "cp -rf /etc/skel/ /home/$NEWUSER" 2>$ERR - check_for_errors "cp -rf /etc/skel/ /home/$NEWUSER" || return 1 - fi + infobox "$_ConfRoot" "\nSetting root password\n" 1 + chroot_cmd "echo 'root:$ROOT_PASS' | chpasswd" 2>$ERR + check_for_errors "chpasswd root" + infobox "$_ConfUser" "$_UserSetBody" 1 + swap_livuser chroot_cmd "echo '$NEWUSER:$USER_PASS' | chpasswd" 2>$ERR - check_for_errors "chpasswd $NEWUSER" || return 1 + check_for_errors "chpasswd $NEWUSER" chroot_cmd "chown -Rf $NEWUSER:users /home/$NEWUSER" 2>$ERR - check_for_errors "chown -Rf $NEWUSER:users /home/$NEWUSER" || return 1 - - if [[ $AUTOLOGIN == true && $LOGIN_TYPE == 'lightdm' ]]; then - sed -i "/#autologin-user=/ c autologin-user=${NEWUSER}" $MNT/etc/lightdm/lightdm.conf - fi - - fix_home_files - - if [[ $UNPACKED_BASE == true && $TIMEZONE_SET == true ]]; then - [[ $SET_ROOT_PASSWD == true && $BOOT_DONE == true ]] && FULL_DONE=true - fi + check_for_errors "chown -Rf $NEWUSER:users /home/$NEWUSER" + setup_user_home return 0 } @@ -536,25 +438,35 @@ swap_livuser() { # edit the required files in /etc/ to swap the liveuser account name sed -i "s/${LIVE}/${NEWUSER}/g" $MNT/etc/{group,gshadow,passwd,shadow} - if [[ $AUTOLOGIN != true || $LOGIN_TYPE == 'lightdm' ]]; then - rm -rf $MNT/etc/systemd/system/getty@tty1.service.d >/dev/null 2>&1 - elif [[ $LOGIN_TYPE != 'lightdm' ]]; then + # set standard groups for the new user + local groups="rfkill,wheel,network,lp,storage,power,video,audio,lp,autologin" + + if [[ $AUTOLOGIN == true && $LOGIN_TYPE == 'lightdm' ]]; then + # add the nopasswdlogin group for lightdm autologin + groups="$groups,nopasswdlogin" + elif [[ $AUTOLOGIN == true ]]; then + # setup autologin on tty1 with systemd + xinit sed -i "s/${LIVE}/${NEWUSER}/g" $MNT/etc/systemd/system/getty@tty1.service.d/autologin.conf fi + chroot_cmd "mv -f /home/$LIVE /home/$NEWUSER" 2>$ERR + check_for_errors "mv -f /home/$LIVE /home/$NEWUSER" + chroot_cmd "usermod -aG $groups $NEWUSER" 2>$ERR + check_for_errors "usermod -aG $groups $NEWUSER" + return 0 } -fix_home_files() { +setup_user_home() { local user_home="$MNT/home/$NEWUSER" - sed -i "s/${LIVE}/${NEWUSER}/g" $user_home/.config/{openbox/autostart,gtk-3.0/bookmarks} \ + sed -i "s/${LIVE}/${NEWUSER}/g" $user_home/.config/gtk-3.0/bookmarks \ $user_home/.mozilla/firefox/{archlabs.default/prefs.js,archlabs.default/sessionstore.js} + rm -rf $user_home/.config/awesome if [[ $AUTOLOGIN == true ]]; then if [[ $LOGIN_TYPE == 'lightdm' ]]; then rm -rf $user_home/.{zprofile,xinitrc} - sed -i "/#autologin-user=/ c autologin-user=${NEWUSER}" $MNT/etc/lightdm/lightdm.conf else sed -i "s/:-openbox/:-${LOGIN_WM}/g" $user_home/.xinitrc sed -i '/archlabs-installer/d' $user_home/.zprofile @@ -566,72 +478,63 @@ fix_home_files() { sed -i "s/:-openbox/:-${LOGIN_WM}/g" $user_home/.xinitrc fi + if ! [[ $INSTALL_WMS =~ openbox ]]; then + rm -rf $user_home/.config/{openbox,ob-autostart,obmenu-generator} + elif ! [[ $INSTALL_WMS =~ bspwm ]]; then + rm -rf $user_home/.config/{bspwm,sxhkd} + elif ! [[ $INSTALL_WMS =~ i3-gaps ]]; then + rm -rf $user_home/.config/i3 + fi return 0 } -user_input_values() { - local user="$1" - local pass pass2 +user_setup() { tput cnorm local values - if [[ $SET_ROOT_PASSWD != true ]]; then - values="$(dialog --stdout --no-cancel --separator '~' --ok-label "Submit" --backtitle "$BT" \ - --title " $_UserTitle " --insecure --mixedform "$_UserBody" 27 75 10 \ - "$_Username" 1 1 "$user" 1 $((${#_Username} + 2)) 71 0 0 \ - "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \ - "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1 \ - "$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) 71 0 2 \ - "$_Password" 8 1 "" 8 $((${#_Password} + 2)) 71 0 1 \ - "$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) 71 0 1)" - else - values="$(dialog --stdout --no-cancel --separator '~' --ok-label "Submit" --backtitle "$BT" \ - --title " $_UserTitle " --insecure --mixedform "$_UserBody" 20 75 4 \ - "$_Username" 1 1 "$user" 1 $((${#_Username} + 2)) 71 0 0 \ - "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \ - "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1)" - fi + values="$(dialog --stdout --no-cancel --separator '~' --ok-label "Submit" --backtitle "$BT" \ + --title " $_UserTitle " --insecure --mixedform "$_UserBody" 27 75 10 \ + "$_Username" 1 1 "" 1 $((${#_Username} + 2)) 71 0 0 \ + "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \ + "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1 \ + "$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) 71 0 2 \ + "$_Password" 8 1 "" 8 $((${#_Password} + 2)) 71 0 1 \ + "$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) 71 0 1)" [[ $? != 0 || $values == "" ]] && return 1 + + local user user="$(awk -F'~' '{print $1}' <<< "$values")" + local pass pass2 pass="$(awk -F'~' '{print $2}' <<< "$values")" pass2="$(awk -F'~' '{print $3}' <<< "$values")" - - # if the root password has not yet been set local rpass rpass2 - if [[ $SET_ROOT_PASSWD != true ]]; then - rpass="$(awk -F'~' '{print $5}' <<< "$values")" - rpass2="$(awk -F'~' '{print $6}' <<< "$values")" + rpass="$(awk -F'~' '{print $5}' <<< "$values")" + rpass2="$(awk -F'~' '{print $6}' <<< "$values")" - # when both passwords match but are empty - # resort to using the user passwords instead - if [[ $rpass == "" && $rpass2 == "" ]]; then - rpass="$pass" - rpass2="$pass2" - fi - fi + # both root passwords are empty, so use the user passwords instead + [[ $rpass == "" && $rpass2 == "" ]] && { rpass="$pass"; rpass2="$pass2"; } - # make sure we dont have anything wrong and that the passwords match + # make sure a username was entered and that the passwords match if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9\ ] || $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then - tput civis - # passwords don't match if [[ $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then - if [[ "$rpass" != "$rpass2" ]]; then + # password was left empty or doesn't match + if [[ $pass == "" ]]; then + msgbox "$_ErrTitle" "\nUser $_Password CANNOT be left empty.\n$_TryAgain" + elif [[ "$rpass" != "$rpass2" ]]; then msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain" else msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain" fi - else - # bad username + else # bad username msgbox "$_UserErrTitle" "$_UserErrBody" user="" fi - - # recursively loop back unless the user chooses cancel, then bail - user_input_values "$user" || return 1 + # recursively loop back unless the user cancels + user_setup || return 1 else NEWUSER="$user" USER_PASS="$pass" - [[ $SET_ROOT_PASSWD != true ]] && ROOT_PASS="$rpass" + ROOT_PASS="$rpass" fi return 0 @@ -647,6 +550,7 @@ window_manager() { "openbox" "A lightweight, powerful, and highly configurable stacking window manager" off \ "bspwm" "A tiling window manager that represents windows as the leaves of a binary tree" off \ "i3-gaps" "A fork of i3 window manager with more features including gaps" off \ + "dwm" "A customized fork of dwm with patches and modifications" off \ "gnome" "A desktop environment that aims to be simple and easy to use" off \ "cinnamon" "A desktop environment combining a traditional desktop layout with modern graphical effects" off \ "xfce4" "A lightweight and modular desktop environment based on GTK+ 2 and 3" off)" @@ -703,6 +607,7 @@ extra_packages() { "firefox" "A popular open-source graphical web browser from Mozilla" off \ "chromium" "an open-source graphical web browser based on the Blink rendering engine" off \ "opera" "Fast and secure, free of charge web browser from Opera Software" off \ + "epiphany" "A GNOME web browser based on the WebKit rendering engine" off \ "qutebrowser" "A keyboard-focused vim-like web browser based on Python and PyQt5" off \ "atom" "An open-source text editor developed by GitHub that is licensed under the MIT License" off \ "geany" "A fast and lightweight IDE" off \ @@ -720,6 +625,9 @@ extra_packages() { "gnome-system-monitor" "View current processes and monitor system state" off \ "steam steam-native-runtime" "A popular game distribution platform by Valve" off \ "vlc qt4" "a free and open source cross-platform multimedia player" off \ + "mpd mpc" "Flexible, powerful, server-side application for playing music" off \ + "ncmpcpp" "An mpd client and almost exact clone of ncmpc with some new features" off \ + "cmus" "A small, fast and powerful console music player for Unix-like operating systems" off \ "audacious" "A free and advanced audio player based on GTK+" off \ "nicotine+" "A graphical client for Soulseek" off \ "lollypop" "A new music playing application" off \ @@ -740,31 +648,88 @@ extra_packages() { "libreoffice-fresh" "Full featured office suite" off \ "abiword" "Fully-featured word processor" off \ "calligra" "A set of applications for productivity" off \ - "evince" "Document viewer" off \ - "zathura" "Minimalistic document viewer" off \ + "evince" "A document viewer" off \ + "zathura zathura-pdf-poppler" "Minimalistic document viewer" off \ "qpdfview" "A tabbed PDF viewer" off \ - "mupdf" "Lightweight PDF and XPS viewer" off \ + "mupdf mupdf-tools" "Lightweight PDF and XPS viewer" off \ + "gpicview" "Lightweight image viewer" off \ "gimp" "GNU Image Manipulation Program" off \ "inkscape" "Professional vector graphics editor" off \ "krita" "Edit and paint images" off \ "simplescreenrecorder" "A feature-rich screen recorder" off \ "obs-studio" "Free opensource streaming/recording software" off \ + "openshot" "An open-source, non-linear video editor for Linux based on MLT framework" off \ + "kdenlive" "A non-linear video editor for Linux using the MLT video framework" off \ + "audacity" "A program that lets you manipulate digital audio waveforms" off \ "guvcview" "Capture video from camera devices" off \ "gpick" "Advanced color picker using GTK+ toolkit" off \ "gcolor2" "A simple GTK+2 color selector" off \ - "plank" "Stupidly simple dock" off \ - "docky" "The finest dock no money can buy" off \ - "cairo-dock" "Light, eye-candy filled dock and desklets" off \ - "ttf-hack" "A hand groomed and optically balanced typeface based on Bitstream Vera Mono." off \ + "plank" "An elegant, simple, and clean dock" off \ + "docky" "Full fledged dock that makes opening common applications and managing windows faster and easier" off \ + "cairo-dock cairo-dock-plug-ins" "Light eye-candy fully themable animated dock" off \ + "qt5-styleplugins qt5ct" "GUI for managing Qt based application themes, icons, and fonts" off \ + "ttf-hack" "A hand groomed and optically balanced typeface based on Bitstream Vera Mono" off \ "ttf-anonymous-pro" "A family of four fixed-width fonts designed especially with coding in mind" off \ "ttf-font-awesome" "Iconic font designed for Bootstrap" off \ "ttf-fira-code" "Monospaced font with programming ligatures" off \ - "noto-fonts-cjk" "Google Noto CJK fonts (Chinese, Japanese, Korean)" off)" + "noto-fonts-cjk" "Google Noto CJK fonts (Chinese, Japanese, Korean)" off \ + "noto-fonts noto-fonts-emoji" "Google Noto fonts and emoji" off)" + [[ $? != 0 ]] && return 1 + [[ $EXTRA_PACKAGES =~ kdenlive ]] && EXTRA_PACKAGES="$EXTRA_PACKAGES kdebase-runtime dvdauthor frei0r-plugins breeze breeze-gtk" + + return 0 +} + +choose_kernel() { + if ! grep -qi "hypervisor" <<< "$(dmesg)"; then + local msg="\nUse the standard current Linux kernel or the LTS kernel?" + if yesno "Choose Kernel" "$msg" "Current" "LTS"; then + KERNEL="linux" + else + KERNEL="linux-lts" + fi + fi + return 0 +} + +mirrorlist_cmd() { + MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate" + yesno "$_MirrorTitle" "$_MirrorSetup" "Automatic Sort" "Customize Sort" && return 0 + + infobox "$_MirrorTitle" "\nGathering mirror countries..\n" 0 + local countries + countries="$(reflector --list-countries | awk 'NF > 1 {print $1 " -"}')" + + if [[ $countries != "" ]]; then + tput civis + local country + country="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ + --title "$_MirrorTitle" --menu "$_MirrorCountry" 22 70 10 $countries)" + [[ $? != 0 || $country == "" ]] && return 1 + MIRROR_CMD="reflector --country $country --score 80 --latest 40 --fastest 10 --sort rate" + fi + + local ref=" --score n Limit the list to the n servers with the highest score. + --latest n Limit the list to the n most recently synchronized servers. + --fastest n Return the n fastest mirrors that meet the other criteria. + --sort {age,rate,country,score,delay} + + 'age': Last server synchronization; + 'rate': Download rate; + 'country': Server location; + 'score': MirrorStatus score; + 'delay': MirrorStatus delay." + + tput cnorm + MIRROR_CMD="$(dialog --cr-wrap --no-cancel --stdout --backtitle "$BT" \ + --title " $_MirrorTitle " --inputbox "$_MirrorCmd\n\n$ref\n" 0 0 "$cmd")" + [[ $? != 0 || $MIRROR_CMD == "" ]] && return 1 + return 0 } ###################################################################### -## System Partitioning Functions ## +## Partitioning Functions ## ###################################################################### decrease_part_count() { @@ -775,41 +740,29 @@ decrease_part_count() { return 0 } -wipe_device() { - local device="$1" - if yesno "$_PartWipe" "$_PartBody1 $device $_PartWipeBody2"; then - tput civis - wipe -Ifre "$device" | dialog --cr-wrap --backtitle "$BT" --title " $_PartWipe " \ - --progressbox "\nSecure wiping $device\n" 18 70 - else - create_partitions "$device" - fi -} - mount_partition() { local part="$1" - local mount="$2" + local mount="${MNT}$2" local fs="$(lsblk -lno FSTYPE $part)" - mkdir -p "${MNT}$mount" + mkdir -p "$mount" if [[ ${FS_OPTS[$fs]} != "" && $part != "$BOOT_PART" ]] && select_mount_opts "$part" "$fs"; then - mount -o $MNT_OPTS "$part" "${MNT}$mount" 2>$ERR - check_for_errors "mount -o $MNT_OPTS $part ${MNT}$mount" || return 1 + mount -o $MNT_OPTS $part "$mount" 2>$ERR + check_for_errors "mount -o $MNT_OPTS $part $mount" else - mount "$part" "${MNT}$mount" 2>$ERR - check_for_errors "mount $part ${MNT}$mount" || return 1 + mount $part "$mount" 2>$ERR + check_for_errors "mount $part $mount" fi - confirm_mount "$part" "${MNT}$mount" || return 1 + confirm_mount $part "$mount" || return 1 check_part_is_crypt_or_lvm "$part" return 0 } unmount_partitions() { swapoff -a - - for i in $(mount | grep "$MNT" | awk '{print $3}' | sort -r); do + for i in $(mount | awk "/${MNT//\//\\/}/"' {print $3}' | sort -r); do umount -r "$i" >/dev/null 2>&1 done } @@ -826,13 +779,14 @@ confirm_mount() { # partition failed to mount properly if ! grep -q "$mount" <<< "$(mount)"; then - infobox "$_MntTitle" "$_MntFail\n$msg\n" + infobox "$_MntTitle" "$_MntFail\n$msg\n" 1 return 1 + else + # mount was successful + infobox "$_MntTitle" "$_MntSucc\n$msg\n" 1 + decrease_part_count "$part" fi - # mount was successful - infobox "$_MntTitle" "$_MntSucc\n$msg\n" - decrease_part_count "$part" return 0 } @@ -877,26 +831,27 @@ auto_partition() { # confirm or bail yesno "$_PrepParts" "$_PartBody1 $device $_PartBody2" || return 0 - infobox "$_PrepParts" "\nAuto partitioning device: $device\n" + infobox "$_PrepParts" "\nAuto partitioning device: $device\n" 0 swapoff -a # make sure swap is disabled in case the device was used for swap - # walk the partitions on the device in reverse order and delete them local dev_info="$(parted -s $device print)" + + # walk the partitions on the device in reverse order and delete them for i in $(awk '/^ [1-9][0-9]?/ {print $1}' <<< "$dev_info" | sort -r); do parted -s $device rm $i 2>$ERR - check_for_errors "parted -s $device rm $i" || { break; return 1; } + check_for_errors "parted -s $device rm $i" done # make sure we have the correct device table for the system type, gpt or msdos - local table="$(awk '/Table:/ {print $3}' <<< "$dev_info")" local newtable="gpt" + local table="$(awk '/Table:/ {print $3}' <<< "$dev_info")" [[ $SYS == BIOS ]] && newtable="msdos" # if the current device table isn't correct run mklabel if [[ $table != "$newtable" ]]; then parted -s $device mklabel $newtable 2>$ERR - check_for_errors "parted -s $device mklabel $newtable" || return 1 + check_for_errors "parted -s $device mklabel $newtable" fi # when device contains the string 'nvme' then add 'p' before the part number @@ -908,29 +863,29 @@ auto_partition() { if [[ $SYS == "BIOS" ]]; then parted -s $device mkpart primary ext4 1MiB 513MiB 2>$ERR - check_for_errors "parted -s $device mkpart primary ext4 1MiB 513MiB" || return 1 + check_for_errors "parted -s $device mkpart primary ext4 1MiB 513MiB" mkfs.ext4 -q $BOOT_PART >/dev/null 2>$ERR - check_for_errors "mkfs.ext4 -q $BOOT_PART" || return 1 + check_for_errors "mkfs.ext4 -q $BOOT_PART" else parted -s $device mkpart ESP fat32 1MiB 513MiB 2>$ERR - check_for_errors "parted -s $device mkpart ESP fat32 1MiB 513MiB" || return 1 + check_for_errors "parted -s $device mkpart ESP fat32 1MiB 513MiB" mkfs.vfat -F32 $BOOT_PART >/dev/null 2>$ERR - check_for_errors "mkfs.vfat -F32 $BOOT_PART" || return 1 + check_for_errors "mkfs.vfat -F32 $BOOT_PART" parted -s $device set $part_num esp on 2>$ERR - check_for_errors "parted -s $device set $part_num esp on" || return 1 + check_for_errors "parted -s $device set $part_num esp on" fi parted -s $device set $part_num boot on 2>$ERR - check_for_errors "parted -s $device set $part_num boot on" || return 1 + check_for_errors "parted -s $device set $part_num boot on" (( part_num++ )) # increment the partition number BOOT_DEVICE="$device" # only grub on BIOS systems uses this ROOT_PART="${device}${nvme}$part_num" # set root partition label to the second partition parted -s $device mkpart primary ext4 514MiB 100% 2>$ERR - check_for_errors "parted -s $device mkpart primary ext4 514MiB 100%" || return 1 + check_for_errors "parted -s $device mkpart primary ext4 514MiB 100%" mkfs.ext4 -q $ROOT_PART >/dev/null 2>$ERR - check_for_errors "mkfs.ext4 -q $ROOT_PART" || return 1 + check_for_errors "mkfs.ext4 -q $ROOT_PART" tput civis; sleep 0.5 echo -e "\nAuto partitioning complete.\n" > /tmp/.devlist @@ -941,29 +896,32 @@ auto_partition() { create_partitions() { local device="$1" - local choice + tput civis - if hash gparted >/dev/null 2>&1 && [[ $DISPLAY ]]; then - choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PartTitle " \ - --menu "$_PartBody" 0 0 0 "$_PartAuto" "BIOS & UEFI" \ - "gparted" "BIOS & UEFI" "cfdisk" "BIOS & UEFI" "parted" "BIOS & UEFI" "$_PartWipe" "BIOS & UEFI")" - else - choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PartTitle " \ - --menu "$_PartBody" 0 0 0 "$_PartAuto" "BIOS & UEFI" \ - "cfdisk" "BIOS & UEFI" "parted" "BIOS & UEFI" "$_PartWipe" "BIOS & UEFI")" - fi - [[ $? != 0 || $choice == "" ]] && return 1 || clear + local choice + choice="$(dialog --cr-wrap --stdout --backtitle "$BT" \ + --title " $_PartTitle " --menu "$_PartBody" 0 0 0 "$_PartAuto" "-" \ + $( ([[ $DISPLAY ]] && hash gparted >/dev/null 2>&1) && echo -n "gparted -") "cfdisk" "-"\ + "parted" "-" "$_PartWipe" "-")" + [[ $? != 0 || $choice == "" ]] && return 1 + + clear + tput cnorm if [[ $choice != "$_PartWipe" && $choice != "$_PartAuto" ]]; then $choice $device elif [[ $choice == "$_PartWipe" ]]; then - wipe_device $device && create_partitions $device + if yesno "$_PartWipe" "$_PartBody1 $device $_PartWipeBody2"; then + wipe -Ifrev $device + fi + create_partitions $device else + # if auto_partition fails we need to re-initialize the variables, just to be sure auto_partition $device || { initialize_variables; return 1; } fi } -get_swap_size() { +swapfile_size() { tput cnorm SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "$SWAP_SIZE")" [[ $? != 0 || $SWAP_SIZE == "" ]] && return 1 @@ -972,8 +930,21 @@ get_swap_size() { if ! [[ ${SWAP_SIZE:0:1} =~ [1-9] && ${SWAP_SIZE: -1} =~ (M|G) ]]; then msgbox "$_SelSwpSetup Error" "\n$_SelSwpErr $SWAP_SIZE\n" SWAP_SIZE="${SYS_MEM}M" - get_swap_size || return 1 + swapfile_size || return 1 + else + fallocate -l $SWAP_SIZE $MNT/swapfile >/dev/null 2>&1 + chmod 600 $MNT/swapfile >/dev/null 2>&1 fi + + return 0 +} + +enable_swap() { + local swap="$1" + mkswap $swap >/dev/null 2>$ERR + check_for_errors "mkswap $swap" + swapon $swap >/dev/null 2>$ERR + check_for_error "swapon $swap" || return 1 return 0 } @@ -984,58 +955,39 @@ select_swap() { [[ $? != 0 || $SWAP == "$_SelSwpNone" ]] && return 0 if [[ $SWAP == "$_SelSwpFile" ]]; then - get_swap_size || return 1 - - fallocate -l $SWAP_SIZE $MNT/swapfile 2>$ERR - check_for_errors "fallocate -l $size $MNT/swapfile" || return 1 - chmod 600 $MNT/swapfile 2>$ERR - check_for_errors "chmod 600 $MNT/swapfile" || return 1 - - mkswap $MNT/swapfile >/dev/null 2>$ERR - check_for_errors "mkswap $MNT/swapfile" || return 1 - swapon $MNT/swapfile >/dev/null 2>$ERR - check_for_errors "swapon $MNT/swapfile" || return 1 - SWAP_FILE="/swapfile" + swapfile_size || return 1 + enable_swap "$MNT/swapfile" || return 1 + SWAP="/swapfile" else - # Warn user if creating a new swap on the chosen partition - if ! grep -qi "swap" <<< "$(lsblk -o FSTYPE $SWAP)"; then - yesno "$_PrepMount" "\nmkswap $SWAP\n" || return 0 - mkswap $SWAP >/dev/null 2>$ERR - check_for_errors "mkswap $SWAP" || return 1 - fi - - swapon $SWAP >/dev/null 2>$ERR - check_for_error "swapon $SWAP" || return 1 + enable_swap "$SWAP" || return 1 decrease_part_count "$SWAP" - SWAP_FILE="$SWAP" fi return 0 } select_device() { - local msg="" + local msg [[ $1 == 'boot' ]] && msg="$_DevSelTitle for bootloader\n" if (( DEV_COUNT == 1 )); then DEVICE="$(awk '{print $1}' <<< "$SYS_DEVS")" - infobox "$_DevSelTitle" "\nOnly one device available$([[ $1 == 'boot' ]] && echo -n " for bootloader"): $DEVICE\n" + msg="\nOnly one device available$([[ $1 == 'boot' ]] && echo -n " for grub bootloader"):" + infobox "$_DevSelTitle" "$msg $DEVICE\n" 1 elif (( DEV_COUNT > 1 )); then tput civis DEVICE="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_DevSelTitle " \ --menu "${msg}$_DevSelBody" 0 0 0 $SYS_DEVS)" [[ $? != 0 || $DEVICE == "" ]] && return 1 else - msgbox "$_ErrTitle" "\nNo available devices for installation to use.\n\nExiting.." - pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail" - tput cnorm - clear - exit 1 + msg="\nNo available devices for installation to use$([[ $1 == 'boot' ]] && echo -n " for grub bootloader")." + msgbox "$_ErrTitle" "$msg\n$_Exit" + die 1 fi - # if the device selected was for grub, set the BOOT_DEVICE + # if the device selected was for grub bootloader, set the BOOT_DEVICE # this is needed because grub uses the base device for BIOS, not the partition - [[ $msg != "" ]] && BOOT_DEVICE="$DEVICE" + [[ $1 == 'boot' ]] && BOOT_DEVICE="$DEVICE" return 0 } @@ -1074,9 +1026,9 @@ select_filesystem() { [[ $choice == "" ]] && return 1 if yesno "$_FSTitle" "\nFormat $part as $choice?\n"; then - infobox "$_FSTitle" "\nFormatting: $part\n\nCommand: ${FS_CMDS[$choice]}\n" + infobox "$_FSTitle" "\nFormatting: $part\n\nCommand: ${FS_CMDS[$choice]}\n" 0 ${FS_CMDS[$choice]} $part >/dev/null 2>$ERR - check_for_errors "${FS_CMDS[$choice]} $part" || return 1 + check_for_errors "${FS_CMDS[$choice]} $part" else select_filesystem "$part" || return 1 fi @@ -1091,33 +1043,23 @@ select_boot_setup() { --title " $_PrepMount " --menu "$_MntBootBody" 0 0 0 ${BOOTLOADERS[$SYS]})" [[ $? != 0 || $BOOTLOADER == "" ]] && return 1 - if [[ $SYS == 'BIOS' ]]; then - if [[ $BOOTLOADER == "grub" && $BOOT_DEVICE == "" ]]; then - # grub BIOS needs an install device eg. /dev/sda - select_device 'boot' || return 1 - BOOT_DEVICE="$DEVICE" - else - local cmd - cmd="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_InstSysTitle " \ - --menu "$_InstSysBody\nDefault: ${BOOT_CMDS[syslinux]}" 0 0 0 \ - "syslinux-install_update -iam" "[MBR]" \ - "syslinux-install_update -i" "[/]")" - [[ $? != 0 || $cmd == "" ]] && return 1 - BOOT_CMDS[syslinux]="$cmd" - EDIT_FILES[9]="/boot/syslinux/syslinux.cfg" - fi - else - if [[ $BOOTLOADER == 'systemd-boot' ]]; then - EDIT_FILES[9]="/boot/loader/entries/archlabs.conf" - else - EDIT_FILES[9]="/etc/default/grub" - fi + if [[ $SYS == 'BIOS' && $BOOTLOADER == 'grub' && $BOOT_DEVICE == "" ]]; then + # grub on BIOS needs an install device, NOT partition eg. /dev/sda + select_device 'boot' || return 1 fi - # if BOOT_PART was set, mount the partition to the correct mountpoint - if [[ $BOOT_PART != "" ]]; then - mount_partition "$BOOT_PART" "${BOOT_MNTS[$SYS-$BOOTLOADER]}" || return 1 - SEPERATE_BOOT=1 + if [[ $BOOTLOADER == 'systemd-boot' ]]; then + EDIT_FILES[9]="/boot/loader/entries/$DIST.conf" + elif [[ $BOOTLOADER == 'syslinux' ]]; then + if [[ $SYS == 'BIOS' ]]; then + BOOT_CMDS[$BOOTLOADER]="$(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 (/)")" + [[ $? != 0 || ${BOOT_CMDS[$BOOTLOADER]} == "" ]] && return 1 + fi + else + EDIT_FILES[9]="/etc/default/grub" fi return 0 @@ -1125,14 +1067,14 @@ select_boot_setup() { select_efi_partition() { format_efi_as_vfat() { - infobox "$_FSTitle" "\nFormatting $1 as vfat/fat32.\n" + infobox "$_FSTitle" "\nFormatting $1 as vfat/fat32.\n" 0 mkfs.vfat -F32 "$1" >/dev/null 2>$ERR - check_for_errors "mkfs.vfat -F32 $1" || return 1 + check_for_errors "mkfs.vfat -F32 $1" } if (( COUNT == 1 )); then BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" - infobox "$_PrepMount" "\nOnly one partition available for EFI: $BOOT_PART\n" + infobox "$_PrepMount" "$_OnlyOne for EFI: $BOOT_PART\n" 1 else tput civis BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepMount " \ @@ -1155,9 +1097,9 @@ select_efi_partition() { select_bios_boot_partition() { format_as_ext4() { - infobox "$_FSTitle" "\nFormatting $1 as ext4.\n" + infobox "$_FSTitle" "\nFormatting $1 as ext4.\n" 0 mkfs.ext4 -q "$1" >/dev/null 2>$ERR - check_for_errors "mkfs.ext4 -q $1" || return 1 + check_for_errors "mkfs.ext4 -q $1" } tput civis @@ -1176,18 +1118,19 @@ select_bios_boot_partition() { format_as_ext4 "$BOOT_PART" || return 1 fi - # set BOOT_DEVICE for BIOS grub by removing digit from the end - BOOT_DEVICE="${BOOT_PART%[1-9]}" - PART_NUM="${BOOT_PART#$BOOT_DEVICE}" + # set BOOT_DEVICE for grub on BIOS systems and syslinux on UEFI + BOOT_DEVICE="${BOOT_PART%%([1-9]|(p)[1-9])}" + BOOT_PART_NUM="${BOOT_PART: -1}" - parted -s $BOOT_DEVICE set $PART_NUM boot on 2>$ERR - check_for_errors "parted -s $BOOT_DEVICE set $PART_NUM boot on" || return 1 + parted -s $BOOT_DEVICE set $BOOT_PART_NUM boot on 2>$ERR + check_for_errors "parted -s $BOOT_DEVICE set $BOOT_PART_NUM boot on" fi return 0 } select_root_partition() { + # if we used LUKS and no LVM or LUKS+LVM if (( LUKS == 1 && LVM == 0 )); then ROOT_PART="/dev/mapper/$LUKS_NAME" decrease_part_count "$LUKS_PART" @@ -1199,18 +1142,19 @@ select_root_partition() { if [[ $COUNT -eq 1 && $ROOT_PART == "" ]]; then ROOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" - infobox "$_PrepMount" "\nOnly one partition available for root (/): $ROOT_PART\n" + infobox "$_PrepMount" "$_OnlyOne for root (/): $ROOT_PART\n" 1 elif [[ $ROOT_PART == "" || $LVM -eq 1 ]]; then tput civis ROOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" --title "$_PrepMount" \ --menu "$_SelRootBody" 0 0 0 $PARTS)" [[ $? != 0 || $ROOT_PART == "" ]] && return 1 else - infobox "$_PrepMount" "\nUsing $([[ $LUKS -eq 1 ]] && echo -n "encrypted ")root partition: $ROOT_PART\n" + local msg="\nUsing $([[ $LUKS -eq 1 ]] && echo -n "encrypted ")root partition:" + infobox "$_PrepMount" "$msg $ROOT_PART\n" 1 fi select_filesystem "$ROOT_PART" || { ROOT_PART=""; return 1; } - mount_partition "$ROOT_PART" "" || { ROOT_PART=""; return 1; } + mount_partition "$ROOT_PART" || { ROOT_PART=""; return 1; } return 0 } @@ -1235,8 +1179,6 @@ select_extra_partitions() { local part part="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepMount " \ --menu "$_ExtPartBody" 0 0 0 "$_Done" "-" $PARTS)" - - # cancel or done, exit normally [[ $? != 0 || $part == "$_Done" || $part == "" ]] && break # choose what filesystem and get mountpoint @@ -1272,10 +1214,16 @@ select_install_partitions() { select_bios_boot_partition || { BOOT_PART=""; return 1; } fi else - infobox "$_PrepMount" "\nUsing boot partition: $BOOT_PART\n" + infobox "$_PrepMount" "\nUsing boot partition: $BOOT_PART\n" 1 fi select_boot_setup || { BOOTLOADER=""; return 1; } + + if [[ $BOOT_PART != "" ]]; then + mount_partition "$BOOT_PART" "${BOOT_MNTS[$SYS-$BOOTLOADER]}" || return 1 + SEPERATE_BOOT=1 + fi + select_swap || return 1 select_extra_partitions || return 1 @@ -1328,7 +1276,7 @@ check_part_is_crypt_or_lvm() { } ###################################################################### -## Encryption (dm_crypt) Functions ## +## LUKS Functions ## ###################################################################### luks_open() { @@ -1340,7 +1288,7 @@ luks_open() { if (( COUNT == 1 )); then LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" - infobox "$_LuksOpen" "\nOnly one partition available: $LUKS_PART\n" + infobox "$_LuksOpen" "${_OnlyOne}: $LUKS_PART\n" 1 else tput civis LUKS_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_LuksOpen " \ @@ -1351,9 +1299,9 @@ luks_open() { # get password and name for encryption luks_input_values "$_LuksOpen" "$LUKS_NAME" || return 1 - infobox "$_LuksOpen" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" + infobox "$_LuksOpen" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 echo "$LUKS_PASS" | cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" 2>$ERR - check_for_errors "cryptsetup open --type luks $LUKS_PART $LUKS_NAME" || return 1 + check_for_errors "cryptsetup open --type luks $LUKS_PART $LUKS_NAME" LUKS=1 luks_show @@ -1364,7 +1312,9 @@ luks_input_values() { local title="$1" local name="$2" LUKS_PASS="" + tput cnorm + local values values="$(dialog --stdout --separator '~' --ok-label "Submit" --backtitle "$BT" \ --title " $title " --insecure --mixedform "$_LuksOpenBody" 16 75 4 \ @@ -1372,6 +1322,7 @@ luks_input_values() { "$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \ "$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1)" [[ $? != 0 || $values == "" ]] && return 1 + name="$(awk -F'~' '{print $1}' <<< "$values")" local pass pass2 @@ -1399,7 +1350,7 @@ luks_setup() { if (( COUNT == 1 )); then LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")" - infobox "$_LuksEncrypt" "\nOnly one partition available: $LUKS_PART\n" + infobox "$_LuksEncrypt" "${_OnlyOne}: $LUKS_PART\n" 1 else tput civis LUKS_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \ @@ -1407,27 +1358,24 @@ luks_setup() { [[ $? != 0 || $LUKS_PART == "" ]] && return 1 fi else - infobox "$_PrepMount" "\nUsing root partition created in auto partitioning: $ROOT_PART\n" + infobox "$_PrepMount" "\nUsing root partition created earlier: $ROOT_PART\n" 1 LUKS_PART="$ROOT_PART" fi - # get password and name for encryption + # get password and name for encrypted device luks_input_values "$_LuksEncrypt" "$LUKS_NAME" || return 1 - return 0 } luks_default() { luks_setup || return 1 - - local msg="$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" - infobox "$_LuksEncrypt" "$msg" + infobox "$_LuksEncrypt" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 echo "$LUKS_PASS" | cryptsetup -q luksFormat "$LUKS_PART" 2>$ERR - check_for_errors "cryptsetup -q luksFormat $LUKS_PART" || return 1 + check_for_errors "cryptsetup -q luksFormat $LUKS_PART" echo "$LUKS_PASS" | cryptsetup open "$LUKS_PART" "$LUKS_NAME" 2>$ERR - check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME" || return 1 + check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME" LUKS=1 luks_show @@ -1441,13 +1389,13 @@ luks_cipher_key() { cipher="$(getinput "$_PrepLUKS" "$_LuksCipherKey" "-s 512 -c aes-xts-plain64")" [[ $? != 0 || $cipher == "" ]] && return 1 - infobox "$_LuksEncryptAdv" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" + infobox "$_LuksEncryptAdv" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0 echo "$LUKS_PASS" | cryptsetup -q $cipher luksFormat $LUKS_PART 2>$ERR - check_for_errors "cryptsetup -q $cipher luksFormat $LUKS_PART" || return 1 + check_for_errors "cryptsetup -q $cipher luksFormat $LUKS_PART" echo "$LUKS_PASS" | cryptsetup open $LUKS_PART "$LUKS_NAME" 2>$ERR - check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME" || return 1 + check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME" luks_show return 0 @@ -1490,7 +1438,7 @@ luks_keyfile() { # to enter password for decryption twice, this is annoying if [[ ! -e $MNT/crypto_keyfile.bin ]]; then - infobox "$_LuksKeyFileTitle" "$_LuksKeyFileCreate" + infobox "$_LuksKeyFileTitle" "$_LuksKeyFileCreate" 0 local dev dev="/dev/$(lsblk -lno NAME,UUID,TYPE | awk "/$LUKS_UUID/"' && /part|crypt|lvm/ {print $1}')" @@ -1500,17 +1448,17 @@ luks_keyfile() { keycmd="$keycmd && echo '$LUKS_PASS' | cryptsetup luksAddKey $dev /crypto_keyfile.bin" chroot_cmd "$keycmd" 2>$ERR - check_for_errors "$keycmd" || return 1 + check_for_errors "$keycmd" sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf 2>$ERR - check_for_errors 'sed -i "s/FILES=()/FILES=(/crypto_keyfile.bin)/g"' || return 1 + check_for_errors 'sed -i "s/FILES=()/FILES=(/crypto_keyfile.bin)/g"' fi return 0 } ###################################################################### -## Logical Volume Management Functions ## +## LVM Functions ## ###################################################################### lvm_detect() { @@ -1519,10 +1467,10 @@ lvm_detect() { VOLUMES="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)" if [[ $VOLUMES && $VOLUME_GROUP && $PHYSICAL_VOLUMES ]]; then - infobox "$_PrepLVM" "$_LvmDetBody" + infobox "$_PrepLVM" "$_LvmDetBody" 0 modprobe dm-mod 2>$ERR - check_for_errors 'modprobe dm-mod' || return 1 + check_for_errors 'modprobe dm-mod' vgscan >/dev/null 2>&1 vgchange -ay >/dev/null 2>&1 @@ -1551,7 +1499,7 @@ lvm_show_vg() { get_lv_size() { tput cnorm local ttl=" $_LvmCreateVG (LV:$VOL_COUNT) " - local msg="${VOLUME_GROUP}: ${VOL_GROUP_SIZE}$VOL_GROUP_SIZE_TYPE (${VOL_GROUP_MB}MB $_LvmLvSizeBody1).$_LvmLvSizeBody2" + local msg="${VOLUME_GROUP}: ${GROUP_SIZE}$GROUP_SIZE_TYPE (${VOL_GROUP_MB}MB $_LvmLvSizeBody1).$_LvmLvSizeBody2" VOLUME_SIZE="$(getinput "$ttl" "$msg" "")" [[ $? != 0 || $VOLUME_SIZE == "" ]] && return 1 @@ -1576,23 +1524,13 @@ get_lv_size() { esac if (( ERR_SIZE == 0 )); then - s=${VOLUME_SIZE:0:$lv} - m=$((s * 1000)) + local s=${VOLUME_SIZE:0:$lv} + local m=$((s * 1000)) # check whether the value is greater than or equal to the LV remaining Size. # if not, convert into MB for VG space remaining. case ${VOLUME_SIZE:$lv:1} in - [Gg]) - if (( m >= VOL_GROUP_MB )); then - ERR_SIZE=1 - else - VOL_GROUP_MB=$((VOL_GROUP_MB - m)) - fi ;; - [Mm]) - if (( ${VOLUME_SIZE:0:$lv} >= VOL_GROUP_MB )); then - ERR_SIZE=1 - else - VOL_GROUP_MB=$((VOL_GROUP_MB - s)) - fi ;; + [Gg]) (( m >= VOL_GROUP_MB )) && ERR_SIZE=1 || VOL_GROUP_MB=$((VOL_GROUP_MB - m)) ;; + [Mm]) (( ${VOLUME_SIZE:0:$lv} >= VOL_GROUP_MB )) && ERR_SIZE=1 || VOL_GROUP_MB=$((VOL_GROUP_MB - s)) ;; *) ERR_SIZE=1 esac fi @@ -1652,10 +1590,10 @@ lvm_extra_lvs() { # create it lvcreate -L "$VOLUME_SIZE" "$VOLUME_GROUP" -n "$VOLUME_NAME" 2>$ERR - check_for_errors "lvcreate -L $VOLUME_SIZE $VOLUME_GROUP -n $VOLUME_NAME" || { break; return 1; } + check_for_errors "lvcreate -L $VOLUME_SIZE $VOLUME_GROUP -n $VOLUME_NAME" msgbox "$_LvmCreateVG (LV:$VOL_COUNT)" "$_Done LV $VOLUME_NAME ($VOLUME_SIZE) $_LvmPvDoneBody2." - ((VOL_COUNT--)) # decrement the number of volumes chosen to end the loop + ((VOL_COUNT--)) # decrement the number of volumes chosen after each loop done return 0 @@ -1664,71 +1602,76 @@ lvm_extra_lvs() { lvm_volume_count() { VOL_COUNT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_LvmCreateVG " \ --radiolist "$_LvmLvNumBody1 $VOLUME_GROUP\n$_LvmLvNumBody2" 0 0 0 \ - "1" "-" off "2" "-" off "3" "-" off "4" "-" off "5" "-" off "6" "-" off "7" "-" off "8" "-" off "9" "-" off) + "1" "-" off "2" "-" off "3" "-" off "4" "-" off "5" "-" off \ + "6" "-" off "7" "-" off "8" "-" off "9" "-" off) [[ $? != 0 || $VOL_COUNT == "" ]] && return 1 return 0 } +lvm_partitions() { + find_partitions 'part|crypt' + PARTS="$(awk 'NF > 0 {print $0 " off"}' <<< "$PARTS")" + + # choose partitions + tput civis + GROUP_PARTS="$(dialog --cr-wrap --stdout --backtitle "$BT" \ + --title "$_LvmCreateVG" --checklist "$_LvmPvSelBody" 0 0 0 $PARTS)" + [[ $? != 0 || $GROUP_PARTS == "" ]] && return 1 + + return 0 +} + +lvm_create_group() { + # get volume group name + lvm_group_name || return 1 + + # loop while setup is not confirmed by the user + while ! yesno "$_LvmCreateVG" "$_LvmPvConfBody1 $VOLUME_GROUP\n\n$_LvmPvConfBody2 $GROUP_PARTS\n"; do + lvm_partitions || { break; return 1; } + lvm_group_name || { break; return 1; } + done + + # create it + infobox "$_LvmCreateVG" "$_LvmPvActBody1 $VOLUME_GROUP\n" 0 + vgcreate -f "$VOLUME_GROUP" "$GROUP_PARTS" >/dev/null 2>$ERR + check_for_errors "vgcreate -f $VOLUME_GROUP $GROUP_PARTS" + + # get volume size size and transform size to MB if size is given in GB + GROUP_SIZE=$(vgdisplay "$VOLUME_GROUP" | awk '/VG Size/ {print int($3)}') + GROUP_SIZE_TYPE="$(vgdisplay "$VOLUME_GROUP" | awk '/VG Size/ {print substr($NF, 0, 1)}')" + [[ $GROUP_SIZE_TYPE == 'G' ]] && VOL_GROUP_MB=$((GROUP_SIZE * 1000)) || VOL_GROUP_MB=$GROUP_SIZE + + # finished volume group creation + local msg="$_LvmPvDoneBody1 $VOLUME_GROUP ($GROUP_SIZE $GROUP_SIZE_TYPE)" + msgbox "$_LvmCreateVG" "$msg $_LvmPvDoneBody2\n" + return 0 +} + lvm_create() { VOLUME_GROUP="" - VOL_GROUP_PARTS="" + GROUP_PARTS="" VOL_GROUP_MB=0 unmount_partitions if [[ $LUKS -eq 1 && $LUKS_NAME != "" ]]; then - VOL_GROUP_PARTS="/dev/mapper/$LUKS_NAME" - infobox "$_LvmCreateVG" "\nUsing encrypted partition created earlier: $VOL_GROUP_PARTS\n" + GROUP_PARTS="/dev/mapper/$LUKS_NAME" + infobox "$_LvmCreateVG" "\nUsing encrypted partition created earlier: $GROUP_PARTS\n" 1 else - find_partitions 'part|crypt' - tput civis - PARTS="$(awk 'NF > 0 {print $0 " off"}' <<< "$PARTS")" - - # choose partitions - VOL_GROUP_PARTS="$(dialog --cr-wrap --stdout --backtitle "$BT" \ - --title "$_LvmCreateVG" --checklist "$_LvmPvSelBody" 0 0 0 $PARTS)" - [[ $? != 0 || $VOL_GROUP_PARTS == "" ]] && return 1 + lvm_partitions || return 1 fi - # get volume group name then confirm or bail out - lvm_group_name || return 1 - yesno "$_LvmCreateVG" "$_LvmPvConfBody1 $VOLUME_GROUP\n\n$_LvmPvConfBody2 $VOL_GROUP_PARTS\n" || return 1 - - # create it - infobox "$_LvmCreateVG" "$_LvmPvActBody1 $VOLUME_GROUP\n" - vgcreate -f "$VOLUME_GROUP" "$VOL_GROUP_PARTS" >/dev/null 2>$ERR - check_for_errors "vgcreate -f $VOLUME_GROUP $VOL_GROUP_PARTS" || return 1 - - # get volume size and size type (MB, GB, etc..) - VOL_GROUP_SIZE=$(vgdisplay "$VOLUME_GROUP" | awk '/VG Size/ {gsub(/\..*|[^0-9]*/, ""); print}') - VOL_GROUP_SIZE_TYPE="$(vgdisplay "$VOLUME_GROUP" | awk '/VG Size/ {print $4}')" - - # transform size to MB if needed - if [[ ${VOL_GROUP_SIZE_TYPE:0:1} == "G" ]]; then - VOL_GROUP_MB=$((VOL_GROUP_SIZE * 1000)) - else - VOL_GROUP_MB=$VOL_GROUP_SIZE - fi - - # finished volume group creation - msgbox "$_LvmCreateVG" "$_LvmPvDoneBody1 $VOLUME_GROUP ($VOL_GROUP_SIZE $VOL_GROUP_SIZE_TYPE) $_LvmPvDoneBody2\n" - tput civis - - # how many logical volumes - lvm_volume_count || return 1 - - # if we chose more than one logical volume create all but the last - lvm_extra_lvs || return 1 + lvm_create_group || return 1 # create the volume group we'll be using + lvm_volume_count || return 1 # how many logical volumes to create on the group + lvm_extra_lvs || return 1 # if we chose more than one logical volume create all but the last # last or only logical volume lvm_volume_name "$_LvmLvNameBody1 $_LvmLvNameBody2 (${VOL_GROUP_MB}MB)" || return 1 - - # create it lvcreate -l +100%FREE "$VOLUME_GROUP" -n "$VOLUME_NAME" 2>$ERR - check_for_errors "lvcreate -l +100%FREE $VOLUME_GROUP -n $VOLUME_NAME" || return 1 + check_for_errors "lvcreate -l +100%FREE $VOLUME_GROUP -n $VOLUME_NAME" + LVM=1 - # offer the user to see the device tree - yesno "$_LvmCreateVG" "$_LvmCompBody" && show_devices + show_devices return 0 } @@ -1783,117 +1726,134 @@ lvm_menu() { } ###################################################################### -## Installation Functions ## +## Install Functions ## ###################################################################### install_main() { - if [[ $UNPACKED_BASE != true ]]; then - # whether to use a custom mirror sorting command later - mirrorlist_cmd || MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate" - window_manager || return 1 - extra_packages + # whether to use a custom mirror sorting command later + oneshot set_hostname || return 1 + oneshot set_locale || return 1 + oneshot set_timezone || return 1 + oneshot user_setup || return 1 + oneshot mirrorlist_cmd || return 1 + oneshot window_manager || return 1 # choose which window managers/desktop environment to install + oneshot extra_packages || return 1 + oneshot choose_kernel - if yesno "Choose Kernel" "\nWant to use the standard linux or linux LTS kernel" "Linux" "Linux LTS"; then - KERNEL="linux" - else - KERNEL="linux-lts" - fi - - # user can choose to bail at this point - unpack_base_system || { initialize_variables; return 1; } - fi + # unpack the whole filesystem to install directory $MNT + oneshot install_base genfstab -U $MNT > $MNT/etc/fstab 2>$ERR - check_for_errors "genfstab -U $MNT > $MNT/etc/fstab" || return 1 + check_for_errors "genfstab -U $MNT > $MNT/etc/fstab" if [[ -f $MNT/swapfile ]]; then sed -i "s~${MNT}~~" $MNT/etc/fstab 2>$ERR - check_for_errors "sed -i s~${MNT}~~ $MNT/etc/fstab" || return 1 + check_for_errors "sed -i s~${MNT}~~ $MNT/etc/fstab" fi + # run package operations before bootloader and mkinitcpio + # due to the possibility of choosing lts kernel earlier + oneshot update_mirrorlist + oneshot update_system + oneshot install_packages + [[ $LOGIN_TYPE == 'lightdm' ]] && oneshot setup_lightdm + run_mkinitcpio || return 1 - setup_bootloader || return 1 + install_bootloader || return 1 - if [[ $HAS_NETWORK == true && $DONE_UPDATE != true ]]; then - update_mirrorlist - update_system - DONE_UPDATE=true - else - if ! grep -qi "hypervisor" <<< "$(dmesg)"; then - chroot_cmd "pacman -Rns archlabs-installer virtualbox-guest-utils virtualbox-guest-modules-arch --noconfirm" 2>/dev/null - [[ -e $MNT/etc/xdg/autostart/vboxclient.desktop ]] && rm -f $MNT/etc/xdg/autostart/vboxclient.desktop - else - chroot_cmd "pacman -Rs archlabs-installer --noconfirm" 2>/dev/null - fi - fi - - # these also only should need to be run once, when done jump to the config edit menu - if [[ $FULL_DONE != true ]]; then - configure_menu - if edit_config_menu; then - [[ $FULL_DONE == true ]] && return 0 - fi - fi + oneshot set_hwclock + oneshot create_user || return 1 + oneshot edit_configs return 0 } -unpack_base_system() { - # continue or bail - local msg="Boot Partition: ${BOOT_PART:-none}\nBootloader: $BOOTLOADER\nSwapfile: $SWAP_FILE" - yesno "$_InstTitle" "$_BeginInst $ROOT_PART\n$msg\n\n$_ContinueYN" || return 1 - - # create a loading bar while copying files using find, < <(), and a loop - # using awk, sed, or other means doesn't seem to work well (or at all). - local files=($(find /run/archiso/sfs/airootfs/ -maxdepth 1 -mindepth 1)) - local total=${#files[@]} - local increment=0 - tput civis - dialog --cr-wrap --backtitle "$BT" --title " $_InstTitle " \ - --gauge "\nUnpacking the system\n" 7 70 < <( - for f in "${files[@]}"; do - current_percent=$((100 * (++increment) / total)) - base="${f#/run/archiso/sfs/airootfs/}" - cat <$ERR + check_for_errors 'locale-gen' + chroot_cmd "ln -sf /usr/share/zoneinfo/$ZONE/$SUBZONE /etc/localtime" 2>$ERR + check_for_errors "ln -sf /usr/share/zoneinfo/$ZONE/$SUBZONE /etc/localtime" + + # setup xorg vsync config for intel graphics + if [[ $(lspci | grep ' VGA ' | grep 'Intel') != "" ]]; then + cat > $MNT/etc/X11/xorg.conf.d/20-intel.conf < $MNT/etc/X11/xorg.conf.d/00-keyboard.conf < $MNT/etc/default/keyboard < $MNT/etc/vconsole.conf < $MNT/etc/hostname + cat > $MNT/etc/hosts << EOF +127.0.0.1 localhost +127.0.1.1 $HOSTNAME +::1 localhost ip6-localhost ip6-loopback +ff02::1 ip6-allnodes +ff02::2 ip6-allrouters +EOF return 0 } update_system() { + tput cnorm local pkgcmd if [[ $KERNEL == 'linux-lts' ]]; then pkgcmd="pacman -Rs linux --noconfirm ; pacman -S iputils --noconfirm ; pacman -S base-devel git linux-lts linux-lts-headers --needed --noconfirm" @@ -1915,10 +1875,7 @@ update_system() { find $MNT/boot/ -name 'grub*' -exec rm -rf '{}' \; >/dev/null 2>&1 fi - tput cnorm chroot_cmd "pacman -Syyu --noconfirm ; $pkgcmd" 2>/dev/null - - install_packages return 0 } @@ -1939,18 +1896,33 @@ install_packages() { REMOVE_PKGS="$(pacman -Qssq 'xfce4*' 2>/dev/null)" fi + if [[ $INSTALL_WMS =~ dwm ]]; then + oldPWD="$PWD" + mkdir -p $MNT/home/$NEWUSER/suckless + for n in dwm st dmenu; do + git clone https://bitbucket.org/natemaia/$n $MNT/home/$NEWUSER/suckless/$n + cd $MNT/home/$NEWUSER/suckless/$n + make clean install && make clean + echo -e "\n$n has been installed..\n\nSee /home/$NEWUSER/suckless/$n to customize and rebuild\n" + done + cd "$oldPWD" + fi + local pkgcmd="pacman -S $pkgs --needed --noconfirm" # are we removing some packages [[ $REMOVE_PKGS != "" ]] && pkgcmd="pacman -Rs $REMOVE_PKGS --noconfirm ; $pkgcmd" chroot_cmd "$pkgcmd" 2>/dev/null - - [[ $LOGIN_TYPE == 'lightdm' ]] && setup_lightdm return 0 } setup_lightdm() { + # due to the user's information not being entered yet at this point, if they chose + # autologin then there is one value in the lightdm config that must be changed later + # + # autologin-user=$USER + chroot_cmd 'systemctl enable lightdm.service && systemctl set-default graphical.target' >/dev/null 2>&1 local cfg="$MNT/etc/lightdm/lightdm-gtk-greeter.conf" @@ -1962,212 +1934,198 @@ setup_lightdm() { sed -i '/\[greeter]/ a default-user-image=/usr/share/icons/ArchLabs-Dark/64x64/places/distributor-logo-archlabs.png' $cfg sed -i '/\[greeter]/ a active-monitor=0' $cfg + rm -rf $MNT/etc/systemd/system/getty@tty1.service.d >/dev/null 2>&1 + if [[ $AUTOLOGIN == true ]]; then chroot_cmd 'groupadd -r nopasswdlogin' >/dev/null 2>&1 sed -i '/#%PAM-1.0/ a auth sufficient pam_succeed_if.so user ingroup nopasswdlogin' $MNT/etc/pam.d/lightdm sed -i "/#autologin-session=/ c autologin-session=${LOGIN_WM}" $MNT/etc/lightdm/lightdm.conf + sed -i "/#autologin-user=/ c autologin-user=${NEWUSER}" $MNT/etc/lightdm/lightdm.conf fi } -mirrorlist_cmd() { - if ! yesno "$_MirrorTitle" "$_MirrorSetup" "Automatic Sort" "Customize Sort"; then - infobox "$_MirrorTitle" "\nGathering mirror countries..\n" - local countries - countries="$(reflector --list-countries | awk 'NF > 1 {print $1 " -"}')" - - if [[ $countries != "" ]]; then - tput civis - local country - country="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \ - --title "$_MirrorTitle" --menu "$_MirrorCountry" 22 70 10 $countries)" - MIRROR_CMD="reflector --country $country --score 80 --latest 40 --fastest 10 --sort rate" - fi - - local ref=" --score n Limit the list to the n servers with the highest score. - -l n, --latest n Limit the list to the n most recently synchronized servers. - -f n, --fastest n Return the n fastest mirrors that meet the other criteria. - --sort {age,rate,country,score,delay} - 'age': last server synchronization; 'rate': download rate; - 'country': server's location; 'score': MirrorStatus score; - 'delay': MirrorStatus delay." - - tput cnorm - MIRROR_CMD="$(dialog --cr-wrap --no-cancel --stdout --backtitle "$BT" \ - --title " $_MirrorTitle " --inputbox "$_MirrorCmd\n\n$ref\n" 0 0 "$cmd")" - fi - - return 0 -} - update_mirrorlist() { - infobox "$_MirrorTitle" "$_MirrorSort" - - if ! $MIRROR_CMD --save $MNT/etc/pacman.d/mirrorlist; then - infobox "$_ErrTitle" "\nAn error occurred while updating the mirrorlist.\n\nFalling back to automatic sorting...\n" - reflector --score 100 -l 50 -f 10 --sort rate --save $MNT/etc/pacman.d/mirrorlist - fi - + $MIRROR_CMD --verbose --save $MNT/etc/pacman.d/mirrorlist && return 0 + infobox "$_ErrTitle" "\nAn error occurred while updating the mirrorlist.\n\nFalling back to automatic sorting...\n" + reflector --score 100 -l 50 -f 10 --sort rate --verbose --save $MNT/etc/pacman.d/mirrorlist return 0 } bootloader_config() { - ROOT_PART_ID="$ROOT_PART" - if ! grep -q "/dev/mapper/" <<< "$ROOT_PART"; then + # if not on an LVM we can use the UUID for booting + if ! [[ $ROOT_PART =~ /dev/mapper ]]; then ROOT_PART_ID="UUID=$(blkid -s PARTUUID $ROOT_PART | sed 's/.*=//g; s/"//g')" - [[ $BOOTLOADER == "systemd-boot" ]] && ROOT_PART_ID="PART$ROOT_PART_ID" + [[ $BOOTLOADER == 'systemd-boot' ]] && ROOT_PART_ID="PART$ROOT_PART_ID" + else + # for LVM use the partition name eg. /dev/mapper/cryptroot + ROOT_PART_ID="$ROOT_PART" fi - if [[ $BOOTLOADER == "grub" ]]; then + if [[ $BOOTLOADER == 'grub' ]]; then local cfg="$MNT/etc/default/grub" - sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g; s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $cfg + sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g; + s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $cfg + if (( LUKS == 1 )); then - sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $cfg + sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; + s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $cfg fi - if [[ $SYS != "UEFI" ]]; then - if (( LVM == 1 && SEPERATE_BOOT == 0 )) || (( SEPERATE_BOOT == 2 )); then - sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" $cfg - fi + + if [[ $SYS != 'UEFI' && $LVM -eq 1 && $SEPERATE_BOOT -eq 0 ]]; then + sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" $cfg fi - elif [[ $BOOTLOADER == "syslinux" ]]; then - local cfgdir="$MNT/boot/syslinux" + + elif [[ $BOOTLOADER == 'syslinux' ]]; then + if [[ $SYS == 'BIOS' ]]; then + local cfgdir="$MNT/boot/syslinux" + local cfgsrcdir="/usr/lib/syslinux/bios/" + else + local cfgdir="$MNT/boot/EFI/syslinux" + local cfgsrcdir="/usr/lib/syslinux/efi64/" + fi + mkdir -p $cfgdir - cp -f /usr/lib/syslinux/bios/vesamenu.c32 $cfgdir/ - cp -f /run/archiso/bootmnt/arch/boot/syslinux/splash.png $cfgdir/ + cp -r $cfgsrcdir $cfgdir/ cat > $cfgdir/syslinux.cfg << EOF -UI vesamenu.c32 -DEFAULT archlabs +UI menu.c32 PROMPT 0 MENU TITLE $DIST Syslinux Boot Menu -MENU BACKGROUND splash.png TIMEOUT 50 +DEFAULT $DIST -MENU WIDTH 78 -MENU MARGIN 4 -MENU ROWS 5 -MENU VSHIFT 10 -MENU TIMEOUTROW 13 -MENU TABMSGROW 11 -MENU CMDLINEROW 11 -MENU HELPMSGROW 16 -MENU HELPMSGENDROW 29 - -# Refer to https://www.syslinux.org/wiki/index.php/Comboot/menu.c32 - -MENU COLOR border 30;44 #40ffffff #a0000000 std -MENU COLOR title 1;36;44 #9033ccff #a0000000 std -MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all -MENU COLOR unsel 37;44 #50ffffff #a0000000 std -MENU COLOR help 37;40 #c0ffffff #a0000000 std -MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std -MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std -MENU COLOR msg07 37;40 #90ffffff #a0000000 std -MENU COLOR tabmsg 31;40 #30ffffff #00000000 std - -LABEL archlabs +LABEL $DIST MENU LABEL $DIST Linux LINUX ../vmlinuz-$KERNEL APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw INITRD ../initramfs-$KERNEL.img + $([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] && + echo -en "\ninitrd /intel-ucode.img") -LABEL archlabsfallback +LABEL ${DIST}fallback MENU LABEL $DIST Linux Fallback LINUX ../vmlinuz-$KERNEL APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw INITRD ../initramfs-$KERNEL-fallback.img - -LABEL hdt - MENU LABEL HDT (Hardware Detection Tool) - COM32 hdt.c32 - -LABEL reboot - MENU LABEL Reboot - COM32 reboot.c32 - -LABEL poweroff - MENU LABEL Poweroff - COM32 poweroff.c32 + $([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] && + echo -en "\ninitrd /intel-ucode.img") EOF + else # systemd-boot requires this before running bootctl systemd-machine-id-setup --root="$MNT" >/dev/null 2>&1 + + # create the boot entry configs mkdir -p $MNT/boot/loader/entries cat > $MNT/boot/loader/loader.conf << EOF -default archlabs +default $DIST timeout 5 editor no EOF - cat > $MNT/boot/loader/entries/${DIST,,}.conf << EOF + cat > $MNT/boot/loader/entries/${DIST}.conf << EOF title $DIST Linux -linux /vmlinuz-$KERNEL +linux /vmlinuz-${KERNEL}$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] && + echo -en "\ninitrd /intel-ucode.img") initrd /initramfs-$KERNEL.img -options root=$ROOT_PART_ID rw +options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV")rw EOF - for file in $MNT/boot/loader/entries/arch*?.conf; do - (( LUKS == 1 )) && sed -i "s~rw~$LUKS_DEV rw~g" "$file" - done + # add pacman hook to update the bootloader when systemd receives an update + mkdir -p $MNT/pacman.d/hooks + cat > $MNT/pacman.d/hooks/systemd-boot.hook << EOF +[Trigger] +Type = Package +Operation = Upgrade +Target = systemd + +[Action] +Description = Updating systemd-boot +When = PostTransaction +Exec = /usr/bin/bootctl --path=${BOOT_MNTS[UEFI-systemd-boot]} update +EOF + fi + + return 0 +} + +uefi_bootloader_fallback() { + # some UEFI firmware is finicky and requires a specific folder in + # /boot/efi/EFI/ and named 'boot', 'Boot', or 'BOOT' + # copy the bootloaders efi stub to that directory as bootx64.efi + + local default="BOOT" + local esp="${MNT}${BOOT_MNTS[$SYS-$BOOTLOADER]}" + for i in $(find "$esp/EFI/" -maxdepth 1 -mindepth 1 -type d 2>/dev/null); do + grep -qi "boot" <<< "$(basename $i)" && { default="$(basename $i)"; break; } + done + + mkdir -p $esp/EFI/$default + if [[ $1 == 'syslinux' ]]; then + cp -f $esp/EFI/$1/* $esp/EFI/$default/ + cp -f $esp/EFI/$1/syslinux.efi $esp/EFI/$default/bootx64.efi + else + cp -f $esp/EFI/$1/grubx64.efi $esp/EFI/$default/bootx64.efi fi return 0 } -grub_uefi_fallback() { - # some UEFI firmware is finicky and requires a specific folder in - # /boot/efi/EFI/ and named 'boot', 'Boot', or 'BOOT' - local fb="boot" - local esp="${MNT}${BOOT_MNTS[$SYS-$BOOTLOADER]}/EFI/" - for i in $(find "$esp" -maxdepth 1 -mindepth 1 -type d 2>/dev/null); do - if grep -qi "boot" <<< "$(basename $i)"; then - fb="$(basename $i)" - break - fi - done - - # copy grub's efi stub binary to that directory as $stub - mkdir -p ${esp}$fb - cp -f ${esp}$DIST/grubx64.efi ${esp}$fb/bootx64.efi - return 0 -} - -setup_bootloader() { - chroot_cmd "export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/core_perl" - - local msg="$_InstBootloader $BOOTLOADER\n" - [[ $BOOT_PART != "" ]] && msg="$msg\n$_InstBootDev $BOOT_PART\n" - - infobox "$_InstBootTitle" "$msg\nMountpoint: ${BOOT_MNTS[$SYS-$BOOTLOADER]}\n" - +prep_for_bootloader() { if [[ $SYS == "UEFI" ]]; then local eficmd="mount -o remount,rw -t efivarfs efivarfs /sys/firmware/efi/efivars" $eficmd >/dev/null 2>&1 BOOT_CMDS[$BOOTLOADER]="$eficmd ; ${BOOT_CMDS[$BOOTLOADER]}" - find $MNT/boot/efi/EFI/ -maxdepth 1 -mindepth 1 -name '[aA][rR][cC][hH][lL]abs*' -type d -exec rm -rf '{}' \; >/dev/null 2>&1 - find $MNT/boot/efi/EFI/ -maxdepth 1 -mindepth 1 -name '[Bb][oO][oO][tT]' -type d -exec rm -rf '{}' \; >/dev/null 2>&1 - fi - # grub is finicky and requires special treatment - if [[ $BOOTLOADER == "grub" ]]; then - # needed for os-prober module to work properly in the chroot - local udevcmd="mkdir -p /run/udev && mount --rbind /run/udev /run/udev" - $udevcmd >/dev/null 2>&1 - BOOT_CMDS[grub]="$udevcmd ; ${BOOT_CMDS[grub]}" - [[ $SYS == "BIOS" ]] && BOOT_CMDS[grub]="${BOOT_CMDS[grub]} $BOOT_DEVICE" - BOOT_CMDS[grub]="${BOOT_CMDS[grub]} ; grub-mkconfig -o /boot/grub/grub.cfg" - fi + local esp="$MNT/boot/efi/EFI/" + [[ ! -d $MNT/boot/efi/EFI && -d $MNT/boot/EFI ]] && esp="$MNT/boot/EFI/" + find $esp -maxdepth 1 -mindepth 1 \ + \( -name '[aA][rR][cC][hH][lL]abs' -o -name '[Bb][oO][oO][tT]' \) \ + -type d -exec rm -rf '{}' \; >/dev/null 2>&1 - # create the bootloader configs and run the setup commands, BOOT_CMDS[$BOOTLOADER] + if [[ $BOOTLOADER == "grub" ]]; then + BOOT_CMDS[$BOOTLOADER]="${BOOT_CMDS[$BOOTLOADER]} --bootloader-id=$DIST && grub-mkconfig -o /boot/grub/grub.cfg" + elif [[ $BOOTLOADER == 'syslinux' ]]; then + EDIT_FILES[9]="/boot/EFI/syslinux/syslinux.cfg" + BOOT_CMDS[$BOOTLOADER]="efibootmgr -c -d $BOOT_DEVICE -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST" + fi + else + if [[ $BOOTLOADER == "grub" ]]; then + BOOT_CMDS[$BOOTLOADER]="${BOOT_CMDS[$BOOTLOADER]} $BOOT_DEVICE && grub-mkconfig -o /boot/grub/grub.cfg" + elif [[ $BOOTLOADER == 'syslinux' ]]; then + EDIT_FILES[9]="/boot/syslinux/syslinux.cfg" + fi + fi +} + +install_bootloader() { + chroot_cmd "export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/core_perl" + + local msg="$_InstBootloader $BOOTLOADER\n" + [[ $BOOT_PART != "" ]] && msg="$msg\n$_InstBootDev $BOOT_PART\n" + infobox "$_InstBootTitle" "$msg\nMountpoint: ${BOOT_MNTS[$SYS-$BOOTLOADER]}\n" 0 + + prep_for_bootloader + + # needed for os-prober module to work properly in the chroot + mkdir -p $MNT/run/udev && mount --rbind /run/udev $MNT/run/udev >/dev/null 2>&1 + # BOOT_CMDS[grub]="mount --rbind /run/udev /run/udev ; ${BOOT_CMDS[grub]}" + + # create the bootloader config(s) bootloader_config - chroot_cmd "${BOOT_CMDS[$BOOTLOADER]}" 2>$ERR >/dev/null 2>&1 - check_for_errors "${BOOT_CMDS[$BOOTLOADER]}" || return 1 - # copy grub efi stub to generic catch all - grub_uefi_fallback - BOOT_DONE=true + # run the bootloader command + chroot_cmd "${BOOT_CMDS[$BOOTLOADER]}" 2>$ERR >/dev/null 2>&1 + check_for_errors "${BOOT_CMDS[$BOOTLOADER]}" + + # copy bootloader efi stub to generic catch all + local boot_dir + [[ $BOOTLOADER == 'syslinux' ]] && boot_dir="syslinux" || boot_dir="$DIST" + [[ $SYS == 'UEFI' && $BOOTLOADER =~ (grub|syslinux) ]] && uefi_bootloader_fallback "$boot_dir" return 0 } run_mkinitcpio() { local conf="$MNT/etc/mkinitcpio.conf" + local add # setup a keyfile for LUKS.. Only when choosing grub and system is UEFI if [[ $LUKS -eq 1 && $SYS == 'UEFI' && $BOOTLOADER == 'grub' && $LUKS_PASS && $LUKS_UUID ]]; then @@ -2175,134 +2133,20 @@ run_mkinitcpio() { fi # new HOOKS needed in /etc/mkinitcpio.conf if we used LUKS and/or LVM - local add (( LVM == 1 )) && add="lvm2" (( LUKS == 1 )) && add="encrypt$([[ $add != "" ]] && echo -n " $add")" - if [[ ! -e $MNT/boot/vmlinuz-linux ]]; then - cp -f /run/archiso/bootmnt/arch/boot/x86_64/vmlinuz $MNT/boot/vmlinuz-linux - fi - sed -i "s/block filesystems/block ${add} filesystems ${MKINIT_HOOKS}/g" $conf 2>$ERR - check_for_errors "sed -i 's/block filesystems/block ${add} filesystems ${MKINIT_HOOKS}/g' $conf" || return 1 + check_for_errors "sed -i 's/block filesystems/block ${add} filesystems ${MKINIT_HOOKS}/g' $conf" tput civis chroot_cmd "mkinitcpio -p $KERNEL" 2>$ERR - check_for_errors "mkinitcpio -p $KERNEL" || return 1 + check_for_errors "mkinitcpio -p $KERNEL" return 0 } -###################################################################### -## Menu Dialogs ## -###################################################################### - -main_menu() { - if [[ $FIRST_PREP != true ]]; then - FIRST_PREP=true - prepare_menu - fi - - if [[ $CURRENT_MENU != "main" ]]; then - MENU_HIGHLIGHT=1 - CURRENT_MENU="main" - elif (( MENU_HIGHLIGHT < 5 )); then - ((MENU_HIGHLIGHT++)) - fi - - tput civis - MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" \ - --title " $_MainTitle " --default-item $MENU_HIGHLIGHT --menu "$_MainBody" 0 0 0 \ - "1" "$_PrepTitle" "2" "$_InstTitle" "3" "$_ConfTitle" "4" "$_EditTitle" "5" "$_Done") - - if [[ -n $MENU_HIGHLIGHT ]]; then - # if trying to unpack the system make sure the partitions are mounted - if (( MENU_HIGHLIGHT == 2 )) && ! check_parts_are_mounted; then - return 1 - elif (( MENU_HIGHLIGHT == 3 || MENU_HIGHLIGHT == 4 )); then - # when trying to use config_menu() or edit config files make sure - # the system is unpacked and the partitions are mounted - if ! (check_parts_are_mounted && check_base_unpacked); then - return 1 - fi - fi - fi - - case $MENU_HIGHLIGHT in - 1) prepare_menu ;; - 2) install_main ;; - 3) configure_menu ;; - 4) edit_config_menu ;; - *) wrap_up "$_CloseInstBody" 'Exit' 'Back' 'exit' - esac -} - -prepare_menu() { - if [[ $ROOT_PART != "" && $BOOTLOADER != "" ]]; then - if check_parts_are_mounted; then - # this is where all the action happens, the rest is mostly automated - # the user will likely reboot after and never get back here, but if we do - # returning goes to the main menu - install_main && return 0 - fi - fi - - if [[ $CURRENT_MENU != "prep" ]]; then - MENU_HIGHLIGHT=1 - CURRENT_MENU="prep" - elif (( MENU_HIGHLIGHT < 7 )); then - ((MENU_HIGHLIGHT++)) - fi - - tput civis - MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepTitle " \ - --default-item $MENU_HIGHLIGHT --menu "$_PrepBody" 0 0 0 \ - "1" "$_PrepLayout" "2" "$_PrepShowDev" "3" "$_PrepParts" "4" "$_PrepLUKS" \ - "5" "$_PrepLVM" "6" "$_PrepMount" "7" "$_Back") - - case $MENU_HIGHLIGHT in - 1) set_keymap ;; - 2) show_devices ;; - 3) unmount_partitions && select_device 'root' && create_partitions "$DEVICE" ;; - 4) luks_menu ;; - 5) lvm_menu ;; - 6) select_install_partitions ;; - *) return 0 - esac - - prepare_menu -} - -configure_menu() { - chroot_cmd "export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/core_perl" - - if [[ $FIRST_CONFIG != true ]]; then - FIRST_CONFIG=true - set_hostname && set_locale && create_user - [[ $FULL_DONE == true ]] && return 0 - elif [[ $CURRENT_MENU != "config" ]]; then - MENU_HIGHLIGHT=1 - CURRENT_MENU="config" - elif (( MENU_HIGHLIGHT < 4 )); then - ((MENU_HIGHLIGHT++)) - fi - - tput civis - MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_ConfTitle " \ - --default-item $MENU_HIGHLIGHT --menu "$_ConfBody" 0 0 0 \ - "1" "$_ConfHost" "2" "$_ConfLocale" "3" "$_ConfUser" "4" "$_Back") - - case $MENU_HIGHLIGHT in - 1) set_hostname ;; - 2) set_locale ;; - 3) create_user ;; - *) return 0 - esac - - configure_menu -} - -edit_config_menu() { +edit_configs() { if [[ $CURRENT_MENU != "edit" ]]; then MENU_HIGHLIGHT=1 CURRENT_MENU="edit" @@ -2310,8 +2154,7 @@ edit_config_menu() { ((MENU_HIGHLIGHT++)) fi - local msg - [[ $FULL_DONE == true ]] && msg="${_Final}$_EditBody" || msg="$_EditBody" + local msg="${_Final}$_EditBody" tput civis MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_EditTitle " \ @@ -2319,37 +2162,63 @@ edit_config_menu() { "1" "$_Done" "2" "keymaps" "3" "locale" "4" "hostname" "5" "sudoers" \ "6" "mkinitcpio.conf" "7" "fstab" "8" "crypttab" "9" "$BOOTLOADER" "10" "pacman.conf") if [[ $MENU_HIGHLIGHT == "" || $MENU_HIGHLIGHT == 1 ]]; then - if [[ $FULL_DONE == true && $CONFIRM_DONE != true ]]; then - CONFIRM_DONE=true - wrap_up "$_InstFinBody" 'Exit & Reboot' 'Go Back' 'reboot' - fi - return 0 - fi + wrap_up "$_InstFinBody" 'Exit & Reboot' 'Go Back' 'reboot' + else + local existing_files="" - local existing_files="" - for f in $(echo "${EDIT_FILES[$MENU_HIGHLIGHT]}"); do - [[ -e ${MNT}$f ]] && existing_files="$existing_files ${MNT}$f" - done + for f in $(echo "${EDIT_FILES[$MENU_HIGHLIGHT]}"); do + [[ -e ${MNT}$f ]] && existing_files="$existing_files ${MNT}$f" + done - if [[ $existing_files != "" ]]; then - if [[ $EDITOR_CHOICE == "" && $DISPLAY ]] && hash geany >/dev/null 2>&1; then - if yesno "$_EditTitle" "\nOpen file(s) in Geany or Vim?\n" "Geany" "Vim"; then - EDITOR_CHOICE="geany -i" + if [[ $existing_files != "" ]]; then + if [[ $DISPLAY ]] && hash geany >/dev/null 2>&1; then geany -i $existing_files else - EDITOR_CHOICE="vim -O" vim -O $existing_files fi - elif [[ $EDITOR_CHOICE ]]; then - $EDITOR_CHOICE $existing_files else - vim -O $existing_files + msgbox "$_ErrTitle" "$_NoFileErr" fi - else - msgbox "$_ErrTitle" "$_NoFileErr" fi - edit_config_menu + edit_configs +} + +main() { + if [[ $ROOT_PART != "" && $BOOTLOADER != "" && ($SYS == "BIOS" || $BOOT_PART != "") ]]; then + # if at least one partition is NOT mounted at $MNT bail + check_parts_are_mounted || return 1 + + # this is where all the action happens, the rest is mostly automated + # once the needed steps are done, this will begin the install + install_main || return 1 + fi + + if [[ $CURRENT_MENU != "main" ]]; then + MENU_HIGHLIGHT=1 + CURRENT_MENU="main" + elif (( MENU_HIGHLIGHT < 8 )); then + ((MENU_HIGHLIGHT++)) + fi + + tput civis + MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepTitle " \ + --default-item $MENU_HIGHLIGHT --menu "$_PrepBody" 0 0 0 \ + "1" "$_PrepShowDev" "2" "$_PrepParts" "3" "$_PrepLUKS" "4" "$_PrepLVM" \ + "5" "$_PrepMount" "6" "$_InstTitle" "7" "$_Done") + + # if trying to install the system, make sure the partitions are mounted first + ([[ -n $MENU_HIGHLIGHT && $MENU_HIGHLIGHT -eq 6 ]] && ! check_parts_are_mounted) && { MENU_HIGHLIGHT=5; return 1; } + + case $MENU_HIGHLIGHT in + 1) show_devices ;; + 2) unmount_partitions && select_device 'root' && create_partitions "$DEVICE" ;; + 3) luks_menu ;; + 4) lvm_menu ;; + 5) select_install_partitions ;; + 6) install_main ;; + *) wrap_up "$_CloseInstBody" 'Exit' 'Back' 'exit' + esac } for arg in "$@"; do @@ -2359,12 +2228,11 @@ done initialize_variables luks_variable_init select_language +set_keymap check_requirements identify_system - -# welcome message msgbox "$_WelTitle $DIST Installer" "$_WelBody" while true; do - main_menu + main done diff --git a/translations/english.trans b/translations/english.trans index 4016fec..8ce376f 100644 --- a/translations/english.trans +++ b/translations/english.trans @@ -64,6 +64,7 @@ _CloseInstBody="\nUnmount partitions and close the installer?\n" _BeginInst="\nRoot Partition:" _ContinueYN="\nDo you want to begin install?\n" _TakeOneMin="\nThis will take a minute" +_OnlyOne="\nOnly one partition available" # finished _InstFinBody="\nThe installation is now finished.\n\nWould you like to close the installer and reboot?\n" @@ -72,7 +73,7 @@ _InstFinBody="\nThe installation is now finished.\n\nWould you like to close the _GenLocale="\nGenerating locale:" # error message -_ErrChoice="\nDo you want to keep the current install and fix manually, or wipe and start over? (preserves /boot)\n" +_ErrChoice="\nUnmount the partitions and shutdown or keep them mounted and continue?\n" # keyfile creation _LuksKeyFileTitle="Create Encryption Keyfile"