Change directory structure, separate sections of script into library files, add install script
This commit is contained in:
parent
a361e75c5e
commit
224ea1c18a
11
install.sh
Executable file
11
install.sh
Executable file
@ -0,0 +1,11 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
readonly SCRIPT_DIR="$(readlink -f ${0%/*})"
|
||||||
|
|
||||||
|
echo; echo "This requires root privileges"
|
||||||
|
sudo mkdir -pv /usr/share/archlabs/{docs,lib,lang}
|
||||||
|
sudo cp -fv $SCRIPT_DIR/src/archlabs-installer /usr/bin/
|
||||||
|
sudo cp -fv $SCRIPT_DIR/src/lib/*.sh /usr/share/archlabs/lib/
|
||||||
|
sudo cp -fv $SCRIPT_DIR/lang/*.trans /usr/share/archlabs/lang/
|
||||||
|
sudo cp -fv $SCRIPT_DIR/{LICENSE,README.md} /usr/share/archlabs/docs/
|
||||||
|
echo; echo "Install complete"
|
@ -66,6 +66,7 @@ _GenLocale="\nGenerating locale:"
|
|||||||
|
|
||||||
# error message
|
# error message
|
||||||
_ErrChoice="\nUnmount the partitions and shutdown or keep them mounted and continue?\n"
|
_ErrChoice="\nUnmount the partitions and shutdown or keep them mounted and continue?\n"
|
||||||
|
_ErrChoiceConsole="\nUnmount the partitions and exit to view the error log or keep them mounted and continue?\n"
|
||||||
|
|
||||||
# keyfile creation
|
# keyfile creation
|
||||||
_LuksKeyFileTitle="Create Encryption Keyfile"
|
_LuksKeyFileTitle="Create Encryption Keyfile"
|
File diff suppressed because it is too large
Load Diff
618
src/archlabs-installer
Executable file
618
src/archlabs-installer
Executable file
@ -0,0 +1,618 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# This program is free software, provided under the GNU GPL
|
||||||
|
|
||||||
|
# Written by Nathaniel Maia for use in Archlabs
|
||||||
|
# Some ideas and code were taken from other installers
|
||||||
|
# AIF, Cnichi, Calamares, The Arch Wiki.. Credit where credit is due
|
||||||
|
|
||||||
|
# dry run performing no action, good for checking syntax errors
|
||||||
|
# set -n
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
## Script Setup Functions ##
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# immutable variables {
|
||||||
|
|
||||||
|
readonly DIST="ArchLabs" # Linux distributor
|
||||||
|
readonly VER="1.6.54" # Installer version
|
||||||
|
readonly LIVE="liveuser" # Live session user
|
||||||
|
readonly MNT="/mnt/install" # Install mountpoint
|
||||||
|
readonly ERR="/tmp/errlog" # Built-in error log
|
||||||
|
readonly EFI="/sys/firmware/efi/efivars"
|
||||||
|
readonly LIB="/usr/share/archlabs/installer/lib"
|
||||||
|
readonly TRN="/usr/share/archlabs/installer/lang"
|
||||||
|
|
||||||
|
# hardware check
|
||||||
|
readonly VM="$(dmesg | grep -i "hypervisor")"
|
||||||
|
|
||||||
|
# create a regex string of all usb devices on the system
|
||||||
|
for dev in $(lsblk -lno NAME,TRAN | awk '/usb/ {print $1}'); do
|
||||||
|
USB_DEVS="${dev}$([[ $USB_DEVS ]] && echo -n "|$USB_DEVS")"
|
||||||
|
done
|
||||||
|
|
||||||
|
# determine which device was used for booting to ignore later during partition select
|
||||||
|
readonly IGNORE_DEV="$(lsblk -lno NAME,TYPE,TRAN,MOUNTPOINT |
|
||||||
|
awk "/$USB_DEVS/"' && /\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
|
||||||
|
readonly SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE,TRAN |
|
||||||
|
awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')"
|
||||||
|
readonly LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if($1) print $1 " -"}' /etc/locale.gen)"
|
||||||
|
readonly SYS_MEM=$(grep 'MemTotal' /proc/meminfo | awk '{print int($2 / 1024)}')
|
||||||
|
readonly DEV_COUNT="$(wc -l <<< "$SYS_DEVS")"
|
||||||
|
readonly KBD="$(find /usr/share/kbd/keymaps -name '*.map.gz')"
|
||||||
|
readonly CONSOLE_MAPS="$(awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " -"}' <<< "$KBD" | sort -r)"
|
||||||
|
|
||||||
|
# create associative array for SUBZONES[zone], value is: 'sub-zone country_code'
|
||||||
|
declare -Ag SUBZONES
|
||||||
|
for zone in America Australia Asia Atlantic Africa Europe Indian Pacific Arctic Antarctica; do
|
||||||
|
SUBZONES[$zone]="$(awk "/$zone\// {gsub(/$zone\//, \"\"); print \$3 \" \"\$1}" /usr/share/zoneinfo/zone.tab)"
|
||||||
|
done
|
||||||
|
readonly SUBZONES # make it read only
|
||||||
|
|
||||||
|
if [[ $DISPLAY && $TERM != 'linux' ]]; then
|
||||||
|
for t in st termite xterm; do
|
||||||
|
hash $t >/dev/null 2>&1 && { readonly TERM_CMD="$t"; break; }
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
# static string of keymap codes and respective language
|
||||||
|
readonly KEYMAPS="us English cm English gb English au English gh English za English
|
||||||
|
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=(
|
||||||
|
[UEFI-grub]="/boot/efi" [UEFI-systemd-boot]="/boot" [BIOS-grub]="/boot"
|
||||||
|
[BIOS-syslinux]="/boot" [UEFI-syslinux]="/boot"
|
||||||
|
)
|
||||||
|
|
||||||
|
# static list of bootloaders & boot partition mountpoints stored as the system type (BIOS or UEFI)
|
||||||
|
declare -Agr BOOTLOADERS=([BIOS]="grub ${BOOT_MNTS[BIOS-grub]} syslinux ${BOOT_MNTS[BIOS-syslinux]}"
|
||||||
|
[UEFI]="grub ${BOOT_MNTS[UEFI-grub]} systemd-boot ${BOOT_MNTS[UEFI-systemd-boot]} syslinux ${BOOT_MNTS[UEFI-syslinux]}"
|
||||||
|
)
|
||||||
|
|
||||||
|
# static mkfs commands for each filesystem offered
|
||||||
|
declare -Agr FS_CMDS=(
|
||||||
|
[ext2]="mkfs.ext2 -q" [ext3]="mkfs.ext3 -q" [ext4]="mkfs.ext4 -q"
|
||||||
|
[f2fs]="mkfs.f2fs" [jfs]="mkfs.jfs -q" [xfs]="mkfs.xfs -f" [nilfs2]="mkfs.nilfs2 -q"
|
||||||
|
[ntfs]="mkfs.ntfs -q" [reiserfs]="mkfs.reiserfs -q" [vfat]="mkfs.vfat -F32"
|
||||||
|
)
|
||||||
|
|
||||||
|
# static filesystem mount options
|
||||||
|
declare -Agr FS_OPTS=([vfat]="" [ntfs]="" [ext2]="" [ext3]=""
|
||||||
|
[ext4]="dealloc - off discard - off nofail - off noacl - off relatime - off noatime - off nobarrier - off nodelalloc - off"
|
||||||
|
[jfs]="discard - off errors=continue - off errors=panic - off nointegrity - off"
|
||||||
|
[reiserfs]="acl - off nolog - off notail - off replayonly - off user_xattr - off"
|
||||||
|
[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"
|
||||||
|
[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"
|
||||||
|
)
|
||||||
|
# }
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
# Some may never be used, depending on the system and choices made
|
||||||
|
|
||||||
|
declare -g BT="$DIST Installer - (x86_64) - Version $VER"
|
||||||
|
declare -g ROOT_PART=""
|
||||||
|
declare -g BOOT_DEVICE=""
|
||||||
|
declare -g BOOT_PART=""
|
||||||
|
declare -g BOOTLOADER=""
|
||||||
|
declare -g EXTRA_MNT=""
|
||||||
|
declare -g SWAP="none"
|
||||||
|
declare -g SWAP_SIZE="${SYS_MEM}M"
|
||||||
|
declare -g KERNEL="linux"
|
||||||
|
declare -g NEWUSER=""
|
||||||
|
declare -g USER_PASS=""
|
||||||
|
declare -g ROOT_PASS=""
|
||||||
|
declare -g LOGIN_WM=""
|
||||||
|
declare -g LOGIN_TYPE=""
|
||||||
|
declare -g INSTALL_WMS=""
|
||||||
|
declare -g WM_PACKAGES=""
|
||||||
|
declare -g EXTRA_PACKAGES=""
|
||||||
|
declare -g REMOVE_PKGS=""
|
||||||
|
declare -g CURRENT_MENU=""
|
||||||
|
declare -g MENU_HIGHLIGHT
|
||||||
|
declare -g EDITOR_CHOICE=""
|
||||||
|
declare -g MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate"
|
||||||
|
|
||||||
|
# boolean checks
|
||||||
|
declare -g AUTOLOGIN=false
|
||||||
|
declare -g CONFIG_DONE=false
|
||||||
|
declare -g IS_64BIT=false
|
||||||
|
|
||||||
|
# Commands used to install each bootloader.
|
||||||
|
# NOTE: syslinux and grub in particular can/will change during runtime
|
||||||
|
declare -Ag BOOT_CMDS=(
|
||||||
|
[syslinux]="syslinux-install_update -iam"
|
||||||
|
[grub]="grub-install --recheck --force"
|
||||||
|
[systemd-boot]="bootctl --path=${BOOT_MNTS[UEFI-systemd-boot]} install"
|
||||||
|
)
|
||||||
|
|
||||||
|
# files able to be reviewed when finishing install
|
||||||
|
# item index [9] can change depending on which bootloader is selected
|
||||||
|
declare -Ag EDIT_FILES=(
|
||||||
|
[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"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
source_file() {
|
||||||
|
source $1 2>/dev/null && return 0
|
||||||
|
echo -e "\nFailed to source library file $1"
|
||||||
|
die 1
|
||||||
|
}
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
## System Setup Functions ##
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
select_language() {
|
||||||
|
tput civis
|
||||||
|
local lang
|
||||||
|
lang=$(dialog --cr-wrap --stdout --backtitle "$BT" --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_file $TRN/english.trans
|
||||||
|
declare -g FONT="ter-i18n"
|
||||||
|
|
||||||
|
case $lang in
|
||||||
|
1) LOC="en_US.UTF-8" ;;
|
||||||
|
2) source_file $TRN/spanish.trans && LOC="es_ES.UTF-8" ;;
|
||||||
|
3) source_file $TRN/p_brasil.trans && LOC="pt_BR.UTF-8" ;;
|
||||||
|
4) source_file $TRN/portuguese.trans && LOC="pt_PT.UTF-8" ;;
|
||||||
|
5) source_file $TRN/french.trans && LOC="fr_FR.UTF-8" ;;
|
||||||
|
6) source_file $TRN/russian.trans && LOC="ru_RU.UTF-8" FONT="LatKaCyrHeb-14" ;;
|
||||||
|
7) source_file $TRN/italian.trans && LOC="it_IT.UTF-8" ;;
|
||||||
|
8) source_file $TRN/dutch.trans && LOC="nl_NL.UTF-8" ;;
|
||||||
|
9) source_file $TRN/hungarian.trans && LOC="hu_HU.UTF-8" FONT="lat2-16" ;;
|
||||||
|
10) source_file $TRN/chinese.trans && LOC="zh_CN.UTF-8" ;;
|
||||||
|
*) die 0
|
||||||
|
esac
|
||||||
|
|
||||||
|
sed -i "s/#en_US.UTF-8/en_US.UTF-8/" /etc/locale.gen
|
||||||
|
|
||||||
|
if [[ $LOC != "en_US.UTF-8" ]]; then
|
||||||
|
sed -i "s/#${LOC}/${LOC}/" /etc/locale.gen
|
||||||
|
locale-gen >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
setfont $FONT >/dev/null 2>&1
|
||||||
|
export LANG="$LOC"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_keymap() {
|
||||||
|
tput civis
|
||||||
|
declare -g KEYMAP
|
||||||
|
KEYMAP="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
|
||||||
|
--title " $_PrepLayout " --menu "$_XMapBody" 20 70 12 $KEYMAPS)"
|
||||||
|
[[ $? != 0 || $KEYMAP == "" ]] && return 1
|
||||||
|
|
||||||
|
# when a matching console map is not available open a selection dialog
|
||||||
|
if ! [[ $CONSOLE_MAPS =~ "$KEYMAP -" ]]; then
|
||||||
|
tput civis
|
||||||
|
CONSOLE_MAP="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
|
||||||
|
--title " $_CMapTitle " --menu "$_CMapBody" 20 70 12 $CONSOLE_MAPS)"
|
||||||
|
[[ $? != 0 || $CONSOLE_MAP == "" ]] && return 1
|
||||||
|
else
|
||||||
|
CONSOLE_MAP="$KEYMAP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
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
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_locale() {
|
||||||
|
tput civis
|
||||||
|
declare -g LOCALE
|
||||||
|
LOCALE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
|
||||||
|
--title " $_ConfLocale " --menu "$_LocaleBody" 25 70 12 $LOCALES)"
|
||||||
|
[[ $? != 0 || $LOCALE == "" ]] && return 1 || return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_timezone() {
|
||||||
|
tput civis
|
||||||
|
declare -g ZONE
|
||||||
|
ZONE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
|
||||||
|
--title " $_TimeZTitle " --menu "$_TimeZBody" 20 70 10 America - Australia - \
|
||||||
|
Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica -)"
|
||||||
|
declare -g SUBZONE
|
||||||
|
SUBZONE="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
|
||||||
|
--title " $_TimeZTitle " --menu "$_TimeSubZBody" 20 70 12 ${SUBZONES[$ZONE]})"
|
||||||
|
|
||||||
|
yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n" && return 0 || setup_timezone
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_hostname() {
|
||||||
|
tput cnorm
|
||||||
|
declare -g HOSTNAME
|
||||||
|
HOSTNAME="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")"
|
||||||
|
[[ $? != 0 || $HOSTNAME == "" ]] && return 1 || return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
user_setup() {
|
||||||
|
tput cnorm
|
||||||
|
|
||||||
|
local values
|
||||||
|
values="$(dialog --stdout --no-cancel --separator '~' --ok-label "Submit" --backtitle "$BT" \
|
||||||
|
--title " $_UserTitle " --insecure --mixedform "$_UserBody" 27 75 10 \
|
||||||
|
"$_Username" 1 1 "" 1 $((${#_Username} + 2)) 71 0 0 \
|
||||||
|
"$_Password" 2 1 "" 2 $((${#_Password} + 2)) 71 0 1 \
|
||||||
|
"$_Password2" 3 1 "" 3 $((${#_Password2} + 2)) 71 0 1 \
|
||||||
|
"$_RootBody" 6 1 "" 6 $((${#_RootBody} + 1)) 71 0 2 \
|
||||||
|
"$_Password" 8 1 "" 8 $((${#_Password} + 2)) 71 0 1 \
|
||||||
|
"$_Password2" 9 1 "" 9 $((${#_Password2} + 2)) 71 0 1)"
|
||||||
|
[[ $? != 0 || $values == "" ]] && return 1
|
||||||
|
|
||||||
|
local user
|
||||||
|
user="$(awk -F'~' '{print $1}' <<< "$values")"
|
||||||
|
local pass pass2
|
||||||
|
pass="$(awk -F'~' '{print $2}' <<< "$values")"
|
||||||
|
pass2="$(awk -F'~' '{print $3}' <<< "$values")"
|
||||||
|
local rpass rpass2
|
||||||
|
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"; }
|
||||||
|
|
||||||
|
# make sure a username was entered and that the passwords match
|
||||||
|
if [[ ${#user} -eq 0 || $user =~ \ |\' || $user =~ [^a-z0-9\ ] || $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
|
||||||
|
if [[ $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
|
||||||
|
# password was left empty or doesn't match
|
||||||
|
if [[ $pass == "" ]]; then
|
||||||
|
msgbox "$_ErrTitle" "\nUser $_Password CANNOT be left empty.\n$_TryAgain"
|
||||||
|
elif [[ "$rpass" != "$rpass2" ]]; then
|
||||||
|
msgbox "$_ErrTitle" "$_RootPassErr\n$_TryAgain"
|
||||||
|
else
|
||||||
|
msgbox "$_ErrTitle" "$_UserPassErr\n$_TryAgain"
|
||||||
|
fi
|
||||||
|
else # bad username
|
||||||
|
msgbox "$_UserErrTitle" "$_UserErrBody"
|
||||||
|
user=""
|
||||||
|
fi
|
||||||
|
# recursively loop back unless the user cancels
|
||||||
|
user_setup || return 1
|
||||||
|
else
|
||||||
|
NEWUSER="$user"
|
||||||
|
USER_PASS="$pass"
|
||||||
|
ROOT_PASS="$rpass"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
window_manager() {
|
||||||
|
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 \
|
||||||
|
"dwm" "A customized fork of dwm, with patches and modifications" off \
|
||||||
|
"gnome" "A desktop environment that aims to be simple and easy to use" off \
|
||||||
|
"cinnamon" "A desktop environment combining a traditional desktop layout with modern graphical effects" off \
|
||||||
|
"xfce4" "A lightweight and modular desktop environment based on GTK+ 2 and 3" off)"
|
||||||
|
|
||||||
|
INSTALL_WMS="${INSTALL_WMS:-openbox}"
|
||||||
|
WM_NUM=$(awk '{print NF}' <<< "$INSTALL_WMS")
|
||||||
|
|
||||||
|
# if dwm is not the only WM chosen offer lightdm
|
||||||
|
if yesno "$_WMLogin" "$_LoginTypeBody\n" "xinit" "lightdm"; then
|
||||||
|
LOGIN_TYPE='lightdm'
|
||||||
|
else
|
||||||
|
LOGIN_TYPE='xinit'
|
||||||
|
fi
|
||||||
|
|
||||||
|
if yesno "$_WMLogin" "$_AutoLoginBody\n"; then
|
||||||
|
AUTOLOGIN=true
|
||||||
|
else
|
||||||
|
AUTOLOGIN=false
|
||||||
|
fi
|
||||||
|
|
||||||
|
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")"
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $LOGIN_WM in
|
||||||
|
i3-gaps) LOGIN_WM='i3' ;;
|
||||||
|
gnome) LOGIN_WM='gnome-session' ;;
|
||||||
|
cinnamon) LOGIN_WM='cinnamon-session' ;;
|
||||||
|
openbox) LOGIN_WM='openbox-session' ;;
|
||||||
|
xfce4) LOGIN_WM='startxfce4' ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
extra_packages() {
|
||||||
|
EXTRA_PACKAGES="$(dialog --cr-wrap --stdout --no-cancel --backtitle "$BT" \
|
||||||
|
--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 \
|
||||||
|
"epiphany" "A GNOME web browser based on the WebKit rendering engine" off \
|
||||||
|
"qutebrowser" "A keyboard-focused vim-like web browser based on Python and PyQt5" off \
|
||||||
|
"atom" "An open-source text editor developed by GitHub that is licensed under the MIT License" off \
|
||||||
|
"geany" "A fast and lightweight IDE" off \
|
||||||
|
"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 \
|
||||||
|
"termite" "A minimal VTE-based 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 based in the Xfce Desktop Environment" off \
|
||||||
|
"thunar" "A modern file manager for the Xfce Desktop Environment" off \
|
||||||
|
"pcmanfm" "A fast and lightweight file manager based in Lxde" 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 \
|
||||||
|
"mpd mpc" "Flexible, powerful, server-side application for playing music" off \
|
||||||
|
"ncmpcpp" "An mpd client and almost exact clone of ncmpc with some new features" off \
|
||||||
|
"cmus" "A small, fast and powerful console music player for Unix-like operating systems" off \
|
||||||
|
"audacious" "A free and advanced audio player based on GTK+" off \
|
||||||
|
"nicotine+" "A graphical client for Soulseek" off \
|
||||||
|
"lollypop" "A new music playing application" off \
|
||||||
|
"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 \
|
||||||
|
"evince" "A document viewer" off \
|
||||||
|
"zathura zathura-pdf-poppler" "Minimalistic document viewer" off \
|
||||||
|
"qpdfview" "A tabbed PDF viewer" off \
|
||||||
|
"mupdf mupdf-tools" "Lightweight PDF and XPS viewer" off \
|
||||||
|
"gpicview" "Lightweight image viewer" off \
|
||||||
|
"gimp" "GNU Image Manipulation Program" off \
|
||||||
|
"inkscape" "Professional vector graphics editor" off \
|
||||||
|
"krita" "Edit and paint images" off \
|
||||||
|
"simplescreenrecorder" "A feature-rich screen recorder" off \
|
||||||
|
"obs-studio" "Free opensource streaming/recording software" off \
|
||||||
|
"openshot" "An open-source, non-linear video editor for Linux based on MLT framework" off \
|
||||||
|
"kdenlive" "A non-linear video editor for Linux using the MLT video framework" off \
|
||||||
|
"audacity" "A program that lets you manipulate digital audio waveforms" off \
|
||||||
|
"guvcview" "Capture video from camera devices" off \
|
||||||
|
"gpick" "Advanced color picker using GTK+ toolkit" off \
|
||||||
|
"gcolor2" "A simple GTK+2 color selector" off \
|
||||||
|
"plank" "An elegant, simple, and clean dock" off \
|
||||||
|
"docky" "Full fledged dock that makes opening common applications and managing windows faster and easier" off \
|
||||||
|
"cairo-dock cairo-dock-plug-ins" "Light eye-candy fully themable animated dock" off \
|
||||||
|
"qt5-styleplugins qt5ct" "GUI for managing Qt based application themes, icons, and fonts" off \
|
||||||
|
"ttf-hack" "A hand groomed and optically balanced typeface based on Bitstream Vera Mono" off \
|
||||||
|
"ttf-anonymous-pro" "A family of four fixed-width fonts designed especially with coding in mind" off \
|
||||||
|
"ttf-font-awesome" "Iconic font designed for Bootstrap" off \
|
||||||
|
"ttf-fira-code" "Monospaced font with programming ligatures" off \
|
||||||
|
"noto-fonts-cjk" "Google Noto CJK fonts (Chinese, Japanese, Korean)" off \
|
||||||
|
"noto-fonts 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 ! [[ $VM ]] && ! yesno 'Choose Kernel' "\nUse the current Linux kernel or the LTS kernel?\n" 'Current' 'LTS'; then
|
||||||
|
KERNEL='linux-lts'
|
||||||
|
else
|
||||||
|
KERNEL='linux'
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mirrorlist_cmd() {
|
||||||
|
MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate"
|
||||||
|
yesno "$_MirrorTitle" "$_MirrorSetup" "Automatic" "Custom" && 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")"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
## Main Menu Functions ##
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
edit_configs() {
|
||||||
|
if [[ $CURRENT_MENU != "edit" ]]; then
|
||||||
|
MENU_HIGHLIGHT=1
|
||||||
|
CURRENT_MENU="edit"
|
||||||
|
elif (( MENU_HIGHLIGHT < 10 )); then
|
||||||
|
((MENU_HIGHLIGHT++))
|
||||||
|
fi
|
||||||
|
|
||||||
|
tput civis
|
||||||
|
MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_EditTitle " --default-item $MENU_HIGHLIGHT --menu "$_EditBody" 0 0 0 \
|
||||||
|
"1" "$_Done" "2" "keyboard" "3" "language + 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=""
|
||||||
|
|
||||||
|
for f in $(echo "${EDIT_FILES[$MENU_HIGHLIGHT]}"); do
|
||||||
|
[[ -e ${MNT}$f ]] && existing_files="$existing_files ${MNT}$f"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $existing_files != "" ]]; then
|
||||||
|
if [[ $DISPLAY && $TERM != 'linux' ]] && hash geany >/dev/null 2>&1; then
|
||||||
|
geany -i $existing_files
|
||||||
|
else
|
||||||
|
vim -O $existing_files
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
msgbox "$_ErrTitle" "$_NoFileErr"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
edit_configs
|
||||||
|
}
|
||||||
|
|
||||||
|
configure_install() {
|
||||||
|
# whether to use a custom mirror sorting command later
|
||||||
|
setup_hostname || return 1
|
||||||
|
setup_locale || return 1
|
||||||
|
setup_timezone || return 1
|
||||||
|
user_setup || return 1
|
||||||
|
mirrorlist_cmd || return 1
|
||||||
|
window_manager || return 1
|
||||||
|
extra_packages || return 1
|
||||||
|
choose_kernel
|
||||||
|
CONFIG_DONE=true
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local retval
|
||||||
|
|
||||||
|
if [[ $CURRENT_MENU != "main" ]]; then
|
||||||
|
MENU_HIGHLIGHT=1
|
||||||
|
CURRENT_MENU="main"
|
||||||
|
elif (( MENU_HIGHLIGHT < 8 )); then
|
||||||
|
((MENU_HIGHLIGHT++)) # increment the highlighted menu item
|
||||||
|
fi
|
||||||
|
|
||||||
|
tput civis
|
||||||
|
MENU_HIGHLIGHT=$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepTitle " --default-item $MENU_HIGHLIGHT --menu "$_PrepBody" 0 0 0 \
|
||||||
|
"1" "$_PrepShowDev" "2" "$_PrepParts" "3" "$_PrepLUKS" "4" "$_PrepLVM" \
|
||||||
|
"5" "$_PrepMount" "6" "$_PrepConfig" "7" "$_PrepInstall" "8" "$_Done")
|
||||||
|
|
||||||
|
# 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
|
||||||
|
retval=$?
|
||||||
|
[[ $retval -gt 0 ]] && { MENU_HIGHLIGHT=$retval; return 1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
case $MENU_HIGHLIGHT in
|
||||||
|
1) show_devices ;;
|
||||||
|
2) edit_partitions ;;
|
||||||
|
3) luks_menu || MENU_HIGHLIGHT=1 ;;
|
||||||
|
4) lvm_menu || MENU_HIGHLIGHT=1 ;;
|
||||||
|
5) mount_main || MENU_HIGHLIGHT=1 ;;
|
||||||
|
6) configure_install ;;
|
||||||
|
7) install_main && edit_configs ;;
|
||||||
|
*) wrap_up "$_CloseInstBody" 'Exit' 'Back' 'exit'
|
||||||
|
esac
|
||||||
|
}
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
## Execution ##
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
# source the library files before anything else to get access to functions
|
||||||
|
for file in utils.sh mount.sh partition.sh bootloader.sh package.sh lvm.sh luks.sh install.sh; do
|
||||||
|
source_file $LIB/$file
|
||||||
|
done
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
for arg in "$@"; do
|
||||||
|
[[ $arg == "--debug" || $arg == "-d" ]] && debug # from $LIB/utils.sh
|
||||||
|
done
|
||||||
|
|
||||||
|
initialize_variables
|
||||||
|
luks_variable_init
|
||||||
|
select_language
|
||||||
|
setup_keymap
|
||||||
|
|
||||||
|
check_requirements
|
||||||
|
identify_system
|
||||||
|
|
||||||
|
msgbox "$_WelTitle $DIST Installer" "$_WelBody"
|
||||||
|
|
||||||
|
while true; do
|
||||||
|
main
|
||||||
|
done
|
223
src/lib/bootloader.sh
Normal file
223
src/lib/bootloader.sh
Normal file
@ -0,0 +1,223 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
select_boot_setup() {
|
||||||
|
# choose bootloader and by extension mountpoint (if needed)
|
||||||
|
tput civis
|
||||||
|
BOOTLOADER="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepMount " --menu "$_MntBootBody" 0 0 0 ${BOOTLOADERS[$SYS]})"
|
||||||
|
[[ $? != 0 || $BOOTLOADER == "" ]] && return 1
|
||||||
|
|
||||||
|
if [[ $SYS == 'BIOS' && $BOOTLOADER == 'grub' && $BOOT_DEVICE == "" ]]; then
|
||||||
|
# grub on BIOS needs an install device, NOT partition eg. /dev/sda
|
||||||
|
select_device 'boot' || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $BOOTLOADER == 'systemd-boot' ]]; then
|
||||||
|
EDIT_FILES[9]="/boot/loader/entries/$DIST.conf"
|
||||||
|
elif [[ $BOOTLOADER == 'syslinux' && $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
|
||||||
|
else
|
||||||
|
EDIT_FILES[9]="/etc/default/grub"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
shim_secure_boot() {
|
||||||
|
# still a W.I.P
|
||||||
|
|
||||||
|
local shim_file="shim64.efi"
|
||||||
|
[[ $IS_64BIT != true ]] && shim_file="shim.efi"
|
||||||
|
efibootmgr -c -w -L $DIST -d $BOOT_DEVICE -p $BOOT_PART_NUM -l ${MNT}${BOOT_MNTS[$SYS-$BOOTLOADER]}/$shim_file
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
uefi_boot_fallback() {
|
||||||
|
# some UEFI firmware is finicky and requires a specific folder in
|
||||||
|
# /boot/efi/EFI/ and named 'boot', 'Boot', or 'BOOT'
|
||||||
|
# copy the bootloaders efi stub to that directory as bootx64.efi
|
||||||
|
|
||||||
|
local default="boot"
|
||||||
|
local esp="${MNT}${BOOT_MNTS[$SYS-$BOOTLOADER]}"
|
||||||
|
for i in $(find "$esp/EFI/" -maxdepth 1 -mindepth 1 -type d 2>/dev/null); do
|
||||||
|
grep -qi "boot" <<< "$(basename $i)" && { default="$(basename $i)"; break; }
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ -d $esp/EFI/$default ]]; then
|
||||||
|
rm -f $esp/EFI/$default/*
|
||||||
|
else
|
||||||
|
mkdir -p $esp/EFI/$default
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $1 == 'syslinux' ]]; then
|
||||||
|
cp -rf $esp/EFI/$1/* $esp/EFI/$default/
|
||||||
|
cp -f $esp/EFI/$1/syslinux.efi $esp/EFI/$default/bootx64.efi
|
||||||
|
else
|
||||||
|
local grub_file="grubx64.efi"
|
||||||
|
local boot_file="bootx64.efi"
|
||||||
|
if [[ $IS_64BIT != true ]]; then
|
||||||
|
local grub_file="grubia32.efi"
|
||||||
|
local boot_file="bootia32.efi"
|
||||||
|
fi
|
||||||
|
cp -f $esp/EFI/$1/$grub_file $esp/EFI/$default/$boot_file
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prep_for_grub() {
|
||||||
|
local cfg="$MNT/etc/default/grub"
|
||||||
|
|
||||||
|
if [[ $SYS == 'UEFI' ]]; then
|
||||||
|
local gtype='x86_64-efi'
|
||||||
|
[[ $IS_64BIT != true ]] && gtype='i386-efi'
|
||||||
|
BOOT_CMDS[grub]="${BOOT_CMDS[grub]} --target=$gtype --bootloader-id=$DIST"
|
||||||
|
else
|
||||||
|
BOOT_CMDS[grub]="${BOOT_CMDS[grub]} --target=i386-pc $BOOT_DEVICE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
BOOT_CMDS[grub]="${BOOT_CMDS[grub]} && grub-mkconfig -o /boot/grub/grub.cfg"
|
||||||
|
|
||||||
|
sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g;
|
||||||
|
s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $cfg
|
||||||
|
|
||||||
|
if (( LUKS == 1 )); then
|
||||||
|
sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
|
||||||
|
s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $cfg
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $SYS != 'UEFI' && $LVM -eq 1 && $SEPERATE_BOOT -eq 0 ]]; then
|
||||||
|
sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" $cfg
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prep_for_systemd-boot() {
|
||||||
|
# create the boot entry configs
|
||||||
|
mkdir -p $MNT/boot/loader/entries
|
||||||
|
cat > $MNT/boot/loader/loader.conf << EOF
|
||||||
|
default $DIST
|
||||||
|
timeout 5
|
||||||
|
editor no
|
||||||
|
EOF
|
||||||
|
cat > $MNT/boot/loader/entries/${DIST}.conf << EOF
|
||||||
|
title $DIST Linux
|
||||||
|
linux /vmlinuz-${KERNEL}$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] && echo -en "\ninitrd /intel-ucode.img")
|
||||||
|
initrd /initramfs-$KERNEL.img
|
||||||
|
options root=$ROOT_PART_ID $([[ $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 update
|
||||||
|
EOF
|
||||||
|
# systemd-boot requires this before running bootctl
|
||||||
|
systemd-machine-id-setup --root="$MNT" >/dev/null 2>&1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
prep_for_syslinux() {
|
||||||
|
local cfgdir="$MNT/boot/syslinux"
|
||||||
|
local cfgsrcdir="/usr/lib/syslinux/bios/"
|
||||||
|
EDIT_FILES[9]="/boot/syslinux/syslinux.cfg"
|
||||||
|
|
||||||
|
if [[ $SYS == 'UEFI' ]]; then
|
||||||
|
EDIT_FILES[9]="/boot/EFI/syslinux/syslinux.cfg"
|
||||||
|
BOOT_CMDS[syslinux]="efibootmgr -c -d $BOOT_DEVICE -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST"
|
||||||
|
cfgdir="$MNT/boot/EFI/syslinux"
|
||||||
|
cfgsrcdir="/usr/lib/syslinux/efi64/"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p $cfgdir
|
||||||
|
cp -r $cfgsrcdir $cfgdir/
|
||||||
|
cat > $cfgdir/syslinux.cfg << EOF
|
||||||
|
UI menu.c32
|
||||||
|
PROMPT 0
|
||||||
|
|
||||||
|
MENU TITLE $DIST Syslinux Boot Menu
|
||||||
|
TIMEOUT 50
|
||||||
|
DEFAULT $DIST
|
||||||
|
|
||||||
|
LABEL $DIST
|
||||||
|
MENU LABEL $DIST Linux
|
||||||
|
LINUX ../vmlinuz-$KERNEL
|
||||||
|
APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw
|
||||||
|
INITRD ../initramfs-$KERNEL.img
|
||||||
|
$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] && echo -en "\ninitrd /intel-ucode.img")
|
||||||
|
|
||||||
|
LABEL ${DIST}fallback
|
||||||
|
MENU LABEL $DIST Linux Fallback
|
||||||
|
LINUX ../vmlinuz-$KERNEL
|
||||||
|
APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && echo -n "$LUKS_DEV ")rw
|
||||||
|
INITRD ../initramfs-$KERNEL-fallback.img
|
||||||
|
$([[ $(grep 'GenuineIntel' /proc/cpuinfo) && -e $MNT/boot/intel-ucode.img ]] && echo -en "\ninitrd /intel-ucode.img")
|
||||||
|
EOF
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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"
|
||||||
|
echo -e "$msg\nMountpoint: ${BOOT_MNTS[$SYS-$BOOTLOADER]}\n"
|
||||||
|
|
||||||
|
# if not on an LVM we can use the UUID for booting
|
||||||
|
if ! [[ $ROOT_PART =~ /dev/mapper ]]; then
|
||||||
|
ROOT_PART_ID="UUID=$(blkid -s PARTUUID $ROOT_PART | sed 's/.*=//g; s/"//g')"
|
||||||
|
[[ $BOOTLOADER == 'systemd-boot' ]] && ROOT_PART_ID="PART$ROOT_PART_ID"
|
||||||
|
else
|
||||||
|
# for LVM use the partition name eg. /dev/mapper/cryptroot
|
||||||
|
ROOT_PART_ID="$ROOT_PART"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# needed for os-prober module to work properly in the chroot
|
||||||
|
mkdir -p /run/udev && mount --bind /run/udev /run/udev >/dev/null 2>&1
|
||||||
|
BOOT_CMDS[$BOOTLOADER]="mkdir -p /run/udev && mount --bind /run/udev /run/udev ; ${BOOT_CMDS[$BOOTLOADER]}"
|
||||||
|
|
||||||
|
if [[ $SYS == 'UEFI' ]]; then
|
||||||
|
# make sure efivarfs has been mounted
|
||||||
|
mount -o remount,rw -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
|
||||||
|
BOOT_CMDS[$BOOTLOADER]="mount -o remount,rw -t efivarfs efivarfs /sys/firmware/efi/efivars ; ${BOOT_CMDS[$BOOTLOADER]}"
|
||||||
|
|
||||||
|
# remove old boot entries
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
|
||||||
|
# sets up the bootloader config(s) and ${BOOT_CMDS[$BOOTLOADER]}
|
||||||
|
prep_for_$BOOTLOADER
|
||||||
|
|
||||||
|
# run the bootloader command
|
||||||
|
chroot_cmd "${BOOT_CMDS[$BOOTLOADER]}"
|
||||||
|
check_for_errors "${BOOT_CMDS[$BOOTLOADER]}"
|
||||||
|
|
||||||
|
if [[ $SYS == 'UEFI' && $BOOTLOADER =~ (grub|syslinux) ]]; then
|
||||||
|
local boot_dir="$DIST"
|
||||||
|
[[ $BOOTLOADER == 'syslinux' ]] && boot_dir="syslinux"
|
||||||
|
|
||||||
|
# copy efi stub to generic catch all
|
||||||
|
uefi_boot_fallback "$boot_dir"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
215
src/lib/install.sh
Normal file
215
src/lib/install.sh
Normal file
@ -0,0 +1,215 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
install_main() {
|
||||||
|
# this assumes all needed variables/settings are setup as needed
|
||||||
|
# no additional user confirmation are performed aside from what is needed
|
||||||
|
|
||||||
|
# unpack the whole filesystem to install directory $MNT
|
||||||
|
oneshot install_base
|
||||||
|
|
||||||
|
genfstab -U $MNT > $MNT/etc/fstab 2>$ERR
|
||||||
|
check_for_errors "genfstab -U $MNT > $MNT/etc/fstab"
|
||||||
|
|
||||||
|
# touch up fstab if we used a swapfile
|
||||||
|
if [[ -f $MNT/swapfile ]]; then
|
||||||
|
sed -i "s~${MNT}~~" $MNT/etc/fstab 2>$ERR
|
||||||
|
check_for_errors "sed -i s~${MNT}~~ $MNT/etc/fstab"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# run package operations before bootloader and mkinitcpio
|
||||||
|
# due to the possibility of choosing lts kernel earlier
|
||||||
|
oneshot update_mirrorlist
|
||||||
|
oneshot update_system
|
||||||
|
oneshot install_packages
|
||||||
|
[[ $LOGIN_TYPE == 'lightdm' ]] && oneshot setup_lightdm
|
||||||
|
|
||||||
|
run_mkinitcpio || return 1
|
||||||
|
install_bootloader || return 1
|
||||||
|
|
||||||
|
oneshot set_hwclock
|
||||||
|
oneshot create_user || return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
install_base() {
|
||||||
|
# unpack the main system
|
||||||
|
tput cnorm
|
||||||
|
clear && echo -e "\nUnpacking base filesystem..\n\n"
|
||||||
|
rsync -ah --info=progress2 /run/archiso/sfs/airootfs/ $MNT/
|
||||||
|
|
||||||
|
# remove archiso init files
|
||||||
|
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}
|
||||||
|
|
||||||
|
# cleanup system permissions
|
||||||
|
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
|
||||||
|
|
||||||
|
# for virtual machines remove configs for xorg, these cause mouse issues
|
||||||
|
[[ $VM ]] && 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
|
||||||
|
cp -rf /etc/NetworkManager/system-connections $MNT/etc/NetworkManager/
|
||||||
|
cp -f /etc/resolv.conf $MNT/etc/
|
||||||
|
|
||||||
|
# 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
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
create_user() {
|
||||||
|
echo -e "\nSetting root password\n"
|
||||||
|
chroot_cmd "echo 'root:$ROOT_PASS' | chpasswd"
|
||||||
|
|
||||||
|
echo -e "$_UserSetBody"
|
||||||
|
# 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
|
||||||
|
groups="$groups,nopasswdlogin"
|
||||||
|
elif [[ $AUTOLOGIN == true ]]; then
|
||||||
|
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"
|
||||||
|
chroot_cmd "usermod -aG $groups $NEWUSER"
|
||||||
|
chroot_cmd "echo '$NEWUSER:$USER_PASS' | chpasswd"
|
||||||
|
chroot_cmd "chown -Rf $NEWUSER:users /home/$NEWUSER"
|
||||||
|
|
||||||
|
setup_user_home
|
||||||
|
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}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
set_hwclock() {
|
||||||
|
chroot_cmd "hwclock --systohc --utc"
|
||||||
|
[[ $? != 0 ]] && chroot_cmd "hwclock --systohc --utc --directisa"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
update_mirrorlist() {
|
||||||
|
echo -e "\nSorting the mirrorlist..\n"
|
||||||
|
$MIRROR_CMD --verbose --save $MNT/etc/pacman.d/mirrorlist && return 0
|
||||||
|
echo -e "\nAn error occurred while updating the mirrorlist.\n\nFalling back to automatic sorting...\n"
|
||||||
|
reflector --score 100 -l 50 -f 10 --sort rate --verbose --save $MNT/etc/pacman.d/mirrorlist
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
run_mkinitcpio() {
|
||||||
|
local conf="$MNT/etc/mkinitcpio.conf"
|
||||||
|
local add
|
||||||
|
|
||||||
|
# setup a keyfile for LUKS.. Only when choosing grub and system is UEFI
|
||||||
|
if [[ $LUKS -eq 1 && $SYS == 'UEFI' && $BOOTLOADER == 'grub' && $LUKS_PASS && $LUKS_UUID ]]; then
|
||||||
|
luks_keyfile || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
tput civis
|
||||||
|
chroot_cmd "mkinitcpio -p $KERNEL" 2>$ERR
|
||||||
|
check_for_errors "mkinitcpio -p $KERNEL"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
185
src/lib/luks.sh
Normal file
185
src/lib/luks.sh
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
luks_open() {
|
||||||
|
LUKS_PART=""
|
||||||
|
modprobe -a dm-mod dm_crypt
|
||||||
|
unmount_partitions
|
||||||
|
find_partitions 'part|crypt|lvm' || return 1
|
||||||
|
tput civis
|
||||||
|
|
||||||
|
if (( COUNT == 1 )); then
|
||||||
|
LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
|
||||||
|
infobox "$_LuksOpen" "${_OnlyOne}: $LUKS_PART\n" 1
|
||||||
|
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
|
||||||
|
|
||||||
|
# get password and name for encryption
|
||||||
|
luks_pass "$_LuksOpen" "$LUKS_NAME" || return 1
|
||||||
|
|
||||||
|
infobox "$_LuksOpen" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0
|
||||||
|
echo "$LUKS_PASS" | cryptsetup open --type luks $LUKS_PART "$LUKS_NAME" 2>$ERR
|
||||||
|
check_for_errors "cryptsetup open --type luks $LUKS_PART $LUKS_NAME"
|
||||||
|
|
||||||
|
LUKS=1
|
||||||
|
luks_show
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
luks_pass() {
|
||||||
|
local title="$1"
|
||||||
|
local name="$2"
|
||||||
|
LUKS_PASS=""
|
||||||
|
LUKS_NAME=""
|
||||||
|
|
||||||
|
tput cnorm
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
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"
|
||||||
|
luks_pass "$title" "$name" || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
LUKS_PASS="$pass"
|
||||||
|
LUKS_NAME="$name"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
luks_setup() {
|
||||||
|
LUKS_PART=""
|
||||||
|
modprobe -a dm-mod dm_crypt
|
||||||
|
unmount_partitions
|
||||||
|
|
||||||
|
if [[ $ROOT_PART == "" || $LVM -eq 1 ]]; then
|
||||||
|
find_partitions 'part|lvm' || return 1
|
||||||
|
[[ $BOOT_PART != "" ]] && decr_count "$BOOT_PART"
|
||||||
|
|
||||||
|
if (( COUNT == 1 )); then
|
||||||
|
LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
|
||||||
|
infobox "$_LuksEncrypt" "${_OnlyOne}: $LUKS_PART\n" 1
|
||||||
|
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
|
||||||
|
infobox "$_PrepMount" "\nUsing root partition created earlier: $ROOT_PART\n" 1
|
||||||
|
LUKS_PART="$ROOT_PART"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# get password and name for encrypted device
|
||||||
|
luks_pass "$_LuksEncrypt" "$LUKS_NAME" || return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
luks_default() {
|
||||||
|
luks_setup || return 1
|
||||||
|
infobox "$_LuksEncrypt" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0
|
||||||
|
|
||||||
|
echo "$LUKS_PASS" | cryptsetup -q luksFormat "$LUKS_PART" 2>$ERR
|
||||||
|
check_for_errors "cryptsetup -q luksFormat $LUKS_PART"
|
||||||
|
|
||||||
|
echo "$LUKS_PASS" | cryptsetup open "$LUKS_PART" "$LUKS_NAME" 2>$ERR
|
||||||
|
check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME"
|
||||||
|
LUKS=1
|
||||||
|
|
||||||
|
luks_show
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
luks_keycmd() {
|
||||||
|
if luks_setup; then
|
||||||
|
tput cnorm
|
||||||
|
local cipher
|
||||||
|
cipher="$(getinput "$_PrepLUKS" "$_LuksCipherKey" "-s 512 -c aes-xts-plain64")"
|
||||||
|
[[ $? != 0 || $cipher == "" ]] && return 1
|
||||||
|
|
||||||
|
infobox "$_LuksEncryptAdv" "$_LuksWaitBody $LUKS_NAME $_LuksWaitBody2 $LUKS_PART\n" 0
|
||||||
|
|
||||||
|
echo "$LUKS_PASS" | cryptsetup -q $cipher luksFormat $LUKS_PART 2>$ERR
|
||||||
|
check_for_errors "cryptsetup -q $cipher luksFormat $LUKS_PART"
|
||||||
|
|
||||||
|
echo "$LUKS_PASS" | cryptsetup open $LUKS_PART "$LUKS_NAME" 2>$ERR
|
||||||
|
check_for_errors "cryptsetup open $LUKS_PART $LUKS_NAME"
|
||||||
|
|
||||||
|
luks_show
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
luks_show() {
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
luks_menu() {
|
||||||
|
tput civis
|
||||||
|
local choice
|
||||||
|
choice="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_PrepLUKS " \
|
||||||
|
--menu "${_LuksMenuBody}${_LuksMenuBody2}${_LuksMenuBody3}" 0 0 0 \
|
||||||
|
"$_LuksEncrypt" "cryptsetup -q luksFormat" \
|
||||||
|
"$_LuksOpen" "cryptsetup open --type luks" \
|
||||||
|
"$_LuksEncryptAdv" "cryptsetup -q -s -c luksFormat" \
|
||||||
|
"$_Back" "-")"
|
||||||
|
|
||||||
|
case $choice in
|
||||||
|
"$_LuksEncrypt") luks_default && return 0 ;;
|
||||||
|
"$_LuksOpen") luks_open && return 0 ;;
|
||||||
|
"$_LuksEncryptAdv") luks_keycmd && return 0 ;;
|
||||||
|
*) 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 ]]; then
|
||||||
|
infobox "$_LuksKeyFileTitle" "$_LuksKeyFileCreate" 0
|
||||||
|
|
||||||
|
local dev
|
||||||
|
dev="/dev/$(lsblk -lno NAME,UUID,TYPE | awk "/$LUKS_UUID/"' && /part|crypt|lvm/ {print $1}')"
|
||||||
|
|
||||||
|
local keycmd
|
||||||
|
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"
|
||||||
|
|
||||||
|
chroot_cmd "$keycmd" 2>$ERR
|
||||||
|
check_for_errors "$keycmd"
|
||||||
|
|
||||||
|
sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf 2>$ERR
|
||||||
|
check_for_errors 'sed -i "s/FILES=()/FILES=(/crypto_keyfile.bin)/g" /etc/mkinitcpio.conf'
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
275
src/lib/lvm.sh
Normal file
275
src/lib/lvm.sh
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
lvm_detect() {
|
||||||
|
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)"
|
||||||
|
|
||||||
|
if [[ $VOLUMES && $VOLUME_GROUP && $PHYSICAL_VOLUMES ]]; then
|
||||||
|
infobox "$_PrepLVM" "$_LvmDetBody" 0
|
||||||
|
|
||||||
|
modprobe dm-mod 2>$ERR
|
||||||
|
check_for_errors 'modprobe dm-mod'
|
||||||
|
|
||||||
|
vgscan >/dev/null 2>&1
|
||||||
|
vgchange -ay >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_show_vg() {
|
||||||
|
DEL_VG=""
|
||||||
|
VOL_GROUP_LIST=""
|
||||||
|
|
||||||
|
for i in $(lvs --noheadings | awk '{print $2}' | uniq); do
|
||||||
|
VOL_GROUP_LIST="$VOL_GROUP_LIST $i $(vgdisplay "$i" | awk '/VG Size/ {print $3$4}')"
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $VOL_GROUP_LIST == "" ]]; then
|
||||||
|
msgbox "$_ErrTitle" "$_LvmVGErr"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
tput civis
|
||||||
|
DEL_VG="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepLVM " --menu "$_LvmSelVGBody" 18 70 10 $VOL_GROUP_LIST)"
|
||||||
|
[[ $? != 0 || $DEL_VG == "" ]] && return 1
|
||||||
|
}
|
||||||
|
|
||||||
|
get_lv_size() {
|
||||||
|
tput cnorm
|
||||||
|
local ttl=" $_LvmCreateVG (LV:$VOL_COUNT) "
|
||||||
|
local msg="${VOLUME_GROUP}: ${GROUP_SIZE}$GROUP_SIZE_TYPE (${VOL_GROUP_MB}MB $_LvmLvSizeBody1).$_LvmLvSizeBody2"
|
||||||
|
VOLUME_SIZE="$(getinput "$ttl" "$msg" "")"
|
||||||
|
[[ $? != 0 || $VOLUME_SIZE == "" ]] && return 1
|
||||||
|
|
||||||
|
ERR_SIZE=0
|
||||||
|
# if the size is empty or 0
|
||||||
|
(( ${#VOLUME_SIZE} == 0 || ${VOLUME_SIZE:0:1} == 0 )) && ERR_SIZE=1
|
||||||
|
|
||||||
|
if (( ERR_SIZE == 0 )); then
|
||||||
|
# number of characters in VOLUME_SIZE minus the last, which should be a letter
|
||||||
|
local lv="$((${#VOLUME_SIZE} - 1))"
|
||||||
|
|
||||||
|
# loop each character (except the last) in VOLUME_SIZE and ensure they are numbers
|
||||||
|
for (( i=0; i<lv; i++ )); do
|
||||||
|
[[ ${VOLUME_SIZE:$i:1} != [0-9] ]] && { ERR_SIZE=1; break; }
|
||||||
|
done
|
||||||
|
|
||||||
|
if (( ERR_SIZE == 0 )); then
|
||||||
|
# ensure the last character is either m/M or g/G
|
||||||
|
case ${VOLUME_SIZE:$lv:1} in
|
||||||
|
[mMgG]) ERR_SIZE=0 ;;
|
||||||
|
*) ERR_SIZE=1
|
||||||
|
esac
|
||||||
|
|
||||||
|
if (( ERR_SIZE == 0 )); then
|
||||||
|
local s=${VOLUME_SIZE:0:$lv}
|
||||||
|
local m=$((s * 1000))
|
||||||
|
# check whether the value is greater than or equal to the LV remaining Size.
|
||||||
|
# if not, convert into MB for VG space remaining.
|
||||||
|
case ${VOLUME_SIZE:$lv:1} in
|
||||||
|
[Gg]) (( m >= VOL_GROUP_MB )) && ERR_SIZE=1 || VOL_GROUP_MB=$((VOL_GROUP_MB - m)) ;;
|
||||||
|
[Mm]) (( ${VOLUME_SIZE:0:$lv} >= VOL_GROUP_MB )) && ERR_SIZE=1 || VOL_GROUP_MB=$((VOL_GROUP_MB - s)) ;;
|
||||||
|
*) ERR_SIZE=1
|
||||||
|
esac
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if (( ERR_SIZE == 1 )); then
|
||||||
|
msgbox "$_ErrTitle" "$_LvmLvSizeErrBody"
|
||||||
|
get_lv_size || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_volume_name() {
|
||||||
|
local msg="$1"
|
||||||
|
|
||||||
|
local default="volmain"
|
||||||
|
(( VOL_COUNT > 1 )) && default="volextra"
|
||||||
|
|
||||||
|
tput cnorm
|
||||||
|
local name
|
||||||
|
name="$(getinput "$_LvmCreateVG (LV:$VOL_COUNT)" "$msg" "$default")"
|
||||||
|
[[ $? != 0 || $name == "" ]] && return 1
|
||||||
|
|
||||||
|
# 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
|
||||||
|
msgbox "$_ErrTitle" "$_LvmNameVgErr"
|
||||||
|
lvm_group_name || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
VOLUME_GROUP="$group"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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; }
|
||||||
|
|
||||||
|
# create it
|
||||||
|
lvcreate -L "$VOLUME_SIZE" "$VOLUME_GROUP" -n "$VOLUME_NAME" 2>$ERR
|
||||||
|
check_for_errors "lvcreate -L $VOLUME_SIZE $VOLUME_GROUP -n $VOLUME_NAME"
|
||||||
|
msgbox "$_LvmCreateVG (LV:$VOL_COUNT)" "$_Done LV $VOLUME_NAME ($VOLUME_SIZE) $_LvmPvDoneBody2."
|
||||||
|
|
||||||
|
((VOL_COUNT--)) # decrement the number of volumes chosen after each loop
|
||||||
|
done
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_volume_count() {
|
||||||
|
VOL_COUNT=$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_LvmCreateVG " \
|
||||||
|
--radiolist "$_LvmLvNumBody1 $VOLUME_GROUP\n$_LvmLvNumBody2" 0 0 0 \
|
||||||
|
"1" "-" off "2" "-" off "3" "-" off "4" "-" off "5" "-" off \
|
||||||
|
"6" "-" off "7" "-" off "8" "-" off "9" "-" off)
|
||||||
|
[[ $? != 0 || $VOL_COUNT == "" ]] && return 1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_partitions() {
|
||||||
|
find_partitions 'part|crypt' || return 1
|
||||||
|
PARTS="$(awk 'NF > 0 {print $0 " off"}' <<< "$PARTS")"
|
||||||
|
|
||||||
|
# choose partitions
|
||||||
|
tput civis
|
||||||
|
GROUP_PARTS="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_LvmCreateVG " --checklist "$_LvmPvSelBody" 0 0 0 $PARTS)"
|
||||||
|
[[ $? != 0 || $GROUP_PARTS == "" ]] && return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_create_group() {
|
||||||
|
# get volume group name
|
||||||
|
lvm_group_name || return 1
|
||||||
|
|
||||||
|
# loop while setup is not confirmed by the user
|
||||||
|
while ! yesno "$_LvmCreateVG" "$_LvmPvConfBody1 $VOLUME_GROUP\n\n$_LvmPvConfBody2 $GROUP_PARTS\n"; do
|
||||||
|
lvm_partitions || { break; return 1; }
|
||||||
|
lvm_group_name || { break; return 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
# create it
|
||||||
|
infobox "$_LvmCreateVG" "$_LvmPvActBody1 $VOLUME_GROUP\n" 0
|
||||||
|
vgcreate -f "$VOLUME_GROUP" "$GROUP_PARTS" >/dev/null 2>$ERR
|
||||||
|
check_for_errors "vgcreate -f $VOLUME_GROUP $GROUP_PARTS"
|
||||||
|
|
||||||
|
# get volume size size and transform size to MB if size is given in GB
|
||||||
|
GROUP_SIZE=$(vgdisplay "$VOLUME_GROUP" | awk '/VG Size/ {print int($3)}')
|
||||||
|
GROUP_SIZE_TYPE="$(vgdisplay "$VOLUME_GROUP" | awk '/VG Size/ {print substr($NF, 0, 1)}')"
|
||||||
|
[[ $GROUP_SIZE_TYPE == 'G' ]] && VOL_GROUP_MB=$((GROUP_SIZE * 1000)) || VOL_GROUP_MB=$GROUP_SIZE
|
||||||
|
|
||||||
|
# finished volume group creation
|
||||||
|
local msg="$_LvmPvDoneBody1 $VOLUME_GROUP ($GROUP_SIZE $GROUP_SIZE_TYPE)"
|
||||||
|
msgbox "$_LvmCreateVG" "$msg $_LvmPvDoneBody2\n"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_create() {
|
||||||
|
VOLUME_GROUP=""
|
||||||
|
GROUP_PARTS=""
|
||||||
|
VOL_GROUP_MB=0
|
||||||
|
unmount_partitions
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
# last or only logical volume
|
||||||
|
lvm_volume_name "$_LvmLvNameBody1 $_LvmLvNameBody2 (${VOL_GROUP_MB}MB)" || return 1
|
||||||
|
lvcreate -l +100%FREE "$VOLUME_GROUP" -n "$VOLUME_NAME" 2>$ERR
|
||||||
|
check_for_errors "lvcreate -l +100%FREE $VOLUME_GROUP -n $VOLUME_NAME"
|
||||||
|
|
||||||
|
LVM=1
|
||||||
|
|
||||||
|
show_devices
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_del_vg() {
|
||||||
|
if lvm_show_vg; then
|
||||||
|
yesno "$_LvmDelVG" "$_LvmDelQ" && vgremove -f "$DEL_VG" >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_del_all() {
|
||||||
|
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)"
|
||||||
|
|
||||||
|
if yesno "$_LvMDelAll" "$_LvmDelQ"; then
|
||||||
|
for i in $VOLUMES; do
|
||||||
|
lvremove -f "/dev/mapper/$i" >/dev/null 2>&1
|
||||||
|
done
|
||||||
|
for i in $VOLUME_GROUP; do
|
||||||
|
vgremove -f "$i" >/dev/null 2>&1
|
||||||
|
done
|
||||||
|
for i in $PHYSICAL_VOLUMES; do
|
||||||
|
pvremove -f "$i" >/dev/null 2>&1
|
||||||
|
done
|
||||||
|
LVM=0
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
lvm_menu() {
|
||||||
|
lvm_detect
|
||||||
|
tput civis
|
||||||
|
|
||||||
|
local choice
|
||||||
|
choice="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepLVM " --menu "$_LvmMenu" 0 0 0 \
|
||||||
|
"$_LvmCreateVG" "vgcreate -f, lvcreate -L -n" \
|
||||||
|
"$_LvmDelVG" "vgremove -f" \
|
||||||
|
"$_LvMDelAll" "lvrmeove, vgremove, pvremove -f" \
|
||||||
|
"$_Back" "-")"
|
||||||
|
|
||||||
|
case $choice in
|
||||||
|
"$_LvmCreateVG")
|
||||||
|
lvm_create
|
||||||
|
retval=$?
|
||||||
|
[[ $retval != 1 ]] && return $retval
|
||||||
|
;;
|
||||||
|
"$_LvmDelVG") lvm_del_vg ;;
|
||||||
|
"$_LvMDelAll") lvm_del_all ;;
|
||||||
|
*) return 0
|
||||||
|
esac
|
||||||
|
|
||||||
|
lvm_menu
|
||||||
|
}
|
230
src/lib/mount.sh
Normal file
230
src/lib/mount.sh
Normal file
@ -0,0 +1,230 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
mount_main() {
|
||||||
|
msgbox "$_PrepMount" "$_WarnMount"
|
||||||
|
lvm_detect
|
||||||
|
|
||||||
|
# prepare partition list PARTS for dialog
|
||||||
|
unmount_partitions
|
||||||
|
find_partitions 'part|lvm|crypt' || return 1
|
||||||
|
|
||||||
|
# remove boot partition from dialog list if we auto partitioned one
|
||||||
|
[[ $BOOT_PART != "" ]] && decr_count "$BOOT_PART"
|
||||||
|
|
||||||
|
select_root_partition || return 1
|
||||||
|
|
||||||
|
if [[ $BOOT_PART == "" ]]; then
|
||||||
|
if [[ $SYS == "UEFI" ]]; then
|
||||||
|
select_efi_partition || { BOOT_PART=""; return 1; }
|
||||||
|
elif (( $COUNT > 0 )); then
|
||||||
|
select_boot_partition || { BOOT_PART=""; return 1; }
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
infobox "$_PrepMount" "\nUsing boot partition: $BOOT_PART\n" 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
select_boot_setup || { BOOTLOADER=""; return 1; }
|
||||||
|
|
||||||
|
if [[ $BOOT_PART != "" ]]; then
|
||||||
|
setup_boot_device
|
||||||
|
mount_partition "$BOOT_PART" "${BOOT_MNTS[$SYS-$BOOTLOADER]}" || return 1
|
||||||
|
SEPERATE_BOOT=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
select_swap || return 1
|
||||||
|
select_extra_partitions || return 1
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_swap() {
|
||||||
|
# Ask user to select partition or create swapfile
|
||||||
|
tput civis
|
||||||
|
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
|
||||||
|
tput cnorm
|
||||||
|
SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "${SYS_MEM}M")"
|
||||||
|
[[ $? != 0 || $SWAP_SIZE == "" ]] && return 1
|
||||||
|
|
||||||
|
while ! [[ ${SWAP_SIZE:0:1} =~ [1-9] && ${SWAP_SIZE: -1} =~ (M|G) ]]; do
|
||||||
|
msgbox "$_SelSwpSetup Error" "\n$_SelSwpErr $SWAP_SIZE\n"
|
||||||
|
SWAP_SIZE="$(getinput "$_SelSwpSetup" "$_SelSwpSize" "${SYS_MEM}M")"
|
||||||
|
[[ $? != 0 || $SWAP_SIZE == "" ]] && { break; return 1; }
|
||||||
|
done
|
||||||
|
|
||||||
|
enable_swap "$MNT/swapfile"
|
||||||
|
SWAP="/swapfile"
|
||||||
|
else
|
||||||
|
enable_swap "$SWAP"
|
||||||
|
decr_count "$SWAP"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_mount_opts() {
|
||||||
|
local part="$1"
|
||||||
|
local fs="$2"
|
||||||
|
local title="${fs^} Mount Options"
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
if ! yesno "$title" "$_MntConfBody $MNT_OPTS\n"; then
|
||||||
|
select_mount_opts "$part" "$fs" || return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_filesystem() {
|
||||||
|
local part="$1"
|
||||||
|
local cur_fs
|
||||||
|
cur_fs="$(lsblk -lno FSTYPE $part)"
|
||||||
|
tput civis
|
||||||
|
|
||||||
|
local fs
|
||||||
|
fs="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_FSTitle: $part " \
|
||||||
|
--menu "\nPartition: ${part}$([[ $cur_fs != "" ]] && echo -en "\nCurrent: ${cur_fs}")\n$_FSBody" 0 0 0 \
|
||||||
|
$([[ $cur_fs != "" ]] && echo -n "$_Skip -") \
|
||||||
|
"ext4" "${FS_CMDS[ext4]}" "ext3" "${FS_CMDS[ext3]}" \
|
||||||
|
"ext2" "${FS_CMDS[ext2]}" "vfat" "${FS_CMDS[vfat]}" \
|
||||||
|
"ntfs" "${FS_CMDS[ntfs]}" "f2fs" "${FS_CMDS[f2fs]}" \
|
||||||
|
"jfs" "${FS_CMDS[jfs]}" "nilfs2" "${FS_CMDS[nilfs2]}" \
|
||||||
|
"reiserfs" "${FS_CMDS[reiserfs]}" "xfs" "${FS_CMDS[xfs]}")"
|
||||||
|
if [[ $fs == "$_Skip" ]]; then
|
||||||
|
return 0
|
||||||
|
elif [[ $fs == "" ]]; then
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if yesno "$_FSTitle" "\nFormat $part as $fs?\n"; then
|
||||||
|
format $part $fs
|
||||||
|
else
|
||||||
|
select_filesystem $part || return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_efi_partition() {
|
||||||
|
tput civis
|
||||||
|
if (( COUNT == 1 )); then
|
||||||
|
BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
|
||||||
|
infobox "$_PrepMount" "$_OnlyOne for EFI: $BOOT_PART\n" 1
|
||||||
|
else
|
||||||
|
BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepMount " --menu "$_SelUefiBody" 0 0 0 $PARTS)"
|
||||||
|
[[ $? != 0 || $BOOT_PART == "" ]] && return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then
|
||||||
|
local msg="$_FormUefiBody $BOOT_PART $_FormUefiBody2"
|
||||||
|
yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Do Not Format" "no" &&
|
||||||
|
format "$BOOT_PART" "vfat"
|
||||||
|
else
|
||||||
|
format "$BOOT_PART" "vfat"
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_boot_partition() {
|
||||||
|
tput civis
|
||||||
|
BOOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepMount " --menu "$_SelBiosBody" 0 0 0 "$_Skip" "-" $PARTS)"
|
||||||
|
|
||||||
|
if [[ $BOOT_PART == "$_Skip" || $BOOT_PART == "" ]]; then
|
||||||
|
BOOT_PART=""
|
||||||
|
else
|
||||||
|
if grep -q 'ext[34]' <<< "$(fsck -N "$BOOT_PART")"; then
|
||||||
|
local msg="$_FormBiosBody $BOOT_PART $_FormUefiBody2"
|
||||||
|
yesno "$_PrepMount" "$msg" "Format $BOOT_PART" "Skip Formatting" "no" &&
|
||||||
|
format "$BOOT_PART" "ext4"
|
||||||
|
else
|
||||||
|
format "$BOOT_PART" "ext4"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_root_partition() {
|
||||||
|
# if we used LUKS and no LVM or LUKS+LVM
|
||||||
|
# remove the relevant partition labels from the list
|
||||||
|
if (( LUKS == 1 && LVM == 0 )); then
|
||||||
|
ROOT_PART="/dev/mapper/$LUKS_NAME"
|
||||||
|
decr_count "$LUKS_PART"
|
||||||
|
elif (( LUKS == 1 && LVM == 1 )); then
|
||||||
|
decr_count "$LUKS_PART"
|
||||||
|
for part in $(echo "$GROUP_PARTS"); do
|
||||||
|
decr_count "$part"
|
||||||
|
done
|
||||||
|
ROOT_PART=""
|
||||||
|
elif (( LUKS == 0 && LVM == 1 )); then
|
||||||
|
for part in $(echo "$GROUP_PARTS"); do
|
||||||
|
decr_count "$part"
|
||||||
|
done
|
||||||
|
ROOT_PART=""
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $COUNT -eq 1 && $ROOT_PART == "" ]]; then
|
||||||
|
ROOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
|
||||||
|
infobox "$_PrepMount" "$_OnlyOne for root (/): $ROOT_PART\n" 1
|
||||||
|
elif [[ $ROOT_PART == "" || $LVM -eq 1 ]]; then
|
||||||
|
tput civis
|
||||||
|
ROOT_PART="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PrepMount " --menu "$_SelRootBody" 0 0 0 $PARTS)"
|
||||||
|
[[ $? != 0 || $ROOT_PART == "" ]] && return 1
|
||||||
|
else
|
||||||
|
local msg="\nUsing $([[ $LUKS -eq 1 ]] && echo -n "encrypted ")root partition:"
|
||||||
|
infobox "$_PrepMount" "$msg $ROOT_PART\n" 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
select_filesystem "$ROOT_PART" || { ROOT_PART=""; return 1; }
|
||||||
|
mount_partition "$ROOT_PART" || { ROOT_PART=""; return 1; }
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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)"
|
||||||
|
[[ $? != 0 || $part == "$_Done" || $part == "" ]] && break
|
||||||
|
|
||||||
|
# choose what filesystem and get mountpoint
|
||||||
|
select_filesystem "$part" || { break; return 1; }
|
||||||
|
select_mountpoint || { break; return 1; }
|
||||||
|
|
||||||
|
# mount it
|
||||||
|
mount_partition "$part" "$EXTRA_MNT" || { break; return 1; }
|
||||||
|
|
||||||
|
# if the mountpoint was /usr add 'usr' to MKINIT_HOOKS
|
||||||
|
[[ $EXTRA_MNT == "/usr" && $MKINIT_HOOKS != *usr* ]] && MKINIT_HOOKS="usr $MKINIT_HOOKS"
|
||||||
|
done
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_mountpoint() {
|
||||||
|
tput cnorm
|
||||||
|
EXTRA_MNT="$(getinput "$_PrepMount $part" "$_ExtPartBody1 /home /var\n" "/")"
|
||||||
|
[[ $? != 0 || $EXTRA_MNT == "" ]] && return 1
|
||||||
|
|
||||||
|
# bad mountpoint
|
||||||
|
if [[ ${EXTRA_MNT:0:1} != "/" || ${#EXTRA_MNT} -le 1 || $EXTRA_MNT =~ \ |\' ]]; then
|
||||||
|
msgbox "$_ErrTitle" "$_ExtErrBody"
|
||||||
|
select_mountpoint || return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
123
src/lib/package.sh
Normal file
123
src/lib/package.sh
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
update_system() {
|
||||||
|
tput cnorm
|
||||||
|
local pkgcmd
|
||||||
|
if [[ $KERNEL == 'linux-lts' ]]; then
|
||||||
|
pkgcmd="pacman -Rs linux --noconfirm ; pacman -S iputils --noconfirm ; pacman -S base-devel git linux-lts --needed --noconfirm"
|
||||||
|
else
|
||||||
|
pkgcmd="pacman -S iputils --noconfirm ; pacman -S base-devel git --needed --noconfirm"
|
||||||
|
fi
|
||||||
|
|
||||||
|
pkgcmd="pacman -Rs archlabs-installer --noconfirm ; $pkgcmd"
|
||||||
|
|
||||||
|
if [[ $KERNEL == 'linux-lts' && $VM ]]; then
|
||||||
|
pkgcmd="pacman -Rs virtualbox-guest-modules-arch --noconfirm ; pacman -S virtualbox-guest-dkms linux-lts-headers --noconfirm ; $pkgcmd"
|
||||||
|
elif ! [[ $VM ]]; then
|
||||||
|
pkgcmd="pacman -Rs virtualbox-guest-utils virtualbox-guest-modules-arch --noconfirm ; $pkgcmd"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ $BOOTLOADER != 'grub' ]]; then
|
||||||
|
pkgcmd="$pkgcmd ; pacman -Rs grub --noconfirm"
|
||||||
|
rm -f $MNT/etc/default/grub
|
||||||
|
find $MNT/boot/ -name 'grub*' -exec rm -rf '{}' \; >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
chroot_cmd "pacman -Syyu --noconfirm ; $pkgcmd" 2>/dev/null
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
install_packages() {
|
||||||
|
tput civis
|
||||||
|
# packages needed for the selected window manager
|
||||||
|
for wm in $INSTALL_WMS; do
|
||||||
|
WM_LOGIN_CHOICES="${WM_LOGIN_CHOICES}$wm - "
|
||||||
|
case $wm in
|
||||||
|
openbox) WM_PACKAGES="$WM_PACKAGES $wm obconf archlabs-obkey archlabs-kickshaw tint2 conky" ;;
|
||||||
|
bspwm) WM_PACKAGES="$WM_PACKAGES $wm sxhkd" ;;
|
||||||
|
i3-gaps) WM_PACKAGES="$WM_PACKAGES $wm i3status perl-anyevent-i3" ;;
|
||||||
|
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" ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
if [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps) ]]; then
|
||||||
|
WM_PACKAGES="$WM_PACKAGES termite thunar archlabs-polybar archlabs-screenlock archlabs-skippy-xd archlabs-oblogout lxappearance"
|
||||||
|
elif [[ $INSTALL_WMS =~ (xfce4) ]]; then
|
||||||
|
WM_PACKAGES="$WM_PACKAGES archlabs-oblogout archlabs-screenlock"
|
||||||
|
fi
|
||||||
|
|
||||||
|
local pkgs="$WM_PACKAGES"
|
||||||
|
|
||||||
|
# add lightdm packages if chosen
|
||||||
|
if [[ $LOGIN_TYPE == 'lightdm' ]]; then
|
||||||
|
pkgs="$pkgs lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# add extra packages
|
||||||
|
[[ $EXTRA_PACKAGES != "" ]] && pkgs="$pkgs $EXTRA_PACKAGES"
|
||||||
|
|
||||||
|
# for gnome and cinnamon we dont need the xfce provided stuff
|
||||||
|
if [[ $INSTALL_WMS == 'gnome' || $INSTALL_WMS == 'cinnamon' ]]; then
|
||||||
|
REMOVE_PKGS="$(pacman -Qssq 'xfce4*' 2>/dev/null)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ $INSTALL_WMS =~ dwm ]] && setup_dwm
|
||||||
|
|
||||||
|
local pkgcmd="pacman -S $pkgs --needed --noconfirm"
|
||||||
|
|
||||||
|
# are we removing some packages
|
||||||
|
[[ $REMOVE_PKGS != "" ]] && pkgcmd="pacman -Rs $REMOVE_PKGS --noconfirm ; $pkgcmd"
|
||||||
|
|
||||||
|
chroot_cmd "$pkgcmd" 2>/dev/null
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_dwm() {
|
||||||
|
echo -e "\nSetting up dwm..\n\n"
|
||||||
|
mkdir -pv $MNT/home/$LIVE/suckless
|
||||||
|
for prog in dwm st dmenu; do
|
||||||
|
echo -e "\nInstalling $prog..\n"
|
||||||
|
git clone https://bitbucket.org/natemaia/$prog $MNT/home/$LIVE/suckless/$prog
|
||||||
|
chroot_cmd "cd /home/$LIVE/suckless/$prog && sudo make clean install && make clean"
|
||||||
|
echo -e "\n$prog has been installed..
|
||||||
|
\nSee /home/$NEWUSER/suckless/$prog to customize and rebuild\n"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_lightdm() {
|
||||||
|
# due to the user's information not being entered yet at this point, if they chose
|
||||||
|
# autologin then there is one value in the lightdm config that must be changed later
|
||||||
|
#
|
||||||
|
# autologin-user=$USER
|
||||||
|
|
||||||
|
echo -e "\nSetting up lightdm..\n"
|
||||||
|
chroot_cmd 'systemctl enable lightdm.service && systemctl set-default graphical.target'
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
rm -rf $MNT/etc/systemd/system/getty@tty1.service.d
|
||||||
|
|
||||||
|
if [[ $AUTOLOGIN == true ]]; then
|
||||||
|
echo -e "\nSetting up autologin..\n"
|
||||||
|
chroot_cmd 'groupadd -r nopasswdlogin'
|
||||||
|
sed -i '/#%PAM-1.0/ a auth sufficient pam_succeed_if.so user ingroup nopasswdlogin' $MNT/etc/pam.d/lightdm
|
||||||
|
sed -i "/#autologin-session=/ c autologin-session=${LOGIN_WM}" $MNT/etc/lightdm/lightdm.conf
|
||||||
|
sed -i "/#autologin-user=/ c autologin-user=${NEWUSER}" $MNT/etc/lightdm/lightdm.conf
|
||||||
|
fi
|
||||||
|
}
|
288
src/lib/partition.sh
Normal file
288
src/lib/partition.sh
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
format() {
|
||||||
|
infobox "$_FSTitle" "\nFormatting: $1\n\nCommand: ${FS_CMDS[$2]}\n" 0
|
||||||
|
${FS_CMDS[$2]} $1 2>$ERR
|
||||||
|
check_for_errors "${FS_CMDS[$2]} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
decr_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
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_swap() {
|
||||||
|
[[ $1 == "$MNT/swapfile" ]] && { fallocate -l $SWAP_SIZE $1; chmod 600 $1; }
|
||||||
|
mkswap $1 >/dev/null 2>&1
|
||||||
|
swapon $1 >/dev/null 2>&1
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
mount_partition() {
|
||||||
|
local part="$1"
|
||||||
|
local mount="${MNT}$2"
|
||||||
|
local fs="$(lsblk -lno FSTYPE $part)"
|
||||||
|
|
||||||
|
mkdir -p "$mount"
|
||||||
|
|
||||||
|
if [[ ${FS_OPTS[$fs]} != "" && $part != "$BOOT_PART" ]] && select_mount_opts "$part" "$fs"; then
|
||||||
|
mount -o $MNT_OPTS $part "$mount" 2>$ERR
|
||||||
|
check_for_errors "mount -o $MNT_OPTS $part $mount"
|
||||||
|
else
|
||||||
|
mount $part "$mount" 2>$ERR
|
||||||
|
check_for_errors "mount $part $mount"
|
||||||
|
fi
|
||||||
|
|
||||||
|
confirm_mount $part "$mount" || return 1
|
||||||
|
check_cryptlvm "$part"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
infobox "$_MntTitle" "$_MntFail\n$msg\n" 1
|
||||||
|
return 1
|
||||||
|
else
|
||||||
|
# mount was successful
|
||||||
|
infobox "$_MntTitle" "$_MntSucc\n$msg\n" 1
|
||||||
|
decr_count "$part"
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
find_partitions() {
|
||||||
|
local str="$1"
|
||||||
|
local err='NONE'
|
||||||
|
|
||||||
|
# string of partitions as /TYPE/PART SIZE
|
||||||
|
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}')"
|
||||||
|
else
|
||||||
|
PARTS="$(lsblk -lno TYPE,NAME,SIZE | awk "/$str/"' {sub(/^part/, "/dev/"); sub(/^lvm|^crypt/, "/dev/mapper/"); print $1$2 " " $3}')"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# number of partitions total
|
||||||
|
COUNT=$(wc -l <<< "$PARTS")
|
||||||
|
|
||||||
|
# ensure we have enough partitions for the system and action type
|
||||||
|
case $str in
|
||||||
|
'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" ;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
# if there aren't enough partitions show the error message
|
||||||
|
if [[ $err != 'NONE' ]]; then
|
||||||
|
msgbox "$_ErrTitle" "$err"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
check_cryptlvm() {
|
||||||
|
local part="$1"
|
||||||
|
local devs="$(lsblk -lno NAME,FSTYPE,TYPE)"
|
||||||
|
|
||||||
|
# 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/}"
|
||||||
|
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
auto_partition() {
|
||||||
|
local device="$1"
|
||||||
|
|
||||||
|
# confirm or bail
|
||||||
|
yesno "$_PrepParts" "$_PartBody1 $device $_PartBody2" || return 0
|
||||||
|
infobox "$_PrepParts" "\nAuto partitioning device: $device\n" 0
|
||||||
|
|
||||||
|
swapoff -a # make sure swap is disabled in case the device was used for swap
|
||||||
|
|
||||||
|
local dev_info="$(parted -s $device print)"
|
||||||
|
|
||||||
|
# walk the partitions on the device in reverse order and delete them
|
||||||
|
for i in $(awk '/^ [1-9][0-9]?/ {print $1}' <<< "$dev_info" | sort -r); do
|
||||||
|
parted -s $device rm $i >/dev/null 2>&1
|
||||||
|
done
|
||||||
|
|
||||||
|
# make sure we have the correct device table for the system type, gpt or msdos
|
||||||
|
local newtable="gpt"
|
||||||
|
local table="$(awk '/Table:/ {print $3}' <<< "$dev_info")"
|
||||||
|
[[ $SYS == BIOS ]] && newtable="msdos"
|
||||||
|
|
||||||
|
# if the current device table isn't correct run mklabel
|
||||||
|
if [[ $table != "$newtable" ]]; then
|
||||||
|
parted -s $device mklabel $newtable >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# when device contains the string 'nvme' then add 'p' before the part number
|
||||||
|
local nvme=""
|
||||||
|
[[ $device =~ nvme ]] && nvme="p"
|
||||||
|
|
||||||
|
local part_num=1
|
||||||
|
BOOT_PART="$device${nvme}$part_num" # set the boot partition label to the first partition
|
||||||
|
|
||||||
|
if [[ $SYS == "BIOS" ]]; then
|
||||||
|
parted -s $device mkpart primary ext4 1MiB 513MiB >/dev/null 2>&1
|
||||||
|
mkfs.ext4 -q $BOOT_PART >/dev/null 2>&1
|
||||||
|
else
|
||||||
|
parted -s $device mkpart ESP fat32 1MiB 513MiB >/dev/null 2>&1
|
||||||
|
mkfs.vfat -F32 $BOOT_PART >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
(( part_num++ )) # increment the partition number
|
||||||
|
BOOT_DEVICE="$device" # only grub on BIOS systems uses this
|
||||||
|
ROOT_PART="${device}${nvme}$part_num" # set root partition label to the second partition
|
||||||
|
|
||||||
|
parted -s $device mkpart primary ext4 514MiB 100% >/dev/null 2>&1
|
||||||
|
mkfs.ext4 -q $ROOT_PART >/dev/null 2>&1
|
||||||
|
|
||||||
|
tput civis
|
||||||
|
sleep 0.5 # slow the process down, otherwise lsblk output can be wrong for some things
|
||||||
|
|
||||||
|
echo -e "\nAuto partitioning complete.\n" > /tmp/.devlist
|
||||||
|
lsblk $device -o NAME,MODEL,TYPE,FSTYPE,SIZE >> /tmp/.devlist
|
||||||
|
dialog --cr-wrap --backtitle "$BT" --title " $_PrepParts " --textbox /tmp/.devlist 0 0
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
setup_boot_device() {
|
||||||
|
# set BOOT_DEVICE for syslinux on UEFI and grub on BIOS
|
||||||
|
if [[ $BOOT_PART =~ nvme ]]; then
|
||||||
|
BOOT_DEVICE="${BOOT_PART%p[1-9]}"
|
||||||
|
else
|
||||||
|
BOOT_DEVICE="${BOOT_PART%[1-9]}"
|
||||||
|
fi
|
||||||
|
|
||||||
|
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 >/dev/null 2>&1
|
||||||
|
if [[ $SYS == 'UEFI' ]]; then
|
||||||
|
parted -s $BOOT_DEVICE set $BOOT_PART_NUM esp on >/dev/null 2>&1
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
show_devices() {
|
||||||
|
tput civis
|
||||||
|
if [[ $IGNORE_DEV != "" ]]; then
|
||||||
|
lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT |
|
||||||
|
awk "!/$IGNORE_DEV/"' && /disk|part|lvm|crypt|NAME/ {print $0}' > /tmp/.devlist
|
||||||
|
else
|
||||||
|
lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE,MOUNTPOINT |
|
||||||
|
awk '/disk|part|lvm|crypt|NAME/ {print $0}' > /tmp/.devlist
|
||||||
|
fi
|
||||||
|
dialog --cr-wrap --backtitle "$BT" --title " $_PrepShowDev " --textbox /tmp/.devlist 0 0
|
||||||
|
}
|
||||||
|
|
||||||
|
select_device() {
|
||||||
|
local msg
|
||||||
|
[[ $1 == 'boot' ]] && msg="$_DevSelTitle for bootloader\n" || unmount_partitions
|
||||||
|
|
||||||
|
if (( DEV_COUNT == 1 )); then
|
||||||
|
DEVICE="$(awk '{print $1}' <<< "$SYS_DEVS")"
|
||||||
|
msg="\nOnly one device available$([[ $1 == 'boot' ]] && echo -n " for grub bootloader"):"
|
||||||
|
infobox "$_DevSelTitle" "$msg $DEVICE\n" 1
|
||||||
|
elif (( DEV_COUNT > 1 )); then
|
||||||
|
tput civis
|
||||||
|
DEVICE="$(dialog --cr-wrap --stdout --backtitle "$BT" --title " $_DevSelTitle " \
|
||||||
|
--menu "${msg}$_DevSelBody" 0 0 0 $SYS_DEVS)"
|
||||||
|
[[ $? != 0 || $DEVICE == "" ]] && return 1
|
||||||
|
else
|
||||||
|
msg="\nNo available devices for installation to use$([[ $1 == 'boot' ]] && echo -n " for grub bootloader")."
|
||||||
|
msgbox "$_ErrTitle" "$msg\n$_Exit"
|
||||||
|
die 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if the device selected was for grub bootloader, set the BOOT_DEVICE
|
||||||
|
# this is needed because grub uses the base device for BIOS, not the partition
|
||||||
|
[[ $1 == 'boot' ]] && BOOT_DEVICE="$DEVICE"
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
edit_partitions() {
|
||||||
|
local device="$1"
|
||||||
|
if [[ $device == "" ]]; then
|
||||||
|
select_device 'root' || return 1
|
||||||
|
device="$DEVICE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
tput civis
|
||||||
|
local choice
|
||||||
|
choice="$(dialog --cr-wrap --stdout --backtitle "$BT" \
|
||||||
|
--title " $_PartTitle " --menu "$_PartBody" 0 0 0 "$_PartAuto" "-" \
|
||||||
|
$( ([[ $DISPLAY ]] && hash gparted >/dev/null 2>&1) && echo -n "gparted -") "cfdisk" "-"\
|
||||||
|
"parted" "-" "$_PartWipe" "-")"
|
||||||
|
[[ $? != 0 || $choice == "" ]] && return 1
|
||||||
|
|
||||||
|
clear
|
||||||
|
tput cnorm
|
||||||
|
|
||||||
|
if [[ $choice != "$_PartWipe" && $choice != "$_PartAuto" ]]; then
|
||||||
|
$choice $device
|
||||||
|
elif [[ $choice == "$_PartWipe" ]]; then
|
||||||
|
yesno "$_PartWipe" "$_PartBody1 $device $_PartWipeBody2" && { clear; wipe -Ifrev $device; }
|
||||||
|
edit_partitions $device
|
||||||
|
else
|
||||||
|
# if auto_partition fails we need to re-initialize the variables, just to be sure
|
||||||
|
auto_partition $device || { initialize_variables; return 1; }
|
||||||
|
fi
|
||||||
|
}
|
169
src/lib/utils.sh
Normal file
169
src/lib/utils.sh
Normal file
@ -0,0 +1,169 @@
|
|||||||
|
#!/usr/bin/bash
|
||||||
|
|
||||||
|
# vim:ft=sh:fdm=marker:fmr={,}
|
||||||
|
|
||||||
|
# archlabs installer library script file
|
||||||
|
# this file is not meant to be run directly
|
||||||
|
# sourcing this file in a non bash shell is not advised
|
||||||
|
|
||||||
|
chroot_cmd() {
|
||||||
|
arch-chroot $MNT /bin/bash -c "$1"
|
||||||
|
}
|
||||||
|
|
||||||
|
identify_system() {
|
||||||
|
if grep -qi 'apple' /sys/class/dmi/id/sys_vendor; then
|
||||||
|
modprobe -r -q efivars
|
||||||
|
else
|
||||||
|
modprobe -q efivarfs
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d /sys/firmware/efi ]]; then
|
||||||
|
SYS="UEFI"
|
||||||
|
[[ $(mount) =~ $EFI ]] && mount -t efivarfs efivarfs $EFI >/dev/null 2>&1
|
||||||
|
|
||||||
|
local bitness
|
||||||
|
bitness=$(cat /sys/firmware/efi/fw_platform_size)
|
||||||
|
if [[ $bitness != "" && $bitness == 64 ]]; then
|
||||||
|
IS_64BIT=true
|
||||||
|
else
|
||||||
|
IS_64BIT=false
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
SYS="BIOS"
|
||||||
|
fi
|
||||||
|
|
||||||
|
readonly BT="$DIST Installer - $SYS (x86_64) - Version $VER"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_requirements() {
|
||||||
|
local err=0
|
||||||
|
if [[ $(whoami) != "root" ]]; then
|
||||||
|
infobox "$_ErrTitle" "$_NotRoot\n$_Exit"
|
||||||
|
err=1
|
||||||
|
elif ! grep -qw 'lm' /proc/cpuinfo; then
|
||||||
|
infobox "$_ErrTitle" "$_Not64Bit\n$_Exit"
|
||||||
|
err=1
|
||||||
|
elif ! (ping -c 1 archlinux.org || ping -c 1 archlabslinux.com || ping -c 1 google.com || ping -c 1 bitbucket.org || ping -c 1 github.com || ping -c 1 sourceforge.net) >/dev/null 2>&1; then
|
||||||
|
([[ $(systemctl is-active NetworkManager) == "active" ]] && hash nmtui >/dev/null 2>&1) && { tput civis; nmtui; }
|
||||||
|
if ! (ping -c 1 archlinux.org || ping -c 1 archlabslinux.com || ping -c 1 google.com || ping -c 1 bitbucket.org || ping -c 1 github.com || ping -c 1 sourceforge.net) >/dev/null 2>&1; then
|
||||||
|
infobox "$_ErrTitle" "$_NoNetwork\n$_Exit"
|
||||||
|
err=1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
[[ $err -eq 1 ]] && die 1 || return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
check_for_errors() {
|
||||||
|
# return if the last process exited normally
|
||||||
|
(( $? == 0 )) && return 0
|
||||||
|
|
||||||
|
local msg="\nThe command exited abnormally: $1"
|
||||||
|
|
||||||
|
# get error message from logfile and attempt to format slightly better for humans
|
||||||
|
# strip any non-printable characters, escape sequences, and other known messy text
|
||||||
|
local err
|
||||||
|
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"
|
||||||
|
if [[ -e /tmp/debug-log && $TERM == 'linux' ]]; then
|
||||||
|
msg="$([[ $err == "" ]] && echo -n "$msg")\n$_ErrChoiceConsole"
|
||||||
|
yesno "$_ErrTitle" "$msg" "View Log" "Continue" && { less /tmp/debug-log; die 0; }
|
||||||
|
else
|
||||||
|
yesno "$_ErrTitle" "$msg" "Exit & Shutdown" "Ignore & Continue" && die 'shutdown'
|
||||||
|
fi
|
||||||
|
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
unmount_partitions() {
|
||||||
|
swapoff -a
|
||||||
|
for i in $(mount | awk "/${MNT//\//\\/}/"' {print $3}' | sort -r); do
|
||||||
|
umount -r "$i" >/dev/null 2>&1
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
getinput() {
|
||||||
|
local answer
|
||||||
|
answer="$(dialog --cr-wrap --max-input 63 --stdout --no-cancel \
|
||||||
|
--backtitle "$BT" --title " $1 " --inputbox "$2" 0 0 "$3")"
|
||||||
|
[[ $? != 0 || $answer == "" ]] && return 1
|
||||||
|
echo "$answer"
|
||||||
|
}
|
||||||
|
|
||||||
|
msgbox() {
|
||||||
|
tput civis
|
||||||
|
dialog --cr-wrap --backtitle "$BT" --title " $1 " --msgbox "$2\n" 0 0
|
||||||
|
}
|
||||||
|
|
||||||
|
infobox() {
|
||||||
|
local time="$3"
|
||||||
|
tput civis
|
||||||
|
dialog --cr-wrap --backtitle "$BT" --title " $1 " --infobox "$2\n" 0 0
|
||||||
|
sleep ${time:-2}
|
||||||
|
}
|
||||||
|
|
||||||
|
yesno() {
|
||||||
|
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
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
wrap_up() {
|
||||||
|
yesno "$_CloseInst" "$1" "$2" "$3" || return 0
|
||||||
|
[[ $4 == 'reboot' ]] && die 'reboot' || die 0
|
||||||
|
}
|
||||||
|
|
||||||
|
die() {
|
||||||
|
tput cnorm
|
||||||
|
unmount_partitions
|
||||||
|
pgrep -f "$TERM_CMD -e tail" && pkill -f "$TERM_CMD -e tail"
|
||||||
|
[[ $1 =~ [0-9] ]] && exit $1 || systemctl $1
|
||||||
|
}
|
||||||
|
|
||||||
|
sigint() {
|
||||||
|
echo -e "\n** CTRL-C caught"
|
||||||
|
die 1
|
||||||
|
}
|
||||||
|
|
||||||
|
oneshot() {
|
||||||
|
[[ -e /tmp/.ai_$1 || ! $(type $1) ]] && return 0
|
||||||
|
$1 || return 1
|
||||||
|
touch "/tmp/.ai_$1"
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
debug() {
|
||||||
|
set -x
|
||||||
|
exec 3>| /tmp/debug-log
|
||||||
|
BASH_XTRACEFD=3
|
||||||
|
|
||||||
|
if [[ $DISPLAY && $TERM != 'linux' ]]; 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
|
||||||
|
}
|
Reference in New Issue
Block a user