2018-08-12 23:24:38 -05:00
#!/usr/bin/bash
2018-07-18 19:50:37 -05:00
# vim:ft=sh:fdm=marker:fmr={,}
# This program is free software, provided under the GNU GPL
2018-07-18 19:52:06 -05:00
# Written by Nathaniel Maia for use in Archlabs
# Some ideas and code were taken from other installers
# AIF, ABIF, Calamares, Arch Wiki.. Credit where credit is due
2018-07-18 19:50:37 -05:00
2018-08-25 19:52:57 -05:00
# dry run performing no action, good for checking syntax errors
2018-07-18 19:50:37 -05:00
# set -n
2018-07-18 19:52:06 -05:00
# immutable variables {
2018-07-18 19:50:37 -05:00
2018-08-12 23:24:38 -05:00
readonly DIST="Archlabs" # Linux distributor
2018-08-25 23:23:48 -05:00
readonly VER="1.6.46" # Installer version
2018-08-12 23:24:38 -05:00
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
2018-07-18 19:50:37 -05:00
2018-08-18 19:59:25 -05:00
# create a regex string of all usb devices on the system
2018-08-24 03:40:55 -05:00
for dev in $(lsblk -lno NAME,TRAN | awk '/usb/ {print $1}'); do
USB_DEVS="${dev}$([[ $USB_DEVS ]] && echo -n "|$USB_DEVS")"
done
2018-08-18 19:59:25 -05:00
# determine which device was used for booting to ignore later during partition select
2018-08-24 03:40:55 -05:00
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}')"
2018-08-18 19:59:25 -05:00
readonly LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if($1) print $1 " -"}' /etc/locale.gen)"
2018-07-18 19:52:06 -05:00
readonly SYS_MEM=$(grep 'MemTotal' /proc/meminfo | awk '{print int($2 / 1024)}')
readonly DEV_COUNT="$(wc -l <<< "$SYS_DEVS")"
2018-08-18 19:59:25 -05:00
readonly KBD="$(find /usr/share/kbd/keymaps -name '*.map.gz')"
2018-07-18 19:52:06 -05:00
readonly CONSOLE_MAPS="$(awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " -"}' <<< "$KBD" | sort -r)"
2018-07-18 19:50:37 -05:00
2018-08-18 19:59:25 -05:00
# create associative array for SUBZONES[zone], value is: 'sub-zone country_code'
2018-07-18 19:52:06 -05:00
declare -Ag SUBZONES
2018-08-17 20:44:17 -05:00
for zone in America Australia Asia Atlantic Africa Europe Indian Pacific Arctic Antarctica; do
2018-07-18 19:52:06 -05:00
SUBZONES[$zone]="$(awk "/$zone\// {gsub(/$zone\//, \"\"); print \$3 \" \"\$1}" /usr/share/zoneinfo/zone.tab)"
2018-07-18 19:50:37 -05:00
done
2018-07-18 19:52:06 -05:00
readonly SUBZONES # make it read only
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
if [[ $TERM != 'linux' ]]; then
for t in st termite xterm; do
hash $t >/dev/null 2>&1 && { readonly TERM_CMD="$t"; break; }
done
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# static string of keymap codes and respective language
readonly KEYMAPS="us English cm English gb English au English gh English za English
ng English ca French cd French gn French tg French fr French de German at German ch German
es Spanish latam Spanish br Portuguese pt Portuguese ma Arabic sy Arabic ara Arabic
ua Ukrainian cz Czech ru Russian sk Slovak nl Dutch it Italian hu Hungarian cn Chinese
tw Taiwanese vn Vietnamese kr Korean jp Japanese th Thai la Lao pl Polish se Swedish
is Icelandic fi Finnish dk Danish be Belgian in Indian al Albanian am Armenian bd Bangla
ba Bosnian bg Bulgarian dz Berber mm Burmese hr Croatian gr Greek il Hebrew ir Persian iq Iraqi
af Afghani fo Faroese ge Georgian ee Estonian kg Kyrgyz kz Kazakh lt Lithuanian mt Maltese
mn Mongolian no Norwegian ro Romanian rs Serbian si Slovenian tj Tajik lk Sinhala tr Turkish
uz Uzbek ie Irish pk Urdu mv Dhivehi epo Esperanto np Nepali et Amharic sn Wolof ml Bambara
tz Swahili ke Swahili bw Tswana ph Filipino id Indonesian my Malay tm Turkmen bt Dzongkha
lv Latvian md Moldavian mao Maori by Belarusian me Montenegrin mk Macedonian kh Khmer
az Azerbaijani"
declare -Agr BOOT_MNTS=(
2018-08-24 03:40:55 -05:00
[UEFI-grub]="/boot/efi" [UEFI-systemd-boot]="/boot" [BIOS-grub]="/boot"
[BIOS-syslinux]="/boot" [UEFI-syslinux]="/boot"
2018-07-18 19:52:06 -05:00
)
2018-08-17 20:44:17 -05:00
# static list of bootloaders & boot partition mountpoints stored as the system type (BIOS or UEFI)
2018-08-24 03:40:55 -05:00
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]}"
2018-07-18 19:52:06 -05:00
)
2018-08-17 20:44:17 -05:00
2018-07-18 19:52:06 -05:00
# static mkfs commands for each filesystem offered
declare -Agr FS_CMDS=(
2018-08-12 23:24:38 -05:00
[ext2]="mkfs.ext2 -q" [ext3]="mkfs.ext3 -q" [ext4]="mkfs.ext4 -q"
2018-08-17 20:44:17 -05:00
[f2fs]="mkfs.f2fs" [jfs]="mkfs.jfs -q" [xfs]="mkfs.xfs -f" [nilfs2]="mkfs.nilfs2 -q"
2018-08-12 23:24:38 -05:00
[ntfs]="mkfs.ntfs -q" [reiserfs]="mkfs.reiserfs -q" [vfat]="mkfs.vfat -F32"
2018-07-18 19:52:06 -05:00
)
2018-08-17 20:44:17 -05:00
2018-07-18 19:52:06 -05:00
# static filesystem mount options
2018-08-24 03:40:55 -05:00
declare -Agr FS_OPTS=([vfat]="" [ntfs]="" [ext2]="" [ext3]=""
2018-07-18 19:52:06 -05:00
[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"
[xfs]="discard - off filestreams - off ikeep - off largeio - off noalign - off nobarrier - off norecovery - off noquota - off wsync - off"
[nilfs2]="discard - off nobarrier - off errors=continue - off errors=panic - off order=relaxed - off order=strict - off norecovery - off"
2018-08-17 20:44:17 -05:00
[f2fs]="data_flush - off disable_roll_forward - off disable_ext_identify - off discard - off fastboot - off flush_merge - off inline_xattr - off inline_data - off inline_dentry - off no_heap - off noacl - off nobarrier - off noextent_cache - off noinline_data - off norecovery - off"
2018-07-18 19:52:06 -05:00
)
2018-07-18 19:50:37 -05:00
# }
2018-07-28 15:03:43 -05:00
luks_variable_init() {
declare -g LUKS=0
declare -g LVM=0
declare -g VOL_GROUP_MB=0
declare -g LUKS_NAME="cryptroot"
declare -g LUKS_PART=""
declare -g LUKS_PASS=""
declare -g LUKS_UUID=""
declare -g LUKS_DEV=""
declare -g MKINIT_HOOKS="shutdown"
declare -g SEPERATE_BOOT=0
}
2018-07-18 19:52:06 -05:00
initialize_variables() {
# Modified during runtime and are all globally accessible
# This is called once when the script is started, and again if/when an error occurs
2018-08-22 03:22:02 -05:00
# Some may never be used, depending on the system and choices made
2018-07-18 19:52:06 -05:00
declare -g ROOT_PART=""
declare -g BOOT_DEVICE=""
declare -g BOOT_PART=""
declare -g BOOTLOADER=""
declare -g EXTRA_MNT=""
2018-08-24 03:40:55 -05:00
declare -g SWAP="none"
2018-07-18 19:52:06 -05:00
declare -g SWAP_SIZE="${SYS_MEM}M"
2018-08-20 04:26:13 -05:00
declare -g KERNEL="linux"
2018-07-18 19:52:06 -05:00
declare -g NEWUSER=""
declare -g USER_PASS=""
declare -g ROOT_PASS=""
2018-08-12 23:24:38 -05:00
declare -g LOGIN_WM=""
declare -g LOGIN_TYPE=""
declare -g INSTALL_WMS=""
declare -g WM_PACKAGES=""
declare -g EXTRA_PACKAGES=""
2018-08-19 22:32:21 -05:00
declare -g REMOVE_PKGS=""
2018-08-25 19:52:57 -05:00
declare -g CURRENT_MENU=""
declare -g MENU_HIGHLIGHT
2018-07-28 15:03:43 -05:00
declare -g EDITOR_CHOICE=""
2018-07-30 02:30:35 -05:00
declare -g MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate"
2018-07-18 19:52:06 -05:00
# boolean checks
2018-08-12 23:24:38 -05:00
declare -g AUTOLOGIN=false
2018-08-25 19:52:57 -05:00
declare -g CONFIG_DONE=false
2018-07-18 19:52:06 -05:00
# 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"
2018-08-24 03:40:55 -05:00
[grub]="grub-install --recheck --force"
[systemd-boot]="bootctl --path=${BOOT_MNTS[UEFI-systemd-boot]} install"
2018-07-18 19:52:06 -05:00
)
# files able to be reviewed when finishing install
2018-08-17 20:44:17 -05:00
# item index [9] can change depending on which bootloader is selected
2018-07-18 19:52:06 -05:00
declare -Ag EDIT_FILES=(
2018-08-12 23:24:38 -05:00
[2]="/etc/X11/xorg.conf.d/00-keyboard.conf /etc/vconsole.conf /etc/default/keyboard"
[3]="/etc/locale.conf /etc/default/locale"
[4]="/etc/hostname /etc/hosts"
[5]="/etc/sudoers"
[6]="/etc/mkinitcpio.conf"
[7]="/etc/fstab"
[8]="/etc/crypttab"
[9]="/etc/default/grub"
[10]="/etc/pacman.conf"
2018-07-18 19:52:06 -05:00
)
}
2018-07-18 19:50:37 -05:00
######################################################################
2018-08-24 03:40:55 -05:00
## Utility Functions ##
2018-07-18 19:50:37 -05:00
######################################################################
chroot_cmd() {
arch-chroot $MNT /bin/bash -c "$1"
}
show_devices() {
2018-07-18 19:52:06 -05:00
tput civis
2018-08-18 19:59:25 -05:00
if [[ $IGNORE_DEV != "" ]]; then
2018-07-28 15:03:43 -05:00
lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT |
2018-08-18 19:59:25 -05:00
awk "!/$IGNORE_DEV/"' && /disk|part|lvm|crypt|NAME/ {print $0}' > /tmp/.devlist
2018-07-28 15:03:43 -05:00
else
lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT |
awk '/disk|part|lvm|crypt|NAME/ {print $0}' > /tmp/.devlist
fi
2018-07-18 19:52:06 -05:00
dialog --cr-wrap --backtitle "$BT" --title " $_PrepShowDev " --textbox /tmp/.devlist 0 0
2018-07-18 19:50:37 -05:00
}
set_debug() {
set -x
2018-07-18 19:52:06 -05:00
exec 3>| /tmp/debug-log
2018-07-18 19:50:37 -05:00
BASH_XTRACEFD=3
2018-08-12 23:24:38 -05:00
if [[ $DISPLAY ]]; then
if [[ $TERM_CMD == 'st' ]]; then
$TERM_CMD -e tail -f /tmp/debug-log &
else
$TERM_CMD -e "tail -f /tmp/debug-log" &
fi
fi
2018-07-18 19:50:37 -05:00
}
select_language() {
2018-07-18 19:52:06 -05:00
tput civis
local lang
2018-08-25 19:52:57 -05:00
lang=$(dialog --cr-wrap --stdout --backtitle "$DIST Installer - (x86_64) - Version $VER" \
2018-07-18 19:52:06 -05:00
--title " Select Language " --menu \
"\nLanguage - sprache - taal - språk - lingua - idioma - nyelv - língua\n" 0 0 0 \
"1" "English (en_**)" "2" "Español (es_ES)" \
"3" "Português [Brasil] (pt_BR)" "4" "Português (pt_PT)" \
"5" "Français (fr_FR)" "6" "Russkiy (ru_RU)" \
"7" "Italiano (it_IT)" "8" "Nederlands (nl_NL)" \
"9" "Magyar (hu_HU)" "10" "Chinese (zh_CN)")
source $TRN/english.trans 2>/dev/null
2018-08-24 03:40:55 -05:00
declare -g FONT="ter-i16n"
2018-07-18 19:52:06 -05:00
case $lang in
2018-07-18 19:50:37 -05:00
1) LOC="en_US.UTF-8" ;;
2018-07-18 19:52:06 -05:00
2) source $TRN/spanish.trans 2>/dev/null && LOC="es_ES.UTF-8" ;;
3) source $TRN/p_brasil.trans 2>/dev/null && LOC="pt_BR.UTF-8" ;;
4) source $TRN/portuguese.trans 2>/dev/null && LOC="pt_PT.UTF-8" ;;
5) source $TRN/french.trans 2>/dev/null && LOC="fr_FR.UTF-8" ;;
2018-08-12 23:24:38 -05:00
6) source $TRN/russian.trans 2>/dev/null && LOC="ru_RU.UTF-8" FONT="LatKaCyrHeb-14" ;;
2018-07-18 19:52:06 -05:00
7) source $TRN/italian.trans 2>/dev/null && LOC="it_IT.UTF-8" ;;
8) source $TRN/dutch.trans 2>/dev/null && LOC="nl_NL.UTF-8" ;;
2018-08-12 23:24:38 -05:00
9) source $TRN/hungarian.trans 2>/dev/null && LOC="hu_HU.UTF-8" FONT="lat2-16" ;;
2018-07-18 19:52:06 -05:00
10) source $TRN/chinese.trans 2>/dev/null && LOC="zh_CN.UTF-8" ;;
2018-08-24 03:40:55 -05:00
*) die 0
2018-07-18 19:50:37 -05:00
esac
sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen
2018-08-24 03:40:55 -05:00
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
2018-07-18 19:50:37 -05:00
}
identify_system() {
2018-07-18 19:52:06 -05:00
if grep -qi 'apple' /sys/class/dmi/id/sys_vendor; then
2018-08-24 03:40:55 -05:00
modprobe -r -q efivars
2018-07-18 19:50:37 -05:00
else
modprobe -q efivarfs
fi
2018-07-18 19:52:06 -05:00
if [[ -d /sys/firmware/efi ]]; then
2018-07-18 19:50:37 -05:00
SYS="UEFI"
2018-07-18 19:52:06 -05:00
[[ $(mount) =~ /sys/firmware/efi/efivars ]] && mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
2018-07-18 19:50:37 -05:00
else
SYS="BIOS"
fi
readonly BT="$DIST Installer - $SYS (x86_64) - Version $VER"
}
check_requirements() {
2018-08-24 03:40:55 -05:00
local err=0
2018-07-18 19:52:06 -05:00
if [[ $(whoami) != "root" ]]; then
2018-08-24 03:40:55 -05:00
infobox "$_ErrTitle" "$_NotRoot\n$_Exit"
err=1
elif ! grep -qw 'lm' /proc/cpuinfo; then
2018-08-25 19:52:57 -05:00
infobox "$_ErrTitle" "$_Not64Bit\n$_Exit"
2018-08-24 03:40:55 -05:00
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
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
[[ $err -eq 1 ]] && die 1 || return 0
2018-07-18 19:50:37 -05:00
}
check_for_errors() {
2018-08-24 03:40:55 -05:00
# return if the last process exited normally
2018-07-18 19:52:06 -05:00
(( $? == 0 )) && return 0
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
local command="$1"
local msg="\nThe command exited abnormally: $command"
# 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
2018-08-24 03:40:55 -05:00
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'
2018-07-18 19:52:06 -05:00
2018-08-24 03:40:55 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-08-25 19:52:57 -05:00
check_install_ready() {
if ! [[ $(lsblk -o MOUNTPOINT) =~ $MNT ]]; then
msgbox "$_ErrTitle" "$_ErrNoMount"; return 4
elif [[ $CONFIG_DONE != true ]]; then
msgbox "$_ErrTitle" "$_ErrNoConfig"; return 5
fi
return 0
2018-07-18 19:50:37 -05:00
}
getinput() {
2018-07-18 19:52:06 -05:00
local answer
2018-08-25 22:49:06 -05:00
answer="$(dialog --cr-wrap --max-input 63 --stdout --no-cancel \
--backtitle "$BT" --title " $1 " --inputbox "$2" 0 0 "$3")"
2018-07-18 19:52:06 -05:00
[[ $? != 0 || $answer == "" ]] && return 1
echo "$answer"
}
2018-07-18 19:50:37 -05:00
msgbox() {
2018-07-18 19:52:06 -05:00
tput civis
dialog --cr-wrap --backtitle "$BT" --title " $1 " --msgbox "$2\n" 0 0
}
2018-07-18 19:50:37 -05:00
infobox() {
2018-08-24 03:40:55 -05:00
local time="$3"
2018-08-25 19:52:57 -05:00
local bt="${BT:-$DIST Installer - (x86_64) - Version $VER}"
2018-07-18 19:52:06 -05:00
tput civis
dialog --cr-wrap --backtitle "$bt" --title " $1 " --infobox "$2\n" 0 0
2018-08-24 03:40:55 -05:00
sleep ${time:-2}
2018-07-18 19:52:06 -05:00
}
2018-07-18 19:50:37 -05:00
yesno() {
2018-07-18 19:52:06 -05:00
tput civis
if [[ $# -eq 5 && $5 == "no" ]]; then
# option for default no using custom labels
dialog --cr-wrap --backtitle "$BT" --defaultno --title " $1 " \
--yes-label "$3" --no-label "$4" --yesno "$2\n" 0 0
elif [[ $# -eq 4 ]]; then
# option for custom labels with standard default yes
dialog --cr-wrap --backtitle "$BT" --title " $1 " --yes-label "$3" \
--no-label "$4" --yesno "$2\n" 0 0
else
# basic yes no without custom labels and default yes
dialog --cr-wrap --backtitle "$BT" --title " $1 " --yesno "$2\n" 0 0
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
}
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
wrap_up() {
2018-08-24 03:40:55 -05:00
yesno "$_CloseInst" "$1" "$2" "$3" || return 0
2018-08-25 19:52:57 -05:00
[[ $4 == 'reboot' ]] && die 'reboot' || die 0
2018-08-24 03:40:55 -05:00
}
die() {
tput cnorm
unmount_partitions
pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail"
[[ $1 =~ [0-9] ]] && exit $1 || systemctl $1
}
2018-08-25 19:52:57 -05:00
sigint() {
echo -e "\n** CTRL-C caught"
die 1
}
2018-08-24 03:40:55 -05:00
oneshot() {
2018-08-25 19:52:57 -05:00
[[ -e /tmp/.ai_$1 || ! $(type $1) ]] && return 0
2018-08-24 03:40:55 -05:00
$1 || return 1
2018-08-25 19:52:57 -05:00
touch "/tmp/.ai_$1"
2018-08-24 03:40:55 -05:00
return 0
2018-07-18 19:52:06 -05:00
}
2018-07-18 19:50:37 -05:00
######################################################################
## System Settings Functions ##
######################################################################
set_keymap() {
2018-07-18 19:52:06 -05:00
tput civis
2018-08-24 03:40:55 -05:00
declare -g KEYMAP
2018-08-25 22:49:06 -05:00
KEYMAP="$(dialog --cr-wrap --stdout --no-cancel \
2018-08-25 19:52:57 -05:00
--backtitle "$DIST Installer - (x86_64) - Version $VER" \
--title " $_PrepLayout " --menu "$_XMapBody" 20 70 12 $KEYMAPS)"
2018-08-24 03:40:55 -05:00
[[ $? != 0 || $KEYMAP == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# when a matching console map is not available open a selection dialog
2018-08-24 03:40:55 -05:00
if ! [[ $CONSOLE_MAPS =~ "$KEYMAP -" ]]; then
2018-07-18 19:52:06 -05:00
tput civis
2018-08-25 22:49:06 -05:00
CONSOLE_MAP="$(dialog --cr-wrap --stdout --no-cancel \
2018-08-25 19:52:57 -05:00
--backtitle "$DIST Installer - (x86_64) - Version $VER" \
2018-08-24 03:40:55 -05:00
--title " $_CMapTitle " --menu "$_CMapBody" 20 70 12 $CONSOLE_MAPS)"
[[ $? != 0 || $CONSOLE_MAP == "" ]] && return 1
2018-08-25 19:52:57 -05:00
else
CONSOLE_MAP="$KEYMAP"
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
2018-08-25 19:52:57 -05:00
if [[ $DISPLAY && $TERM != 'linux' ]]; then
(type setxkbmap >/dev/null 2>&1) && setxkbmap $KEYMAP >/dev/null 2>&1
else
(type loadkeys >/dev/null 2>&1) && loadkeys $CONSOLE_MAP >/dev/null 2>&1
fi
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
set_locale() {
2018-07-18 19:52:06 -05:00
tput civis
2018-08-24 03:40:55 -05:00
declare -g LOCALE
LOCALE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
2018-08-17 03:21:15 -05:00
--title "$_ConfLocale" --menu "$_LocaleBody" 25 70 12 $LOCALES)"
2018-08-24 03:40:55 -05:00
[[ $? != 0 || $LOCALE == "" ]] && return 1
return 0
2018-07-18 19:50:37 -05:00
}
set_timezone() {
2018-07-18 19:52:06 -05:00
tput civis
2018-08-24 03:40:55 -05:00
declare -g ZONE
ZONE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
2018-08-18 19:59:25 -05:00
--title " $_TimeZTitle " --menu "$_TimeZBody" 20 70 10 America - Australia - \
Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica -)"
2018-08-24 03:40:55 -05:00
declare -g SUBZONE
SUBZONE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
--title " $_TimeZTitle " --menu "$_TimeSubZBody" 20 70 12 ${SUBZONES[$ZONE]})"
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
if yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n"; then
return 0
2018-07-18 19:50:37 -05:00
else
2018-08-24 03:40:55 -05:00
set_timezone
2018-07-18 19:50:37 -05:00
fi
}
set_hwclock() {
chroot_cmd "hwclock --systohc --utc"
2018-08-24 03:40:55 -05:00
[[ $? != 0 ]] && chroot_cmd "hwclock --systohc --utc --directisa"
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
set_hostname() {
2018-07-18 19:52:06 -05:00
tput cnorm
2018-08-24 03:40:55 -05:00
declare -g HOSTNAME
HOSTNAME="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")"
[[ $? != 0 || $HOSTNAME == "" ]] && return 1
return 0
2018-07-18 19:50:37 -05:00
}
2018-08-24 03:40:55 -05:00
user_setup() {
2018-08-20 04:26:13 -05:00
tput cnorm
local values
2018-08-24 03:40:55 -05:00
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)"
2018-08-20 04:26:13 -05:00
[[ $? != 0 || $values == "" ]] && return 1
2018-08-24 03:40:55 -05:00
local user
2018-08-20 04:26:13 -05:00
user="$(awk -F'~' '{print $1}' <<< "$values")"
2018-08-24 03:40:55 -05:00
local pass pass2
2018-08-20 04:26:13 -05:00
pass="$(awk -F'~' '{print $2}' <<< "$values")"
pass2="$(awk -F'~' '{print $3}' <<< "$values")"
local rpass rpass2
2018-08-24 03:40:55 -05:00
rpass="$(awk -F'~' '{print $5}' <<< "$values")"
rpass2="$(awk -F'~' '{print $6}' <<< "$values")"
# both root passwords are empty, so use the user passwords instead
[[ $rpass == "" && $rpass2 == "" ]] && { rpass="$pass"; rpass2="$pass2"; }
2018-08-20 04:26:13 -05:00
2018-08-24 03:40:55 -05:00
# make sure a username was entered and that the passwords match
2018-08-20 04:26:13 -05:00
if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9\ ] || $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
if [[ $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
2018-08-24 03:40:55 -05:00
# 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
2018-08-20 04:26:13 -05:00
msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain"
else
msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain"
fi
2018-08-24 03:40:55 -05:00
else # bad username
2018-08-20 04:26:13 -05:00
msgbox "$_UserErrTitle" "$_UserErrBody"
user=""
fi
2018-08-24 03:40:55 -05:00
# recursively loop back unless the user cancels
user_setup || return 1
2018-08-20 04:26:13 -05:00
else
NEWUSER="$user"
USER_PASS="$pass"
2018-08-24 03:40:55 -05:00
ROOT_PASS="$rpass"
2018-08-20 04:26:13 -05:00
fi
return 0
}
window_manager() {
2018-08-12 23:24:38 -05:00
LOGIN_WM=""
LOGIN_TYPE=""
WM_PACKAGES=""
INSTALL_WMS="$(dialog --cr-wrap --stdout --backtitle "$BT" --no-cancel \
--title " $_WMChoice " --checklist "$_WMChoiceBody\n" 0 0 0 \
"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 \
2018-08-25 22:49:06 -05:00
"dwm" "A customized fork of dwm, with patches and modifications" off \
2018-08-19 22:32:21 -05:00
"gnome" "A desktop environment that aims to be simple and easy to use" off \
2018-08-20 04:26:13 -05:00
"cinnamon" "A desktop environment combining a traditional desktop layout with modern graphical effects" off \
2018-08-12 23:24:38 -05:00
"xfce4" "A lightweight and modular desktop environment based on GTK+ 2 and 3" off)"
INSTALL_WMS="${INSTALL_WMS:-openbox}"
WM_NUM=$(awk '{print NF}' <<< "$INSTALL_WMS")
for wm in $INSTALL_WMS; do
WM_LOGIN_CHOICES="${WM_LOGIN_CHOICES}$wm - "
case $wm in
2018-08-20 04:26:13 -05:00
openbox) WM_PACKAGES="$WM_PACKAGES $wm obconf archlabs-ob-autostart archlabs-obkey archlabs-kickshaw" ;;
bspwm) WM_PACKAGES="$WM_PACKAGES $wm sxhkd lxappearance" ;;
i3-gaps) WM_PACKAGES="$WM_PACKAGES $wm i3status perl-anyevent-i3 lxappearance" ;;
gnome) WM_PACKAGES="$WM_PACKAGES $wm gnome-extra" ;;
cinnamon) WM_PACKAGES="$WM_PACKAGES $wm" ;;
xfce4) WM_PACKAGES="$WM_PACKAGES $wm xfce4-goodies xfce4-pulseaudio-plugin" ;;
2018-08-12 23:24:38 -05:00
esac
2018-07-18 19:52:06 -05:00
done
2018-07-18 19:50:37 -05:00
2018-08-12 23:24:38 -05:00
if yesno "$_WMLogin" "$_LoginTypeBody\n" "xinit" "lightdm"; then
LOGIN_TYPE="xinit"
else
LOGIN_TYPE="lightdm"
fi
if yesno "$_WMLogin" "$_AutoLoginBody\n"; then
AUTOLOGIN=true
else
AUTOLOGIN=false
fi
2018-07-18 19:52:06 -05:00
2018-08-12 23:24:38 -05:00
if [[ $WM_NUM -eq 1 ]]; then
LOGIN_WM="$INSTALL_WMS"
else
LOGIN_WM="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
--title " $_WMLogin " --menu "$_WMLoginBody" 0 0 0 $WM_LOGIN_CHOICES)"
[[ $LOGIN_WM == "" ]] && LOGIN_WM="$(awk '{print $1}' <<< "$INSTALL_WMS")"
2018-07-18 19:52:06 -05:00
fi
2018-08-12 23:24:38 -05:00
2018-08-19 22:32:21 -05:00
case $LOGIN_WM in
2018-08-20 04:26:13 -05:00
i3-gaps) LOGIN_WM='i3' ;;
gnome) LOGIN_WM='gnome-session' ;;
cinnamon) LOGIN_WM='cinnamon-session' ;;
openbox) LOGIN_WM='openbox-session' ;;
xfce4) LOGIN_WM='startxfce4' ;;
2018-08-19 22:32:21 -05:00
esac
2018-08-18 19:59:25 -05:00
2018-08-12 23:24:38 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-08-20 04:26:13 -05:00
extra_packages() {
2018-08-25 22:49:06 -05:00
EXTRA_PACKAGES="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
2018-08-22 03:22:02 -05:00
--title " $_WMChoice " --checklist "$_WMChoiceBody\n" 0 0 20 \
"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 \
2018-08-24 03:40:55 -05:00
"epiphany" "A GNOME web browser based on the WebKit rendering engine" off \
2018-08-22 03:22:02 -05:00
"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 \
"emacs" "An extensible, customizable, self-documenting real-time display editor" off \
"neovim" "A fork of Vim aiming to improve user experience, plugins, and GUIs." off \
"mousepad" "A simple text editor" off \
"urxvt" "A unicode enabled rxvt-clone terminal emulator" off \
"tilix" "A tiling terminal emulator for Linux using GTK+ 3" off \
"terminator" "Terminal emulator that supports tabs and grids" off \
"tilda" "A Gtk based drop down terminal for Linux and Unix" off \
"xfce4-terminal" "A terminal emulator primarily for the XFCE desktop" off \
"termite" "A minimal VTE-based terminal emulator" off \
"pcmanfm" "A fast and lightweight file manager" off \
"gnome-disk-utility" "Disk Management Utility" off \
"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 \
2018-08-24 03:40:55 -05:00
"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 \
2018-08-22 03:22:02 -05:00
"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 \
"rhythmbox" "Music playback and management application" off \
"deadbeef" "A GTK+ audio player for GNU/Linux" off \
"clementine" "A modern music player and library organizer" off \
"thunderbird" "Standalone mail and news reader from mozilla" off \
"geary" "A lightweight email client for the GNOME desktop" off \
"evolution" "Manage your email, contacts and schedule" off \
"mutt" "Small but very powerful text-based mail client" off \
"deluge" "A BitTorrent client written in python" off \
"transmission-gtk" "Free BitTorrent client GTK+ GUI" off \
"qbittorrent" "An advanced BitTorrent client" off \
"hexchat" "A popular and easy to use graphical IRC client" off \
"pidgin" "Multi-protocol instant messaging client" off \
"weechat" "Fast, light and extensible IRC client" off \
"irssi" "Modular text mode IRC client" off \
"libreoffice-fresh" "Full featured office suite" off \
"abiword" "Fully-featured word processor" off \
"calligra" "A set of applications for productivity" off \
2018-08-24 03:40:55 -05:00
"evince" "A document viewer" off \
"zathura zathura-pdf-poppler" "Minimalistic document viewer" off \
2018-08-22 03:22:02 -05:00
"qpdfview" "A tabbed PDF viewer" off \
2018-08-24 03:40:55 -05:00
"mupdf mupdf-tools" "Lightweight PDF and XPS viewer" off \
"gpicview" "Lightweight image viewer" off \
2018-08-22 03:22:02 -05:00
"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 \
2018-08-24 03:40:55 -05:00
"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 \
2018-08-22 03:22:02 -05:00
"guvcview" "Capture video from camera devices" off \
"gpick" "Advanced color picker using GTK+ toolkit" off \
"gcolor2" "A simple GTK+2 color selector" off \
2018-08-24 03:40:55 -05:00
"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 \
2018-08-22 03:22:02 -05:00
"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 \
2018-08-24 03:40:55 -05:00
"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)"
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")"
2018-08-20 04:26:13 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
######################################################################
2018-08-24 03:40:55 -05:00
## Partitioning Functions ##
2018-07-18 19:50:37 -05:00
######################################################################
2018-08-17 03:21:15 -05:00
decrease_part_count() {
# remove a partition from the dialog list and decrement the number partitions left
local p="$1"
PARTS="$(sed "s~${p} [0-9]*[G-M]~~; s~${p} [0-9]*\.[0-9]*[G-M]~~" <<< "$PARTS")"
(( COUNT > 0 )) && (( COUNT-- ))
return 0
}
2018-07-18 19:50:37 -05:00
mount_partition() {
local part="$1"
2018-08-24 03:40:55 -05:00
local mount="${MNT}$2"
2018-07-18 19:52:06 -05:00
local fs="$(lsblk -lno FSTYPE $part)"
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
mkdir -p "$mount"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if [[ ${FS_OPTS[$fs]} != "" && $part != "$BOOT_PART" ]] && select_mount_opts "$part" "$fs"; then
2018-08-24 03:40:55 -05:00
mount -o $MNT_OPTS $part "$mount" 2>$ERR
check_for_errors "mount -o $MNT_OPTS $part $mount"
2018-07-18 19:50:37 -05:00
else
2018-08-24 03:40:55 -05:00
mount $part "$mount" 2>$ERR
check_for_errors "mount $part $mount"
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
confirm_mount $part "$mount" || return 1
2018-08-25 19:52:57 -05:00
check_cryptlvm "$part"
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
unmount_partitions() {
swapoff -a
2018-08-24 03:40:55 -05:00
for i in $(mount | awk "/${MNT//\//\\/}/"' {print $3}' | sort -r); do
2018-07-18 19:52:06 -05:00
umount -r "$i" >/dev/null 2>&1
2018-07-18 19:50:37 -05:00
done
}
2018-07-18 19:52:06 -05:00
confirm_mount() {
local part="$1"
local mount="$2"
if [[ "$mount" == "$MNT" ]]; then
local msg="Partition: $part\nMountpoint: / (root)"
else
local msg="Partition: $part\nMountpoint: ${mount#$MNT}"
fi
# partition failed to mount properly
if ! grep -q "$mount" <<< "$(mount)"; then
2018-08-24 03:40:55 -05:00
infobox "$_MntTitle" "$_MntFail\n$msg\n" 1
2018-07-18 19:52:06 -05:00
return 1
2018-08-24 03:40:55 -05:00
else
# mount was successful
infobox "$_MntTitle" "$_MntSucc\n$msg\n" 1
decrease_part_count "$part"
2018-07-18 19:52:06 -05:00
fi
return 0
}
2018-07-18 19:50:37 -05:00
find_partitions() {
local str="$1"
2018-07-18 19:52:06 -05:00
local err='NONE'
2018-07-18 19:50:37 -05:00
2018-07-28 14:36:08 -05:00
# string of partitions as /TYPE/PART SIZE
2018-08-18 19:59:25 -05:00
if [[ $IGNORE_DEV != "" ]]; then
PARTS="$(lsblk -lno TYPE,NAME,SIZE |
awk "/$str/"' && !'"/$IGNORE_DEV/"' {sub(/^part/, "/dev/"); sub(/^lvm|^crypt/, "/dev/mapper/"); print $1$2 " " $3}')"
2018-07-28 15:03:43 -05:00
else
2018-08-18 19:59:25 -05:00
PARTS="$(lsblk -lno TYPE,NAME,SIZE |
awk "/$str/"' {sub(/^part/, "/dev/"); sub(/^lvm|^crypt/, "/dev/mapper/"); print $1$2 " " $3}')"
2018-07-28 15:03:43 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# number of partitions total
COUNT=$(wc -l <<< "$PARTS")
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# ensure we have enough partitions for the system and action type
2018-07-18 19:50:37 -05:00
case $str in
2018-07-18 19:52:06 -05:00
'part|lvm|crypt') [[ $COUNT -eq 0 || ($SYS == 'UEFI' && $COUNT -lt 2) ]] && err="$_PartErrBody" ;;
'part|crypt') (( COUNT == 0 )) && err="$_LvmPartErrBody" ;;
'part|lvm') (( COUNT < 2 )) && err="$_LuksPartErrBody" ;;
2018-07-18 19:50:37 -05:00
esac
2018-07-18 19:52:06 -05:00
# if an error was found with the partition setup and there aren't enough partitions
# show the appropriate error message for the given $str types were using
if [[ $err != 'NONE' ]]; then
2018-07-18 19:50:37 -05:00
msgbox "$_ErrTitle" "$err"
2018-07-18 19:52:06 -05:00
if select_device 'root'; then
create_partitions "$DEVICE"
else
return 1
fi
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-07-18 19:52:06 -05:00
auto_partition() {
2018-07-18 19:50:37 -05:00
local device="$1"
2018-07-18 19:52:06 -05:00
# confirm or bail
yesno "$_PrepParts" "$_PartBody1 $device $_PartBody2" || return 0
2018-08-24 03:40:55 -05:00
infobox "$_PrepParts" "\nAuto partitioning device: $device\n" 0
2018-07-18 19:50:37 -05:00
2018-08-21 12:28:19 -05:00
swapoff -a # make sure swap is disabled in case the device was used for swap
2018-07-18 19:52:06 -05:00
local dev_info="$(parted -s $device print)"
2018-08-24 03:40:55 -05:00
# walk the partitions on the device in reverse order and delete them
2018-08-17 03:21:15 -05:00
for i in $(awk '/^ [1-9][0-9]?/ {print $1}' <<< "$dev_info" | sort -r); do
parted -s $device rm $i 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "parted -s $device rm $i"
2018-07-18 19:52:06 -05:00
done
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# make sure we have the correct device table for the system type, gpt or msdos
2018-08-21 12:28:19 -05:00
local newtable="gpt"
2018-08-24 03:40:55 -05:00
local table="$(awk '/Table:/ {print $3}' <<< "$dev_info")"
2018-08-21 12:28:19 -05:00
[[ $SYS == BIOS ]] && newtable="msdos"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# if the current device table isn't correct run mklabel
2018-08-17 03:21:15 -05:00
if [[ $table != "$newtable" ]]; then
2018-07-18 19:52:06 -05:00
parted -s $device mklabel $newtable 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "parted -s $device mklabel $newtable"
2018-07-18 19:50:37 -05:00
fi
2018-08-21 12:28:19 -05:00
# when device contains the string 'nvme' then add 'p' before the part number
local nvme=""
[[ $device =~ nvme ]] && nvme="p"
2018-07-18 19:52:06 -05:00
local part_num=1
2018-08-21 12:28:19 -05:00
BOOT_PART="$device${nvme}$part_num" # set the boot partition label to the first partition
2018-07-18 19:50:37 -05:00
if [[ $SYS == "BIOS" ]]; then
2018-07-18 19:52:06 -05:00
parted -s $device mkpart primary ext4 1MiB 513MiB 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "parted -s $device mkpart primary ext4 1MiB 513MiB"
2018-07-18 19:52:06 -05:00
mkfs.ext4 -q $BOOT_PART >/dev/null 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "mkfs.ext4 -q $BOOT_PART"
2018-08-25 23:23:48 -05:00
parted -s $device set $part_num boot on 2>$ERR
check_for_errors "parted -s $device set $part_num boot on"
2018-07-18 19:52:06 -05:00
else
parted -s $device mkpart ESP fat32 1MiB 513MiB 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "parted -s $device mkpart ESP fat32 1MiB 513MiB"
2018-07-18 19:52:06 -05:00
mkfs.vfat -F32 $BOOT_PART >/dev/null 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "mkfs.vfat -F32 $BOOT_PART"
2018-08-21 12:28:19 -05:00
parted -s $device set $part_num esp on 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "parted -s $device set $part_num esp on"
2018-07-18 19:50:37 -05:00
fi
2018-08-21 12:28:19 -05:00
(( 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
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
parted -s $device mkpart primary ext4 514MiB 100% 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "parted -s $device mkpart primary ext4 514MiB 100%"
2018-07-18 19:52:06 -05:00
mkfs.ext4 -q $ROOT_PART >/dev/null 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "mkfs.ext4 -q $ROOT_PART"
2018-07-18 19:50:37 -05:00
2018-08-21 12:28:19 -05:00
tput civis; sleep 0.5
2018-07-18 19:52:06 -05:00
echo -e "\nAuto partitioning complete.\n" > /tmp/.devlist
2018-07-28 14:36:08 -05:00
lsblk $device -o NAME,MODEL,TYPE,FSTYPE,SIZE >> /tmp/.devlist
2018-07-18 19:52:06 -05:00
dialog --cr-wrap --backtitle "$BT" --title " $_PrepParts " --textbox /tmp/.devlist 0 0
return 0
}
create_partitions() {
local device="$1"
2018-08-24 03:40:55 -05:00
2018-07-18 19:52:06 -05:00
tput civis
2018-08-24 03:40:55 -05:00
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
2018-07-18 19:52:06 -05:00
if [[ $choice != "$_PartWipe" && $choice != "$_PartAuto" ]]; then
2018-08-12 23:24:38 -05:00
$choice $device
2018-07-18 19:52:06 -05:00
elif [[ $choice == "$_PartWipe" ]]; then
2018-08-24 03:40:55 -05:00
if yesno "$_PartWipe" "$_PartBody1 $device $_PartWipeBody2"; then
wipe -Ifrev $device
fi
create_partitions $device
2018-07-18 19:52:06 -05:00
else
2018-08-24 03:40:55 -05:00
# if auto_partition fails we need to re-initialize the variables, just to be sure
2018-07-29 14:53:14 -05:00
auto_partition $device || { initialize_variables; return 1; }
2018-07-18 19:50:37 -05:00
fi
}
2018-08-24 03:40:55 -05:00
swapfile_size() {
2018-07-18 19:52:06 -05:00
tput cnorm
SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "$SWAP_SIZE")"
[[ $? != 0 || $SWAP_SIZE == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# size is incorrect
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"
2018-08-24 03:40:55 -05:00
swapfile_size || return 1
else
fallocate -l $SWAP_SIZE $MNT/swapfile >/dev/null 2>&1
chmod 600 $MNT/swapfile >/dev/null 2>&1
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
return 0
}
enable_swap() {
local swap="$1"
mkswap $swap >/dev/null 2>$ERR
check_for_errors "mkswap $swap"
swapon $swap >/dev/null 2>$ERR
2018-08-25 19:52:57 -05:00
check_for_error "swapon $swap"
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
select_swap() {
2018-08-14 21:58:07 -05:00
# Ask user to select partition or create swapfile
SWAP="$(dialog --backtitle "$BT" --cr-wrap --stdout --title " $_SelSwpSetup " \
--menu "$_SelSwpBody" 0 0 0 "$_SelSwpNone" "-" "$_SelSwpFile" "-" $PARTS)"
[[ $? != 0 || $SWAP == "$_SelSwpNone" ]] && return 0
if [[ $SWAP == "$_SelSwpFile" ]]; then
2018-08-24 03:40:55 -05:00
swapfile_size || return 1
2018-08-25 19:52:57 -05:00
enable_swap "$MNT/swapfile"
2018-08-24 03:40:55 -05:00
SWAP="/swapfile"
2018-08-14 21:58:07 -05:00
else
2018-08-25 19:52:57 -05:00
enable_swap "$SWAP"
2018-08-14 21:58:07 -05:00
decrease_part_count "$SWAP"
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
select_device() {
2018-08-24 03:40:55 -05:00
local msg
2018-07-18 19:52:06 -05:00
[[ $1 == 'boot' ]] && msg="$_DevSelTitle for bootloader\n"
if (( DEV_COUNT == 1 )); then
DEVICE="$(awk '{print $1}' <<< "$SYS_DEVS")"
2018-08-24 03:40:55 -05:00
msg="\nOnly one device available$([[ $1 == 'boot' ]] && echo -n " for grub bootloader"):"
infobox "$_DevSelTitle" "$msg $DEVICE\n" 1
2018-07-18 19:52:06 -05:00
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
2018-08-24 03:40:55 -05:00
msg="\nNo available devices for installation to use$([[ $1 == 'boot' ]] && echo -n " for grub bootloader")."
msgbox "$_ErrTitle" "$msg\n$_Exit"
die 1
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# if the device selected was for grub bootloader, set the BOOT_DEVICE
2018-07-18 19:52:06 -05:00
# this is needed because grub uses the base device for BIOS, not the partition
2018-08-24 03:40:55 -05:00
[[ $1 == 'boot' ]] && BOOT_DEVICE="$DEVICE"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
select_mount_opts() {
local part="$1"
local fs="$2"
local title="${fs^} Mount Options"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
tput civis
MNT_OPTS="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $title " \
--checklist "$_MntBody" 0 0 0 ${FS_OPTS[$fs]} | sed 's/ /,/g; $s/,$//')"
[[ $? != 0 || $MNT_OPTS == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if ! yesno "$title" "$_MntConfBody $MNT_OPTS\n"; then
select_mount_opts "$part" "$fs" || return 1
2018-07-18 19:50:37 -05:00
fi
return 0
}
2018-07-18 19:52:06 -05:00
select_filesystem() {
local part="$1"
2018-07-28 15:03:43 -05:00
local cur_fs
cur_fs="$(lsblk -lno FSTYPE $part)"
2018-07-18 19:52:06 -05:00
tput civis
local choice
2018-07-28 14:36:08 -05:00
choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_FSTitle: $part" \
2018-08-17 03:21:15 -05:00
--menu "\nPartition: ${part}$([[ $cur_fs != "" ]] && echo -n "\nCurrent: ${cur_fs}")\n$_FSBody" 0 0 0 \
$([[ $cur_fs != "" ]] && echo -n "$_Skip -") \
2018-08-12 23:24:38 -05:00
"ext4" "${FS_CMDS[ext4]}" "ext3" "${FS_CMDS[ext3]}" \
"ext2" "${FS_CMDS[ext2]}" "vfat" "${FS_CMDS[vfat]}" \
"ntfs" "${FS_CMDS[ntfs]}" "f2fs" "${FS_CMDS[f2fs]}" \
"jfs" "${FS_CMDS[jfs]}" "nilfs2" "${FS_CMDS[nilfs2]}" \
"reiserfs" "${FS_CMDS[reiserfs]}" "xfs" "${FS_CMDS[xfs]}")"
2018-08-17 03:21:15 -05:00
[[ $choice == "$_Skip" ]] && return 0
2018-08-17 20:44:17 -05:00
[[ $choice == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if yesno "$_FSTitle" "\nFormat $part as $choice?\n"; then
2018-08-24 03:40:55 -05:00
infobox "$_FSTitle" "\nFormatting: $part\n\nCommand: ${FS_CMDS[$choice]}\n" 0
2018-07-18 19:52:06 -05:00
${FS_CMDS[$choice]} $part >/dev/null 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "${FS_CMDS[$choice]} $part"
2018-07-18 19:52:06 -05:00
else
select_filesystem "$part" || return 1
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-07-18 19:52:06 -05:00
select_boot_setup() {
# choose bootloader and by extension mountpoint (if needed)
tput civis
2018-08-17 03:21:15 -05:00
BOOTLOADER="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_PrepMount " --menu "$_MntBootBody" 0 0 0 ${BOOTLOADERS[$SYS]})"
2018-07-18 19:52:06 -05:00
[[ $? != 0 || $BOOTLOADER == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
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
2018-07-18 19:52:06 -05:00
fi
2018-08-24 03:40:55 -05:00
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"
2018-07-18 19:50:37 -05:00
fi
return 0
}
2018-08-25 19:52:57 -05:00
setup_boot_device() {
# set BOOT_DEVICE for syslinux on UEFI and grub on BIOS
2018-08-25 23:23:48 -05:00
if [[ $BOOT_PART =~ nvme ]]; then
BOOT_DEVICE="${BOOT_PART%p[1-9]}"
else
BOOT_DEVICE="${BOOT_PART%[1-9]}"
fi
2018-08-25 19:52:57 -05:00
BOOT_PART_NUM="${BOOT_PART: -1}"
# setup the needed partition flags for boot on both system types
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"
if [[ $SYS == 'UEFI' ]]; then
parted -s $BOOT_DEVICE set $BOOT_PART_NUM esp on 2>$ERR
check_for_errors "parted -s $BOOT_DEVICE set $BOOT_PART_NUM boot on"
fi
2018-08-25 23:23:48 -05:00
2018-08-25 19:52:57 -05:00
return 0
}
2018-07-18 19:52:06 -05:00
select_efi_partition() {
format_efi_as_vfat() {
2018-08-24 03:40:55 -05:00
infobox "$_FSTitle" "\nFormatting $1 as vfat/fat32.\n" 0
2018-07-18 19:52:06 -05:00
mkfs.vfat -F32 "$1" >/dev/null 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "mkfs.vfat -F32 $1"
2018-07-18 19:52:06 -05:00
}
2018-07-18 19:50:37 -05:00
2018-08-25 19:52:57 -05:00
tput civis
2018-07-18 19:52:06 -05:00
if (( COUNT == 1 )); then
BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
2018-08-24 03:40:55 -05:00
infobox "$_PrepMount" "$_OnlyOne for EFI: $BOOT_PART\n" 1
2018-07-18 19:52:06 -05:00
else
2018-08-25 19:52:57 -05:00
BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_PrepMount " --menu "$_SelUefiBody" 0 0 0 $PARTS)"
2018-07-18 19:52:06 -05:00
[[ $? != 0 || $BOOT_PART == "" ]] && return 1
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then
local msg="$_FormUefiBody $BOOT_PART $_FormUefiBody2"
2018-08-25 19:52:57 -05:00
yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Do Not Format" "no" &&
format_efi_as_vfat "$BOOT_PART"
2018-07-18 19:52:06 -05:00
else
2018-08-25 19:52:57 -05:00
format_efi_as_vfat "$BOOT_PART"
2018-07-18 19:52:06 -05:00
fi
return 0
}
2018-07-18 19:50:37 -05:00
2018-08-25 19:52:57 -05:00
select_boot_partition() {
2018-07-30 02:30:35 -05:00
format_as_ext4() {
2018-08-24 03:40:55 -05:00
infobox "$_FSTitle" "\nFormatting $1 as ext4.\n" 0
2018-07-30 02:30:35 -05:00
mkfs.ext4 -q "$1" >/dev/null 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "mkfs.ext4 -q $1"
2018-07-30 02:30:35 -05:00
}
2018-07-27 23:51:57 -05:00
tput civis
2018-08-25 19:52:57 -05:00
BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title "$_PrepMount" --menu "$_SelBiosBody" 0 0 0 "$_Skip" "-" $PARTS)"
2018-07-18 19:50:37 -05:00
2018-08-22 03:22:02 -05:00
if [[ $BOOT_PART == "$_Skip" || $BOOT_PART == "" ]]; then
2018-07-28 15:03:43 -05:00
BOOT_PART=""
2018-07-18 19:52:06 -05:00
else
2018-07-30 02:30:35 -05:00
if grep -q 'ext[34]' <<< "$(fsck -N "$BOOT_PART")"; then
local msg="$_FormBiosBody $BOOT_PART $_FormUefiBody2"
if yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Skip Formatting" "no"; then
2018-08-25 19:52:57 -05:00
format_as_ext4 "$BOOT_PART"
2018-07-30 02:30:35 -05:00
fi
else
2018-08-25 19:52:57 -05:00
format_as_ext4 "$BOOT_PART"
2018-07-30 02:30:35 -05:00
fi
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-07-18 19:52:06 -05:00
select_root_partition() {
2018-08-24 03:40:55 -05:00
# if we used LUKS and no LVM or LUKS+LVM
2018-08-25 19:52:57 -05:00
# remove the relevant partition labels from the list
2018-07-18 19:52:06 -05:00
if (( LUKS == 1 && LVM == 0 )); then
ROOT_PART="/dev/mapper/$LUKS_NAME"
decrease_part_count "$LUKS_PART"
2018-07-28 14:59:12 -05:00
elif (( LUKS == 1 && LVM == 1 )); then
decrease_part_count "$LUKS_PART"
2018-08-25 19:52:57 -05:00
for part in $(echo "$GROUP_PARTS"); do
decrease_part_count "$part"
done
ROOT_PART=""
elif (( LUKS == 0 && LVM == 1 )); then
for part in $(echo "$GROUP_PARTS"); do
decrease_part_count "$part"
done
2018-07-28 15:03:43 -05:00
ROOT_PART=""
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-07-28 15:03:43 -05:00
if [[ $COUNT -eq 1 && $ROOT_PART == "" ]]; then
2018-07-18 19:52:06 -05:00
ROOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
2018-08-24 03:40:55 -05:00
infobox "$_PrepMount" "$_OnlyOne for root (/): $ROOT_PART\n" 1
2018-07-18 19:52:06 -05:00
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
2018-07-18 19:50:37 -05:00
else
2018-08-24 03:40:55 -05:00
local msg="\nUsing $([[ $LUKS -eq 1 ]] && echo -n "encrypted ")root partition:"
infobox "$_PrepMount" "$msg $ROOT_PART\n" 1
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
select_filesystem "$ROOT_PART" || { ROOT_PART=""; return 1; }
2018-08-24 03:40:55 -05:00
mount_partition "$ROOT_PART" || { ROOT_PART=""; return 1; }
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
select_mountpoint() {
tput cnorm
2018-07-30 02:30:35 -05:00
EXTRA_MNT="$(getinput "$_PrepMount $part" "$_ExtPartBody1 /home /var\n" "/")"
2018-07-18 19:52:06 -05:00
[[ $? != 0 || $EXTRA_MNT == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# bad mountpoint
if [[ ${EXTRA_MNT:0:1} != "/" || ${#EXTRA_MNT} -le 1 || $EXTRA_MNT =~ \ |\' ]]; then
msgbox "$_ErrTitle" "$_ExtErrBody"
select_mountpoint || return 1
2018-07-18 19:50:37 -05:00
fi
return 0
}
2018-07-18 19:52:06 -05:00
select_extra_partitions() {
while (( COUNT > 0 )); do
tput civis
local part
part="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepMount " \
--menu "$_ExtPartBody" 0 0 0 "$_Done" "-" $PARTS)"
2018-07-28 14:36:08 -05:00
[[ $? != 0 || $part == "$_Done" || $part == "" ]] && break
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# choose what filesystem and get mountpoint
select_filesystem "$part" || { break; return 1; }
select_mountpoint || { break; return 1; }
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# mount it
mount_partition "$part" "$EXTRA_MNT" || { break; return 1; }
2018-07-18 19:50:37 -05:00
2018-07-28 14:36:08 -05:00
# if the mountpoint was /usr add 'usr' to MKINIT_HOOKS
[[ $EXTRA_MNT == "/usr" && $MKINIT_HOOKS != *usr* ]] && MKINIT_HOOKS="usr $MKINIT_HOOKS"
2018-07-18 19:52:06 -05:00
done
2018-07-18 19:50:37 -05:00
return 0
}
2018-08-25 19:52:57 -05:00
select_partitions() {
2018-07-18 19:52:06 -05:00
msgbox "$_PrepMount" "$_WarnMount"
2018-07-18 19:50:37 -05:00
lvm_detect
2018-07-18 19:52:06 -05:00
# prepare partition list PARTS for dialog
2018-07-18 19:50:37 -05:00
unmount_partitions
2018-07-18 19:52:06 -05:00
find_partitions 'part|lvm|crypt' || return 1
# remove boot partition from dialog list if we auto partitioned one
[[ $BOOT_PART != "" ]] && decrease_part_count "$BOOT_PART"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
select_root_partition || return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if [[ $BOOT_PART == "" ]]; then
if [[ $SYS == "UEFI" ]]; then
select_efi_partition || { BOOT_PART=""; return 1; }
2018-08-25 19:52:57 -05:00
elif (( $COUNT > 0 )); then
select_boot_partition || { BOOT_PART=""; return 1; }
2018-07-18 19:52:06 -05:00
fi
else
2018-08-24 03:40:55 -05:00
infobox "$_PrepMount" "\nUsing boot partition: $BOOT_PART\n" 1
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
select_boot_setup || { BOOTLOADER=""; return 1; }
2018-08-24 03:40:55 -05:00
if [[ $BOOT_PART != "" ]]; then
2018-08-25 23:23:48 -05:00
setup_boot_device
2018-08-24 03:40:55 -05:00
mount_partition "$BOOT_PART" "${BOOT_MNTS[$SYS-$BOOTLOADER]}" || return 1
SEPERATE_BOOT=1
fi
2018-07-18 19:50:37 -05:00
select_swap || return 1
2018-07-28 14:36:08 -05:00
select_extra_partitions || return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
2018-08-25 19:52:57 -05:00
check_cryptlvm() {
2018-07-18 19:52:06 -05:00
local part="$1"
local devs="$(lsblk -lno NAME,FSTYPE,TYPE)"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# Identify if $part is "crypt" (LUKS on LVM, or LUKS alone)
if [[ $(lsblk -lno TYPE "$part") =~ 'crypt' ]]; then
LUKS=1
LUKS_NAME="${part#/dev/mapper/}"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
for dev in $(awk '/lvm/ && /crypto_LUKS/ {print "/dev/mapper/"$1}' <<< "$devs" | uniq); do
if grep -q "$LUKS_NAME" <<< "$(lsblk -lno NAME "$dev")"; then
LUKS_DEV="$LUKS_DEV cryptdevice=$dev:$LUKS_NAME"
LVM=1
break
fi
done
for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | uniq); do
if grep -q "$LUKS_NAME" <<< "$(lsblk -lno NAME "$dev")"; then
LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
LUKS_DEV="$LUKS_DEV cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME"
break
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
done
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
elif [[ $(lsblk -lno TYPE "$part") =~ 'lvm' ]]; then
LVM=1
VOLUME_NAME="${part#/dev/mapper/}"
for dev in $(awk '/crypt/ && /lvm2_member/ {print "/dev/mapper/"$1}' <<< "$devs" | uniq); do
if grep -q "$VOLUME_NAME" <<< "$(lsblk -lno NAME "$dev")"; then
LUKS_NAME="$(sed 's~/dev/mapper/~~g' <<< "$dev")"
break
fi
done
for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | uniq); do
if grep -q "$LUKS_NAME" <<< "$(lsblk -lno NAME "$dev")"; then
LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
LUKS_DEV="$LUKS_DEV cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME"
LUKS=1
break
fi
done
fi
2018-07-18 19:50:37 -05:00
}
######################################################################
2018-08-24 03:40:55 -05:00
## LUKS Functions ##
2018-07-18 19:50:37 -05:00
######################################################################
luks_open() {
2018-07-18 19:52:06 -05:00
LUKS_PART=""
modprobe -a dm-mod dm_crypt
2018-07-18 19:50:37 -05:00
unmount_partitions
2018-07-18 19:52:06 -05:00
find_partitions 'part|crypt|lvm'
tput civis
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if (( COUNT == 1 )); then
LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
2018-08-24 03:40:55 -05:00
infobox "$_LuksOpen" "${_OnlyOne}: $LUKS_PART\n" 1
2018-07-18 19:52:06 -05:00
else
tput civis
LUKS_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_LuksOpen " \
--menu "$_LuksMenuBody" 0 0 0 $PARTS)"
[[ $? != 0 || $LUKS_PART == "" ]] && return 1
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# get password and name for encryption
2018-08-25 19:52:57 -05:00
luks_pass "$_LuksOpen" "$LUKS_NAME" || return 1
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
infobox "$_LuksOpen" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0
2018-07-18 19:52:06 -05:00
echo "$LUKS_PASS" | cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "cryptsetup open --type luks $LUKS_PART $LUKS_NAME"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
LUKS=1
luks_show
return 0
}
2018-07-18 19:50:37 -05:00
2018-08-25 19:52:57 -05:00
luks_pass() {
2018-07-18 19:52:06 -05:00
local title="$1"
local name="$2"
LUKS_PASS=""
2018-08-25 19:52:57 -05:00
LUKS_NAME=""
2018-08-24 03:40:55 -05:00
2018-07-18 19:52:06 -05:00
tput cnorm
2018-08-24 03:40:55 -05:00
2018-07-18 19:52:06 -05:00
local values
values="$(dialog --stdout --separator '~' --ok-label "Submit" --backtitle "$BT" \
--title " $title " --insecure --mixedform "$_LuksOpenBody" 16 75 4 \
"$_Name" 1 1 "$name" 1 $((${#_Name} + 2)) 71 0 0 \
"$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \
"$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1)"
[[ $? != 0 || $values == "" ]] && return 1
2018-08-24 03:40:55 -05:00
2018-07-18 19:52:06 -05:00
name="$(awk -F'~' '{print $1}' <<< "$values")"
local pass pass2
pass="$(awk -F'~' '{print $2}' <<< "$values")"
pass2="$(awk -F'~' '{print $3}' <<< "$values")"
if [[ $pass == "" || "$pass" != "$pass2" ]]; then
msgbox "$_ErrTitle" "$_PassErr\n$_TryAgain"
2018-08-25 19:52:57 -05:00
luks_pass "$title" "$name" || return 1
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
LUKS_PASS="$pass"
LUKS_NAME="$name"
return 0
2018-07-18 19:50:37 -05:00
}
luks_setup() {
2018-07-18 19:52:06 -05:00
LUKS_PART=""
2018-07-18 19:50:37 -05:00
modprobe -a dm-mod dm_crypt
unmount_partitions
2018-07-18 19:52:06 -05:00
if [[ $ROOT_PART == "" || $LVM -eq 1 ]]; then
find_partitions 'part|lvm'
[[ $BOOT_PART != "" ]] && decrease_part_count "$BOOT_PART"
if (( COUNT == 1 )); then
LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
2018-08-24 03:40:55 -05:00
infobox "$_LuksEncrypt" "${_OnlyOne}: $LUKS_PART\n" 1
2018-07-18 19:52:06 -05:00
else
tput civis
LUKS_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title "$_LuksEncrypt" --menu "$_LuksEncryptBody" 0 0 0 $PARTS)"
[[ $? != 0 || $LUKS_PART == "" ]] && return 1
fi
else
2018-08-24 03:40:55 -05:00
infobox "$_PrepMount" "\nUsing root partition created earlier: $ROOT_PART\n" 1
2018-07-18 19:52:06 -05:00
LUKS_PART="$ROOT_PART"
fi
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# get password and name for encrypted device
2018-08-25 19:52:57 -05:00
luks_pass "$_LuksEncrypt" "$LUKS_NAME" || return 1
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
luks_default() {
2018-07-18 19:52:06 -05:00
luks_setup || return 1
2018-08-24 03:40:55 -05:00
infobox "$_LuksEncrypt" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
echo "$LUKS_PASS" | cryptsetup -q luksFormat "$LUKS_PART" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "cryptsetup -q luksFormat $LUKS_PART"
2018-07-18 19:52:06 -05:00
echo "$LUKS_PASS" | cryptsetup open "$LUKS_PART" "$LUKS_NAME" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME"
2018-07-18 19:52:06 -05:00
LUKS=1
luks_show
return 0
2018-07-18 19:50:37 -05:00
}
2018-08-25 19:52:57 -05:00
luks_keycmd() {
2018-07-18 19:50:37 -05:00
if luks_setup; then
2018-07-18 19:52:06 -05:00
tput cnorm
local cipher
cipher="$(getinput "$_PrepLUKS" "$_LuksCipherKey" "-s 512 -c aes-xts-plain64")"
[[ $? != 0 || $cipher == "" ]] && return 1
2018-08-24 03:40:55 -05:00
infobox "$_LuksEncryptAdv" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
echo "$LUKS_PASS" | cryptsetup -q $cipher luksFormat $LUKS_PART 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "cryptsetup -q $cipher luksFormat $LUKS_PART"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
echo "$LUKS_PASS" | cryptsetup open $LUKS_PART "$LUKS_NAME" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME"
2018-07-18 19:50:37 -05:00
luks_show
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
return 1
2018-07-18 19:50:37 -05:00
}
luks_show() {
2018-07-18 19:52:06 -05:00
tput civis
sleep 0.5
echo -e "$_LuksEncryptSucc" > /tmp/.devlist
lsblk -o NAME,TYPE,FSTYPE,SIZE $LUKS_PART >> /tmp/.devlist
dialog --cr-wrap --backtitle "$BT" --title " $_LuksEncrypt " --textbox /tmp/.devlist 0 0
2018-07-18 19:50:37 -05:00
}
luks_menu() {
2018-07-18 19:52:06 -05:00
tput civis
local choice
choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepLUKS " \
--menu "${_LuksMenuBody}${_LuksMenuBody2}${_LuksMenuBody3}" 0 0 0 \
2018-07-18 19:50:37 -05:00
"$_LuksEncrypt" "cryptsetup -q luksFormat" \
2018-07-18 19:52:06 -05:00
"$_LuksOpen" "cryptsetup open --type luks" \
2018-07-18 19:50:37 -05:00
"$_LuksEncryptAdv" "cryptsetup -q -s -c luksFormat" \
2018-07-18 19:52:06 -05:00
"$_Back" "-")"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
case $choice in
"$_LuksEncrypt") luks_default && return 0 ;;
"$_LuksOpen") luks_open && return 0 ;;
2018-08-25 19:52:57 -05:00
"$_LuksEncryptAdv") luks_keycmd && return 0 ;;
2018-07-18 19:50:37 -05:00
*) return 0
esac
2018-07-18 19:52:06 -05:00
2018-07-18 19:50:37 -05:00
luks_menu
}
luks_keyfile() {
2018-08-22 03:22:02 -05:00
# Only used when choosing grub as bootloader.
# Without a keyfile, during boot the user will be asked
# to enter password for decryption twice, this is annoying
if [[ ! -e $MNT/crypto_keyfile.bin ]]; then
2018-08-24 03:40:55 -05:00
infobox "$_LuksKeyFileTitle" "$_LuksKeyFileCreate" 0
2018-07-18 19:50:37 -05:00
local dev
2018-08-22 03:22:02 -05:00
dev="/dev/$(lsblk -lno NAME,UUID,TYPE | awk "/$LUKS_UUID/"' && /part|crypt|lvm/ {print $1}')"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
local keycmd
2018-08-22 03:22:02 -05:00
keycmd="dd bs=512 count=8 if=/dev/urandom of=/crypto_keyfile.bin && chmod 000 /crypto_keyfile.bin"
keycmd="$keycmd && echo '$LUKS_PASS' | cryptsetup luksAddKey $dev /crypto_keyfile.bin"
2018-07-18 19:52:06 -05:00
chroot_cmd "$keycmd" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "$keycmd"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors 'sed -i "s/FILES=()/FILES=(/crypto_keyfile.bin)/g"'
2018-07-18 19:50:37 -05:00
fi
return 0
}
######################################################################
2018-08-24 03:40:55 -05:00
## LVM Functions ##
2018-07-18 19:50:37 -05:00
######################################################################
lvm_detect() {
2018-07-18 19:52:06 -05:00
PHYSICAL_VOLUMES="$(pvs -o pv_name --noheading 2>/dev/null)"
VOLUME_GROUP="$(vgs -o vg_name --noheading 2>/dev/null)"
VOLUMES="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if [[ $VOLUMES && $VOLUME_GROUP && $PHYSICAL_VOLUMES ]]; then
2018-08-24 03:40:55 -05:00
infobox "$_PrepLVM" "$_LvmDetBody" 0
2018-07-18 19:50:37 -05:00
modprobe dm-mod 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors 'modprobe dm-mod'
2018-07-18 19:50:37 -05:00
vgscan >/dev/null 2>&1
vgchange -ay >/dev/null 2>&1
fi
}
lvm_show_vg() {
2018-07-28 02:25:31 -05:00
DEL_VG=""
2018-07-18 19:52:06 -05:00
VOL_GROUP_LIST=""
2018-07-18 19:50:37 -05:00
for i in $(lvs --noheadings | awk '{print $2}' | uniq); do
2018-07-18 19:52:06 -05:00
VOL_GROUP_LIST="$VOL_GROUP_LIST $i $(vgdisplay "$i" | awk '/VG Size/ {print $3$4}')"
2018-07-18 19:50:37 -05:00
done
2018-07-28 02:25:31 -05:00
if [[ $VOL_GROUP_LIST == "" ]]; then
msgbox "$_ErrTitle" "$_LvmVGErr"
2018-07-18 19:50:37 -05:00
return 1
fi
2018-07-18 19:52:06 -05:00
tput civis
2018-07-28 02:25:31 -05:00
DEL_VG="$(dialog --cr-wrap --stdout --backtitle "$BT" \
2018-07-18 19:52:06 -05:00
--title " $_PrepLVM " --menu "$_LvmSelVGBody" 18 70 10 $VOL_GROUP_LIST)"
2018-07-28 02:25:31 -05:00
[[ $? != 0 || $DEL_VG == "" ]] && return 1
2018-07-18 19:50:37 -05:00
}
2018-07-18 19:52:06 -05:00
get_lv_size() {
tput cnorm
local ttl=" $_LvmCreateVG (LV:$VOL_COUNT) "
2018-08-24 03:40:55 -05:00
local msg="${VOLUME_GROUP}: ${GROUP_SIZE}$GROUP_SIZE_TYPE (${VOL_GROUP_MB}MB $_LvmLvSizeBody1).$_LvmLvSizeBody2"
2018-07-18 19:52:06 -05:00
VOLUME_SIZE="$(getinput "$ttl" "$msg" "")"
[[ $? != 0 || $VOLUME_SIZE == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
ERR_SIZE=0
# if the size is empty or 0
(( ${#VOLUME_SIZE} == 0 || ${VOLUME_SIZE:0:1} == 0 )) && ERR_SIZE=1
2018-07-18 19:50:37 -05:00
if (( ERR_SIZE == 0 )); then
2018-07-18 19:52:06 -05:00
# number of characters in VOLUME_SIZE minus the last, which should be a letter
local lv="$((${#VOLUME_SIZE} - 1))"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# loop each character (except the last) in VOLUME_SIZE and ensure they are numbers
2018-07-18 19:50:37 -05:00
for (( i=0; i<lv; i++ )); do
2018-07-18 19:52:06 -05:00
[[ ${VOLUME_SIZE:$i:1} != [0-9] ]] && { ERR_SIZE=1; break; }
2018-07-18 19:50:37 -05:00
done
if (( ERR_SIZE == 0 )); then
2018-07-18 19:52:06 -05:00
# ensure the last character is either m/M or g/G
case ${VOLUME_SIZE:$lv:1} in
2018-07-18 19:50:37 -05:00
[mMgG]) ERR_SIZE=0 ;;
*) ERR_SIZE=1
esac
if (( ERR_SIZE == 0 )); then
2018-08-24 03:40:55 -05:00
local s=${VOLUME_SIZE:0:$lv}
local m=$((s * 1000))
2018-07-18 19:52:06 -05:00
# 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
2018-08-24 03:40:55 -05:00
[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)) ;;
2018-07-18 19:50:37 -05:00
*) ERR_SIZE=1
esac
fi
fi
fi
if (( ERR_SIZE == 1 )); then
msgbox "$_ErrTitle" "$_LvmLvSizeErrBody"
2018-07-18 19:52:06 -05:00
get_lv_size || return 1
2018-07-18 19:50:37 -05:00
fi
return 0
}
2018-07-18 19:52:06 -05:00
lvm_volume_name() {
local msg="$1"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
local default="volmain"
(( VOL_COUNT > 1 )) && default="volextra"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
tput cnorm
local name
name="$(getinput "$_LvmCreateVG (LV:$VOL_COUNT)" "$msg" "$default")"
[[ $? != 0 || $name == "" ]] && return 1
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# bad volume name answer or name already in use
if [[ ${name:0:1} == "/" || ${#name} -eq 0 || $name =~ \ |\' ]] || grep -q "$name" <<< "$(lsblk)"; then
msgbox "$_ErrTitle" "$_LvmLvNameErrBody"
lvm_volume_name "$msg" || return 1
fi
VOLUME_NAME="$name"
return 0
}
lvm_group_name() {
tput cnorm
local group
group="$(getinput "$_LvmCreateVG" "$_LvmNameVgBody" "VolGroup")"
[[ $? != 0 || $group == "" ]] && return 1
# bad answer or group name already taken
if [[ ${group:0:1} == "/" || ${#group} -eq 0 || $group =~ \ |\' ]] || grep -q "$group" <<< "$(lsblk)"; then
2018-07-18 19:50:37 -05:00
msgbox "$_ErrTitle" "$_LvmNameVgErr"
2018-07-18 19:52:06 -05:00
lvm_group_name || return 1
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
VOLUME_GROUP="$group"
return 0
}
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
lvm_extra_lvs() {
while (( VOL_COUNT > 1 )); do
# get the name and size
lvm_volume_name "$_LvmLvNameBody1" || { break; return 1; }
get_lv_size || { break; return 1; }
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# create it
lvcreate -L "$VOLUME_SIZE" "$VOLUME_GROUP" -n "$VOLUME_NAME" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "lvcreate -L $VOLUME_SIZE $VOLUME_GROUP -n $VOLUME_NAME"
2018-07-18 19:52:06 -05:00
msgbox "$_LvmCreateVG (LV:$VOL_COUNT)" "$_Done LV $VOLUME_NAME ($VOLUME_SIZE) $_LvmPvDoneBody2."
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
((VOL_COUNT--)) # decrement the number of volumes chosen after each loop
2018-07-18 19:52:06 -05:00
done
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
lvm_volume_count() {
VOL_COUNT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_LvmCreateVG " \
2018-07-27 22:54:09 -05:00
--radiolist "$_LvmLvNumBody1 $VOLUME_GROUP\n$_LvmLvNumBody2" 0 0 0 \
2018-08-24 03:40:55 -05:00
"1" "-" off "2" "-" off "3" "-" off "4" "-" off "5" "-" off \
"6" "-" off "7" "-" off "8" "-" off "9" "-" off)
2018-07-18 19:52:06 -05:00
[[ $? != 0 || $VOL_COUNT == "" ]] && return 1
return 0
}
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
lvm_partitions() {
find_partitions 'part|crypt'
PARTS="$(awk 'NF > 0 {print $0 " off"}' <<< "$PARTS")"
2018-07-18 19:52:06 -05:00
2018-08-24 03:40:55 -05:00
# 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
2018-07-18 19:52:06 -05:00
2018-08-24 03:40:55 -05:00
return 0
}
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
lvm_create_group() {
# get volume group name
2018-07-18 19:52:06 -05:00
lvm_group_name || return 1
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# 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
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# 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"
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# 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
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# finished volume group creation
2018-08-24 03:40:55 -05:00
local msg="$_LvmPvDoneBody1 $VOLUME_GROUP ($GROUP_SIZE $GROUP_SIZE_TYPE)"
msgbox "$_LvmCreateVG" "$msg $_LvmPvDoneBody2\n"
return 0
}
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
lvm_create() {
VOLUME_GROUP=""
GROUP_PARTS=""
VOL_GROUP_MB=0
unmount_partitions
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
if [[ $LUKS -eq 1 && $LUKS_NAME != "" ]]; then
GROUP_PARTS="/dev/mapper/$LUKS_NAME"
infobox "$_LvmCreateVG" "\nUsing encrypted partition created earlier: $GROUP_PARTS\n" 1
else
lvm_partitions || return 1
fi
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
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
# last or only logical volume
2018-07-27 22:54:09 -05:00
lvm_volume_name "$_LvmLvNameBody1 $_LvmLvNameBody2 (${VOL_GROUP_MB}MB)" || return 1
2018-07-18 19:52:06 -05:00
lvcreate -l +100%FREE "$VOLUME_GROUP" -n "$VOLUME_NAME" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "lvcreate -l +100%FREE $VOLUME_GROUP -n $VOLUME_NAME"
2018-07-18 19:50:37 -05:00
LVM=1
2018-08-24 03:40:55 -05:00
show_devices
2018-07-18 19:50:37 -05:00
return 0
}
lvm_del_vg() {
2018-07-28 02:25:31 -05:00
if lvm_show_vg; then
yesno "$_LvmDelVG" "$_LvmDelQ" && vgremove -f "$DEL_VG" >/dev/null 2>&1
fi
2018-07-18 19:50:37 -05:00
return 0
}
lvm_del_all() {
2018-07-18 19:52:06 -05:00
PHYSICAL_VOLUMES="$(pvs -o pv_name --noheading 2>/dev/null)"
VOLUME_GROUP="$(vgs -o vg_name --noheading 2>/dev/null)"
VOLUMES="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)"
2018-07-18 19:50:37 -05:00
if yesno "$_LvMDelAll" "$_LvmDelQ"; then
2018-07-18 19:52:06 -05:00
for i in $VOLUMES; do
2018-07-18 19:50:37 -05:00
lvremove -f "/dev/mapper/$i" >/dev/null 2>&1
done
2018-07-18 19:52:06 -05:00
for i in $VOLUME_GROUP; do
2018-07-18 19:50:37 -05:00
vgremove -f "$i" >/dev/null 2>&1
done
2018-07-18 19:52:06 -05:00
for i in $PHYSICAL_VOLUMES; do
2018-07-18 19:50:37 -05:00
pvremove -f "$i" >/dev/null 2>&1
done
LVM=0
fi
return 0
}
lvm_menu() {
lvm_detect
2018-07-18 19:52:06 -05:00
tput civis
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
local choice
choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepLVM " \
--menu "$_LvmMenu" 0 0 0 \
2018-07-18 19:50:37 -05:00
"$_LvmCreateVG" "vgcreate -f, lvcreate -L -n" \
"$_LvmDelVG" "vgremove -f" \
"$_LvMDelAll" "lvrmeove, vgremove, pvremove -f" \
2018-07-18 19:52:06 -05:00
"$_Back" "-")"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
case $choice in
"$_LvmCreateVG") lvm_create && return 0 ;;
2018-07-18 19:50:37 -05:00
"$_LvmDelVG") lvm_del_vg ;;
"$_LvMDelAll") lvm_del_all ;;
*) return 0
esac
lvm_menu
}
######################################################################
2018-08-24 03:40:55 -05:00
## Install Functions ##
2018-07-18 19:50:37 -05:00
######################################################################
2018-08-25 19:52:57 -05:00
config_install() {
2018-08-24 03:40:55 -05:00
# 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
2018-08-25 19:52:57 -05:00
oneshot window_manager || return 1
2018-08-24 03:40:55 -05:00
oneshot extra_packages || return 1
oneshot choose_kernel
2018-08-25 19:52:57 -05:00
CONFIG_DONE=true
return 0
}
install_main() {
# this assumes all needed variables/settings are setup as needed
# no additional user confirmation are performed aside from what is needed
2018-08-24 03:40:55 -05:00
# unpack the whole filesystem to install directory $MNT
oneshot install_base
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
genfstab -U $MNT > $MNT/etc/fstab 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "genfstab -U $MNT > $MNT/etc/fstab"
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
if [[ -f $MNT/swapfile ]]; then
sed -i "s~${MNT}~~" $MNT/etc/fstab 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "sed -i s~${MNT}~~ $MNT/etc/fstab"
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# 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
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
run_mkinitcpio || return 1
install_bootloader || return 1
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
oneshot create_user || return 1
2018-08-25 19:52:57 -05:00
oneshot set_hwclock
2018-08-24 03:40:55 -05:00
oneshot edit_configs
2018-08-20 04:26:13 -05:00
return 0
2018-07-18 19:52:06 -05:00
}
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
install_base() {
# unpack the main system
tput cnorm
rsync -avh /run/archiso/sfs/airootfs/ $MNT/
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# remove archiso init files
2018-07-18 19:52:06 -05:00
find $MNT/usr/lib/initcpio -name 'archiso*' -type f -exec rm '{}' \;
rm -rf $MNT/etc/{mkinitcpio-archiso.conf,sudoers.d/g_wheel,polkit-1/rules.d/49-nopasswd_global.rules}
2018-08-24 03:40:55 -05:00
# cleanup system permissions
2018-07-18 19:52:06 -05:00
sed -i 's/volatile/auto/g' $MNT/etc/systemd/journald.conf
sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" $MNT/etc/sudoers
2018-08-24 03:40:55 -05:00
# for virtual machines remove configs for xorg, these cause mouse issues
grep -qi "hypervisor" <<< "$(dmesg)" && rm -rf $MNT/etc/X11/xorg.conf.d
# if not installing the lts kernel, copy the kernel image
[[ $KERNEL != 'linux-lts' ]] && cp -f /run/archiso/bootmnt/arch/boot/x86_64/vmlinuz $MNT/boot/vmlinuz-linux
setup_configs
return 0
}
setup_configs() {
# copy network settings
2018-07-18 19:52:06 -05:00
cp -rf /etc/NetworkManager/system-connections $MNT/etc/NetworkManager/
2018-07-18 19:50:37 -05:00
cp -f /etc/resolv.conf $MNT/etc/
2018-08-24 03:40:55 -05:00
# set the locale and timezone
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" 2>$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 <<EOF
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "TearFree" "true"
EndSection
EOF
fi
# set the keymaps
cat > $MNT/etc/X11/xorg.conf.d/00-keyboard.conf <<EOF
# Use localectl(1) to instruct systemd-localed to update it.
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbLayout" "$KEYMAP"
EndSection
EOF
cat > $MNT/etc/default/keyboard <<EOF
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL=""
XKBLAYOUT="$KEYMAP"
XKBVARIANT=""
XKBOPTIONS=""
BACKSPACE="guess"
EOF
# console keymap
cat > $MNT/etc/vconsole.conf <<EOF
KEYMAP=$CONSOLE_MAP
FONT=$FONT
EOF
# set the hostname
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
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-08-20 04:26:13 -05:00
update_system() {
2018-08-24 03:40:55 -05:00
tput cnorm
2018-08-20 04:26:13 -05:00
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"
else
pkgcmd="pacman -S iputils --noconfirm ; pacman -S base-devel git --needed --noconfirm"
fi
2018-08-25 22:49:06 -05:00
pkgcmd="pacman -Rs archlabs-installer --noconfirm ; $pkgcmd"
2018-08-20 04:26:13 -05:00
if ! grep -qi "hypervisor" <<< "$(dmesg)"; then
2018-08-25 22:49:06 -05:00
pkgcmd="pacman -Rs virtualbox-guest-utils virtualbox-guest-modules-arch --noconfirm ; $pkgcmd"
2018-08-20 04:26:13 -05:00
fi
2018-08-25 22:49:06 -05:00
if [[ $BOOTLOADER != 'grub' ]]; then
pkgcmd="$pkgcmd ; pacman -Rs grub --noconfirm"
rm -f $MNT/etc/default/grub
2018-08-20 04:26:13 -05:00
find $MNT/boot/ -name 'grub*' -exec rm -rf '{}' \; >/dev/null 2>&1
fi
2018-08-22 03:22:02 -05:00
chroot_cmd "pacman -Syyu --noconfirm ; $pkgcmd" 2>/dev/null
2018-08-20 04:26:13 -05:00
return 0
}
2018-08-12 23:24:38 -05:00
install_packages() {
2018-07-18 19:52:06 -05:00
tput civis
2018-08-22 03:22:02 -05:00
# packages needed for the selected window manager
2018-08-12 23:24:38 -05:00
local pkgs="$WM_PACKAGES"
2018-08-22 03:22:02 -05:00
# add lightdm packages if chosen
2018-08-12 23:24:38 -05:00
[[ $LOGIN_TYPE == 'lightdm' ]] && pkgs="$pkgs lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice"
2018-08-22 03:22:02 -05:00
# add extra packages
2018-08-14 21:58:07 -05:00
[[ $EXTRA_PACKAGES != "" ]] && pkgs="$pkgs $EXTRA_PACKAGES"
2018-07-18 19:52:06 -05:00
2018-08-22 03:22:02 -05:00
# for gnome and cinnamon we dont need the xfce provided stuff
2018-08-20 04:26:13 -05:00
if [[ $INSTALL_WMS == 'gnome' || $INSTALL_WMS == 'cinnamon' ]]; then
2018-08-19 23:10:03 -05:00
REMOVE_PKGS="$(pacman -Qssq 'xfce4*' 2>/dev/null)"
fi
2018-08-25 22:49:06 -05:00
if [[ $INSTALL_WMS =~ dwm && -d $MNT/home/$NEWUSER ]]; then
2018-08-24 03:40:55 -05:00
mkdir -p $MNT/home/$NEWUSER/suckless
2018-08-25 22:49:06 -05:00
for prog in dwm st dmenu; do
echo -e "\nInstalling $prog..\n"
git clone https://bitbucket.org/natemaia/$prog $MNT/home/$NEWUSER/suckless/$prog
chroot_cmd "cd /home/$NEWUSER/suckless/$prog && make clean install && make clean"
echo -e "\n$prog has been installed..\n\nSee /home/$NEWUSER/suckless/$prog to customize and rebuild\n"
2018-08-24 03:40:55 -05:00
done
fi
2018-08-19 22:32:21 -05:00
local pkgcmd="pacman -S $pkgs --needed --noconfirm"
2018-08-22 03:22:02 -05:00
# are we removing some packages
[[ $REMOVE_PKGS != "" ]] && pkgcmd="pacman -Rs $REMOVE_PKGS --noconfirm ; $pkgcmd"
chroot_cmd "$pkgcmd" 2>/dev/null
2018-08-12 23:24:38 -05:00
return 0
}
2018-08-19 22:32:21 -05:00
setup_lightdm() {
2018-08-24 03:40:55 -05:00
# 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
2018-08-19 22:32:21 -05:00
chroot_cmd 'systemctl enable lightdm.service && systemctl set-default graphical.target' >/dev/null 2>&1
2018-08-14 21:58:07 -05:00
2018-08-19 22:32:21 -05:00
local cfg="$MNT/etc/lightdm/lightdm-gtk-greeter.conf"
sed -i '/#background=/ c background=/usr/share/backgrounds/archlabs/archlabs.jpg' $cfg
sed -i '/#theme-name=/ c theme-name=ArchLabs-dARK' $cfg
sed -i '/#icon-theme-name=/ c icon-theme-name=ArchLabs-Light' $cfg
sed -i '/#position=/ c position=34%,end 66%,end' $cfg
sed -i '/#font-name=/ c font-name=DejaVu Sans Mono 11' $cfg
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
2018-08-14 21:58:07 -05:00
2018-08-24 03:40:55 -05:00
rm -rf $MNT/etc/systemd/system/getty@tty1.service.d >/dev/null 2>&1
2018-08-19 22:32:21 -05:00
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
2018-08-24 03:40:55 -05:00
sed -i "/#autologin-user=/ c autologin-user=${NEWUSER}" $MNT/etc/lightdm/lightdm.conf
2018-08-19 22:32:21 -05:00
fi
}
2018-08-14 21:58:07 -05:00
2018-08-25 19:52:57 -05:00
create_user() {
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"
chroot_cmd "chown -Rf $NEWUSER:users /home/$NEWUSER" 2>$ERR
check_for_errors "chown -Rf $NEWUSER:users /home/$NEWUSER"
setup_user_home
return 0
}
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}
# 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
}
setup_user_home() {
local user_home="$MNT/home/$NEWUSER"
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}
else
sed -i "s/:-openbox/:-${LOGIN_WM}/g" $user_home/.xinitrc
sed -i '/archlabs-installer/d' $user_home/.zprofile
echo '[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && exec startx -- vt1 &>/dev/null' >> $user_home/.zprofile
fi
else
sed -i '/archlabs-installer/d' $user_home/.zprofile
echo '[[ -z $DISPLAY && $XDG_VTNR -eq 1 ]] && exec startx -- vt1 &>/dev/null' >> $user_home/.zprofile
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
}
2018-07-30 02:30:35 -05:00
update_mirrorlist() {
2018-08-24 03:40:55 -05:00
$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
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-07-18 19:52:06 -05:00
bootloader_config() {
2018-08-24 03:40:55 -05:00
# if not on an LVM we can use the UUID for booting
if ! [[ $ROOT_PART =~ /dev/mapper ]]; then
2018-07-18 19:52:06 -05:00
ROOT_PART_ID="UUID=$(blkid -s PARTUUID $ROOT_PART | sed 's/.*=//g; s/"//g')"
2018-08-24 03:40:55 -05:00
[[ $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"
2018-07-18 19:52:06 -05:00
fi
2018-08-24 03:40:55 -05:00
if [[ $BOOTLOADER == 'grub' ]]; then
2018-07-18 19:52:06 -05:00
local cfg="$MNT/etc/default/grub"
2018-08-24 03:40:55 -05:00
sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g;
s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $cfg
2018-07-18 19:50:37 -05:00
if (( LUKS == 1 )); then
2018-08-24 03:40:55 -05:00
sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $cfg
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
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
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/"
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
2018-07-18 19:52:06 -05:00
mkdir -p $cfgdir
2018-08-24 03:40:55 -05:00
cp -r $cfgsrcdir $cfgdir/
2018-07-18 19:50:37 -05:00
cat > $cfgdir/syslinux.cfg << EOF
2018-08-24 03:40:55 -05:00
UI menu.c32
2018-07-18 19:52:06 -05:00
PROMPT 0
MENU TITLE $DIST Syslinux Boot Menu
TIMEOUT 50
2018-08-24 03:40:55 -05:00
DEFAULT $DIST
2018-07-18 19:52:06 -05:00
2018-08-24 03:40:55 -05:00
LABEL $DIST
2018-07-18 19:52:06 -05:00
MENU LABEL $DIST Linux
2018-08-20 04:26:13 -05:00
LINUX ../vmlinuz-$KERNEL
2018-07-18 19:52:06 -05:00
APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw
2018-08-20 04:26:13 -05:00
INITRD ../initramfs-$KERNEL.img
2018-08-24 03:40:55 -05:00
$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] &&
echo -en "\ninitrd /intel-ucode.img")
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
LABEL ${DIST}fallback
2018-07-18 19:52:06 -05:00
MENU LABEL $DIST Linux Fallback
2018-08-20 04:26:13 -05:00
LINUX ../vmlinuz-$KERNEL
2018-07-18 19:52:06 -05:00
APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw
2018-08-20 04:26:13 -05:00
INITRD ../initramfs-$KERNEL-fallback.img
2018-08-24 03:40:55 -05:00
$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] &&
echo -en "\ninitrd /intel-ucode.img")
2018-07-18 19:50:37 -05:00
EOF
2018-08-24 03:40:55 -05:00
2018-07-18 19:50:37 -05:00
else
2018-07-18 19:52:06 -05:00
# systemd-boot requires this before running bootctl
systemd-machine-id-setup --root="$MNT" >/dev/null 2>&1
2018-08-24 03:40:55 -05:00
# create the boot entry configs
2018-07-18 19:52:06 -05:00
mkdir -p $MNT/boot/loader/entries
2018-07-18 19:50:37 -05:00
cat > $MNT/boot/loader/loader.conf << EOF
2018-08-24 03:40:55 -05:00
default $DIST
2018-07-18 19:50:37 -05:00
timeout 5
editor no
EOF
2018-08-24 03:40:55 -05:00
cat > $MNT/boot/loader/entries/${DIST}.conf << EOF
2018-07-18 19:52:06 -05:00
title $DIST Linux
2018-08-24 03:40:55 -05:00
linux /vmlinuz-${KERNEL}$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] &&
echo -en "\ninitrd /intel-ucode.img")
2018-08-20 04:26:13 -05:00
initrd /initramfs-$KERNEL.img
2018-08-24 03:40:55 -05:00
options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV")rw
EOF
# 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
2018-07-18 19:50:37 -05:00
EOF
fi
2018-08-24 03:40:55 -05:00
2018-07-18 19:50:37 -05:00
return 0
}
2018-08-24 03:40:55 -05:00
uefi_bootloader_fallback() {
2018-08-17 03:21:15 -05:00
# some UEFI firmware is finicky and requires a specific folder in
# /boot/efi/EFI/ and named 'boot', 'Boot', or 'BOOT'
2018-08-24 03:40:55 -05:00
# 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; }
2018-07-18 19:52:06 -05:00
done
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
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
2018-08-14 23:00:11 -05:00
return 0
2018-07-18 19:52:06 -05:00
}
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
prep_for_bootloader() {
2018-08-17 03:21:15 -05:00
if [[ $SYS == "UEFI" ]]; then
2018-07-18 19:52:06 -05:00
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]}"
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
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
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
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
}
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
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
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)
2018-07-18 19:52:06 -05:00
bootloader_config
2018-08-24 03:40:55 -05:00
# run the bootloader command
2018-07-18 19:52:06 -05:00
chroot_cmd "${BOOT_CMDS[$BOOTLOADER]}" 2>$ERR >/dev/null 2>&1
2018-08-24 03:40:55 -05:00
check_for_errors "${BOOT_CMDS[$BOOTLOADER]}"
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
# 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"
2018-07-18 19:50:37 -05:00
return 0
}
run_mkinitcpio() {
local conf="$MNT/etc/mkinitcpio.conf"
2018-08-24 03:40:55 -05:00
local add
2018-07-18 19:50:37 -05:00
2018-08-22 03:22:02 -05:00
# 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
luks_keyfile || return 1
fi
2018-07-18 19:52:06 -05:00
# new HOOKS needed in /etc/mkinitcpio.conf if we used LUKS and/or LVM
(( LVM == 1 )) && add="lvm2"
(( LUKS == 1 )) && add="encrypt$([[ $add != "" ]] && echo -n " $add")"
sed -i "s/block filesystems/block ${add} filesystems ${MKINIT_HOOKS}/g" $conf 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "sed -i 's/block filesystems/block ${add} filesystems ${MKINIT_HOOKS}/g' $conf"
2018-07-18 19:52:06 -05:00
tput civis
2018-08-22 03:22:02 -05:00
chroot_cmd "mkinitcpio -p $KERNEL" 2>$ERR
2018-08-24 03:40:55 -05:00
check_for_errors "mkinitcpio -p $KERNEL"
2018-07-18 19:52:06 -05:00
return 0
2018-07-18 19:50:37 -05:00
}
2018-08-24 03:40:55 -05:00
edit_configs() {
if [[ $CURRENT_MENU != "edit" ]]; then
2018-07-18 19:52:06 -05:00
MENU_HIGHLIGHT=1
2018-08-24 03:40:55 -05:00
CURRENT_MENU="edit"
elif (( MENU_HIGHLIGHT < 10 )); then
2018-07-18 19:52:06 -05:00
((MENU_HIGHLIGHT++))
2018-07-18 19:50:37 -05:00
fi
2018-07-18 19:52:06 -05:00
tput civis
2018-08-24 03:40:55 -05:00
MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_EditTitle " \
2018-08-25 19:52:57 -05:00
--default-item $MENU_HIGHLIGHT --menu "${_Final}$_EditBody" 0 0 0 \
2018-08-24 03:40:55 -05:00
"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
wrap_up "$_InstFinBody" 'Exit & Reboot' 'Go Back' 'reboot'
else
local existing_files=""
2018-07-18 19:50:37 -05:00
2018-08-24 03:40:55 -05:00
for f in $(echo "${EDIT_FILES[$MENU_HIGHLIGHT]}"); do
[[ -e ${MNT}$f ]] && existing_files="$existing_files ${MNT}$f"
done
if [[ $existing_files != "" ]]; then
2018-08-25 19:52:57 -05:00
if [[ $DISPLAY && $TERM != 'linux' ]] && hash geany >/dev/null 2>&1; then
2018-08-24 03:40:55 -05:00
geany -i $existing_files
else
vim -O $existing_files
2018-07-18 19:50:37 -05:00
fi
2018-08-24 03:40:55 -05:00
else
msgbox "$_ErrTitle" "$_NoFileErr"
2018-07-18 19:50:37 -05:00
fi
fi
2018-08-24 03:40:55 -05:00
edit_configs
2018-07-18 19:50:37 -05:00
}
2018-08-24 03:40:55 -05:00
main() {
if [[ $CURRENT_MENU != "main" ]]; then
2018-07-18 19:52:06 -05:00
MENU_HIGHLIGHT=1
2018-08-24 03:40:55 -05:00
CURRENT_MENU="main"
elif (( MENU_HIGHLIGHT < 8 )); then
2018-08-25 19:52:57 -05:00
((MENU_HIGHLIGHT++)) # increment the highlighted menu item
2018-07-18 19:52:06 -05:00
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
tput civis
2018-08-25 19:52:57 -05:00
MENU_HIGHLIGHT=$(dialog --cr-wrap --no-cancel --stdout --backtitle "$BT" \
--title " $_PrepTitle " --default-item $MENU_HIGHLIGHT --menu "$_PrepBody" 0 0 0 \
2018-08-25 22:49:06 -05:00
"1" "$_PrepShowDev" "2" "$_PrepParts" "3" "$_PrepLUKS" "4" "$_PrepLVM" \
"5" "$_PrepMount" "6" "$_PrepConfig" "7" "$_PrepInstall" "8" "$_Done")
2018-08-25 19:52:57 -05:00
# if trying to install the system, make sure the partitions are mounted
# and that the needed config variables and user variables have been set up
if [[ $MENU_HIGHLIGHT && $MENU_HIGHLIGHT -eq 7 ]]; then
check_install_ready
local return_val=$?
if [[ $return_val -gt 0 ]]; then
# when check_install_ready() returns (value > 0) we set the next menu highlight
# to (missing step - 1) due to the value being incremented at the beginning
# so the missing step is highlighted automatically during the next run
MENU_HIGHLIGHT=$return_val
return 1 # were inside of a (while true) loop, so returning loops the menu again
fi
fi
2018-07-18 19:50:37 -05:00
2018-07-18 19:52:06 -05:00
case $MENU_HIGHLIGHT in
2018-08-24 03:40:55 -05:00
1) show_devices ;;
2) unmount_partitions && select_device 'root' && create_partitions "$DEVICE" ;;
3) luks_menu ;;
4) lvm_menu ;;
2018-08-25 19:52:57 -05:00
5) select_partitions ;;
6) config_install ;;
7) install_main ;;
2018-08-24 03:40:55 -05:00
*) wrap_up "$_CloseInstBody" 'Exit' 'Back' 'exit'
2018-07-18 19:50:37 -05:00
esac
}
2018-08-25 19:52:57 -05:00
# trap ctrl-c and call sigint() to properly exit, without this
# exiting via Ctrl-c can leave the terminal in a messed up state
trap sigint INT
2018-07-18 19:52:06 -05:00
for arg in "$@"; do
2018-07-18 19:50:37 -05:00
[[ $arg == "--debug" || $arg == "-d" ]] && set_debug
done
2018-07-18 19:52:06 -05:00
initialize_variables
2018-07-28 15:03:43 -05:00
luks_variable_init
2018-07-18 19:50:37 -05:00
select_language
2018-08-24 03:40:55 -05:00
set_keymap
2018-07-18 19:50:37 -05:00
check_requirements
identify_system
msgbox "$_WelTitle $DIST Installer" "$_WelBody"
while true; do
2018-08-24 03:40:55 -05:00
main
2018-07-18 19:50:37 -05:00
done