2099 lines
66 KiB
Plaintext
2099 lines
66 KiB
Plaintext
|
#!/usr/bin/env bash
|
||
|
|
||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||
|
|
||
|
# Written by Nathaniel Maia for use in Archlabs
|
||
|
# Some ideas and code were taken from other installers
|
||
|
# AIF, ABIF, Calamares.. Credit where credit is due
|
||
|
|
||
|
# This program is free software, provided under the GNU GPL
|
||
|
|
||
|
|
||
|
# dry run performing no action, used to check for syntax errors
|
||
|
# set -n
|
||
|
|
||
|
# no unbound variables
|
||
|
# set -u
|
||
|
|
||
|
# set verbose, print lines as they are read
|
||
|
# set -v
|
||
|
|
||
|
# immutable vaulues {
|
||
|
|
||
|
readonly LIVEUSER="liveuser" # Live user
|
||
|
readonly DIST="Archlabs" # Distributor
|
||
|
readonly VER="1.5.48" # Version
|
||
|
readonly MNT="/mnt/install" # Mountpoint
|
||
|
readonly ANS="/tmp/answer" # Stores answers
|
||
|
readonly OPT="/tmp/opts" # Mount options
|
||
|
readonly ERR="/tmp/errlog" # Error logging
|
||
|
readonly LOG="/tmp/log" # set -x logging
|
||
|
|
||
|
# }
|
||
|
|
||
|
# mutable values and prep {
|
||
|
|
||
|
EFI="/boot/efi" # EFI system partition mountpoint
|
||
|
EFI_PARTITION="NONE"
|
||
|
|
||
|
VG_MB=0
|
||
|
SEPERATE_BOOT=0
|
||
|
MKINIT_HOOKS="shutdown"
|
||
|
|
||
|
# timezones used for manual setup if automatic fails
|
||
|
FULLZONES="$(awk '{print $3}' < /usr/share/zoneinfo/zone.tab |
|
||
|
grep ".*/.*" |
|
||
|
sort -ud)"
|
||
|
ZONES=""
|
||
|
for i in $(awk -F'/' '{print $1}' <<< "$FULLZONES" | uniq); do
|
||
|
ZONES="$ZONES $i -"
|
||
|
done
|
||
|
|
||
|
# list of available countries for reflector
|
||
|
COUNTRIES="$(reflector --list-countries |
|
||
|
awk '{print $1}' |
|
||
|
grep -v '[0-9]')"
|
||
|
COUNTRY=""
|
||
|
for i in $COUNTRIES; do
|
||
|
COUNTRY="$COUNTRY $i -"
|
||
|
done
|
||
|
|
||
|
# parsed locales from /etc/locale.gen
|
||
|
FULL_LOCALES="$(grep -v "# " /etc/locale.gen |
|
||
|
sed 's/#//g; s/ UTF-8//g' |
|
||
|
grep .UTF-8)"
|
||
|
LOCALES=""
|
||
|
for i in $FULL_LOCALES; do
|
||
|
LOCALES="$LOCALES $i -"
|
||
|
done
|
||
|
|
||
|
# parsed console maps from /usr/share/kbd/keymaps
|
||
|
FULL_CONSOLE_MAPS="$(ls -R /usr/share/kbd/keymaps |
|
||
|
grep "map.gz" |
|
||
|
sed 's/\.map\.gz//g' |
|
||
|
sort)"
|
||
|
CONSOLE_MAPS=""
|
||
|
for i in $FULL_CONSOLE_MAPS; do
|
||
|
CONSOLE_MAPS="$CONSOLE_MAPS $i -"
|
||
|
done
|
||
|
|
||
|
# raw set of available keyboard maps and their language
|
||
|
FULL_XORG_MAPS=("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" "gr Greek" "hu Hungarian" "by Belarusian"
|
||
|
"is Icelandic" "cn Chinese" "ua Ukrainian" "cz Czech" "ru Russian" "dk Danish"
|
||
|
"it Italian" "br Portuguese" "pt Portuguese" "in Indian" "se Swedish" "ara Arabic"
|
||
|
"al Albanian" "am Armenian" "be Belgian" "bd Bangla" "ba Bosnian" "az Azerbaijani"
|
||
|
"bg Bulgarian" "dz Berber" "ma Arabic" "mm Burmese" "hr Croatian" "il Hebrew"
|
||
|
"ee Estonian" "ir Persian" "iq Iraqi" "fo Faroese" "fi Finnish" "ge Georgian"
|
||
|
"kg Kyrgyz" "kh Khmer" "kz Kazakh" "la Lao" "latam Spanish" "lt Lithuanian"
|
||
|
"me Montenegrin" "mk Macedonian" "mt Maltese" "mn Mongolian" "no Norwegian" "pl Polish"
|
||
|
"ro Romanian" "rs Serbian" "si Slovenian" "sk Slovak" "es Spanish" "sy Arabic"
|
||
|
"tj Tajik" "lk Sinhala" "th Thai" "tr Turkish" "tw Taiwanese" "uz Uzbek"
|
||
|
"vn Vietnamese" "kr Korean" "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" "nec_vndr/jp Japanese" "jp Japanese"
|
||
|
"tm Turkmen" "bt Dzongkha" "nl Dutch" "lv Latvian" "md Moldavian" "mao Maori" "af Afghani")
|
||
|
XORG_MAPS=""
|
||
|
for i in "${FULL_XORG_MAPS[@]}"; do
|
||
|
XORG_MAPS="$XORG_MAPS $i"
|
||
|
done
|
||
|
|
||
|
# }
|
||
|
|
||
|
######################################################################
|
||
|
## Utility and Check Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
chroot_cmd() {
|
||
|
arch-chroot $MNT /bin/bash -c "$1"
|
||
|
}
|
||
|
|
||
|
show_devices() {
|
||
|
lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT |
|
||
|
grep "disk\|part\|lvm\|crypt\|NAME\|TYPE\|SIZE" >/tmp/.devlist
|
||
|
dialog --backtitle "$BT" --title " $_PrepShowDev " --textbox /tmp/.devlist 0 0
|
||
|
}
|
||
|
|
||
|
set_debug() {
|
||
|
local cmd
|
||
|
echo "" >$LOG
|
||
|
|
||
|
set -x
|
||
|
exec 3>| $LOG
|
||
|
BASH_XTRACEFD=3
|
||
|
|
||
|
if hash st &>/dev/null; then
|
||
|
st -e tail -f $LOG &
|
||
|
elif hash termite &>/dev/null; then
|
||
|
termite -e tail -f $LOG &
|
||
|
else
|
||
|
xterm -e tail -f $LOG &
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
cleanup() {
|
||
|
[[ -e $ANS ]] && rm -rf $ANS
|
||
|
[[ -e $OPT ]] && rm -rf $OPT
|
||
|
[[ -e $ERR ]] && rm -rf $ERR
|
||
|
[[ -e $LOG ]] && rm -rf $LOG
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
select_language() {
|
||
|
dialog --backtitle "$DIST Installer - (x86_64)" --title " Select Language " --menu \
|
||
|
"\nLanguage - sprache - taal - språk - lingua - idioma - nyelv - língua\n" 0 0 10 \
|
||
|
"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)" 2> $ANS
|
||
|
|
||
|
# always source the english translation first.
|
||
|
# it acts as a set of fallback values should any other
|
||
|
# translations be missing or lack values
|
||
|
source /installer/english.trans 2>/dev/null
|
||
|
|
||
|
case "$(cat $ANS)" in
|
||
|
1) LOC="en_US.UTF-8" ;;
|
||
|
2) source /installer/spanish.trans 2>/dev/null && LOC="es_ES.UTF-8" ;;
|
||
|
3) source /installer/p_brasil.trans 2>/dev/null && LOC="pt_BR.UTF-8" ;;
|
||
|
4) source /installer/portuguese.trans 2>/dev/null && LOC="pt_PT.UTF-8" ;;
|
||
|
5) source /installer/french.trans 2>/dev/null && LOC="fr_FR.UTF-8" ;;
|
||
|
6) source /installer/russian.trans 2>/dev/null && LOC="ru_RU.UTF-8" ;;
|
||
|
7) source /installer/italian.trans 2>/dev/null && LOC="it_IT.UTF-8" ;;
|
||
|
8) source /installer/dutch.trans 2>/dev/null && LOC="nl_NL.UTF-8" ;;
|
||
|
9) source /installer/hungarian.trans 2>/dev/null && LOC="hu_HU.UTF-8" ;;
|
||
|
10) source /installer/chinese.trans 2>/dev/null && LOC="zh_CN.UTF-8" ;;
|
||
|
*) clear && exit 0
|
||
|
esac
|
||
|
|
||
|
sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen
|
||
|
[[ $LOC != "en_US.UTF-8" ]] && sed -i "s/#${LOC}/${LOC}/" /etc/locale.gen
|
||
|
|
||
|
locale-gen &>/dev/null
|
||
|
|
||
|
export LANG="$LOC"
|
||
|
}
|
||
|
|
||
|
identify_system() {
|
||
|
if grep -q 'Apple' /sys/class/dmi/id/sys_vendor; then
|
||
|
modprobe -r -q efivars || true
|
||
|
else
|
||
|
modprobe -q efivarfs
|
||
|
fi
|
||
|
|
||
|
if [[ -d "/sys/firmware/efi/" ]]; then
|
||
|
if grep -q /sys/firmware/efi/efivars <<< "$(mount)"; then
|
||
|
mount -t efivarfs efivarfs /sys/firmware/efi/efivars
|
||
|
fi
|
||
|
SYS="UEFI"
|
||
|
else
|
||
|
SYS="BIOS"
|
||
|
fi
|
||
|
|
||
|
readonly BT="$DIST Installer - $SYS (x86_64) - Version $VER"
|
||
|
}
|
||
|
|
||
|
check_requirements() {
|
||
|
local msg cur_user
|
||
|
cur_user="$(whoami)"
|
||
|
|
||
|
if [[ $cur_user != "root" ]] || ! (ping -c 1 archlabslinux.com &>/dev/null || ping -c 1 bitbucket.org &>/dev/null || ping -c 1 github.com &>/dev/null); then
|
||
|
|
||
|
[[ $cur_user != "root" ]] && msg="$_NotRoot" || msg="$_NoNetwork"
|
||
|
|
||
|
infobox "$_ErrTitle" "$msg\n$_Exit"
|
||
|
clear && exit 1
|
||
|
fi
|
||
|
|
||
|
echo "" > $ERR
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
check_for_errors() {
|
||
|
# check if last process exited with non zero
|
||
|
if (( $? != 0 )); then # grep -wqi "$1" "$ERR"
|
||
|
|
||
|
# clean escape sequences from the error message
|
||
|
local err
|
||
|
err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")"
|
||
|
|
||
|
# show the error message if any
|
||
|
[[ $err ]] && msgbox "$_ErrTitle" "$err"
|
||
|
|
||
|
local yes="Manual Fix"
|
||
|
local no="Wipe Install"
|
||
|
if ! yesno "$_ErrTitle" "$_ErrChoice" 0 0 --yes-label "$yes" --no-label "$no"; then
|
||
|
for d in $MNT/?*; do
|
||
|
if ! grep -q "boot" <<< "$d"; then
|
||
|
rm -rf "$d"
|
||
|
fi
|
||
|
done
|
||
|
fi
|
||
|
|
||
|
cleanup
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
check_parts_are_mounted() {
|
||
|
grep -q "$MNT" <<< "$(lsblk -o MOUNTPOINT)" && return 0
|
||
|
|
||
|
# partitions aren't mounted
|
||
|
msgbox "$_ErrTitle" "$_ErrNoMount"
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
check_base_unpacked() {
|
||
|
[[ -e $MNT/etc ]] && return 0
|
||
|
|
||
|
# base isn't unpacked
|
||
|
msgbox "$_ErrTitle" "$_ErrNoBase"
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
check_part_is_crypt_or_lvm() {
|
||
|
local part="$1"
|
||
|
local fullblock
|
||
|
fullblock="$(lsblk -lno NAME,FSTYPE,TYPE)"
|
||
|
|
||
|
# Identify if $part is "crypt" (LUKS on LVM, or LUKS alone)
|
||
|
if grep -qi "crypt" <<< "$(lsblk -lno TYPE "$part")"; then
|
||
|
|
||
|
LUKS=1
|
||
|
LUKS_NAME="$(sed "s~^/dev/mapper/~~g" <<< "$part")"
|
||
|
|
||
|
local cryptlv
|
||
|
cryptlv="$(grep "lvm" <<< "$fullblock" |
|
||
|
grep -i "crypto_luks" |
|
||
|
awk '{print "/dev/mapper/"$1}' |
|
||
|
uniq)"
|
||
|
|
||
|
for i in $cryptlv; do
|
||
|
if grep -q "$LUKS_NAME" <<< "$(lsblk -lno NAME "$i")"; then
|
||
|
LUKS_DEV="$LUKS_DEV cryptdevice=$i:$LUKS_NAME"
|
||
|
LVM=1
|
||
|
break
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
local crypt
|
||
|
crypt="$(grep "part" <<< "$fullblock" |
|
||
|
grep -i "crypto_luks" |
|
||
|
awk '{print "/dev/"$1}' |
|
||
|
uniq)"
|
||
|
|
||
|
for i in $crypt; do
|
||
|
if grep -q "$LUKS_NAME" <<< "$(lsblk -lno NAME "$i")"; then
|
||
|
LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$i" |
|
||
|
grep 'part' |
|
||
|
grep -i 'crypto_luks' |
|
||
|
awk '{print $1}')"
|
||
|
LUKS_DEV="$LUKS_DEV cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME"
|
||
|
break
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
elif grep -qi "lvm" <<< "$(lsblk -lno TYPE "$part")"; then
|
||
|
LVM=1
|
||
|
LV_NAME="$(sed "s~^/dev/mapper/~~g" <<< "$part")"
|
||
|
|
||
|
local lvcrypt
|
||
|
lvcrypt="$(grep "crypt" <<< "$fullblock" |
|
||
|
grep -i "lvm2_member" |
|
||
|
awk '{print "/dev/mapper/"$1}' |
|
||
|
uniq)"
|
||
|
|
||
|
for i in $lvcrypt; do
|
||
|
if grep -q "$LV_NAME" <<< "$(lsblk -lno NAME "$i")"; then
|
||
|
LUKS_NAME="$(sed 's~/dev/mapper/~~g' <<< "$i")"
|
||
|
break
|
||
|
fi
|
||
|
done
|
||
|
|
||
|
local crypt
|
||
|
crypt="$(grep "part" <<< "$fullblock" |
|
||
|
grep -i "crypto_luks" |
|
||
|
awk '{print "/dev/"$1}' |
|
||
|
uniq)"
|
||
|
|
||
|
for i in $crypt; do
|
||
|
if grep -q "$LUKS_NAME" <<< "$(lsblk -lno NAME "$i")"; then
|
||
|
LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$i" |
|
||
|
grep 'part' |
|
||
|
grep -i 'crypto_luks' |
|
||
|
awk '{print $1}')"
|
||
|
LUKS_DEV="$LUKS_DEV cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME"
|
||
|
LUKS=1
|
||
|
break
|
||
|
fi
|
||
|
done
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
######################################################################
|
||
|
## Dialog Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
getpass() {
|
||
|
dialog --backtitle "$BT" --title " $1 " --insecure --passwordbox "$2" ${3:-0} ${4:-0} 2>$ANS || return 1
|
||
|
return 0
|
||
|
} # }}
|
||
|
|
||
|
getinput() {
|
||
|
dialog --backtitle "$BT" --title " $1 " --inputbox "$2" ${4:-0} ${5:-0} "$3" 2>$ANS || return 1
|
||
|
return 0
|
||
|
} # }}}
|
||
|
|
||
|
msgbox() {
|
||
|
if [[ $# -gt 4 ]]; then
|
||
|
dialog --backtitle "$BT" --title " $1 " $5 "$6" --msgbox "$2" ${3:-0} ${4:-0}
|
||
|
else
|
||
|
dialog --backtitle "$BT" --title " $1 " --msgbox "$2" ${3:-0} ${4:-0}
|
||
|
fi
|
||
|
return 0
|
||
|
} # }}
|
||
|
|
||
|
infobox() {
|
||
|
local bt="${BT:-$DIST Installer - (x86_64)}"
|
||
|
dialog --backtitle "$bt" --title " $1 " --infobox "$2" ${3:-0} ${4:-0}
|
||
|
sleep 2
|
||
|
} # }}
|
||
|
|
||
|
yesno() {
|
||
|
# when additional args (--yes-label, --no-label) are passed ensure text ($6, $8) is quoted
|
||
|
if [[ $# -eq 8 ]]; then
|
||
|
dialog --backtitle "$BT" --title " $1 " $5 "$6" $7 "$8" --yesno "$2" $3 $4 && return 0
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $1 " --yesno "$2" ${3:-0} ${4:-0} && return 0
|
||
|
return 1
|
||
|
} # }}
|
||
|
|
||
|
######################################################################
|
||
|
## System Settings Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
set_keymap() {
|
||
|
KEYMAP=""
|
||
|
|
||
|
console_keymap() {
|
||
|
local map
|
||
|
dialog --backtitle "$BT" --title " $_CMapTitle " --menu "$_CMapBody" 0 0 16 $CONSOLE_MAPS 2>$ANS
|
||
|
map="$(cat $ANS)"
|
||
|
map="${map:-us}"
|
||
|
localectl set-keymap
|
||
|
echo "KEYMAP=$map" >/tmp/vconsole.conf
|
||
|
}
|
||
|
|
||
|
xorg_keymap() {
|
||
|
local map
|
||
|
dialog --backtitle "$BT" --title " $_PrepLayout " --menu "$_XMapBody" 0 0 16 $XORG_MAPS 2>$ANS
|
||
|
map="$(sed 's/_.*//' $ANS)"
|
||
|
map="${map:-us}"
|
||
|
KEYMAP="$map"
|
||
|
setxkbmap "$map" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
cat >/tmp/00-keyboard.conf <<EOF
|
||
|
# Use localectl(1) to instruct systemd-localed to update it.
|
||
|
Section "InputClass"
|
||
|
Identifier "system-keyboard"
|
||
|
MatchIsKeyboard "on"
|
||
|
Option "XkbLayout" "$map"
|
||
|
EndSection
|
||
|
|
||
|
EOF
|
||
|
cat >/tmp/keyboard <<EOF
|
||
|
# KEYBOARD CONFIGURATION FILE
|
||
|
# Consult the keyboard(5) manual page.
|
||
|
XKBMODEL=""
|
||
|
XKBLAYOUT="$map"
|
||
|
XKBVARIANT=""
|
||
|
XKBOPTIONS=""
|
||
|
BACKSPACE="guess"
|
||
|
|
||
|
EOF
|
||
|
}
|
||
|
|
||
|
xorg_keymap
|
||
|
if grep -qw "^$KEYMAP$" <<< "$FULL_CONSOLE_MAPS"; then
|
||
|
echo "KEYMAP=${KEYMAP:-us}" >/tmp/vconsole.conf
|
||
|
else
|
||
|
console_keymap
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
set_locale() {
|
||
|
local locale
|
||
|
|
||
|
dialog --backtitle "$BT" --title "$_ConfLocale" \
|
||
|
--menu "$_LocaleBody" 0 0 12 $LOCALES 2>$ANS || return 1
|
||
|
locale="$(cat $ANS)"
|
||
|
|
||
|
infobox "$_ConfLocale" "$_GenLocale $locale\n\n"
|
||
|
|
||
|
sed -i "s/en_US.UTF-8/${locale}/g" $MNT/etc/locale.conf
|
||
|
|
||
|
cp -f $MNT/etc/locale.conf $MNT/etc/default/locale
|
||
|
|
||
|
sed -i "s/#en_US.UTF-8/en_US.UTF-8/g; s/#${locale}/${locale}/g" $MNT/etc/locale.gen
|
||
|
|
||
|
chroot_cmd "locale-gen" >/dev/null 2>$ERR
|
||
|
|
||
|
check_for_errors || return 1
|
||
|
set_timezone
|
||
|
}
|
||
|
|
||
|
set_timezone() {
|
||
|
local zone subzone
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_TimeZTitle " --menu "$_TimeZBody" 0 0 10 $ZONES 2>$ANS || return 1
|
||
|
zone="$(cat $ANS)"
|
||
|
|
||
|
for i in $(grep "$zone/" <<< "$FULLZONES" | awk -F'/' '{print $2}' | sort -ud); do
|
||
|
SUBZONES="$SUBZONES $i -"
|
||
|
done
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_TimeZTitle " --menu "$_TimeSubZBody" 0 0 10 $SUBZONES 2>$ANS || return 1
|
||
|
subzone="$(cat $ANS)"
|
||
|
|
||
|
if [[ $zone && $subzone ]] && yesno "$_TimeZTitle" "$_TimeZQ $zone/$subzone?\n\n"; then
|
||
|
chroot_cmd "ln -sf /usr/share/zoneinfo/$zone/$subzone /etc/localtime" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
else
|
||
|
set_timezone
|
||
|
fi
|
||
|
|
||
|
# step done and continue to set hwclock
|
||
|
TIMEZONE_SET="True"
|
||
|
set_hwclock
|
||
|
}
|
||
|
|
||
|
set_hwclock() {
|
||
|
# try setting the default setting for hwclock
|
||
|
chroot_cmd "hwclock --systohc --utc"
|
||
|
if (( $? != 0 )); then
|
||
|
|
||
|
# when errors occur attempt handling them with a fallback
|
||
|
chroot_cmd "hwclock --systohc --utc --directisa"
|
||
|
|
||
|
# if still failing, alert the user and just continue
|
||
|
if (( $? != 0 )); then
|
||
|
msgbox "$_ErrTitle" "Hwclock setup and fallback attempts failed..\n\nContinuing anyway."
|
||
|
fi
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
set_hostname() {
|
||
|
local hostentry
|
||
|
|
||
|
getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}" 14 60 || return 1
|
||
|
hostentry="$(cat $ANS)"
|
||
|
|
||
|
echo "$hostentry" >$MNT/etc/hostname
|
||
|
|
||
|
cat > $MNT/etc/hosts << EOF
|
||
|
127.0.0.1 localhost
|
||
|
127.0.1.1 $hostentry
|
||
|
::1 localhost ip6-localhost ip6-loopback
|
||
|
ff02::1 ip6-allnodes
|
||
|
ff02::2 ip6-allrouters
|
||
|
EOF
|
||
|
}
|
||
|
|
||
|
root_password() {
|
||
|
getpass "$_ConfRoot" "$_RootBody" 10 40 || return 1
|
||
|
PASSWD="$(cat $ANS)"
|
||
|
|
||
|
getpass "$_ConfRoot" "$_RootBody2" 10 40 || return 1
|
||
|
PASSWD2="$(cat $ANS)"
|
||
|
|
||
|
if [[ "$PASSWD" == "$PASSWD2" ]]; then
|
||
|
echo -e "$PASSWD\n$PASSWD" >/tmp/.passwd
|
||
|
chroot_cmd "passwd root" </tmp/.passwd >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
rm -f /tmp/.passwd
|
||
|
SET_ROOT_PASSWD="True"
|
||
|
return 0
|
||
|
fi
|
||
|
|
||
|
# passwords don't match
|
||
|
msgbox "$_ErrTitle" "${_PassErr}$_TryAgain"
|
||
|
root_password
|
||
|
}
|
||
|
|
||
|
create_user() {
|
||
|
local newuser
|
||
|
|
||
|
getinput "$_UserTitle" "$_UserBody" "" || return 1
|
||
|
newuser="$(cat $ANS)"
|
||
|
|
||
|
# bad name answer
|
||
|
while [[ ${#newuser} -eq 0 || $newuser =~ \ |\' || $newuser =~ [^a-z0-9\ ] ]]; do
|
||
|
getinput "$_UserTitle" "$_UserErrBody" "" 14 40 || { break; return 1; }
|
||
|
newuser="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
getpass "$_ConfUser" "$_UserPass $newuser" 10 40 || return 1
|
||
|
PASSWD="$(cat $ANS)"
|
||
|
|
||
|
getpass "$_ConfUser" "$_UserPass2 $newuser" 10 40 || return 1
|
||
|
PASSWD2="$(cat $ANS)"
|
||
|
|
||
|
# passwords don't match
|
||
|
while [[ "$PASSWD" != "$PASSWD2" ]]; do
|
||
|
msgbox "$_ErrTitle" "${_PassErr}$_TryAgain" 8 60
|
||
|
|
||
|
getpass "$_ConfUser" "$_UserPass $newuser" 10 40 || { break; return 1; }
|
||
|
PASSWD="$(cat $ANS)"
|
||
|
|
||
|
getpass "$_ConfUser" "$_UserPass2 $newuser" 10 40 || { break; return 1; }
|
||
|
PASSWD2="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
infobox "$_ConfUser" "$_UserSetBody"
|
||
|
echo -e "$PASSWD\n$PASSWD" >/tmp/.passwd
|
||
|
|
||
|
# for first user created, swap the live user account
|
||
|
if [[ -e $MNT/home/$LIVEUSER ]]; then
|
||
|
chroot_cmd "passwd $LIVEUSER" </tmp/.passwd >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" $MNT/etc/sudoers
|
||
|
|
||
|
local tty_autologin
|
||
|
if [[ -e $MNT/etc/systemd/system/autologin@.service ]]; then
|
||
|
tty_autologin="systemd/system/autologin@.service"
|
||
|
elif [[ -e $MNT/etc/systemd/system/getty@tty1.service.d/override.conf ]]; then
|
||
|
tty_autologin="systemd/system/getty@tty1.service.d/override.conf"
|
||
|
elif [[ -e $MNT/etc/systemd/system/getty@tty1.service.d/autologin.conf ]]; then
|
||
|
tty_autologin="systemd/system/getty@tty1.service.d/autologin.conf"
|
||
|
fi
|
||
|
|
||
|
for f in group gshadow passwd shadow $tty_autologin; do
|
||
|
sed -i "s/${LIVEUSER}/${newuser}/g" "$MNT/etc/$f"
|
||
|
done
|
||
|
|
||
|
chroot_cmd "mv /home/$LIVEUSER /home/$newuser" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
chroot_cmd "chown -R $newuser:users /home/$newuser" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
chroot_cmd "usermod -aG rfkill,wheel,autologin,network,lp,storage,power,video,audio,lp $newuser" 2>$ERR
|
||
|
else
|
||
|
# create new user account
|
||
|
chroot_cmd "useradd $newuser -m -g users -G rfkill,wheel,autologin,network,lp,storage,power,video,audio,lp -s /bin/zsh" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
chroot_cmd "passwd $newuser" < /tmp/.passwd >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
chroot_cmd "cp -R /etc/skel/ /home/$newuser" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
chroot_cmd "chown -R ${newuser}:users /home/$newuser" 2>$ERR
|
||
|
fi
|
||
|
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
[[ -e /tmp/.passwd ]] && rm /tmp/.passwd
|
||
|
|
||
|
# if all the needed steps are not finished, bail early
|
||
|
[[ -z $UNPACKED_BASE || -z $TIMEZONE_SET || -z $SET_ROOT_PASSWD || -z $BOOT_DONE ]] && return 0
|
||
|
|
||
|
local yes="Exit and Reboot"
|
||
|
local no="Go Back"
|
||
|
yesno "$_InstFin" "$_InstFinBody" 0 0 --yes-label "$yes" --no-label "$no" && { unmount_partitions; reboot; } || return 1
|
||
|
}
|
||
|
|
||
|
######################################################################
|
||
|
## System Partitioning Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
confirm_mount() {
|
||
|
local part="$1"
|
||
|
local mntpnt="$2"
|
||
|
|
||
|
# partition failed to mount properly
|
||
|
if ! grep -q "$mntpnt" <<< "$(mount)"; then
|
||
|
infobox "$_MntTitle" "$_MntFail"
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
# mount was successful
|
||
|
infobox "$_MntTitle" "$_MntSucc"
|
||
|
|
||
|
# sed s~${part}$' -'~~
|
||
|
# remove mounted partition from dialog list
|
||
|
PARTS="$(sed "s~${part} [0-9]*[G-M]~~; s~${part} [0-9]*\.[0-9]*[G-M]~~" <<< "$PARTS")"
|
||
|
|
||
|
# decrement the number of partitions left, used in while loop
|
||
|
((PART_COUNT--))
|
||
|
}
|
||
|
|
||
|
mount_partition() {
|
||
|
local part="$1"
|
||
|
local mntp="$2"
|
||
|
|
||
|
mkdir -p "${MNT}$mntp"
|
||
|
|
||
|
# get mount options if any
|
||
|
if (( ${#FS_OPTS[@]} > 0 )) && select_mount_opts "$part"; then
|
||
|
mount -o $MNT_OPTS "$part" "${MNT}$mntp" 2>$ERR
|
||
|
else
|
||
|
# generic auto mount
|
||
|
mount "$part" "${MNT}$mntp" 2>$ERR
|
||
|
fi
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
confirm_mount "$part" "${MNT}$mntp" || return 1
|
||
|
check_part_is_crypt_or_lvm "$part"
|
||
|
}
|
||
|
|
||
|
unmount_partitions() {
|
||
|
swapoff -a
|
||
|
for i in $(mount | grep "$MNT" | awk '{print $3}' | sort -r); do
|
||
|
umount -r "$i" &>/dev/null
|
||
|
done
|
||
|
}
|
||
|
|
||
|
find_partitions() {
|
||
|
local str="$1"
|
||
|
|
||
|
# string of partitions as: /TYPE/PART SIZE
|
||
|
PARTS="$(lsblk -lno TYPE,NAME,SIZE |
|
||
|
grep "$str" |
|
||
|
sed 's|^part|/dev/|g; s|^lvm|/dev/mapper/|g; s|^crypt|/dev/mapper/|g' |
|
||
|
awk '{print $1$2 " " $3}' |
|
||
|
sort -u)"
|
||
|
|
||
|
PART_COUNT=0
|
||
|
for i in $PARTS; do
|
||
|
((PART_COUNT++))
|
||
|
done
|
||
|
|
||
|
# due to storing the device size, we need half the number of fields
|
||
|
PART_COUNT=$((PART_COUNT / 2))
|
||
|
|
||
|
local err="NONE"
|
||
|
|
||
|
case $str in
|
||
|
'part\|lvm\|crypt')
|
||
|
([[ $PART_COUNT -eq 0 ]] || [[$SYS == "UEFI" && $PART_COUNT -lt 2 ]]) && err="$_PartErrBody"
|
||
|
;;
|
||
|
'part\|crypt')
|
||
|
(( PART_COUNT == 0 )) && err="$_LvmPartErrBody"
|
||
|
;;
|
||
|
'part\|lvm')
|
||
|
(( PART_COUNT < 2 )) && err="$_LuksPartErrBody"
|
||
|
esac
|
||
|
|
||
|
if [[ $err != "NONE" ]]; then
|
||
|
msgbox "$_ErrTitle" "$err"
|
||
|
select_device && create_partitions "$DEVICE" || return 1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
create_partitions() {
|
||
|
local choice
|
||
|
local device="$1"
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_PartTitle " --menu "$_PartBody" 0 0 5 \
|
||
|
"$_PartWipe" "BIOS & UEFI" \
|
||
|
"$_PartAuto" "BIOS & UEFI" \
|
||
|
"gparted" "BIOS & UEFI" \
|
||
|
"cfdisk" "BIOS/MBR" \
|
||
|
"parted" "UEFI/GPT" 2>$ANS
|
||
|
|
||
|
choice="$(cat $ANS)"
|
||
|
[[ -z $choice ]] && return 1 || clear
|
||
|
|
||
|
if [[ $choice != "$_PartWipe" && $choice != "$_PartAuto" ]]; then
|
||
|
$choice "$device"
|
||
|
|
||
|
elif [[ $choice == "$_PartWipe" ]]; then
|
||
|
wipe_device "$device" && create_partitions "$device"
|
||
|
|
||
|
else
|
||
|
auto_partition "$device"
|
||
|
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
auto_partition() {
|
||
|
local device="$1"
|
||
|
|
||
|
if [[ $SYS == "BIOS" ]]; then
|
||
|
_PartBody2="will be destroyed.\n\nAn ext4 partition will be created using all available space."
|
||
|
fi
|
||
|
|
||
|
if yesno "$_PrepParts" "$_PartBody1 $device $_PartBody2 $_PartBody3"; then
|
||
|
current_parts="$(parted -s "$device" print |
|
||
|
awk '/^ / {print $1}' |
|
||
|
sort -r)"
|
||
|
|
||
|
for part in $current_parts; do
|
||
|
parted -s "$device" rm $part 2>$ERR
|
||
|
check_for_errors || { break; return 1; }
|
||
|
done
|
||
|
|
||
|
part_table="$(parted -s "$device" print |
|
||
|
grep -i 'partition table' |
|
||
|
awk '{print $3}')"
|
||
|
|
||
|
if [[ $SYS == "BIOS" && $part_table != "msdos" ]]; then
|
||
|
parted -s "$device" mklabel msdos 2>$ERR
|
||
|
elif [[ $SYS == "UEFI" && $part_table != "gpt" ]]; then
|
||
|
parted -s "$device" mklabel gpt 2>$ERR
|
||
|
fi
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
if [[ $SYS == "BIOS" ]]; then
|
||
|
parted -s "$device" mkpart primary ext4 1MiB 100% 2>$ERR
|
||
|
else
|
||
|
parted -s "$device" mkpart ESP fat32 1MiB 513MiB 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
parted -s "$device" set 1 boot on 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
parted -s "$device" mkpart primary ext4 513MiB 100% 2>$ERR
|
||
|
fi
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
lsblk "$device" -o NAME,TYPE,FSTYPE,SIZE >/tmp/.devlist
|
||
|
dialog --backtitle "$BT" --title " $_PrepParts " --textbox /tmp/.devlist 0 0
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
wipe_device() {
|
||
|
local device="$1"
|
||
|
|
||
|
if yesno "$_PartWipe" "$_PartBody1 $device $_PartBody2 $_PartBody3"; then
|
||
|
clear
|
||
|
echo -e "Secure wiping $device this will take a while.."
|
||
|
wipe -Ifre "$device"
|
||
|
else
|
||
|
create_partitions "$device"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
select_swap() {
|
||
|
local ans msg mem tot swap_part
|
||
|
|
||
|
mem="$(grep MemTotal /proc/meminfo |
|
||
|
awk '{print $2/1024}' |
|
||
|
sed 's/\..*//')"
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_PrepMount " --menu "$_SelSwpBody" 0 0 7 \
|
||
|
"$_Skip" "-" \
|
||
|
"$_SelSwpFile" "${mem}M" \
|
||
|
$PARTS 2>$ANS || return 0
|
||
|
|
||
|
ans="$(cat $ANS)"
|
||
|
|
||
|
if [[ $ans && $ans != "$_Skip" ]]; then
|
||
|
if [[ $ans == "$_SelSwpFile" ]]; then
|
||
|
|
||
|
msg="Enter size for swapfile below\n\nM = MB, G = GB"
|
||
|
getinput "$_SelSwpFile" "$msg" "${mem}M" 10 40 || return 0
|
||
|
tot="$(cat $ANS)"
|
||
|
|
||
|
# bad answer
|
||
|
while ! [[ ${tot: -1} =~ [MG] ]]; do
|
||
|
msgbox "$_SelSwpFile" "\n$_SelSwpFile $_ErrTitle: M = MB, G = GB\n\n" 7 40
|
||
|
msg="Enter size for swapfile below\n\nM = MB, G = GB"
|
||
|
getinput "$_SelSwpFile" "$msg" "${mem}M" 10 40 || { break; return 0; }
|
||
|
tot="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
fallocate -l "$tot" $MNT/swapfile 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
chmod 600 $MNT/swapfile 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
mkswap $MNT/swapfile >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
swapon $MNT/swapfile >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
else
|
||
|
swap_part="$(cat $ANS)"
|
||
|
|
||
|
if [[ $(lsblk -o FSTYPE "$swap_part" | grep -i "swap") != "swap" ]]; then
|
||
|
if yesno "$_PrepMount" "\nmkswap $swap_part\n$_ContinueYN"; then
|
||
|
mkswap "$swap_part" >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
else
|
||
|
return 0
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
swapon "$swap_part" >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
# sed s~${swap_part}$' -'~~
|
||
|
# remove mounted partition from dialog list
|
||
|
PARTS="$(sed "s~${swap_part} [0-9]*[G-M]~~; s~${swap_part} [0-9]*\.[0-9]*[G-M]~~" <<< "$PARTS")"
|
||
|
|
||
|
((PART_COUNT--))
|
||
|
fi
|
||
|
fi
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
select_device() {
|
||
|
local msg
|
||
|
|
||
|
if [[ $1 == "bootloader" ]]; then
|
||
|
msg="$_DevSelTitle $_DevSelBoot $ROOT_PARTITION\n"
|
||
|
else
|
||
|
msg="$_DevSelBody"
|
||
|
fi
|
||
|
|
||
|
DEVICE=""
|
||
|
DEVS="$(lsblk -lno NAME,SIZE,TYPE |
|
||
|
grep 'disk' |
|
||
|
awk '{print "/dev/" $1 " " $2}' |
|
||
|
sort -u)"
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_DevSelTitle " --menu "$msg" 0 0 4 $DEVS 2>$ANS || return 1
|
||
|
|
||
|
[[ $1 == "bootloader" && $(cat $ANS) != "" ]] && BOOT_DEVICE="$(cat $ANS)"
|
||
|
[[ $(cat $ANS) != "" ]] && DEVICE="$(cat $ANS)" || return 1
|
||
|
}
|
||
|
|
||
|
select_filesystem() {
|
||
|
local part="$1"
|
||
|
|
||
|
FS_OPTS=()
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_FSTitle " --menu "$_FSBody" 0 0 12 \
|
||
|
"$_Skip" "-" \
|
||
|
"ext4" "mkfs.ext4 -q" \
|
||
|
"ext3" "mkfs.ext3 -q" \
|
||
|
"ext2" "mkfs.ext2 -q" \
|
||
|
"vfat" "mkfs.vfat -F32" \
|
||
|
"btrfs" "mkfs.btrfs -f" \
|
||
|
"ntfs" "mkfs.ntfs -q" \
|
||
|
"f2fs" "mkfs.f2fs" \
|
||
|
"jfs" "mkfs.jfs -q" \
|
||
|
"nilfs2" "mkfs.nilfs2 -q" \
|
||
|
"reiserfs" "mkfs.reiserfs -q" \
|
||
|
"xfs" "mkfs.xfs -f" 2>$ANS || return 1
|
||
|
|
||
|
local choice
|
||
|
choice="$(cat $ANS)"
|
||
|
|
||
|
case $choice in
|
||
|
"$_Skip") FS_TYPE="$_Skip" ;;
|
||
|
ext4) FS_TYPE="mkfs.ext4 -q"
|
||
|
FS_OPTS=(dealloc discard noacl noatime nobarrier nodelalloc) ;;
|
||
|
ext3) FS_TYPE="mkfs.ext3 -q" ;;
|
||
|
ext2) FS_TYPE="mkfs.ext2 -q" ;;
|
||
|
vfat) FS_TYPE="mkfs.vfat -F32" ;;
|
||
|
ntfs) FS_TYPE="mkfs.ntfs -q" ;;
|
||
|
btrfs) FS_TYPE="mkfs.btrfs -f"
|
||
|
FS_OPTS=(autodefrag "compress=zlib" "compress=lzo" "compress=no"
|
||
|
"compress-force=zlib" "compress-force=lzo" discard noacl noatime
|
||
|
nodatasum nospace_cache recovery skip_balance space_cache ssd ssd_spread)
|
||
|
modprobe btrfs
|
||
|
;;
|
||
|
f2fs) FS_TYPE="mkfs.f2fs"
|
||
|
FS_OPTS=(data_flush disable_roll_forward disable_ext_identify
|
||
|
discard fastboot flush_merge inline_xattr inline_data inline_dentry
|
||
|
no_heap noacl nobarrier noextent_cache noinline_data norecovery)
|
||
|
modprobe f2fs ;;
|
||
|
jfs) FS_TYPE="mkfs.jfs -q"
|
||
|
FS_OPTS=(discard "errors=continue" "errors=panic" nointegrity) ;;
|
||
|
nilfs2) FS_TYPE="mkfs.nilfs2 -q"
|
||
|
FS_OPTS=(discard nobarrier "errors=continue"
|
||
|
"errors=panic" "order=relaxed" "order=strict" norecovery)
|
||
|
;;
|
||
|
reiserfs) FS_TYPE="mkfs.reiserfs -q"
|
||
|
FS_OPTS=(acl nolog notail replayonly user_xattr) ;;
|
||
|
xfs) FS_TYPE="mkfs.xfs -f"
|
||
|
FS_OPTS=(discard filestreams ikeep largeio
|
||
|
noalign nobarrier norecovery noquota wsync)
|
||
|
;;
|
||
|
*) return 1
|
||
|
esac
|
||
|
|
||
|
if [[ $FS_TYPE != "$_Skip" ]]; then
|
||
|
if yesno "$_FSTitle" "\nFormat $part as $choice?\n\n"; then
|
||
|
infobox "$_FSTitle" "\nFormatting $part as $choice\n\n"
|
||
|
$FS_TYPE $part >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
else
|
||
|
select_filesystem "$part" || return 1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
select_mount_opts() {
|
||
|
echo "" >$OPT
|
||
|
|
||
|
local part="$1"
|
||
|
local list=""
|
||
|
|
||
|
for i in "${FS_OPTS[@]}"; do
|
||
|
list="$list $i - off"
|
||
|
done
|
||
|
|
||
|
local title="$(sed "s/.*\.//g; s/-.*//g" <<< "$FS_TYPE") Mount Options"
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $title " --checklist "$_MntBody" 0 0 7 $list 2>$OPT || return 1
|
||
|
|
||
|
MNT_OPTS="$(cat $OPT | sed 's/ /,/g; $s/,$//')"
|
||
|
|
||
|
if [[ $MNT_OPTS ]]; then
|
||
|
if ! yesno "$title" "${_MntConfBody}$MNT_OPTS" 9 45; then
|
||
|
select_mount_opts
|
||
|
fi
|
||
|
return 0
|
||
|
fi
|
||
|
|
||
|
# no mount options were chosen or cancel was pressed
|
||
|
return 1
|
||
|
}
|
||
|
|
||
|
select_boot_setup() {
|
||
|
# choose mountpoint and bootloader
|
||
|
if [[ $SYS == "UEFI" ]]; then
|
||
|
dialog --backtitle "$BT" --title " $_PrepMount " --menu "$_MntUefiBody" 0 0 2 \
|
||
|
"grub" "/boot/efi" \
|
||
|
"systemd-boot" "/boot" 2>$ANS || return 1
|
||
|
|
||
|
BOOTLOADER="$(cat $ANS)"
|
||
|
BOOTLOADER="${BOOTLOADER:-grub}"
|
||
|
|
||
|
# $EFI only needs to be modified when not using grub
|
||
|
# otherwise the default /boot/efi works
|
||
|
if [[ $BOOTLOADER != "grub" ]]; then
|
||
|
EFI="/boot"
|
||
|
fi
|
||
|
|
||
|
mkdir -p "${MNT}$EFI"
|
||
|
mount "$EFI_PARTITION" "${MNT}$EFI" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
confirm_mount "$EFI_PARTITION" "${MNT}$EFI" || return 1
|
||
|
|
||
|
else
|
||
|
dialog --backtitle "$BT" --title " $_InstBiosBtTitle " \
|
||
|
--menu "$_InstBiosBtBody" 0 0 2 \
|
||
|
"grub" "-" \
|
||
|
"syslinux" "-" 2>$ANS || return 1
|
||
|
|
||
|
BOOTLOADER="$(cat $ANS)"
|
||
|
BOOTLOADER="${BOOTLOADER:-grub}"
|
||
|
|
||
|
if [[ $BOOTLOADER == "grub" ]]; then
|
||
|
select_device "bootloader" || return 1
|
||
|
BOOT_DEVICE="$DEVICE"
|
||
|
else
|
||
|
dialog --backtitle "$BT" --title " $_InstSysTitle " --menu "$_InstSysBody" 0 0 2 \
|
||
|
"syslinux-install_update -iam" "[MBR]" \
|
||
|
"syslinux-install_update -i" "[/]" 2>$ANS || return 1
|
||
|
SYSLNUX_CMD="$(cat $ANS)"
|
||
|
SYSLNUX_CMD="${SYSLNUX_CMD:-syslinux-install_update -iam}"
|
||
|
|
||
|
BOOT_DEVICE="$ROOT_PARTITION / (root)"
|
||
|
if grep -q "iam" <<< "$SYSLNUX_CMD"; then
|
||
|
BOOT_DEVICE="$ROOT_PARTITION MBR"
|
||
|
fi
|
||
|
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
select_efi_partition() {
|
||
|
dialog --backtitle "$BT" --title " $_PrepMount " \
|
||
|
--menu "$_SelUefiBody" 0 0 7 $PARTS 2>$ANS || return 1
|
||
|
|
||
|
EFI_PARTITION="$(cat $ANS)"
|
||
|
BOOT_DEVICE="$EFI_PARTITION"
|
||
|
|
||
|
format_efi_as_vfat() {
|
||
|
infobox "$_FSTitle" "\nFormatting $BOOT_DEVICE as vfat/fat32.\n"
|
||
|
mkfs.vfat -F32 "$EFI_PARTITION" >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
}
|
||
|
|
||
|
if grep -q 'fat' <<< "$(fsck -N "$EFI_PARTITION")"; then
|
||
|
local yes="Skip Formatting"
|
||
|
local no="Format $EFI_PARTITION"
|
||
|
local msg="$_FormUefiBody $EFI_PARTITION $_FormUefiBody2"
|
||
|
|
||
|
if ! yesno "$_PrepMount" "$msg" 0 0 --yes-label "$yes" --no-label "$no"; then
|
||
|
format_efi_as_vfat || return 1
|
||
|
fi
|
||
|
else
|
||
|
format_efi_as_vfat || return 1
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
select_install_partitions() {
|
||
|
msgbox "$_PrepMount" "$_WarnMount1 '$_Skip' $_WarnMount2"
|
||
|
lvm_detect
|
||
|
|
||
|
# prepare partition list for menu
|
||
|
unmount_partitions
|
||
|
find_partitions 'part\|lvm\|crypt' || return 1
|
||
|
|
||
|
# select root (/)
|
||
|
dialog --backtitle "$BT" --title "$_PrepMount" \
|
||
|
--menu "$_SelRootBody" 0 0 7 $PARTS 2>$ANS || return 1
|
||
|
ROOT_PARTITION="$(cat $ANS)"
|
||
|
|
||
|
# choose filesystem
|
||
|
select_filesystem "$ROOT_PARTITION" || return 1
|
||
|
|
||
|
# choose mount options and mount the partition
|
||
|
mount_partition "$ROOT_PARTITION" || return 1
|
||
|
|
||
|
select_swap || return 1
|
||
|
|
||
|
if [[ $SYS == "UEFI" ]]; then
|
||
|
select_efi_partition || return 1
|
||
|
fi
|
||
|
|
||
|
select_boot_setup || return 1
|
||
|
|
||
|
# remaining partitions
|
||
|
while (( PART_COUNT > 0 )); do
|
||
|
dialog --backtitle "$BT" --title " $_PrepMount " \
|
||
|
--menu "$_ExtPartBody" 0 0 7 "$_Done" "-" $PARTS 2>$ANS
|
||
|
|
||
|
local part="$(cat $ANS)"
|
||
|
|
||
|
# return to main menu
|
||
|
if [[ $? == 1 || $part == "$_Done" ]]; then
|
||
|
break
|
||
|
return 0
|
||
|
else
|
||
|
select_filesystem "$part" || return 1
|
||
|
|
||
|
local title="$_PrepMount $part"
|
||
|
local examples
|
||
|
[[ $SYS == "UEFI" ]] && examples="/home /var" || examples="/boot /home /var"
|
||
|
|
||
|
# get mountpoint
|
||
|
getinput "$title" "${_ExtPartBody1}$examples\n" "/" || { break; return 1; }
|
||
|
|
||
|
local mntp="$(cat $ANS)"
|
||
|
|
||
|
# bad mountpoint
|
||
|
while [[ ${mntp:0:1} != "/" || ${#mntp} -le 1 || $mntp =~ \ |\' ]]; do
|
||
|
msgbox "$_ErrTitle" "$_ExtErrBody"
|
||
|
getinput "$title" "${_ExtPartBody1}$examples\n" "/" || { break 2; return 1; }
|
||
|
mntp="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
# mount it
|
||
|
mount_partition "$part" "$mntp" || return 1
|
||
|
|
||
|
# add needed hooks for certain mountpoints
|
||
|
if [[ $mntp == "/usr" ]]; then
|
||
|
! grep -q "usr" <<< "$MKINIT_HOOKS" && MKINIT_HOOKS="usr $MKINIT_HOOKS"
|
||
|
elif [[ $mntp == "/boot" ]]; then
|
||
|
if grep -q "lvm" <<< "$(lsblk -lno TYPE "$part")"; then
|
||
|
SEPERATE_BOOT=2
|
||
|
else
|
||
|
SEPERATE_BOOT=1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
((PART_COUNT--))
|
||
|
fi
|
||
|
done
|
||
|
}
|
||
|
|
||
|
######################################################################
|
||
|
## Encryption (dm_crypt) Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
luks_pass() {
|
||
|
getpass "$_PrepLUKS" "$_LuksPassBody" || return 1
|
||
|
PASSWD="$(cat $ANS)"
|
||
|
|
||
|
getpass "$_PrepLUKS" "$_UserPass2 $LUKS_ROOT_NAME" || return 1
|
||
|
PASSWD2="$(cat $ANS)"
|
||
|
|
||
|
if [[ $PASSWD != "$PASSWD2" ]]; then
|
||
|
msgbox "$_ErrTitle" "${_PassErr}$_TryAgain"
|
||
|
luks_pass
|
||
|
fi
|
||
|
|
||
|
LUKS_PASSWD="$PASSWD"
|
||
|
}
|
||
|
|
||
|
luks_open() {
|
||
|
unmount_partitions
|
||
|
find_partitions 'part\|crypt\|lvm'
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_LuksOpen " \
|
||
|
--menu "$_LuksMenuBody" 15 50 7 $PARTS 2>$ANS || return 1
|
||
|
LUKS_PART="$(cat $ANS)"
|
||
|
|
||
|
getinput "$_LuksOpen" "$_LuksOpenBody" "cryptroot" || return 1
|
||
|
LUKS_ROOT_NAME="$(cat $ANS)"
|
||
|
|
||
|
if luks_pass; then
|
||
|
infobox "$_LuksOpen" "$_LuksWaitBody $LUKS_ROOT_NAME $_LuksWaitBody2 $LUKS_PART\n"
|
||
|
|
||
|
echo "$LUKS_PASSWD" | cryptsetup open --type luks "$LUKS_PART" "$LUKS_ROOT_NAME" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
luks_show
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
luks_setup() {
|
||
|
modprobe -a dm-mod dm_crypt
|
||
|
unmount_partitions
|
||
|
find_partitions 'part\|lvm'
|
||
|
|
||
|
dialog --backtitle "$BT" --title "$_LuksEncrypt" \
|
||
|
--menu "$_LuksEncryptBody" 0 0 7 $PARTS 2>$ANS || return 1
|
||
|
LUKS_PART="$(cat $ANS)"
|
||
|
|
||
|
getinput "$_LuksEncrypt" "$_LuksOpenBody" "cryptroot" || return 1
|
||
|
LUKS_ROOT_NAME="$(cat $ANS)"
|
||
|
|
||
|
luks_pass || return 1
|
||
|
}
|
||
|
|
||
|
luks_default() {
|
||
|
if luks_setup; then
|
||
|
infobox "$_LuksEncrypt" "$_LuksWaitBody $LUKS_ROOT_NAME $_LuksWaitBody2 $LUKS_PART\n"
|
||
|
|
||
|
echo "$LUKS_PASSWD" | cryptsetup -q luksFormat "$LUKS_PART" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
echo "$LUKS_PASSWD" | cryptsetup open "$LUKS_PART" "$LUKS_ROOT_NAME" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
luks_show
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
luks_key() {
|
||
|
if luks_setup; then
|
||
|
getinput "$_PrepLUKS" "$_LuksCipherKey" "-s 512 -c aes-xts-plain64" || return 1
|
||
|
|
||
|
local msg="$_LuksWaitBody $LUKS_ROOT_NAME $_LuksWaitBody2 $LUKS_PART\n"
|
||
|
infobox "$_LuksEncryptAdv" "$msg"
|
||
|
|
||
|
echo "$LUKS_PASSWD" | cryptsetup -q "$(cat $ANS)" luksFormat "$LUKS_PART" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
echo "$LUKS_PASSWD" | cryptsetup open "$LUKS_PART" "$LUKS_ROOT_NAME" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
luks_show
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
luks_show() {
|
||
|
echo -e "$_LuksEncryptSucc" >/tmp/.devlist
|
||
|
lsblk -o NAME,TYPE,FSTYPE,SIZE "$LUKS_PART" |
|
||
|
grep "part\|crypt\|NAME\|TYPE\|FSTYPE\|SIZE" >>/tmp/.devlist
|
||
|
dialog --backtitle "$BT" --title " $_LuksEncrypt " --textbox /tmp/.devlist 0 0
|
||
|
}
|
||
|
|
||
|
luks_menu() {
|
||
|
dialog --backtitle "$BT" --title " $_PrepLUKS " \
|
||
|
--menu "${_LuksMenuBody}${_LuksMenuBody2}${_LuksMenuBody3}" 0 0 4 \
|
||
|
"$_LuksOpen" "cryptsetup open --type luks" \
|
||
|
"$_LuksEncrypt" "cryptsetup -q luksFormat" \
|
||
|
"$_LuksEncryptAdv" "cryptsetup -q -s -c luksFormat" \
|
||
|
"$_Back" "-" 2> $ANS || return 0
|
||
|
|
||
|
case "$(cat $ANS)" in
|
||
|
"$_LuksOpen") luks_open ;;
|
||
|
"$_LuksEncrypt") luks_default ;;
|
||
|
"$_LuksEncryptAdv") luks_key ;;
|
||
|
*) return 0
|
||
|
esac
|
||
|
luks_menu
|
||
|
}
|
||
|
|
||
|
luks_keyfile() {
|
||
|
# 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 ]] && yesno "$_LuksKeyFileTitle" "$_LuksKeyFile"; then
|
||
|
|
||
|
infobox "$_LuksKeyFileTitle" "$_LuksKeyFileCreate\n"
|
||
|
|
||
|
local dev
|
||
|
dev="$(lsblk -lno NAME,UUID,TYPE |
|
||
|
grep "part\|crypt\|lvm" |
|
||
|
grep "$LUKS_UUID" |
|
||
|
awk '{print $1}')"
|
||
|
|
||
|
(( LVM == 1 )) && dev="/dev/mapper/$dev" || dev="/dev/$dev"
|
||
|
|
||
|
chroot_cmd "dd bs=512 count=8 if=/dev/urandom of=/crypto_keyfile.bin" &>/dev/null
|
||
|
chroot_cmd "chmod 000 /crypto_keyfile.bin" &>/dev/null
|
||
|
chroot_cmd "echo '$LUKS_PASSWD' | cryptsetup luksAddKey $dev /crypto_keyfile.bin" &>/dev/null
|
||
|
|
||
|
sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf &>/dev/null
|
||
|
|
||
|
chroot_cmd "mkinitcpio -p linux" 2>$ERR &>/dev/null
|
||
|
check_for_errors || return 1
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
######################################################################
|
||
|
## Logical Volume Management Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
lvm_detect() {
|
||
|
LVM_PV="$(pvs -o pv_name --noheading 2>/dev/null)"
|
||
|
LV_VG="$(vgs -o vg_name --noheading 2>/dev/null)"
|
||
|
LV="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)"
|
||
|
|
||
|
if [[ $LV && $LV_VG && $LVM_PV ]]; then
|
||
|
infobox "$_PrepLVM" "$_LvmDetBody"
|
||
|
|
||
|
modprobe dm-mod 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
vgscan >/dev/null 2>&1
|
||
|
vgchange -ay >/dev/null 2>&1
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
lvm_show_vg() {
|
||
|
VG_LIST=""
|
||
|
|
||
|
for i in $(lvs --noheadings | awk '{print $2}' | uniq); do
|
||
|
VG_LIST="$VG_LIST $i $(vgdisplay "$i" | grep -i "vg size" | awk '{print $3$4}')"
|
||
|
done
|
||
|
|
||
|
if [[ -z $VG_LIST ]]; then
|
||
|
msgbox "$_ErrTitle" "$_LvmVGErr"
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_PrepLVM " --menu "$_LvmSelVGBody" 0 0 5 $VG_LIST 2>$ANS || return 1
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
check_lv_size() {
|
||
|
local lv="$((${#LV_SIZE} - 1))"
|
||
|
|
||
|
(( ${#LV_SIZE} == 0 || ${LV_SIZE:0:1} == 0 )) && ERR_SIZE=1 || ERR_SIZE=0
|
||
|
|
||
|
if (( ERR_SIZE == 0 )); then
|
||
|
|
||
|
for (( i=0; i<lv; i++ )); do
|
||
|
[[ ${LV_SIZE:$i:1} != [0-9] ]] && { ERR_SIZE=1; break; }
|
||
|
done
|
||
|
|
||
|
if (( ERR_SIZE == 0 )); then
|
||
|
case ${LV_SIZE:$lv:1} in
|
||
|
[mMgG]) ERR_SIZE=0 ;;
|
||
|
*) ERR_SIZE=1
|
||
|
esac
|
||
|
|
||
|
if (( ERR_SIZE == 0 )); then
|
||
|
s=${LV_SIZE:0:$lv}
|
||
|
m=$((s * 1000))
|
||
|
|
||
|
case ${LV_SIZE:$lv:1} in
|
||
|
[Gg]) (( m >= VG_MB )) && ERR_SIZE=1 || VG_MB=$((VG_MB - m)) ;;
|
||
|
[Mm]) (( ${LV_SIZE:0:$lv} >= VG_MB )) && ERR_SIZE=1 || VG_MB=$((VG_MB - s)) ;;
|
||
|
*) ERR_SIZE=1
|
||
|
esac
|
||
|
fi
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if (( ERR_SIZE == 1 )); then
|
||
|
msgbox "$_ErrTitle" "$_LvmLvSizeErrBody"
|
||
|
|
||
|
msg="$LV_VG: ${VG_SIZE}$VG_SIZE_TYPE (${LV_VG_MB}MB $_LvmLvSizeBody1).$_LvmLvSizeBody2"
|
||
|
getinput "$_LvmCreateVG (LV:$NUM_LVS)" "$msg" "" || { break; return 1; }
|
||
|
LV_SIZE="$(cat $ANS)"
|
||
|
|
||
|
check_lv_size
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
lvm_create() {
|
||
|
LV_VG=""
|
||
|
VG_PARTS=""
|
||
|
VG_MB=0
|
||
|
|
||
|
unmount_partitions
|
||
|
find_partitions 'part\|crypt'
|
||
|
PARTS="$(sed 's/M\|G\|T/& off/g' <<< "$PARTS")"
|
||
|
|
||
|
# get volume group name
|
||
|
getinput "$_LvmCreateVG" "$_LvmNameVgBody" "VolGroup" || return 1
|
||
|
LV_VG="$(cat $ANS)"
|
||
|
|
||
|
# bad answer or volume group name already taken
|
||
|
while [[ ${LV_VG:0:1} == "/" || ${#LV_VG} -eq 0 || $LV_VG =~ \ |\' ]] || grep -q "$LV_VG" <<< "$(lsblk)"; do
|
||
|
msgbox "$_ErrTitle" "$_LvmNameVgErr"
|
||
|
getinput "$_LvmCreateVG" "$_LvmNameVgBody" "VolGroup" || { break; return 1; }
|
||
|
LV_VG="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
# choose partitions
|
||
|
dialog --backtitle "$BT" --title "$_LvmCreateVG" --checklist "$_LvmPvSelBody" 0 0 7 $PARTS 2>$ANS
|
||
|
[[ $(cat $ANS) != "" ]] && VG_PARTS="$(cat $ANS)" || return 1
|
||
|
|
||
|
# confirm or bail out
|
||
|
yesno "$_LvmCreateVG" "$_LvmPvConfBody1 $LV_VG\n$_LvmPvConfBody2 $VG_PARTS" || return 1
|
||
|
|
||
|
# create it
|
||
|
infobox "$_LvmCreateVG" "$_LvmPvActBody1 $LV_VG.\n"
|
||
|
vgcreate -f "$LV_VG" "$VG_PARTS" >/dev/null 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
VG_SIZE=$(vgdisplay "$LV_VG" |
|
||
|
grep 'VG Size' |
|
||
|
sed 's/\..*//; s/[^0-9]*//g')
|
||
|
SIZE_TYPE="$(vgdisplay "$LV_VG" |
|
||
|
grep 'VG Size' |
|
||
|
awk '{print $4}')"
|
||
|
|
||
|
# transform vg size to MB if needed
|
||
|
[[ ${SIZE_TYPE:0:1} == "G" ]] && VG_MB=$((VG_SIZE * 1000)) || VG_MB=$VG_SIZE
|
||
|
|
||
|
# finished volume group creation
|
||
|
msgbox "$_LvmCreateVG" "$_LvmPvDoneBody1 '$LV_VG' ($VG_SIZE $SIZE_TYPE) $_LvmPvDoneBody2\n"
|
||
|
|
||
|
# how many logical volumes
|
||
|
local msg="$_LvmLvNumBody1 '$LV_VG'.\n$_LvmLvNumBody2"
|
||
|
dialog --backtitle "$BT" --title " $_LvmCreateVG " --radiolist "$msg" 0 0 9 \
|
||
|
"1" "-" off \
|
||
|
"2" "-" off \
|
||
|
"3" "-" off \
|
||
|
"4" "-" off \
|
||
|
"5" "-" off \
|
||
|
"6" "-" off \
|
||
|
"7" "-" off \
|
||
|
"8" "-" off \
|
||
|
"9" "-" off 2>$ANS
|
||
|
[[ $(cat $ANS) != "" ]] && NUM_LVS=$(cat $ANS) || return 1
|
||
|
|
||
|
# loop selected amount
|
||
|
while (( NUM_LVS > 1 )); do
|
||
|
local ttl=" $_LvmCreateVG (LV:$NUM_LVS) "
|
||
|
getinput "$ttl" "$_LvmLvNameBody1" "volext" || { break; return 1; }
|
||
|
LV_NAME="$(cat $ANS)"
|
||
|
|
||
|
# bad answer
|
||
|
while [[ ${LV_NAME:0:1} == "/" || ${#LV_NAME} -eq 0 || $LV_NAME =~ \ |\' ]] || grep -q "$LV_NAME" <<< "$(lsblk)"; do
|
||
|
msgbox "$_ErrTitle" "$_LvmLvNameErrBody"
|
||
|
getinput "$ttl" "$_LvmLvNameBody1" "volext" || { break 2; return 1; }
|
||
|
LV_NAME="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
msg="${LV_VG}: ${VG_SIZE}$SIZE_TYPE (${VG_MB}MB $_LvmLvSizeBody1).$_LvmLvSizeBody2"
|
||
|
getinput "$ttl" "$msg" "" || { break; return 1; }
|
||
|
LV_SIZE="$(cat $ANS)"
|
||
|
|
||
|
check_lv_size || return 1
|
||
|
lvcreate -L "$LV_SIZE" "$LV_VG" -n "$LV_NAME" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
msgbox "$ttl" "$_Done LV $LV_NAME ($LV_SIZE) $_LvmPvDoneBody2."
|
||
|
((NUM_LVS--))
|
||
|
done
|
||
|
|
||
|
# last or only
|
||
|
msg="$_LvmLvNameBody1 $_LvmLvNameBody2 (${VG_MB}MB)."
|
||
|
|
||
|
# volume name
|
||
|
getinput "$_LvmCreateVG (LV:$NUM_LVS)" "$msg" "volhome" || return 1
|
||
|
LV_NAME="$(cat $ANS)"
|
||
|
|
||
|
# bad volume name
|
||
|
while [[ ${LV_NAME:0:1} == "/" || ${#LV_NAME} -eq 0 || $LV_NAME =~ \ |\' ]] || grep -q "$LV_NAME" <<< "$(lsblk)"; do
|
||
|
msgbox "$_ErrTitle" "$_LvmLvNameErrBody"
|
||
|
getinput "$_LvmCreateVG (LV:$NUM_LVS)" "$msg" "volhome" || { break; return 1; }
|
||
|
LV_NAME="$(cat $ANS)"
|
||
|
done
|
||
|
|
||
|
# create it
|
||
|
lvcreate -l +100%FREE "$LV_VG" -n "$LV_NAME" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
((NUM_LVS--))
|
||
|
|
||
|
LVM=1
|
||
|
yesno "$_LvmCreateVG" "$_LvmCompBody" && show_devices
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
lvm_del_vg() {
|
||
|
lvm_show_vg
|
||
|
if yesno "$_LvmDelVG" "$_LvmDelQ"; then
|
||
|
vgremove -f "$(cat $ANS)" >/dev/null 2>&1
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
lvm_del_all() {
|
||
|
LVM_PV="$(pvs -o pv_name --noheading 2>/dev/null)"
|
||
|
LV_VG="$(vgs -o vg_name --noheading 2>/dev/null)"
|
||
|
LV="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)"
|
||
|
|
||
|
if yesno "$_LvMDelAll" "$_LvmDelQ"; then
|
||
|
for i in $LV; do
|
||
|
lvremove -f "/dev/mapper/$i" >/dev/null 2>&1
|
||
|
done
|
||
|
|
||
|
for i in $LV_VG; do
|
||
|
vgremove -f "$i" >/dev/null 2>&1
|
||
|
done
|
||
|
|
||
|
for i in $LVM_PV; do
|
||
|
pvremove -f "$i" >/dev/null 2>&1
|
||
|
done
|
||
|
|
||
|
LVM=0
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
lvm_menu() {
|
||
|
lvm_detect
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_PrepLVM " --menu "$_LvmMenu" 0 0 4 \
|
||
|
"$_LvmCreateVG" "vgcreate -f, lvcreate -L -n" \
|
||
|
"$_LvmDelVG" "vgremove -f" \
|
||
|
"$_LvMDelAll" "lvrmeove, vgremove, pvremove -f" \
|
||
|
"$_Back" "-" 2>$ANS || return 0
|
||
|
|
||
|
case "$(cat $ANS)" in
|
||
|
"$_LvmCreateVG") lvm_create ;;
|
||
|
"$_LvmDelVG") lvm_del_vg ;;
|
||
|
"$_LvMDelAll") lvm_del_all ;;
|
||
|
*) return 0
|
||
|
esac
|
||
|
|
||
|
lvm_menu
|
||
|
}
|
||
|
|
||
|
######################################################################
|
||
|
## Installation Functions ##
|
||
|
######################################################################
|
||
|
|
||
|
install_main() {
|
||
|
unpack_base_system || return 0 # user can choose to bail at this point
|
||
|
update_mirrorlist
|
||
|
update_system
|
||
|
|
||
|
genfstab -U -p $MNT >$MNT/etc/fstab 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
# remove /mnt/install prefix from /etc/fstab for swapfile
|
||
|
[[ -f $MNT/swapfile ]] && sed -i "s~${MNT}~~" $MNT/etc/fstab
|
||
|
|
||
|
run_mkinitcpio || return 1
|
||
|
setup_bootloader || return 1
|
||
|
|
||
|
configure_menu || edit_config_menu
|
||
|
}
|
||
|
|
||
|
unpack_base_system() {
|
||
|
[[ $UNPACKED_BASE ]] && return 0
|
||
|
|
||
|
if ! yesno "$_InstTitle" "$_BeginInst $ROOT_PARTITION\n$_ContinueYN"; then
|
||
|
return 1
|
||
|
fi
|
||
|
|
||
|
clear
|
||
|
echo -e "\nUnpacking the system\n\n"
|
||
|
rsync -a --info=progress2 /run/archiso/sfs/airootfs/ $MNT/ 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
rm -rf $MNT/etc/polkit-1/rules.d/49-nopasswd_global.rules
|
||
|
rm -rf $MNT/etc/sudoers.d/g_wheel
|
||
|
rm -rf $MNT/etc/mkinitcpio-archiso.conf
|
||
|
rm -rf $MNT/usr/bin/install-al
|
||
|
rm -rf $MNT/usr/bin/al-installer
|
||
|
rm -rf $MNT/home/$LIVEUSER/.config/keypack
|
||
|
rm -rf $MNT/home/$LIVEUSER/bin/welcome.sh
|
||
|
|
||
|
find $MNT/usr/lib/initcpio -name "archiso*" -type f -exec rm '{}' \;
|
||
|
|
||
|
local openbox="$MNT/home/$LIVEUSER/.config/openbox"
|
||
|
|
||
|
sed -i '/keypack/d; /welcome.sh/d; s/#$HOME/$HOME/g; s|#$HOME/.config/setup &|$HOME/.config/setup &|g' $openbox/autostart
|
||
|
sed -i '/installer/ { N; N; d; }' $openbox/rc.xml
|
||
|
sed -i '/item label="Welcome Screen"/ i\ <separator label="A r c h L a b s"/>' $openbox/menu.xml
|
||
|
sed -i '/item label="Welcome Screen"/ { N; N; N; N; N; N; N; N; N; N; N; d; }' $openbox/menu.xml
|
||
|
sed -i 's/volatile/auto/g' $MNT/etc/systemd/journald.conf
|
||
|
|
||
|
if hash al-hello &>/dev/null; then
|
||
|
if hash st &>/dev/null; then
|
||
|
cmd="st"
|
||
|
elif hash termite &>/dev/null; then
|
||
|
cmd="termite"
|
||
|
else
|
||
|
cmd="xterm"
|
||
|
fi
|
||
|
sed -i "/al-hello/ c sleep 10; ${cmd} -e al-hello &" $openbox/autostart
|
||
|
else
|
||
|
sed -i '/al-hello/d' $openbox/autostart
|
||
|
fi
|
||
|
|
||
|
# vmlinuz, needed for mkinitcpio
|
||
|
cp -f /run/archiso/bootmnt/arch/boot/x86_64/vmlinuz $MNT/boot/vmlinuz-linux
|
||
|
|
||
|
# config files we made during prepare_menu()
|
||
|
cp -f /tmp/keyboard $MNT/etc/default/
|
||
|
cp -f /tmp/vconsole.conf $MNT/etc/
|
||
|
cp -f /tmp/00-keyboard.conf $MNT/etc/X11/xorg.conf.d/
|
||
|
|
||
|
# existing network config
|
||
|
cp -f /etc/resolv.conf $MNT/etc/
|
||
|
cp -rf /etc/NetworkManager/system-connections $MNT/etc/NetworkManager/
|
||
|
|
||
|
UNPACKED_BASE="True"
|
||
|
}
|
||
|
|
||
|
update_system() {
|
||
|
# update system and install needed packages
|
||
|
infobox "$_UpdSysTitle" "$_UpdSysBody\n"
|
||
|
|
||
|
chroot_cmd "pacman -Rs archlabs-installer --noconfirm" &>/dev/null
|
||
|
|
||
|
chroot_cmd "pacman -Syyu --color always --noconfirm" &>/dev/null
|
||
|
|
||
|
chroot_cmd "pacman -S iputils --noconfirm" &>/dev/null
|
||
|
chroot_cmd "pacman -S base-devel git --needed --noconfirm" &>/dev/null
|
||
|
}
|
||
|
|
||
|
update_mirrorlist() {
|
||
|
local yes="Automatic Sort"
|
||
|
local no="Customize Command"
|
||
|
|
||
|
if yesno "$_MirrorTitle" "$_MirrorSetup" 0 0 --yes-label "$yes" --no-label "$no"; then
|
||
|
CMD="reflector --score 100 -l 50 -f 10 --sort rate"
|
||
|
else
|
||
|
dialog --backtitle "$BT" --title "$_MirrorTitle" --menu "$_MirrorCountry" 20 45 10 $COUNTRY 2>$ANS || return 1
|
||
|
COUNTRY="$(cat $ANS)"
|
||
|
|
||
|
CMD="reflector --country $COUNTRY --score 100 --latest 50 --fastest 10 --sort rate"
|
||
|
REF="\n--score n Limit the list to the n servers with the highest score.
|
||
|
\n-l n, --latest n Limit the list to the n most recently synchronized servers.
|
||
|
\n-f n, --fastest n Return the n fastest mirrors that meet the other criteria.
|
||
|
\n--sort {age,rate,country,score,delay}
|
||
|
\n 'age': last server synchronization; 'rate': download rate;
|
||
|
\n 'country': server's location; 'score': MirrorStatus score;
|
||
|
\n 'delay': MirrorStatus delay."
|
||
|
|
||
|
getinput "$_MirrorTitle" "$_MirrorCmd\n$REF\n" "$CMD"
|
||
|
CMD="$(cat $ANS)"
|
||
|
fi
|
||
|
|
||
|
infobox "$_MirrorTitle" "$_MirrorSort"
|
||
|
if ! ${CMD:-reflector --score 100 -l 50 -f 10 --sort rate} --save $MNT/etc/pacman.d/mirrorlist; then
|
||
|
infobox "$_ErrTitle" "\nAn error occurred updating the mirrorlist\n\n"
|
||
|
mirrors
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
create_bootloader_config() {
|
||
|
if [[ $BOOTLOADER == "grub" ]]; then
|
||
|
sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g" $MNT/etc/default/grub 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
if (( LUKS == 1 )); then
|
||
|
sed -i 's/#GRUB_ENABLE_CRYPTODISK/GRUB_ENABLE_CRYPTODISK/g' $MNT/etc/default/grub 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
if [[ $LUKS_DEV ]]; then
|
||
|
sed -i "s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $MNT/etc/default/grub 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
if [[ $SYS != "UEFI" ]]; then
|
||
|
if (( LVM == 1 && SEPERATE_BOOT == 0 )) || (( SEPERATE_BOOT == 2 )); then
|
||
|
sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" $MNT/etc/default/grub 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
elif [[ $BOOTLOADER == "syslinux" ]]; then
|
||
|
local cfgdir="$MNT/boot/syslinux"
|
||
|
[[ ! -d $cfgdir ]] && mkdir -p $cfgdir
|
||
|
|
||
|
# menu would be nice, so try setting that up
|
||
|
if [[ -e /usr/lib/syslinux/bios/vesamenu.c32 && ! -e $cfgdir/vesamenu.c32 ]]; then
|
||
|
cp -f /usr/lib/syslinux/bios/vesamenu.c32 $cfgdir/
|
||
|
if [[ -e /run/archiso/bootmnt/arch/boot/syslinux/splash.png ]]; then
|
||
|
cp -f /run/archiso/bootmnt/arch/boot/syslinux/splash.png $cfgdir/
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
# if the menu exists we can proceed to setup a default list
|
||
|
if [[ -e $cfgdir/vesamenu.c32 ]]; then
|
||
|
local menu_top="UI vesamenu.c32\nDEFAULT archlabs\nPROMPT 0\n"
|
||
|
menu_top="$menu_top\nMENU TITLE ArchLabs\nMENU BACKGROUND splash.png\nTIMEOUT 50\n"
|
||
|
menu_top="$menu_top\nMENU WIDTH 78\nMENU MARGIN 4\nMENU ROWS 5\nMENU VSHIFT 10"
|
||
|
menu_top="$menu_top\nMENU TIMEOUTROW 13\nMENU TABMSGROW 11\nMENU CMDLINEROW 11"
|
||
|
menu_top="$menu_top\nMENU HELPMSGROW 16\nMENU HELPMSGENDROW 29\n"
|
||
|
menu_top="$menu_top\n# Refer to https://www.syslinux.org/wiki/index.php/Comboot/menu.c32\n"
|
||
|
menu_top="$menu_top\nMENU COLOR border 30;44 #40ffffff #a0000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR title 1;36;44 #9033ccff #a0000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR sel 7;37;40 #e0ffffff #20ffffff all"
|
||
|
menu_top="$menu_top\nMENU COLOR unsel 37;44 #50ffffff #a0000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR help 37;40 #c0ffffff #a0000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR timeout_msg 37;40 #80ffffff #00000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR timeout 1;37;40 #c0ffffff #00000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR msg07 37;40 #90ffffff #a0000000 std"
|
||
|
menu_top="$menu_top\nMENU COLOR tabmsg 31;40 #30ffffff #00000000 std"
|
||
|
else
|
||
|
# no menu, but should display 'boot: ' and automatically boot after 5 seconds
|
||
|
local menu_top="PROMPT 1\nTIMEOUT 50\nDEFAULT archlabs"
|
||
|
fi
|
||
|
|
||
|
cat > $cfgdir/syslinux.cfg << EOF
|
||
|
$(echo -e "$menu_top")
|
||
|
|
||
|
LABEL archlabs
|
||
|
MENU LABEL Archlabs Linux
|
||
|
LINUX ../vmlinuz-linux
|
||
|
APPEND root=$ROOT_PARTITION $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw
|
||
|
INITRD ../initramfs-linux.img
|
||
|
|
||
|
LABEL archlabsfallback
|
||
|
MENU LABEL Archlabs Linux Fallback
|
||
|
LINUX ../vmlinuz-linux
|
||
|
APPEND root=$ROOT_PARTITION $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw
|
||
|
INITRD ../initramfs-linux-fallback.img
|
||
|
|
||
|
LABEL hdt
|
||
|
MENU LABEL HDT (Hardware Detection Tool)
|
||
|
COM32 hdt.c32
|
||
|
|
||
|
#LABEL windows
|
||
|
#MENU LABEL Windows
|
||
|
#COM32 chain.c32
|
||
|
#APPEND root=/dev/sda2 rw
|
||
|
|
||
|
#LABEL grub2
|
||
|
#MENU LABEL Grub2
|
||
|
#COM32 chain.c32
|
||
|
#APPEND file=../grub/boot.img
|
||
|
|
||
|
LABEL reboot
|
||
|
MENU LABEL Reboot
|
||
|
COM32 reboot.c32
|
||
|
|
||
|
LABEL poweroff
|
||
|
MENU LABEL Poweroff
|
||
|
COM32 poweroff.c32
|
||
|
EOF
|
||
|
|
||
|
else
|
||
|
# remove leftover grub configs from previous installs
|
||
|
find $MNT/boot/efi/EFI -name '[aA][rR][cC][hH][lL]abs*' -type d -exec rm '{}' \;
|
||
|
find $MNT/boot/efi/EFI -name 'grub*' -type d -exec rm '{}' \;
|
||
|
|
||
|
if grep -q "/dev/mapper/" <<< "$ROOT_PARTITION"; then
|
||
|
ROOT_PART_ID="$ROOT_PARTITION"
|
||
|
else
|
||
|
ROOT_PART_ID="PARTUUID=$(blkid -s PARTUUID $ROOT_PARTITION | sed 's/.*=//g; s/"//g')"
|
||
|
fi
|
||
|
|
||
|
cat > $MNT/boot/loader/loader.conf << EOF
|
||
|
default archlabs
|
||
|
timeout 5
|
||
|
editor no
|
||
|
EOF
|
||
|
cat > $MNT/boot/loader/entries/archlabs.conf << EOF
|
||
|
title Archlabs Linux
|
||
|
linux /vmlinuz-linux
|
||
|
initrd /initramfs-linux.img
|
||
|
options root=$ROOT_PART_ID rw
|
||
|
EOF
|
||
|
for i in $(ls $MNT/boot/loader/entries/arch*.conf); do
|
||
|
[[ $LUKS_DEV ]] && sed -i "s~rw~$LUKS_DEV rw~g" "$i"
|
||
|
done
|
||
|
fi
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
setup_bootloader() {
|
||
|
bootloader_info() {
|
||
|
local msg="$_InstBootloader $BOOTLOADER\n\n$_InstBootDev $BOOT_DEVICE"
|
||
|
if [[ $SYS == "BIOS" ]]; then
|
||
|
infobox "$_InstBiosBtTitle" "$msg\n"
|
||
|
else
|
||
|
infobox "$_InstUefiBtTitle" "$msg\n\nMountpoint: $EFI\n"
|
||
|
fi
|
||
|
}
|
||
|
|
||
|
bios_bootloader_install() {
|
||
|
if [[ $BOOTLOADER == "grub" ]]; then
|
||
|
# must be before running grub-install or it will fail with encrypted devices
|
||
|
create_bootloader_config || return 1
|
||
|
|
||
|
chroot_cmd "grub-install --bootloader-id=$DIST --recheck --force $BOOT_DEVICE" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
chroot_cmd "grub-mkconfig -o /boot/grub/grub.cfg" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
else
|
||
|
chroot_cmd "pacman -Rs grub --noconfirm" &>/dev/null
|
||
|
chroot_cmd "$SYSLNUX_CMD" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
create_bootloader_config
|
||
|
fi
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
uefi_bootloader_install() {
|
||
|
if [[ $BOOTLOADER == "grub" ]]; then
|
||
|
# must be before running grub-install or it will fail with encrypted devices
|
||
|
create_bootloader_config || return 1
|
||
|
|
||
|
chroot_cmd "grub-install --bootloader-id=$DIST --recheck --force" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
local efidir="${MNT}$EFI/EFI"
|
||
|
local fallback="BOOT"
|
||
|
for i in $(find "$efidir" -maxdepth 1 -mindepth 1 -type d); do
|
||
|
if grep -qi "boot" <<< "$(basename $i)"; then
|
||
|
fallback="$(basename $i)"
|
||
|
break
|
||
|
fi
|
||
|
done
|
||
|
mkdir -p $efidir/$fallback
|
||
|
cp -f $efidir/$DIST/grubx64.efi $efidir/$fallback/bootx64.efi
|
||
|
cp -f $efidir/$DIST/grubx64.efi $efidir/$fallback/BOOTX64.EFI
|
||
|
|
||
|
chroot_cmd "grub-mkconfig -o /boot/grub/grub.cfg" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
else
|
||
|
|
||
|
# remove old grub entries from previous installs
|
||
|
chroot_cmd "pacman -Rs grub --noconfirm" &>/dev/null
|
||
|
[[ -d $MNT/boot/efi/EFI/Archlabs ]] && rm -rf $MNT/boot/efi/EFI/{Archlabs,BOOT,boot,Boot}
|
||
|
[[ -d $MNT/boot/EFI/Archlabs ]] && rm -rf $MNT/boot/EFI/{Archlabs,BOOT,boot,Boot}
|
||
|
[[ -d $MNT/boot/grub ]] && rm -rf $MNT/boot/grub
|
||
|
[[ -e $MNT/etc/default/grub ]] && rm -rf $MNT/etc/default/grub
|
||
|
|
||
|
# since systemd v232 systemd-boot requires machine id to be setup first
|
||
|
systemd-machine-id-setup --root="$MNT" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
chroot_cmd "bootctl --path=/boot install" 2>$ERR
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
create_bootloader_config
|
||
|
fi
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
chroot_cmd "export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/bin:/usr/bin/core_perl"
|
||
|
|
||
|
# save repetition of basically the same command
|
||
|
bootloader_info
|
||
|
|
||
|
if [[ $SYS != "UEFI" ]]; then
|
||
|
bios_bootloader_install || return 1
|
||
|
else
|
||
|
if grep -q "/sys/firmware/efi/efivars" <<< "$(mount)"; then
|
||
|
mount -t efivarfs efivarfs /sys/firmware/efi/efivars &>/dev/null
|
||
|
chroot_cmd "mount -t efivarfs efivarfs /sys/firmware/efi/efivars" &>/dev/null
|
||
|
fi
|
||
|
uefi_bootloader_install || return 1
|
||
|
fi
|
||
|
|
||
|
BOOT_DONE="True"
|
||
|
|
||
|
[[ $BOOTLOADER == "grub" && $LUKS -eq 1 && $LUKS_PASSWD && $LUKS_UUID ]] && luks_keyfile
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
run_mkinitcpio() {
|
||
|
local conf="$MNT/etc/mkinitcpio.conf"
|
||
|
local addition
|
||
|
|
||
|
# amend HOOKS in /etc/mkinitcpio.conf
|
||
|
if (( LVM == 1 && LUKS == 0 )); then
|
||
|
sed -i 's/block filesystems/block lvm2 filesystems/g' $conf 2>$ERR &>/dev/null
|
||
|
addition="lvm2"
|
||
|
elif (( LVM == 1 && LUKS == 1 )); then
|
||
|
sed -i 's/block filesystems/block encrypt lvm2 filesystems/g' $conf 2>$ERR &>/dev/null
|
||
|
addition="encrypt lvm2"
|
||
|
elif (( LVM == 0 && LUKS == 1 )); then
|
||
|
sed -i 's/block filesystems/block encrypt filesystems/g' $conf 2>$ERR &>/dev/null
|
||
|
addition="encrypt"
|
||
|
fi
|
||
|
check_for_errors || return 1
|
||
|
sed -i "s/keyboard fsck/keyboard ${MKINIT_HOOKS} fsck/g" $conf 2>$ERR &>/dev/null
|
||
|
check_for_errors || return 1
|
||
|
|
||
|
addition="$addition $MKINIT_HOOKS"
|
||
|
infobox "$_RunMkinit" "$_RunMkinitBody\n\nAdded HOOKS: $addition\n"
|
||
|
chroot_cmd "mkinitcpio -p linux" 2>$ERR &>/dev/null
|
||
|
check_for_errors || return 1
|
||
|
}
|
||
|
|
||
|
######################################################################
|
||
|
## Menu Interfaces ##
|
||
|
######################################################################
|
||
|
|
||
|
main_menu() {
|
||
|
# automatically jump to prepare_menu() on first run
|
||
|
if [[ $FIRST_RUN_PREP != "True" ]]; then
|
||
|
# if prepare_menu() returns non zero begin the install
|
||
|
if ! prepare_menu; then
|
||
|
check_parts_are_mounted && install_main && MAIN_HIGHLIGHT=3
|
||
|
fi
|
||
|
FIRST_RUN_PREP="True"
|
||
|
fi
|
||
|
|
||
|
if [[ $CURRENT_MENU != "main" ]]; then
|
||
|
MAIN_HIGHLIGHT=1
|
||
|
CURRENT_MENU="main"
|
||
|
elif (( MAIN_HIGHLIGHT < 5 )); then
|
||
|
((MAIN_HIGHLIGHT++)) # highlight the next choice
|
||
|
fi
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_MainTitle " \
|
||
|
--default-item $MAIN_HIGHLIGHT --menu "$_MainBody" 0 0 5 \
|
||
|
"1" "$_PrepTitle" \
|
||
|
"2" "$_InstTitle" \
|
||
|
"3" "$_ConfTitle" \
|
||
|
"4" "$_EditTitle" \
|
||
|
"5" "$_Done" 2>$ANS
|
||
|
|
||
|
MAIN_HIGHLIGHT=$(cat $ANS)
|
||
|
|
||
|
if [[ -n $MAIN_HIGHLIGHT ]]; then
|
||
|
# make sure everything has been set before installing or configuring install
|
||
|
if (( MAIN_HIGHLIGHT == 2 )) && ! check_parts_are_mounted; then
|
||
|
return 1
|
||
|
elif (( MAIN_HIGHLIGHT >= 3 && MAIN_HIGHLIGHT <= 4 )); then
|
||
|
if ! (check_parts_are_mounted && check_base_unpacked); then
|
||
|
return 1
|
||
|
fi
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
case $MAIN_HIGHLIGHT in
|
||
|
1) prepare_menu ;;
|
||
|
2) install_main ;;
|
||
|
3) configure_menu ;;
|
||
|
4) edit_config_menu ;;
|
||
|
*)
|
||
|
local yes="Exit Installer"
|
||
|
local no="Go Back"
|
||
|
if yesno "Close Installer" "$_CloseInstBody" 0 0 --yes-label "$yes" --no-label "$no"; then
|
||
|
unmount_partitions
|
||
|
cleanup
|
||
|
clear
|
||
|
exit 0
|
||
|
fi
|
||
|
esac
|
||
|
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
prepare_menu() {
|
||
|
if [[ $CURRENT_MENU != "prep" ]]; then
|
||
|
SUB_HIGHLIGHT=1
|
||
|
CURRENT_MENU="prep"
|
||
|
elif (( SUB_HIGHLIGHT < 7 )); then
|
||
|
((SUB_HIGHLIGHT++)) # increment the highlighted item
|
||
|
|
||
|
# return non zero to main_menu()
|
||
|
# only when we reach the end of the menu and have done required steps
|
||
|
if [[ $SUB_HIGHLIGHT -eq 7 && -n $ROOT_PARTITION ]]; then
|
||
|
([[ $SYS == "UEFI" && -n $EFI_PARTITION ]] || [[ $SYS != "UEFI" ]]) && return 1
|
||
|
fi
|
||
|
fi
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_PrepTitle " \
|
||
|
--default-item $SUB_HIGHLIGHT --menu "$_PrepBody" 0 0 7 \
|
||
|
"1" "$_PrepLayout" \
|
||
|
"2" "$_PrepShowDev" \
|
||
|
"3" "$_PrepParts" \
|
||
|
"4" "$_PrepLUKS" \
|
||
|
"5" "$_PrepLVM" \
|
||
|
"6" "$_PrepMount" \
|
||
|
"7" "$_Back" 2>$ANS
|
||
|
|
||
|
SUB_HIGHLIGHT=$(cat $ANS)
|
||
|
|
||
|
case $SUB_HIGHLIGHT in
|
||
|
1) set_keymap ;;
|
||
|
2) show_devices ;;
|
||
|
3) unmount_partitions && select_device && create_partitions "$DEVICE" ;;
|
||
|
4) luks_menu ;;
|
||
|
5) lvm_menu ;;
|
||
|
6) select_install_partitions ;;
|
||
|
*) return 0
|
||
|
esac
|
||
|
|
||
|
# recurse back until explicitly chosen to leave
|
||
|
prepare_menu
|
||
|
}
|
||
|
|
||
|
configure_menu() {
|
||
|
chroot_cmd "export PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/core_perl"
|
||
|
|
||
|
# run through each step automatically on first run
|
||
|
if [[ $FIRST_RUN_CONFIG != "True" ]]; then
|
||
|
SUB_HIGHLIGHT=1
|
||
|
CURRENT_MENU="config"
|
||
|
FIRST_RUN_CONFIG="True"
|
||
|
set_hostname && set_locale && root_password
|
||
|
|
||
|
# if create_user returns non zero, pass return code back to install_main()
|
||
|
# this will return us to the edit_config_menu()
|
||
|
create_user || return 1
|
||
|
|
||
|
# returning from another menu after first run
|
||
|
elif [[ $CURRENT_MENU != "config" ]]; then
|
||
|
SUB_HIGHLIGHT=1
|
||
|
CURRENT_MENU="config"
|
||
|
|
||
|
# highlight next option
|
||
|
elif (( SUB_HIGHLIGHT < 5 )); then
|
||
|
((SUB_HIGHLIGHT++))
|
||
|
fi
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_ConfTitle " \
|
||
|
--default-item $SUB_HIGHLIGHT --menu "$_ConfBody" 0 0 5 \
|
||
|
"1" "$_ConfHost" \
|
||
|
"2" "$_ConfLocale" \
|
||
|
"3" "$_ConfRoot" \
|
||
|
"4" "$_ConfUser" \
|
||
|
"5" "$_Back" 2>$ANS
|
||
|
|
||
|
SUB_HIGHLIGHT=$(cat $ANS)
|
||
|
|
||
|
case $SUB_HIGHLIGHT in
|
||
|
1) set_hostname ;;
|
||
|
2) set_locale ;;
|
||
|
3) root_password ;;
|
||
|
4) create_user ;;
|
||
|
*) return 0
|
||
|
esac
|
||
|
|
||
|
# recurse back until we explicitly choose to exit
|
||
|
configure_menu
|
||
|
}
|
||
|
|
||
|
edit_config_menu() {
|
||
|
if [[ $CURRENT_MENU != "edit" ]]; then
|
||
|
SUB_HIGHLIGHT=1
|
||
|
CURRENT_MENU="edit"
|
||
|
elif (( SUB_HIGHLIGHT < 11 )); then
|
||
|
((SUB_HIGHLIGHT++))
|
||
|
fi
|
||
|
|
||
|
dialog --backtitle "$BT" --title " $_EditTitle " \
|
||
|
--default-item $SUB_HIGHLIGHT --menu "$_EditBody" 0 0 11 \
|
||
|
"1" "keymap configs" \
|
||
|
"2" "locale configs" \
|
||
|
"3" "/etc/hostname" \
|
||
|
"4" "/etc/hosts" \
|
||
|
"5" "/etc/sudoers" \
|
||
|
"6" "/etc/mkinitcpio.conf" \
|
||
|
"7" "/etc/fstab" \
|
||
|
"8" "/etc/crypttab" \
|
||
|
"9" "bootloader configs" \
|
||
|
"10" "/etc/pacman.conf" \
|
||
|
"11" "$_Back" 2>$ANS
|
||
|
|
||
|
SUB_HIGHLIGHT="$(cat $ANS)"
|
||
|
|
||
|
local file=""
|
||
|
local xorg_conf="etc/X11/xorg.conf.d/00-keyboard.conf"
|
||
|
|
||
|
case $SUB_HIGHLIGHT in
|
||
|
1) [[ -e $MNT/$xorg_conf ]] && file="$MNT/$xorg_conf"
|
||
|
[[ -e $MNT/etc/vconsole.conf ]] && file="$file $MNT/etc/vconsole.conf"
|
||
|
[[ -e $MNT/etc/default/keyboard ]] && file="$file $MNT/etc/default/keyboard" ;;
|
||
|
2) [[ -e $MNT/etc/locale.conf ]] && file="$MNT/etc/locale.conf"
|
||
|
[[ -e $MNT/etc/default/locale ]] && file="$file $MNT/etc/default/locale" ;;
|
||
|
3) [[ -e $MNT/etc/hostname ]] && file="$MNT/etc/hostname" ;;
|
||
|
4) [[ -e $MNT/etc/hosts ]] && file="$MNT/etc/hosts" ;;
|
||
|
5) [[ -e $MNT/etc/sudoers ]] && file="$MNT/etc/sudoers" ;;
|
||
|
6) [[ -e $MNT/etc/mkinitcpio.conf ]] && file="$MNT/etc/mkinitcpio.conf" ;;
|
||
|
7) [[ -e $MNT/etc/fstab ]] && file="$MNT/etc/fstab" ;;
|
||
|
8) [[ -e $MNT/etc/crypttab ]] && file="$MNT/etc/crypttab" ;;
|
||
|
9)
|
||
|
if [[ $BOOTLOADER == "systemd-boot" && -e $MNT/boot/loader/entries/archlabs.conf ]]; then
|
||
|
file="$MNT/boot/loader/entries/archlabs.conf"
|
||
|
elif [[ $BOOTLOADER == "syslinux" && -e $MNT/boot/syslinux/syslinux.cfg ]]; then
|
||
|
file="$MNT/boot/syslinux/syslinux.cfg"
|
||
|
elif [[ $BOOTLOADER == "grub" && -e $MNT/etc/default/grub ]]; then
|
||
|
file="$MNT/etc/default/grub"
|
||
|
fi
|
||
|
;;
|
||
|
10) [[ -e $MNT/etc/pacman.conf ]] && file="$MNT/etc/pacman.conf" ;;
|
||
|
*) return 0
|
||
|
esac
|
||
|
|
||
|
if [[ $file != "" ]]; then
|
||
|
if [[ $DISPLAY ]] && hash geany &>/dev/null; then
|
||
|
geany -i $file
|
||
|
else
|
||
|
vim -O $file
|
||
|
fi
|
||
|
else
|
||
|
msgbox "$_ErrTitle" "$_NoFileErr"
|
||
|
fi
|
||
|
|
||
|
# recurse back after each file edit finishes
|
||
|
edit_config_menu
|
||
|
}
|
||
|
|
||
|
for arg in $@; do
|
||
|
[[ $arg == "--debug" || $arg == "-d" ]] && set_debug
|
||
|
done
|
||
|
|
||
|
select_language
|
||
|
check_requirements
|
||
|
identify_system
|
||
|
|
||
|
# welcome message
|
||
|
msgbox "$_WelTitle $DIST Installer" "$_WelBody"
|
||
|
|
||
|
FIRST_RUN_PREP="False"
|
||
|
FIRST_RUN_CONFIG="False"
|
||
|
|
||
|
CURRENT_MENU="main"
|
||
|
|
||
|
MAIN_HIGHLIGHT=0
|
||
|
SUB_HIGHLIGHT=0
|
||
|
|
||
|
while true; do
|
||
|
main_menu
|
||
|
done
|