diff --git a/archlabs-installer b/archlabs-installer index e88e9ff..41a8a8b 100755 --- a/archlabs-installer +++ b/archlabs-installer @@ -3,25 +3,30 @@ # This program is free software, provided under the GNU GPL # Written by Nathaniel Maia for use in Archlabs # Some ideas and code reworked from other resources -# AIF, Cnichi, Calamares, Arch Wiki.. Credit where credit is due +# AIF, Calamares, and the Arch Wiki.. Credit where credit is due -VER=2.0.86 +# check for syntax errors +# set -n + +VER=2.0.89 # bulk default values { : ${DIST=ArchLabs} # distro name if not set -MNT=/mnt # install mountpoint -ANS=/tmp/ans # dialog answer file +MNT=/mnt # installation root mountpoint +ANS=/tmp/ans # dialog answer output file BOOTDIR=boot # location to mount boot partition FONT=ter-i16n # font used for the linux console -HOOKS=shutdown # list of additional mkinitcpio HOOKS +HOOKS=shutdown # additional mkinitcpio HOOKS SEL=0 # currently selected menu item -SYS=Unknown # bios type to be determined: UEFI/BIOS -ERR=/tmp/errlog # error log used internally -DBG=/tmp/debuglog # debug log when passed -d +SYS=Unknown # bios type, to be determined: UEFI/BIOS +ERR=/tmp/errlog # stderr log used internally by errshow() +DBG=/tmp/debuglog # debug log file when passed -d RUN=/run/archiso/bootmnt/arch/boot # path for live system /boot VM="$(dmesg | grep -i hypervisor)" # system running in a virtual machine -export DIALOGOPTS="--cr-wrap" # see `man dialog` +EXMNTS="" # extra partitions that were mounted, used to verify mountpoint and show user +FORMATTED="" # partitions that have been formatted, allows skipping the format step +export DIALOGOPTS="--cr-wrap" # dialog environment variable to hold default options, see `man dialog` BASE_PKGS="base xorg xorg-drivers sudo git gvfs gtk3 libmad libmatroska tumbler " BASE_PKGS+="playerctl pulseaudio pulseaudio-alsa pavucontrol pamixer scrot xdg-user-dirs " @@ -172,18 +177,18 @@ main() (( SEL < 12 )) && (( SEL++ )) tput civis dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " --default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \ - 1 "Device tree (optional)" \ - 2 "Partitioning (optional)" \ - 3 "LUKS setup (optional)" \ - 4 "LVM setup (optional)" \ - 5 "Mount partitions" \ - 6 "System bootloader" \ - 7 "User and password" \ - 8 "System configuration" \ - 9 "Select WM/DE (optional)" \ - 10 "Select Packages (optional)" \ - 11 "View configuration (optional)" \ - 12 "Start the installation" 2>"$ANS" + 1 "Show device tree" \ + 2 "Partitioning helpers" \ + 3 "LUKS encryption setup" \ + 4 "Logical volume management setup" \ + 5 "* Mount system partitions" \ + 6 "* Select system bootloader" \ + 7 "* Create user and password" \ + 8 "* Basic system configuration" \ + 9 "Select window manager or desktop" \ + 10 "Select additional packages" \ + 11 "View configuration selections" \ + 12 "* Confirm choices and start the installation" 2> "$ANS" read -r SEL < "$ANS" [[ -z $WARN && $SEL =~ (2|5) ]] && { msg "Data Warning" "$_warn"; WARN=true; } @@ -344,7 +349,7 @@ select_mkuser() "Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 \ "--- Root password, if left empty the user password will be used ---" 6 1 '' 6 68 "$COLUMNS" 0 2 \ "Password:" 8 1 '' 8 11 "$COLUMNS" 0 1 \ - "Password2:" 9 1 '' 9 12 "$COLUMNS" 0 1 2>"$ANS" || return 1 + "Password2:" 9 1 '' 9 12 "$COLUMNS" 0 1 2> "$ANS" || return 1 mapfile -t ans <"$ANS" @@ -401,9 +406,9 @@ select_keymap() fi if [[ $TERM == 'linux' ]]; then - loadkeys "$CMAP" >/dev/null 2>&1 + loadkeys "$CMAP" > /dev/null 2>&1 else - setxkbmap "$KEYMAP" >/dev/null 2>&1 + setxkbmap "$KEYMAP" > /dev/null 2>&1 fi return 0 @@ -573,15 +578,7 @@ part_menu() part_shrink "$device" elif [[ $choice == 'auto' ]]; then local root_size txt table boot_fs - root_size=$(lsblk -lno SIZE "$device" | awk 'NR == 1 { - if ($1 ~ "G") { - sub(/G/, "") - print ($1 * 1000 - 512) / 1000 "G" - } else { - sub(/M/, "") - print ($1 - 512) "M" - } - }') + root_size=$(lsblk -lno SIZE "$device" | awk 'NR == 1 {if ($1 ~ "G") {sub(/G/, ""); print ($1 * 1000 - 512) / 1000 "G"} else {sub(/M/, ""); print ($1 - 512) "M"}}') txt="\nWARNING:\n\nALL data on $device will be destroyed and the following partitions will be created\n\n- " if [[ $SYS == 'BIOS' ]]; then table="msdos" boot_fs="ext4" @@ -599,7 +596,7 @@ part_menu() fi if [[ $devhash != "$(lsblk -f | base64)" ]]; then msg "Probing Partitions" "\nInforming kernel of partition changes using partprobe\n" 0 - partprobe >/dev/null 2>&1 + partprobe > /dev/null 2>&1 [[ $choice == 'auto' ]] && return fi done @@ -626,16 +623,16 @@ part_auto() swapoff -a while read -r PART; do - parted -s "$device" rm "$PART" >/dev/null 2>&1 + parted -s "$device" rm "$PART" > /dev/null 2>&1 done <<< "$(awk '/^ [1-9][0-9]?/ {print $1}' <<< "$dev_info" | sort -r)" - [[ $(awk '/Table:/ {print $3}' <<< "$dev_info") != "$table" ]] && parted -s "$device" mklabel "$table" >/dev/null 2>&1 + [[ $(awk '/Table:/ {print $3}' <<< "$dev_info") != "$table" ]] && parted -s "$device" mklabel "$table" > /dev/null 2>&1 msg "Auto Partition" "\nCreating a 512M $boot_fs boot partition.\n" 1 if [[ $SYS == "BIOS" ]]; then - parted -s "$device" mkpart primary "$boot_fs" 1MiB 513MiB >/dev/null 2>&1 + parted -s "$device" mkpart primary "$boot_fs" 1MiB 513MiB > /dev/null 2>&1 else - parted -s "$device" mkpart ESP "$boot_fs" 1MiB 513MiB >/dev/null 2>&1 + parted -s "$device" mkpart ESP "$boot_fs" 1MiB 513MiB > /dev/null 2>&1 fi sleep 0.5 @@ -643,16 +640,16 @@ part_auto() AUTO_BOOT_PART=$(lsblk -lno NAME,TYPE "$device" | awk 'NR==2 {print "/dev/" $1}') if [[ $SYS == "BIOS" ]]; then - mkfs.ext4 -q "$AUTO_BOOT_PART" >/dev/null 2>&1 + mkfs.ext4 -q "$AUTO_BOOT_PART" > /dev/null 2>&1 else - mkfs.vfat -F32 "$AUTO_BOOT_PART" >/dev/null 2>&1 + mkfs.vfat -F32 "$AUTO_BOOT_PART" > /dev/null 2>&1 fi msg "Auto Partition" "\nCreating a $size ext4 root partition.\n" 0 - parted -s "$device" mkpart primary ext4 513MiB 100% >/dev/null 2>&1 + parted -s "$device" mkpart primary ext4 513MiB 100% > /dev/null 2>&1 sleep 0.5 AUTO_ROOT_PART="$(lsblk -lno NAME,TYPE "$device" | awk 'NR==3 {print "/dev/" $1}')" - mkfs.ext4 -q "$AUTO_ROOT_PART" >/dev/null 2>&1 + mkfs.ext4 -q "$AUTO_ROOT_PART" > /dev/null 2>&1 sleep 0.5 msg "Auto Partition" "\nProcess complete.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$device")\n" } @@ -674,12 +671,12 @@ part_shrink() num="${part: -1}" end=$(parted -s "$device" unit KiB print | awk '/^\s*'"$num"'/ {print $3}') # part size in KiB devsize=$(parted -s "$device" unit KiB print | awk '/Disk '"${device//\//\\/}"':/ {print $3}') # whole device size in KiB - mount "$part" "$MNT" >/dev/null 2>&1; sleep 0.5 + mount "$part" "$MNT" > /dev/null 2>&1; sleep 0.5 min=$(df --output=used --block-size=MiB "$part" | awk 'NR == 2 {print int($1) + 256}') max=$(df --output=avail --block-size=MiB "$part" | awk 'NR == 2 {print int($1)}') umount_dir "$MNT" tput cnorm - if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$min" "$max" $((max / 2)) 2>$ANS; then + if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$min" "$max" $((max / 2)) 2> $ANS; then size=$(< "$ANS") size=$((size * 1024)) else @@ -689,7 +686,7 @@ part_shrink() case "$fs" in ntfs) if ntfsresize -fc "$part"; then - ntfsresize -ff --size $(( (size * 1024) / 1000 ))k "$part" 2>$ERR # k=10^3 bytes + ntfsresize -ff --size $(( (size * 1024) / 1000 ))k "$part" 2> $ERR # k=10^3 bytes errshow "ntfsresize -f -s $(( (size * 1024) / 1000 ))k $part" || return 1 else msg "Resize" "\nThe ntfs partition $part cannot be resized because it is scheduled for a consistency check.\n\nTo do a consistency check in windows open command prompt as admin and run:\n\n\tchkdsk /f /r /x\n" @@ -698,7 +695,7 @@ part_shrink() ;; *) e2fsck -f "$part"; sleep 0.5 - resize2fs -f "$part" ${size}K 2>$ERR # K=2^10 bytes + resize2fs -f "$part" ${size}K 2> $ERR # K=2^10 bytes errshow "resize2fs -f $part ${size}K" || return 1 ;; esac @@ -707,10 +704,10 @@ part_shrink() (( size++ )) sleep 0.5 if [[ $devsize == "$end" ]]; then - parted -s "$device" mkpart primary ext4 ${size}KiB 100% 2>$ERR + parted -s "$device" mkpart primary ext4 ${size}KiB 100% 2> $ERR errshow "parted -s $device mkpart primary ext4 ${size}KiB 100%" || return 1 else - parted -s "$device" mkpart primary ext4 ${size}KiB ${end}KiB 2>$ERR + parted -s "$device" mkpart primary ext4 ${size}KiB ${end}KiB 2> $ERR errshow "parted -s $device mkpart primary ext4 ${size}KiB ${end}KiB" || return 1 fi msg "Resize Complete" "\n$part has been successfully resized to $((size / 1024))M.\n" 1 @@ -755,14 +752,14 @@ part_find() part_swap() { if [[ $1 == "$MNT/swapfile" && $SWAP_SIZE ]]; then - fallocate -l $SWAP_SIZE "$1" 2>$ERR + fallocate -l $SWAP_SIZE "$1" 2> $ERR errshow "fallocate -l $SWAP_SIZE $1" - chmod 600 "$1" 2>$ERR + chmod 600 "$1" 2> $ERR errshow "chmod 600 $1" fi - mkswap "$1" >/dev/null 2>$ERR + mkswap "$1" > /dev/null 2> $ERR errshow "mkswap $1" - swapon "$1" >/dev/null 2>$ERR + swapon "$1" > /dev/null 2> $ERR errshow "swapon $1" return 0 } @@ -774,9 +771,9 @@ part_mount() mkdir -p "$mountp" if [[ $fs && ${FS_OPTS[$fs]} && $part != "$BOOT_PART" && $part != "$AUTO_ROOT_PART" ]] && select_mntopts "$fs"; then - mount -o "$MNT_OPTS" "$part" "$mountp" >/dev/null 2>&1 + mount -o "$MNT_OPTS" "$part" "$mountp" > /dev/null 2>&1 else - mount "$part" "$mountp" >/dev/null 2>&1 + mount "$part" "$mountp" > /dev/null 2>&1 fi part_mountconf "$part" "$mountp" || return 1 @@ -790,7 +787,7 @@ part_format() local part="$1" fs="$2" delay="$3" msg "Format" "\nFormatting $part as $fs\n" 0 - mkfs.$fs ${FS_CMD_FLAGS[$fs]} "$part" >/dev/null 2>$ERR + mkfs.$fs ${FS_CMD_FLAGS[$fs]} "$part" > /dev/null 2> $ERR errshow "mkfs.$fs ${FS_CMD_FLAGS[$fs]} "$part"" || return 1 FORMATTED+="$part " sleep $delay @@ -823,9 +820,9 @@ part_bootdev() BOOT_PART_NUM="${BOOT_PART: -1}" [[ $BOOT_PART = /dev/nvme* ]] && BOOT_DEV="${BOOT_PART%p[1-9]}" if [[ $SYS == 'UEFI' ]]; then - parted -s $BOOT_DEV set $BOOT_PART_NUM esp on >/dev/null 2>&1 + parted -s $BOOT_DEV set $BOOT_PART_NUM esp on > /dev/null 2>&1 else - parted -s $BOOT_DEV set $BOOT_PART_NUM boot on >/dev/null 2>&1 + parted -s $BOOT_DEV set $BOOT_PART_NUM boot on > /dev/null 2>&1 fi return 0 } @@ -996,7 +993,7 @@ select_filesystem() { local part="$1" fs='' cur='' local txt="\nSelect which filesystem to use for: $part\n\nDefault: ext4" - cur="$(lsblk -lno FSTYPE "$part" 2>/dev/null)" + cur="$(lsblk -lno FSTYPE "$part" 2> /dev/null)" # bail early if the partition was created in part_auto() [[ $cur && $part == "$AUTO_ROOT_PART" ]] && return 0 @@ -1130,10 +1127,12 @@ select_extra_partitions() install_main() { install_base - genfstab -U "$MNT" >"$MNT/etc/fstab" 2>$ERR 2>&1 - errshow 1 "genfstab -U $MNT >$MNT/etc/fstab" + genfstab -U "$MNT" > "$MNT/etc/fstab" 2> $ERR 2>&1 + errshow 1 "genfstab -U $MNT > $MNT/etc/fstab" [[ -f $MNT/swapfile ]] && sed -i "s~${MNT}~~" "$MNT/etc/fstab" install_packages + # video driver tearfree configs, MUST be done after package install to support nvidia + install_tearfree_conf "$MNT/etc/X11/xorg.conf.d" install_mkinitcpio install_boot chrun "hwclock --systohc --utc" || chrun "hwclock --systohc --utc --directisa" @@ -1177,55 +1176,34 @@ install_base() { clear tput cnorm - while kill -0 $BG_PID 2>/dev/null; do + while kill -0 $BG_PID 2> /dev/null; do clear; printf "\nA background install process is still running...\n"; sleep 1 done trap - EXIT unset BG_PID + # archiso files rm -rf "$MNT/etc/mkinitcpio-archiso.conf" find "$MNT/usr/lib/initcpio" -name 'archiso*' -type f -delete + + # remove/disable customizations done to airootfs during building + chrun "systemctl disable pacman-init.service choose-mirror.service" > /dev/null 2>&1 + rm -f "$MNT/etc/systemd/scripts/choose-mirror" + rm -f "$MNT/etc/systemd/system/"{choose-mirror.service,etc-pacman.d-gnupg.mount,pacman-init.service} sed -i 's/#\(Storage=\)volatile/\1auto/' "$MNT/etc/systemd/journald.conf" + sed -i 's/#\(HandleSuspendKey=\)ignore/\1suspend/' "$MNT/etc/systemd/logind.conf" + sed -i 's/#\(HandleHibernateKey=\)ignore/\1hibernate/' "$MNT/etc/systemd/logind.conf" + sed -i 's/#\(HandleLidSwitch=\)ignore/\1suspend/' "$MNT/etc/systemd/logind.conf" find "$MNT/boot" -name '*-ucode.img' -delete + # changing distro name? [[ $DIST != "ArchLabs" ]] || sed -i "s/ArchLabs/$DIST/g" "$MNT/etc/"{lsb-release,os-release} - if [[ $VM ]]; then - echo "Virtual machine detected, removing xorg configs" - find "$MNT/etc/X11/xorg.conf.d/" -name '*.conf' -delete -printf "remove %p\n" - elif lspci | grep ' VGA ' | grep -q 'Intel'; then - echo "Creating Intel Tear Free config /etc/X11/xorg.conf.d/20-intel.conf" - cat > "$MNT/etc/X11/xorg.conf.d/20-intel.conf" <<- EOF - Section "Device" - Identifier "Intel Graphics" - Driver "intel" - Option "TearFree" "true" - EndSection - EOF - elif lspci | grep ' VGA ' | grep -q 'AMD/ATI.*RX'; then # newer RX cards can use the amdgpu driver - echo "Creating AMD Tear Free config /etc/X11/xorg.conf.d/20-amdgpu.conf" - cat > "$MNT/etc/X11/xorg.conf.d/20-amdgpu.conf" <<- EOF - Section "Device" - Identifier "AMD Graphics" - Driver "amdgpu" - Option "TearFree" "true" - EndSection - EOF - elif lspci | grep ' VGA ' | grep -q 'AMD/ATI.*HD [2-6][0-9]*'; then # older HD 2xxx-6xxx cards must use the radeon driver - echo "Creating Radeon Tear Free config /etc/X11/xorg.conf.d/20-radeon.conf" - cat > "$MNT/etc/X11/xorg.conf.d/20-radeon.conf" <<- EOF - Section "Device" - Identifier "AMD Graphics" - Driver "radeon" - Option "TearFree" "on" - EndSection - EOF - fi + # vmlinuz, if this isn't copied the standard kernel may fail mkinitcpio + cp -vf "$RUN/x86_64/vmlinuz" "$MNT/boot/vmlinuz-linux" 2> $ERR 2>&1 + errshow 1 "cp -vf $RUN/x86_64/vmlinuz $MNT/boot/vmlinuz-linux" - if [[ -e /run/archiso/sfs/airootfs ]]; then - cp -vf "$RUN/x86_64/vmlinuz" "$MNT/boot/vmlinuz-linux" 2>$ERR 2>&1 - errshow 1 "cp -vf $RUN/x86_64/vmlinuz $MNT/boot/vmlinuz-linux" - fi + # copy network settings [[ -d /etc/netctl ]] && cp -rfv /etc/netctl "$MNT/etc/" [[ -f /etc/resolv.conf ]] && cp -fv /etc/resolv.conf "$MNT/etc/" [[ -e /etc/NetworkManager/system-connections ]] && cp -rvf /etc/NetworkManager/system-connections "$MNT/etc/NetworkManager/" @@ -1255,6 +1233,7 @@ install_base() BACKSPACE="guess" EOF printf "KEYMAP=%s\nFONT=%s\n" "$CMAP" "$FONT" > "$MNT/etc/vconsole.conf" + echo "$MYHOST" > "$MNT/etc/hostname" cat > "$MNT/etc/hosts" <<- EOF 127.0.0.1 localhost @@ -1285,14 +1264,14 @@ install_boot() fi prerun_$BOOTLDR - chrun "${BCMDS[$BOOTLDR]}" 2>$ERR 2>&1 + chrun "${BCMDS[$BOOTLDR]}" 2> $ERR 2>&1 errshow 1 "${BCMDS[$BOOTLDR]}" if [[ -d $MNT/hostrun ]]; then echo "Unmounting chroot directories" # cleanup the bind mounts we made earlier for the grub-probe module umount_dir "$MNT/hostrun/"{udev,lvm} - rm -rf "$MNT/hostrun" >/dev/null 2>&1 + rm -rf "$MNT/hostrun" > /dev/null 2>&1 fi if [[ $SYS == 'UEFI' ]]; then @@ -1311,27 +1290,28 @@ install_boot() install_user() { - local groups='audio,floppy,log,network,rfkill,scanner,storage,optical,power,wheel' + local groups='audio,video,floppy,log,network,rfkill,scanner,storage,optical,power,wheel' + if [[ -e $MNT/etc/X11/xorg.conf.d/20-nvida.conf && -e $MNT/usr/bin/optirun ]]; then + groups+=',bumblebee' + fi - rm -f "$MNT/root/.zshrc" # remove welcome message from root zshrc + rm -f "$MNT/root/.zlogin" # remove welcome message - chrun "chpasswd <<< 'root:$ROOT_PASS'" 2>$ERR 2>&1 + chrun "chpasswd <<< 'root:$ROOT_PASS'" 2> $ERR 2>&1 errshow 1 "set root password" if [[ $MYSHELL != 'zsh' ]]; then # root uses zsh by default - chrun "usermod -s /bin/$MYSHELL root" 2>$ERR 2>&1 + chrun "usermod -s /bin/$MYSHELL root" 2> $ERR 2>&1 errshow 1 "usermod -s /bin/$MYSHELL root" # copy the default mkshrc to /root if it was selected [[ $MYSHELL == 'mksh' ]] && cp -fv "$MNT/etc/skel/.mkshrc" "$MNT/root/.mkshrc" fi echo "Creating new user $NEWUSER and setting password" - chrun "useradd -m -u 1000 -g users -G $groups -s /bin/$MYSHELL $NEWUSER" 2>$ERR 2>&1 + chrun "useradd -m -u 1000 -g users -G $groups -s /bin/$MYSHELL $NEWUSER" 2> $ERR 2>&1 errshow 1 "useradd -m -u 1000 -g users -G $groups -s /bin/$MYSHELL $NEWUSER" - chrun "chpasswd <<< '$NEWUSER:$USER_PASS'" 2>$ERR 2>&1 + chrun "chpasswd <<< '$NEWUSER:$USER_PASS'" 2> $ERR 2>&1 errshow 1 "set $NEWUSER password" - chrun "pamixer --unmute; gtk-update-icon-cache /usr/share/icons/ArchLabs-Dark /usr/share/icons/ArchLabs-Light /usr/share/icons/ArchLabs" - if [[ $INSTALL_WMS == *dwm* ]];then install_suckless "/home/$NEWUSER" chroot [[ $INSTALL_WMS == 'dwm' ]] && rm -rf "$MNT/home/$NEWUSER/.config/xfce4" @@ -1363,7 +1343,7 @@ install_login() ly|sddm|gdm|lightdm) if [[ $LOGIN_WM == *dwm* ]]; then # dwm doesn't include an xsession file for display managers mkdir -p "$MNT/usr/share/xsessions" - cat >"$MNT/usr/share/xsessions/dwm.desktop" <<- EOF + cat > "$MNT/usr/share/xsessions/dwm.desktop" <<- EOF [Desktop Entry] Encoding=UTF-8 Name=Dwm @@ -1373,7 +1353,7 @@ install_login() EOF fi rm -rf "$serv" "$MNT/home/$NEWUSER/.xinitrc" - chrun "systemctl enable $LOGIN_TYPE.service" 2>$ERR 2>&1 + chrun "systemctl enable $LOGIN_TYPE.service" 2> $ERR 2>&1 errshow 1 "systemctl enable $LOGIN_TYPE.service" ${LOGIN_TYPE}_config ;; @@ -1402,25 +1382,32 @@ install_packages() local rmpkg="" local inpkg="$PACKAGES $USER_PKGS $AL_BASE_PKGS " - if pacman -Qq archlabs-installer >/dev/null 2>&1; then + if pacman -Qq archlabs-installer > /dev/null 2>&1; then rmpkg+="archlabs-installer " fi + if [[ $VM ]] && dmesg | grep -qi 'vbox'; then + inpkg+="virtualbox-guest-utils " + case "$KERNEL" in + linux) inpkg+="virtualbox-guest-modules-arch " ;; + *) inpkg+="virtualbox-guest-modules-dkms ${KERNEL}-headers " ;; + esac + fi + if [[ $MYSHELL == 'zsh' ]]; then inpkg+="zsh-completions " else rmpkg+="zsh " fi - if [[ $INSTALL_WMS == 'dwm' ]]; then # dwm only needs a very limited package set + if [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|fluxbox) ]]; then + inpkg+="$WM_BASE_PKGS " + elif [[ $INSTALL_WMS == 'dwm' ]]; then # dwm only needs a very limited package set inpkg+="nitrogen polkit-gnome gnome-keyring dunst " - else - [[ $INSTALL_WMS =~ (plasma|gnome|cinnamon) ]] || inpkg+="archlabs-ksuperkey " - [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|fluxbox) ]] && inpkg+="$WM_BASE_PKGS " fi # update and install crucial packages first to avoid issues - chrun "pacman -Syyu $KERNEL $BASE_PKGS base-devel ${LOGIN_PKGS[$LOGIN_TYPE]} $MYSHELL --noconfirm --needed" 2>$ERR 2>&1 + chrun "pacman -Syyu $KERNEL $BASE_PKGS base-devel ${LOGIN_PKGS[$LOGIN_TYPE]} $MYSHELL --noconfirm --needed" 2> $ERR 2>&1 errshow 1 "pacman -Syyu $KERNEL $BASE_PKGS base-devel ${LOGIN_PKGS[$LOGIN_TYPE]} $MYSHELL --noconfirm --needed" # remove the packages we don't want on the installed system @@ -1430,19 +1417,19 @@ install_packages() chrun "pacman -S iputils $UCODE --noconfirm" # install the packages chosen throughout the install - chrun "pacman -S $inpkg --needed --noconfirm" 2>$ERR 2>&1 + chrun "pacman -S $inpkg --needed --noconfirm" 2> $ERR 2>&1 errshow 1 "pacman -S $inpkg --needed --noconfirm" # bootloader packages if [[ $BOOTLDR == 'grub' ]]; then [[ $SYS == 'UEFI' ]] && local efib="efibootmgr" - chrun "pacman -S os-prober grub $efib --needed --noconfirm" 2>$ERR 2>&1 + chrun "pacman -S os-prober grub $efib --needed --noconfirm" 2> $ERR 2>&1 errshow 1 "pacman -S os-prober grub $efib --needed --noconfirm" elif [[ $BOOTLDR == 'refind-efi' ]]; then - chrun "pacman -S refind-efi efibootmgr --needed --noconfirm" 2>$ERR 2>&1 + chrun "pacman -S refind-efi efibootmgr --needed --noconfirm" 2> $ERR 2>&1 errshow 1 "pacman -S refind-efi efibootmgr --needed --noconfirm" elif [[ $SYS == 'UEFI' ]]; then - chrun "pacman -S efibootmgr --needed --noconfirm" 2>$ERR 2>&1 + chrun "pacman -S efibootmgr --needed --noconfirm" 2> $ERR 2>&1 errshow 1 "pacman -S efibootmgr --needed --noconfirm" fi @@ -1452,51 +1439,6 @@ install_packages() return 0 } -install_mkinitcpio() -{ - local add='' - [[ $LUKS ]] && add="encrypt" - [[ $LVM ]] && { [[ $add ]] && add+=" lvm2" || add+="lvm2"; } - sed -i "s/block filesystems/block ${add} filesystems ${HOOKS}/g" "$MNT/etc/mkinitcpio.conf" - chrun "mkinitcpio -p $KERNEL" 2>$ERR 2>&1 - errshow 1 "mkinitcpio -p $KERNEL" -} - -install_mirrorlist() -{ - if hash reflector >/dev/null 2>&1; then - reflector --verbose --score 80 -l 40 -f 5 --sort rate --save "$1" - elif hash rankmirrors >/dev/null 2>&1; then - echo "Sorting mirrorlist" - local key="access_key=5f29642060ab983b31fdf4c2935d8c56" - ip_add="$(curl -fsSL "http://api.ipstack.com/check&?$key&fields=ip" | python -c "import sys, json; print(json.load(sys.stdin)['ip'])")" - country="$(curl -fsSL "http://api.ipstack.com/$ip_add?$key&fields=country_code" | python -c "import sys, json; print(json.load(sys.stdin)['country_code'])")" - if [[ "$country" ]]; then - if [[ $country =~ (CA|US) ]]; then - # use both CA and US mirrors for CA or US countries - mirror="https://www.archlinux.org/mirrorlist/?country=US&country=CA&use_mirror_status=on" - elif [[ $country =~ (AU|NZ) ]]; then - # use both AU and NZ mirrors for AU or NZ countries - mirror="https://www.archlinux.org/mirrorlist/?country=AU&country=NZ&use_mirror_status=on" - else - mirror="https://www.archlinux.org/mirrorlist/?country=${country}&use_mirror_status=on" - fi - else # no country code so just grab all mirrors, will be a very slow sort but we don't have other options - mirror="https://www.archlinux.org/mirrorlist/?country=all&use_mirror_status=on" - fi - curl -fsSL "$mirror" | sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -n 6 - >"$1" - fi - - return 0 -} - -install_background() -{ - ( rsync -a /run/archiso/sfs/airootfs/ "$MNT/" && install_mirrorlist "$MNT/etc/pacman.d/mirrorlist" >/dev/null 2>&1 ) & - BG_PID=$! - trap "kill $BG_PID 2>/dev/null" EXIT -} - install_suckless() { local dir="$1/suckless" @@ -1523,6 +1465,118 @@ install_suckless() fi } +install_mkinitcpio() +{ + local add='' + [[ $LUKS ]] && add="encrypt" + [[ $LVM ]] && { [[ $add ]] && add+=" lvm2" || add+="lvm2"; } + sed -i "s/block filesystems/block ${add} filesystems ${HOOKS}/g" "$MNT/etc/mkinitcpio.conf" + chrun "mkinitcpio -p $KERNEL" 2> $ERR 2>&1 + errshow 1 "mkinitcpio -p $KERNEL" +} + +install_mirrorlist() +{ + if hash reflector > /dev/null 2>&1; then + reflector --verbose --score 80 -l 40 -f 5 --sort rate --save "$1" + elif hash rankmirrors > /dev/null 2>&1; then + echo "Sorting mirrorlist" + local key="access_key=5f29642060ab983b31fdf4c2935d8c56" + ip_add="$(curl -fsSL "http://api.ipstack.com/check&?$key&fields=ip" | python -c "import sys, json; print(json.load(sys.stdin)['ip'])")" + country="$(curl -fsSL "http://api.ipstack.com/$ip_add?$key&fields=country_code" | python -c "import sys, json; print(json.load(sys.stdin)['country_code'])")" + if [[ "$country" ]]; then + if [[ $country =~ (CA|US) ]]; then + # use both CA and US mirrors for CA or US countries + mirror="https://www.archlinux.org/mirrorlist/?country=US&country=CA&use_mirror_status=on" + elif [[ $country =~ (AU|NZ) ]]; then + # use both AU and NZ mirrors for AU or NZ countries + mirror="https://www.archlinux.org/mirrorlist/?country=AU&country=NZ&use_mirror_status=on" + else + mirror="https://www.archlinux.org/mirrorlist/?country=${country}&use_mirror_status=on" + fi + else # no country code so just grab all mirrors, will be a very slow sort but we don't have other options + mirror="https://www.archlinux.org/mirrorlist/?country=all&use_mirror_status=on" + fi + curl -fsSL "$mirror" | sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -n 6 - > "$1" + fi +} + +install_background() +{ + ( rsync -a /run/archiso/sfs/airootfs/ "$MNT/" && install_mirrorlist "$MNT/etc/pacman.d/mirrorlist" > /dev/null 2>&1 ) & + BG_PID=$! + trap "kill $BG_PID 2> /dev/null" EXIT +} + +install_tearfree_conf() +{ + local xpath="$1" + + if [[ $VM ]]; then + echo "Virtual machine detected, removing xorg configs" + find "$xpath/" -name '*.conf' -delete -printf "remove %p\n" + elif lspci | grep ' VGA ' | grep -q 'Intel'; then + echo "Creating Intel Tear Free config /etc/X11/xorg.conf.d/20-intel.conf" + cat > "$xpath/20-intel.conf" <<- EOF + Section "Device" + Identifier "Intel Graphics" + Driver "intel" + Option "TearFree" "true" + EndSection + EOF + elif lspci | grep ' VGA ' | grep -q 'AMD/ATI.*RX\|AMD/ATI.*R[579]'; then # newer RX, R5, R7, and R9 cards can use the amdgpu driver + echo "Creating AMD Tear Free config /etc/X11/xorg.conf.d/20-amdgpu.conf" + cat > "$xpath/20-amdgpu.conf" <<- EOF + Section "Device" + Identifier "AMD Graphics" + Driver "amdgpu" + Option "TearFree" "true" + EndSection + EOF + elif lspci | grep ' VGA ' | grep -q 'AMD/ATI.*HD [2-6][0-9]*'; then # older HD 2xxx-6xxx cards must use the radeon driver + echo "Creating Radeon Tear Free config /etc/X11/xorg.conf.d/20-radeon.conf" + cat > "$xpath/20-radeon.conf" <<- EOF + Section "Device" + Identifier "AMD Graphics" + Driver "radeon" + Option "TearFree" "on" + EndSection + EOF + elif lspci | grep ' VGA ' | grep -q 'NVIDIA'; then # nvidia cards require a bit of checking for notebook gpus + echo "Trying nvidia driver install" + if lspci | grep ' VGA ' | grep -q 'Intel\|AMD' && lspci | grep ' VGA ' | grep -q 'NVIDIA.*[6-9][1-8][05]M[X]\?\|NVIDIA.*Quadro.*[KMP][1-6][0-2][0]*M'; then # optimus + if [[ $xpath == *"$MNT"* ]]; then + chrun "nvidia-installer --bumblebee" + else + nvidia-installer --bumblebee + fi + else + if [[ $xpath == *"$MNT"* ]]; then + chrun "nvidia-installer" # unsure which card so try auto detection + else + nvidia-installer + fi + fi + if [[ -e $xpath/20-nvidia.conf ]]; then + echo "NVIDIA driver installed" + if [[ $xpath == *"$MNT"* ]]; then + echo "Trying to load the driver for live session" + nvidia-smi -r + fi + echo "To enable driver vsync:" + echo -e "\trun nvidia-settings (as root) on first boot\n\tenable 'ForceFullCompositionPipeline' under the advanced settings" + echo -e "\tlastly save the change to your nvida xorg config /etc/X11/xorg.conf.d/20-nvidia.conf" + echo -e "\tand remove everything but the Device and Screen sections from the file" + else + echo "Unable to install nvidia driver" + fi + return 0 + fi + + # remove nvidia installer from installed system when not running nvidia gpu + [[ $xpath == *"$MNT"* ]] && rm -rf "$MNT/usr/bin/nvidia-installer" "$MNT/var/lib/nvidia-installer" +} + ############################################################################### # display manager config # these are called based on which DM is chosen after it is installed @@ -1543,17 +1597,17 @@ lightdm_config() ly_config() { - : + : #TODO } gdm_config() { - : + : #TODO } sddm_config() { - : + : #TODO } ############################################################################### @@ -1570,9 +1624,9 @@ setup_grub() [[ $BOOT_DEV ]] || { part_device 1 || return 1; } BCMDS[grub]="grub-install --recheck --force --target=i386-pc $BOOT_DEV" else - BCMDS[grub]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1 + BCMDS[grub]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1 grub-install --recheck --force --target=x86_64-efi --efi-directory=/$BOOTDIR --bootloader-id=$DIST" - grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1 + grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1 fi BCMDS[grub]="mkdir -p /run/udev /run/lvm && @@ -1590,12 +1644,12 @@ prerun_grub() sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g; s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" "$MNT/etc/default/grub" if [[ $LUKS_DEV ]]; then - sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" "$MNT/etc/default/grub" 2>$ERR 2>&1 + sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" "$MNT/etc/default/grub" 2> $ERR 2>&1 errshow 1 "sed -i 's~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g' $MNT/etc/default/grub" fi if [[ $SYS == 'BIOS' && $LVM && -z $SEP_BOOT ]]; then - sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" "$MNT/etc/default/grub" 2>$ERR 2>&1 + sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" "$MNT/etc/default/grub" 2> $ERR 2>&1 errshow 1 "sed -i 's/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g' $MNT/etc/default/grub" fi @@ -1614,7 +1668,7 @@ setup_efistub() prerun_efistub() { - BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1 + BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1 efibootmgr -v -d $BOOT_DEV -p $BOOT_PART_NUM -c -L '${DIST} Linux' -l /vmlinuz-${KERNEL} \ -u 'root=$ROOT_PART_ID rw $([[ $UCODE ]] && printf 'initrd=\%s.img ' "$UCODE")initrd=\initramfs-${KERNEL}.img'" } @@ -1625,7 +1679,7 @@ setup_syslinux() EDIT_FILES[bootloader]="/boot/syslinux/syslinux.cfg" else EDIT_FILES[bootloader]="/boot/EFI/syslinux/syslinux.cfg" - BCMDS[syslinux]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1 + BCMDS[syslinux]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1 efibootmgr -v -c -d $BOOT_DEV -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST" fi } @@ -1640,11 +1694,11 @@ prerun_syslinux() s="/usr/lib/syslinux/efi64" d=''; fi - mkdir -pv "$c" 2>$ERR 2>&1 + mkdir -pv "$c" 2> $ERR 2>&1 errshow 1 "mkdir -pv $c" - cp -rfv "$s/"* "$c/" 2>$ERR 2>&1 + cp -rfv "$s/"* "$c/" 2> $ERR 2>&1 errshow 1 "cp -rfv $s/* $c/" - cp -fv "$RUN/syslinux/splash.png" "$c/" 2>$ERR 2>&1 + cp -fv "$RUN/syslinux/splash.png" "$c/" 2> $ERR 2>&1 errshow 0 "cp -fv $RUN/syslinux/splash.png $c/" cat > "$c/syslinux.cfg" <<- EOF UI vesamenu.c32 @@ -1691,7 +1745,7 @@ prerun_syslinux() setup_refind-efi() { EDIT_FILES[bootloader]="/boot/refind_linux.conf" - BCMDS[refind-efi]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1; refind-install" + BCMDS[refind-efi]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1; refind-install" } prerun_refind-efi() @@ -1721,7 +1775,7 @@ prerun_refind-efi() setup_systemd-boot() { EDIT_FILES[bootloader]="/boot/loader/entries/$DIST.conf" - BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1; bootctl --path=/boot install" + BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1; bootctl --path=/boot install" } prerun_systemd-boot() @@ -1776,7 +1830,7 @@ lvm_menu() "Back" "Return to the main menu" case "$choice" in "$_lvmnew") lvm_create && break ;; - "$_lvmdel") lvm_delgroup && yesno "$_lvmdel" "$_lvmdelask" && vgremove -f "$DEL_VG" >/dev/null 2>&1 ;; + "$_lvmdel") lvm_delgroup && yesno "$_lvmdel" "$_lvmdelask" && vgremove -f "$DEL_VG" > /dev/null 2>&1 ;; "$_lvmdelall") lvm_del_all ;; *) break ;; esac @@ -1788,16 +1842,16 @@ lvm_menu() lvm_detect() { local v pv - pv="$(pvs -o pv_name --noheading 2>/dev/null)" - v="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)" - VGROUP="$(vgs -o vg_name --noheading 2>/dev/null)" + pv="$(pvs -o pv_name --noheading 2> /dev/null)" + v="$(lvs -o vg_name,lv_name --noheading --separator - 2> /dev/null)" + VGROUP="$(vgs -o vg_name --noheading 2> /dev/null)" if [[ $VGROUP && $v && $pv ]]; then msg "LVM Setup" "\nActivating existing logical volume management.\n" 0 - modprobe dm-mod >/dev/null 2>$ERR + modprobe dm-mod > /dev/null 2> $ERR errshow 'modprobe dm-mod' - vgscan >/dev/null 2>&1 - vgchange -ay >/dev/null 2>&1 + vgscan > /dev/null 2>&1 + vgchange -ay > /dev/null 2>&1 fi } @@ -1812,7 +1866,7 @@ lvm_create() lvm_extra_lvs || return 1 lvm_volume_name "$_lvmlvname\nNOTE: This LV will use up all remaining space in the volume group (${VGROUP_MB}MB)" || return 1 msg "$_lvmnew (LV:$VOL_COUNT)" "\nCreating volume $VNAME from remaining space in $VGROUP\n" 0 - lvcreate -l +100%FREE "$VGROUP" -n "$VNAME" >/dev/null 2>$ERR + lvcreate -l +100%FREE "$VGROUP" -n "$VNAME" > /dev/null 2> $ERR errshow "lvcreate -l +100%FREE $VGROUP -n $VNAME" || return 1 LVM='logical volume'; sleep 0.5 txt="\nDone, volume: $VGROUP-$VNAME (${VOLUME_SIZE:-${VGROUP_MB}MB}) has been created.\n" @@ -1871,7 +1925,7 @@ lvm_mkgroup() done msg "$_lvmnew" "\nCreating volume group: $VGROUP\n" 0 - vgcreate -f "$VGROUP" $LVM_PARTS >/dev/null 2>$ERR + vgcreate -f "$VGROUP" $LVM_PARTS > /dev/null 2> $ERR errshow "vgcreate -f $VGROUP $LVM_PARTS" || return 1 SIZE=$(vgdisplay "$VGROUP" | awk '/VG Size/ { gsub(/[^0-9.]/, ""); print int($0) }') @@ -1889,15 +1943,15 @@ lvm_mkgroup() lvm_del_all() { local v pv - pv="$(pvs -o pv_name --noheading 2>/dev/null)" - v="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)" - VGROUP="$(vgs -o vg_name --noheading 2>/dev/null)" + pv="$(pvs -o pv_name --noheading 2> /dev/null)" + v="$(lvs -o vg_name,lv_name --noheading --separator - 2> /dev/null)" + VGROUP="$(vgs -o vg_name --noheading 2> /dev/null)" if [[ $VGROUP || $v || $pv ]]; then if yesno "$_lvmdelall" "$_lvmdelask"; then - for i in $v; do lvremove -f "/dev/mapper/$i" >/dev/null 2>&1; done - for i in $VGROUP; do vgremove -f "$i" >/dev/null 2>&1; done - for i in $pv; do pvremove -f "$i" >/dev/null 2>&1; done + for i in $v; do lvremove -f "/dev/mapper/$i" > /dev/null 2>&1; done + for i in $VGROUP; do vgremove -f "$i" > /dev/null 2>&1; done + for i in $pv; do pvremove -f "$i" > /dev/null 2>&1; done LVM='' fi else @@ -1926,7 +1980,7 @@ lvm_extra_lvs() while (( VOL_COUNT > 1 )); do lvm_volume_name "$_lvmlvname" && lvm_lv_size || return 1 msg "$_lvmnew (LV:$VOL_COUNT)" "\nCreating a $VOLUME_SIZE volume $VNAME in $VGROUP\n" 0 - lvcreate -L "$VOLUME_SIZE" "$VGROUP" -n "$VNAME" >/dev/null 2>$ERR + lvcreate -L "$VOLUME_SIZE" "$VGROUP" -n "$VNAME" > /dev/null 2> $ERR errshow "lvcreate -L $VOLUME_SIZE $VGROUP -n $VNAME" || return 1 msg "$_lvmnew (LV:$VOL_COUNT)" "\nDone, logical volume (LV) $VNAME ($VOLUME_SIZE) has been created.\n" (( VOL_COUNT-- )) @@ -1998,7 +2052,7 @@ luks_menu() luks_open() { - modprobe -a dm-mod dm_crypt >/dev/null 2>&1 + modprobe -a dm-mod dm_crypt > /dev/null 2>&1 umount_dir "$MNT" part_find 'part|crypt|lvm' || return 1 @@ -2012,7 +2066,7 @@ luks_open() luks_pass "$_luksopen" || return 1 msg "$_luksopen" "\nOpening encrypted partition: $LUKS_NAME\n\nUsing device/volume: $LUKS_PART\n" 0 - cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR + cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> $ERR errshow "cryptsetup open --type luks $LUKS_PART $LUKS_NAME" || return 1 LUKS='encrypted'; luks_show return 0 @@ -2029,7 +2083,7 @@ luks_pass() dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " $t " --mixedform "$_luksomenu" 0 0 0 \ "Name:" 1 1 "${ans[0]}" 1 7 "$COLUMNS" 0 0 \ "Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \ - "Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 2>"$ANS" || return 1 + "Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 2> "$ANS" || return 1 mapfile -t ans <"$ANS" @@ -2055,7 +2109,7 @@ luks_show() luks_setup() { - modprobe -a dm-mod dm_crypt >/dev/null 2>&1 + modprobe -a dm-mod dm_crypt > /dev/null 2>&1 umount_dir "$MNT" part_find 'part|lvm' || return 1 @@ -2075,9 +2129,9 @@ luks_basic() { luks_setup || return 1 msg "$_luksnew" "\nCreating encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0 - cryptsetup -q luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2>$ERR + cryptsetup -q luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2> $ERR errshow "cryptsetup -q luksFormat $LUKS_PART" || return 1 - cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR + cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> $ERR errshow "cryptsetup open $LUKS_PART $LUKS_NAME" || return 1 LUKS='encrypted'; luks_show return 0 @@ -2090,9 +2144,9 @@ luks_advanced() dlg cipher input "LUKS Encryption" "$_lukskey" "-s 512 -c aes-xts-plain64" [[ $cipher ]] || return 1 msg "$_luksadv" "\nCreating encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0 - cryptsetup -q $cipher luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2>$ERR + cryptsetup -q $cipher luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2> $ERR errshow "cryptsetup -q $cipher luksFormat $LUKS_PART" || return 1 - cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR + cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> $ERR errshow "cryptsetup open $LUKS_PART $LUKS_NAME" || return 1 luks_show return 0 @@ -2142,16 +2196,16 @@ dlg() tput civis case "$dlg_t" in - menu) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --menu "$body" 0 0 $n "$@" 2>"$ANS" || return 1 ;; - check) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --checklist "$body" 0 0 $n "$@" 2>"$ANS" || return 1 ;; + menu) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --menu "$body" 0 0 $n "$@" 2> "$ANS" || return 1 ;; + check) dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --checklist "$body" 0 0 $n "$@" 2> "$ANS" || return 1 ;; input) tput cnorm local def="$1" # assign default value for input shift if [[ $1 == 'limit' ]]; then - dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 --title " $title " --inputbox "$body" 0 0 "$def" 2>"$ANS" || return 1 + dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 --title " $title " --inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1 else - dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --inputbox "$body" 0 0 "$def" 2>"$ANS" || return 1 + dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1 fi ;; esac @@ -2182,67 +2236,82 @@ live() clear die 0 elif ! net_connect; then - msg "Not Connected" "\nRunning live requires an active internet connection.\n\nExiting..\n" 2 + msg "Not Connected" "\nRunning live requires an active internet connection to install packages.\n\nExiting..\n" 2 die 1 elif (( $(awk '/MemTotal/ {print int($2 / 1024)}' /proc/meminfo) < 2500)); then - msg "Not Enough Memory" "\nRunning live requires at least 2.5G of system memory.\n\nExiting..\n" 2 + msg "Not Enough Memory" "\nLive session requires at least 2.5G of system memory for installing packages.\n\nExiting..\n" 2 die 1 - else - clear - echo "Sorting mirrorlist first" - mount /run/archiso/cowspace -o remount,size=2G - install_mirrorlist "/etc/pacman.d/mirrorlist" - pacman -Syyu --noconfirm || die 1 - pacman -S $BASE_PKGS $AL_BASE_PKGS xorg-xinit --needed --noconfirm || die 1 - case "$ses" in - i3-gaps|openbox|fluxbox|bspwm|awesome) pacman -S "$ses" $WM_BASE_PKGS ${WM_EXT[$ses]} --needed --noconfirm || die 1 ;; - gnome|plasma|cinnamon|xfce4) pacman -S "$ses" ${WM_EXT[$ses]} --needed --noconfirm || die 1 ;; - dwm) { pacman -S git --needed --noconfirm || die 1; }; install_suckless "/root" nochroot ;; - esac - pamixer --unmute - gtk-update-icon-cache /usr/share/icons/ArchLabs-Dark /usr/share/icons/ArchLabs-Light /usr/share/icons/ArchLabs - pacman -Scc --noconfirm - rm -rf "/var/cache/pacman/pkg/"* - cp -rfT /etc/skel /root || die 1 - sed -i "/exec/ c exec ${WM_SESSIONS[$ses]}" /root/.xinitrc - printf "\n%s has been set as the login session in ~/.xinitrc, to start the session simply run\n\n\tstartx\n\n" "${WM_SESSIONS[$ses]}" - die 0 fi + + clear + echo "Sorting mirrorlist" + mount /run/archiso/cowspace -o remount,size=2G + install_mirrorlist "/etc/pacman.d/mirrorlist" + pacman -Syyu --noconfirm || die 1 + rm -rf "/var/cache/pacman/pkg/"* + pacman -S $BASE_PKGS $AL_BASE_PKGS xorg-xinit --needed --noconfirm || die 1 + rm -rf "/var/cache/pacman/pkg/"* + case "$ses" in + i3-gaps|openbox|fluxbox|bspwm|awesome|xfce4) pacman -S "$ses" $WM_BASE_PKGS ${WM_EXT[$ses]} --needed --noconfirm || die 1 ;; + gnome|plasma|cinnamon) pacman -S "$ses" ${WM_EXT[$ses]} --needed --noconfirm || die 1 ;; + dwm) { pacman -S git --needed --noconfirm || die 1; }; install_suckless "/root" nochroot ;; + esac + rm -rf "/var/cache/pacman/pkg/"* + [[ $VM ]] && dmesg | grep -qi 'vbox' && pacman -S virtualbox-guest-utils virtualbox-guest-modules-arch --needed --noconfirm + pacman -Scc --noconfirm + rm -rf "/var/cache/pacman/pkg/"* + cp -rfT /etc/skel /root + install_tearfree_conf "/etc/X11/xorg.conf.d" + case "$ses" in + plasma|gnome|cinnamon) sed -i '/super/d; /nitrogen/d; /compton/d' /root/.xprofile ;; + dwm) sed -i '/super/d; /compton/d' /root/.xprofile ;; + esac + rm -f /root/.zlogin + echo -e "pulseaudio &\n(sleep 1; pamixer --unmute --set-volume 50) &" >> /root/.xprofile + sed -i "/exec/ c exec ${WM_SESSIONS[$ses]}" /root/.xinitrc + printf "\n%s has been set as the login session in ~/.xinitrc, to start the session simply run\n\n\tstartx\n\n" "${WM_SESSIONS[$ses]}" + die 0 } usage() { - cat <<-EOF + cat <<- EOF usage: $1 [-hdl] [session] options: - -h, --help print this message and exit - -l, --live install and setup a live session - -d, --debug enable xtrace and log output to $DBG + -h, --help print this message and exit + -l, --live install and setup a live session + -d, --debug enable xtrace and log output to $DBG sessions: - i3-gaps - A fork of i3wm with more features including gaps - openbox - A lightweight, powerful, and highly configurable stacking wm - dwm - A dynamic WM for X that manages windows in tiled, floating, or monocle layouts - awesome - A customized Awesome WM session created by @elanapan - bspwm - A tiling wm that represents windows as the leaves of a binary tree - fluxbox - A lightweight and highly-configurable window manager - gnome - A desktop environment that aims to be simple and easy to use - cinnamon - A desktop environment combining traditional desktop with modern effects - plasma - A kde software project currently comprising a full desktop environment - xfce4 - A lightweight and modular desktop environment based on gtk+2/3 + i3-gaps - A fork of i3wm with more features including gaps + openbox - A lightweight, powerful, and highly configurable stacking wm + dwm - A dynamic WM for X that manages windows in tiled, floating, or monocle layouts + awesome - A customized Awesome WM session created by @elanapan + bspwm - A tiling wm that represents windows as the leaves of a binary tree + fluxbox - A lightweight and highly-configurable window manager + gnome - A desktop environment that aims to be simple and easy to use + cinnamon - A desktop environment combining traditional desktop with modern effects + plasma - A kde software project currently comprising a full desktop environment + xfce4 - A lightweight and modular desktop environment based on gtk+2/3 distro name: - set the DIST environment variable before launching the installer eg. + set the DIST environment variable before launching the installer eg. - DIST='MyDistro' $1 + DIST='MyDistro' $1 + + root/boot partition: + + set the ROOT_PART and/or BOOT_PART environment variables before launching the installer eg. + + ROOT_PART='/dev/sda2' BOOT_PART='/dev/sda1' $1 editor used: - set the EDITOR environment variable before launching the installer eg. + set the EDITOR environment variable before launching the installer eg. - EDITOR='nano' $1 + EDITOR='nano' $1 EOF exit 0 @@ -2346,9 +2415,9 @@ umount_dir() mount | grep -q 'swap' && swapoff -a for dir; do if [[ -d $dir ]] && mount | grep -q "on $dir "; then - if ! umount "$dir" 2>/dev/null; then + if ! umount "$dir" 2> /dev/null; then sleep 0.5 - umount -f "$dir" 2>/dev/null || umount -l "$dir" + umount -f "$dir" 2> /dev/null || umount -l "$dir" fi fi done @@ -2364,7 +2433,7 @@ net_connect() { if chk_connect; then return 0 - elif hash nmtui >/dev/null 2>&1; then + elif hash nmtui > /dev/null 2>&1; then tput civis if [[ $TERM == 'linux' ]]; then printf "%b" "\e]P1191919" "\e]P4191919" @@ -2374,7 +2443,7 @@ net_connect() nmtui-connect fi chk_connect - elif hash wifi-menu >dev/null 2>&1; then + elif hash wifi-menu > /dev/null 2>&1; then wifi-menu chk_connect else @@ -2421,9 +2490,9 @@ system_identify() UCODE="intel-ucode" fi - modprobe -q efivarfs >/dev/null 2>&1 + modprobe -q efivarfs > /dev/null 2>&1 - _prep="\nOnce a step is finished a step you will be returned here, if the step was successful the cursor will be advanced to the next step.\nIf a step is unsuccessful the cursor will be placed on the step required to advance (when possible).\n\nTo begin the install you should have:\n\n - A root (/) partition mounted." + _prep="\nOnce a step is finished a step you will be returned here, if the step was successful the cursor will be advanced to the next step.\nIf a step is unsuccessful the cursor will be placed on the step required to advance (when possible).\n\nSteps beginning with an asterix (*) are required before continuing.\n\nTo begin the install you should have:\n\n - A root (/) partition mounted." if [[ -d /sys/firmware/efi/efivars ]]; then export SYS="UEFI" grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars @@ -2448,21 +2517,26 @@ if (( UID != 0 )); then elif ! grep -qwm 1 'lm' /proc/cpuinfo; then msg "Not x86_64 Architecture" "\nThis installer only supports x86_64 architectures.\n\nExiting..\n" 2 die 1 -else - case "$1" in - -d|--debug) debug ;; - -h|--help) usage "$0" ;; - -l|--live) - case "$2" in - gnome|cinnamon|dwm|plasma|xfce4|i3-gaps|openbox|fluxbox|bspwm|awesome) live "$2" ;; - *) echo "error: invalid session for -l, --live, see -h, --help"; die 1 ;; - esac ;; - esac fi # trap ^C to perform cleanup trap 'printf "\n^C\n" && die 1' INT +while getopts ":hl:d" OPT; do + case "$OPT" in + d) debug ;; + h) usage "$0" ;; + l) + if [[ "${!WM_SESSIONS[@]}" =~ $OPTARG ]]; then + live "$OPTARG" + else + echo "error: invalid session for -l, see -h for help"; die 1 + fi + ;; + \?) echo "error: invalid option: -$OPTARG"; die 1 ;; + esac +done + system_identify system_devices @@ -2474,8 +2548,6 @@ elif ! net_connect; then msg "Not Connected" "\nThis installer requires an active internet connection.\n\nExiting..\n" 2 die 1 fi -EXMNTS="" -FORMATTED="" while :; do main