This repository has been archived on 2024-09-01. You can view files and clone it, but cannot push or open issues or pull requests.
al-installer/src/archlabs-installer

636 lines
28 KiB
Bash
Executable File

#!/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
# set -n
# immutable variables {
readonly DIST="ArchLabs" # Linux distributor
readonly VER="1.6.88" # 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 TRN="/usr/share/archlabs/installer/lang"
readonly RUN="/run/archiso/bootmnt/arch/boot"
readonly VM="$(dmesg | grep -i "hypervisor")"
readonly SALT="$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)"
readonly SYS_MEM=$(grep 'MemTotal' /proc/meminfo | awk '{print int($2 / 1024)"M"}')
readonly LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if($1) print $1 " -"}' /etc/locale.gen)"
readonly CONSOLE_MAPS="$(find /usr/share/kbd/keymaps -name '*.map.gz' | awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " -"}')"
readonly IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
if [[ $IGNORE_DEV ]]; then
readonly SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')"
else
readonly SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ {print "/dev/" $1 " " $2}')"
fi
readonly DEV_COUNT="$(wc -l <<< "$SYS_DEVS")"
if grep -q 'GenuineIntel' /proc/cpuinfo; then
readonly UCODE="intel-ucode.img"
elif grep -q 'AuthenticAMD' /proc/cpuinfo; then
readonly UCODE="amd-ucode.img"
fi
# create associative array for SUBZONES[zone]
declare -gA 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 termite st 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 BMNTS=(
[UEFI-grub]="/boot/efi" [UEFI-systemd-boot]="/boot" [BIOS-grub]="/boot"
[BIOS-syslinux]="/boot" [UEFI-syslinux]="/boot"
)
declare -Agr BOOTLDRS=([BIOS]="grub ${BMNTS[BIOS-grub]} syslinux ${BMNTS[BIOS-syslinux]}"
[UEFI]="grub ${BMNTS[UEFI-grub]} systemd-boot ${BMNTS[UEFI-systemd-boot]} syslinux ${BMNTS[UEFI-syslinux]}"
)
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"
)
declare -Agr FS_OPTS=([vfat]="" [ntfs]="" [ext2]="" [ext3]=""
[ext4]="discard - off dealloc - 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"
)
# }
init_variables() {
declare -g BT="$DIST Installer - (x86_64) - Version $VER"
declare -g ROOT_PART=""
declare -g BOOT_DEVICE=""
declare -g BOOT_PART=""
declare -g BOOTLDR=""
declare -g EXTRA_MNT=""
declare -g EXTRA_MNTS=""
declare -g SWAP="none"
declare -g SWAP_SIZE="$SYS_MEM"
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 KERNEL="linux"
declare -g WM_PACKAGES=""
declare -g EXTRA_PACKAGES=""
declare -g MKINIT_HOOKS="shutdown"
declare -g WARN=false
declare -g IS_64BIT=false
declare -g AUTOLOGIN=false
declare -g CONFIG_DONE=false
declare -g SEPERATE_BOOT=false
declare -gA BCMDS=(
[syslinux]="syslinux-install_update -iam"
[grub]="grub-install --recheck --force"
[systemd-boot]="bootctl --path=/boot install"
)
declare -gA FILES=(
[2]="/etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard /etc/vconsole.conf"
[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() {
. "$1" || { printf "\nFailed to source library file %s" "$1"; die 1; }
}
user_creation() {
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 |
openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
[[ $? != 0 || $values == "" ]] && return 1
# username doesn't need to be re-encrypted
local user
user="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
awk -F'~' '{print $1}')"
# all of this is a bit hacky, but we don't ever want the passwords to be stored in plain text
# so it decrypts the string '$values', gets the field we want, and re-encrypts it
local pass pass2
pass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
awk -F'~' '{print $2}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
pass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
awk -F'~' '{print $3}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
local rpass rpass2
rpass="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
awk -F'~' '{print $5}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
rpass2="$(openssl enc -pbkdf2 -a -d -salt -pass pass:$SALT <<< "$values" |
awk -F'~' '{print $6}' | openssl enc -pbkdf2 -a -salt -pass pass:$SALT)"
# due to the encryption the string while encrypted will not be empty
local empty
empty="$(openssl enc -pbkdf2 -a -salt -pass pass:$SALT <<< "")"
# 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 == "$empty" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
if [[ $pass == "" || "$pass" != "$pass2" || "$rpass" != "$rpass2" ]]; then
# password was left empty or doesn't match
if [[ $pass == "$empty" ]]; 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_creation || return 1
else
NEWUSER="$user"
USER_PASS="$pass"
ROOT_PASS="$rpass"
fi
return 0
}
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
FONT="ter-i16n"
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-16" ;;
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
[[ $TERM == 'linux' ]] && setfont $FONT >/dev/null 2>&1
export LANG="$LOC"
return 0
}
setup_keymap() {
tput civis
KEYMAP="$(dialog --cr-wrap --stdout --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
CONSOLE_MAP="$(dialog --cr-wrap --stdout --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_timezone() {
tput civis
ZONE="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_TimeZTitle " --menu "$_TimeZBody" 20 70 10 America - Australia - \
Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica -)"
[[ $? != 0 || $ZONE == "" ]] && return 1
SUBZONE="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_TimeZTitle " --menu "$_TimeSubZBody" 20 70 12 ${SUBZONES[$ZONE]})"
[[ $? != 0 || $SUBZONE == "" ]] && return 1
yesno "$_TimeZTitle" "$_TimeZQ $ZONE/$SUBZONE?\n" && return 0 || setup_timezone
}
window_manager() {
INSTALL_WMS="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--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)"
[[ $? != 0 || $INSTALL_WMS == "" ]] && return 1
WM_NUM=$(awk '{print NF}' <<< "$INSTALL_WMS")
# packages needed for the selected window manager
for wm in $INSTALL_WMS; do
LOGIN_CHOICES="${LOGIN_CHOICES}$wm - "
case $wm in
cinnamon) WM_PACKAGES+=" $wm" ;;
bspwm) WM_PACKAGES+=" $wm sxhkd" ;;
gnome) WM_PACKAGES+=" $wm gnome-extra" ;;
i3-gaps) WM_PACKAGES+=" $wm i3status perl-anyevent-i3" ;;
xfce4) WM_PACKAGES+=" $wm xfce4-goodies xfce4-pulseaudio-plugin" ;;
openbox) WM_PACKAGES+=" $wm obconf archlabs-obkey archlabs-kickshaw archlabs-skippy-xd tint2 conky jgmenu" ;;
esac
done
if [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps) ]]; then
WM_PACKAGES+=" archlabs-polybar jsoncpp libmpdclient archlabs-screenlock archlabs-oblogout"
WM_PACKAGES+=" archlabs-paranoid lxappearance rofi termite thunar"
elif [[ $INSTALL_WMS =~ (xfce4) ]]; then
WM_PACKAGES+=" archlabs-oblogout archlabs-screenlock archlabs-paranoid"
fi
# choose which to login
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 $LOGIN_CHOICES)"
[[ $LOGIN_WM == "" ]] && LOGIN_WM="$(awk '{print $1}' <<< "$INSTALL_WMS")"
fi
# chose login type
if yesno "$_WMLogin" "$_LoginTypeBody\n" "xinit" "lightdm"; then
LOGIN_TYPE='xinit'
FILES[11]="/home/$NEWUSER/.xinitrc"
else
LOGIN_TYPE='lightdm'
WM_PACKAGES+=" lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice"
FILES[11]="/etc/lightdm/lightdm.conf $MNT/etc/lightdm/lightdm-gtk-greeter.conf"
fi
EXTRA_PACKAGES="$WM_PACKAGES"
# autologin
yesno "$_WMLogin" "$_AutoLoginBody\n" && AUTOLOGIN=true || AUTOLOGIN=false
case $LOGIN_WM in
i3-gaps) LOGIN_WM='i3' ;;
xfce4) LOGIN_WM='startxfce4' ;;
gnome) LOGIN_WM='gnome-session' ;;
openbox) LOGIN_WM='openbox-session' ;;
cinnamon) LOGIN_WM='cinnamon-session' ;;
esac
return 0
}
extra_packages() {
local pkgs
pkgs="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_ExtraPackages " --checklist "$_ExtraPackagesBody\n" 0 0 30 \
"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 \
"rxvt-unicode" "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" "A popular game distribution platform by Valve" off \
"vlc" "A free and open source cross-platform multimedia player" off \
"mpd" "A 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" "Minimalistic document viewer" off \
"qpdfview" "A tabbed PDF viewer" off \
"mupdf" "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 applications and managing windows faster and easier" off \
"cairo-dock" "Light eye-candy fully themable animated dock" off \
"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" "Google Noto fonts" off \
"noto-fonts-cjk" "Google Noto CJK fonts (Chinese, Japanese, Korean)" off)"
[[ $pkgs =~ vlc ]] && pkgs+=" qt4"
[[ $pkgs =~ mpd ]] && pkgs+=" mpc"
[[ $pkgs =~ mupdf ]] && pkgs+=" mupdf-tools"
[[ $pkgs =~ qt5ct ]] && pkgs+=" qt5-styleplugins"
[[ $pkgs =~ steam ]] && pkgs+=" steam-native-runtime"
[[ $pkgs =~ zathura ]] && pkgs+=" zathura-pdf-poppler"
[[ $pkgs =~ noto-fonts ]] && pkgs+=" noto-fonts-emoji"
[[ $pkgs =~ cairo-dock ]] && pkgs+=" cairo-dock-plug-ins"
[[ $pkgs =~ kdenlive ]] && pkgs+=" kdebase-runtime dvdauthor frei0r-plugins breeze breeze-gtk"
if [[ $INSTALL_WMS =~ dwm ]] && ! [[ $pkgs =~ ttf-hack ]]; then
pkgs+=" ttf-hack"
fi
if [[ $pkgs =~ (qutebrowser|qbittorrent|kdenlive|vlc) ]] && ! [[ $pkgs =~ qt5ct ]]; then
pkgs+=" qt5ct qt5-styleplugins"
fi
EXTRA_PACKAGES="$EXTRA_PACKAGES$([[ $pkgs ]] && printf " %s" "$pkgs")"
return 0
}
mirrorlist_cmd() {
local key="5f29642060ab983b31fdf4c2935d8c56"
local ip="$(curl -s "http://api.ipstack.com/check&fields=ip&?access_key=${key}" |
val_from_json 'ip')"
if hash reflector >/dev/null 2>&1; then
MIRROR_CMD="reflector --score 100 -l 50 -f 10 --sort rate"
yesno "$_MirrorTitle" "$_MirrorSetup" "Automatic" "Custom" && return 0
local c="$(curl -s "http://api.ipstack.com/${ip}?access_key=${key}&fields=country_name" |
val_from_json 'country_name')"
if [[ $c != "" ]]; then
MIRROR_CMD="reflector --country $c --score 80 --latest 40 --fastest 10 --sort rate"
fi
tput cnorm
MIRROR_CMD="$(dialog --cr-wrap --no-cancel --stdout --backtitle "$BT" \
--title " $_MirrorTitle " --inputbox "$_MirrorCmd\n
--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.\n" 0 0 "$MIRROR_CMD")"
else
local c="$(curl -s "http://api.ipstack.com/${ip}?access_key=${key}&fields=country_code" |
val_from_json 'country_code')"
local w="https://www.archlinux.org/mirrorlist"
if [[ $c != "" ]]; then
if [[ $c =~ (CA|US) ]]; then
MIRROR_CMD="curl -s '$w/?country=US&country=CA&protocol=https&use_mirror_status=on'"
else
MIRROR_CMD="curl -s '$w/?country=${c}&protocol=https&use_mirror_status=on'"
fi
else
MIRROR_CMD="curl -s '$w/?country=US&country=CA&country=NZ&country=GB&country=AU&protocol=https&use_mirror_status=on'"
fi
fi
return 0
}
display_selection() {
msgbox "$_PrepTitle" "\nConfiguration values used for install\n\n
Root: $ROOT_PART
Boot: $BOOT_PART
Swap: $SWAP
Extra: ${EXTRA_MNTS:-None}
LVM: $LVM
LUKS: $LUKS
Bootloader: $BOOTLDR
Boot Mount: ${BMNTS[$SYS-$BOOTLDR]}
Boot Command: ${BCMDS[$BOOTLDR]}
New User: $NEWUSER
Login: $LOGIN_WM
Autologin: $AUTOLOGIN
Login Type: $LOGIN_TYPE
Hostname: $HOSTNAME
Locale: $LOCALE
Keymap: $KEYMAP
Timezone: $ZONE/$SUBZONE
Kernel: $KERNEL
Sessions: $INSTALL_WMS
Mirrors: $MIRROR_CMD
Packages: $EXTRA_PACKAGES\n"
}
configure_install() {
tput cnorm
HOSTNAME="$(getinput "$_ConfHost" "$_HostNameBody" "${DIST,,}")"
[[ $? != 0 || $HOSTNAME == "" ]] && return 1
tput civis
LOCALE="$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_ConfLocale " --menu "$_LocaleBody" 25 70 20 $LOCALES)"
[[ $? != 0 || $LOCALE == "" ]] && return 1
setup_timezone || return 1
mirrorlist_cmd || return 1
user_creation || return 1
window_manager || return 1
yesno 'Choose Kernel' "\nUse the current kernel or the LTS kernel?\n" 'Current' 'LTS' &&
KERNEL='linux' || KERNEL='linux-lts'
extra_packages || return 1
CONFIG_DONE=true
return 0
}
edit_configs() {
if [[ $CURRENT_MENU != "edit" ]]; then
SELECTED=1
CURRENT_MENU="edit"
elif (( SELECTED < 10 )); then
(( SELECTED++ ))
fi
tput civis
SELECTED=$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_EditTitle " --default-item $SELECTED --menu "$_EditBody" 0 0 0 \
"1" "Exit & Reboot" "2" "Keyboard" "3" "Locale" "4" "Hostname" "5" "Sudoers" \
"6" "Mkinitcpio.conf" "7" "Fstab" "8" "Crypttab" "9" "${BOOTLDR^}" "10" "Pacman.conf" \
"11" "$LOGIN_TYPE")
if [[ ! $SELECTED || $SELECTED -eq 1 ]]; then
wrap_up "$_InstFinBody" 'Reboot' 'Back' 'reboot'
else
local existing_files=""
for f in $(echo "${FILES[$SELECTED]}"); do
[[ -e ${MNT}$f ]] && existing_files+=" ${MNT}$f"
done
[[ ! $existing_files ]] && msgbox "$_ErrTitle" "$_NoFileErr" || vim -O $existing_files
fi
edit_configs
}
main() {
if [[ $CURRENT_MENU != "main" ]]; then
SELECTED=1
CURRENT_MENU="main"
elif (( SELECTED < 8 )); then
((SELECTED++)) # increment the highlighted menu item
fi
tput civis
SELECTED=$(dialog --cr-wrap --stdout --backtitle "$BT" \
--title " $_PrepTitle " --default-item $SELECTED --menu "$_PrepBody" 0 0 0 \
"1" "$_PrepShowDev" "2" "$_PrepParts" "3" "$_PrepLUKS" "4" "$_PrepLVM" \
"5" "$_PrepMount" "6" "$_PrepConfig" "7" "Check Choices" "8" "$_PrepInstall" \
"9" "$_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 [[ $SELECTED ]]; then
if [[ $SELECTED -eq 8 ]]; then
check_install_ready || return 1
elif [[ ($SELECTED -eq 2 || $SELECTED -eq 5) && $WARN != true ]]; then
msgbox "$_PrepTitle" "$_WarnMount"
WARN=true
fi
fi
case $SELECTED in
1) show_devices ;;
2) edit_partitions ;;
3) luks_menu || SELECTED=1 ;;
4) lvm_menu || SELECTED=1 ;;
5) mount_main || SELECTED=1 ;;
6) configure_install ;;
7) display_selection ;;
8) install_main && edit_configs ;;
*) wrap_up "$_CloseInstBody" 'Exit' 'Back' 'exit'
esac
}
# must be done first
init_variables
for file in /usr/share/archlabs/installer/lib/?*.sh; do
source_file "$file"
done
# trap Ctrl-C to properly exit
trap sigint INT
for arg in $@; do case $arg in
--debug|-d) debug ;;
esac done
select_language
setup_keymap
check_requirements
identify_system
msgbox "$_WelTitle $DIST Installer" "$_WelBody"
while true; do
main
done