636 lines
28 KiB
Bash
Executable File
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
|