2019-02-23 21:09:47 -06:00
#!/bin/bash
# This program is free software, provided under the GNU GPL
2020-05-17 13:05:57 -05:00
# Written by Nathaniel Maia for Archlabs, works in most Arch based distros
2019-02-23 21:09:47 -06:00
# Some ideas and code reworked from other resources
2019-10-19 17:18:42 -05:00
# AIF, Calamares, and the Arch Wiki.. Credit where credit is due
2019-02-23 21:09:47 -06:00
2020-05-14 13:25:10 -05:00
# shellcheck disable=SC2086,SC2046,SC2254,SC2164
2020-05-14 23:06:50 -05:00
VER=2.1.50
2019-02-23 21:09:47 -06:00
2019-10-20 21:49:12 -05:00
# default values {
2019-02-23 21:09:47 -06:00
2020-04-25 22:03:14 -05:00
: "${DIST=ArchLabs}" # distro name if not set
: "${MNT=/mnt}" # installation root mountpoint if not set
2019-10-19 17:18:42 -05:00
ANS=/tmp/ans # dialog answer output file
2019-09-24 01:39:10 -05:00
FONT=ter-i16n # font used for the linux console
2019-10-19 17:18:42 -05:00
HOOKS=shutdown # additional mkinitcpio HOOKS
2019-09-24 01:39:10 -05:00
SEL=0 # currently selected menu item
2020-04-18 16:37:22 -05:00
PACSTRAP=1 # use a fresh pacstrap or copy the iso filesystem
2019-10-19 17:18:42 -05:00
SYS=Unknown # bios type, to be determined: UEFI/BIOS
2019-11-23 19:36:08 -06:00
BG=/tmp/bgout # output from background process
2019-10-19 17:18:42 -05:00
ERR=/tmp/errlog # stderr log used internally by errshow()
DBG=/tmp/debuglog # debug log file when passed -d
2019-09-24 01:39:10 -05:00
RUN=/run/archiso/bootmnt/arch/boot # path for live system /boot
2020-05-14 02:16:20 -05:00
BTRFS=0 # is btrfs used, 1 = btrfs alone, 2 = btrfs + subvolume(s)
2019-10-19 17:18:42 -05:00
EXMNTS="" # extra partitions that were mounted, used to verify mountpoint and show user
2019-10-20 21:49:12 -05:00
USER_CMD="" # optional command(s) entered by the user to run in the chroot
2020-05-03 01:25:41 -05:00
VM="$(systemd-detect-virt)" # system running in a virtual machine
2020-03-01 14:14:10 -06:00
2019-10-19 17:18:42 -05:00
export DIALOGOPTS="--cr-wrap" # dialog environment variable to hold default options, see `man dialog`
2019-02-23 21:09:47 -06:00
2020-04-25 22:03:14 -05:00
# package arrays built later from user selections
typeset -a SES_PKGS USER_PKGS
2020-04-23 23:03:44 -05:00
2020-04-25 22:03:14 -05:00
# packages installed specific to archlabs, installed when any session is chosen {
2020-04-23 23:03:44 -05:00
typeset -a BASE_PKGS=(
2020-04-25 22:03:14 -05:00
"alsa-firmware"
"alsa-lib"
"alsa-plugins"
"archlabs-baph"
"archlabs-fonts"
"archlabs-icons"
"archlabs-keyring"
"archlabs-keyring"
"archlabs-scripts"
"archlabs-skel-base"
"archlabs-themes"
"archlabs-wallpapers"
"ffmpeg"
"gst-libav"
"gst-plugins-base"
"gst-plugins-good"
"gstreamer"
"gtk3"
"gvfs"
"libmad"
"libmatroska"
"pamixer"
"pavucontrol"
"pulseaudio"
"pulseaudio-alsa"
"scrot"
"sudo"
"xdg-user-dirs"
"xorg-drivers" # TODO: should we only install specific drivers?
"xorg-font-utils"
"xorg-iceauth"
"xorg-server"
"xorg-server-common"
2020-04-25 22:37:57 -05:00
"xorg-setxkbmap"
2020-04-25 22:03:14 -05:00
"xorg-xauth"
"xorg-xbacklight"
"xorg-xinput"
"xorg-xkbcomp"
"xorg-xkill"
"xorg-xmodmap"
"xorg-xprop"
"xorg-xrandr"
"xorg-xrdb"
"xorg-xset"
"xorg-xsetroot"
"xterm"
) # }
# packages installed for most window managers to provide some basic functionality {
2020-04-23 23:03:44 -05:00
typeset -a WM_PKGS=(
2020-04-25 22:03:14 -05:00
"arandr"
"dunst"
"exo"
"feh"
"gnome-keyring"
"gsimplecal"
"network-manager-applet"
"nitrogen"
"polkit-gnome"
"picom"
"volumeicon"
"wmctrl"
"xclip"
"xdotool"
"xfce4-power-manager"
"xfce4-settings"
) # }
2019-10-01 01:09:06 -05:00
2020-04-25 22:03:14 -05:00
# packages installed when choosing to use pacstrap {
2020-04-23 23:03:44 -05:00
typeset -a ISO_PKGS=(
2020-04-25 22:03:14 -05:00
"arch-install-scripts"
"crda"
"ddrescue"
"dhclient"
"dhcpcd"
"diffutils"
"dmraid"
"dnsmasq"
"dnsutils"
"dosfstools"
"ethtool"
"exfat-utils"
"f2fs-tools"
"fsarchiver"
"hdparm"
"iputils"
"ipw2100-fw"
"ipw2200-fw"
"iwd"
"lftp"
"linux-firmware"
"lm_sensors"
"lsb-release"
"lsscsi"
"man-db"
"man-pages"
"mdadm"
"mtools"
"nfs-utils"
"nilfs-utils"
"ntp"
"openconnect"
"openssh"
"openvpn"
"p7zip"
"pacman-contrib"
"partclone"
"parted"
"partimage"
"ppp"
"pptpclient"
"reflector"
"rp-pppoe"
"sdparm"
"sg3_utils"
"tcpdump"
"terminus-font"
"testdisk"
"ttf-dejavu"
"usb_modeswitch"
"usbutils"
"vi"
"wireless-regdb"
"wireless_tools"
"wpa_supplicant"
"wvdial"
) # }
2020-04-18 19:11:19 -05:00
2019-04-30 00:57:17 -05:00
SYS_MEM="$(awk '/MemTotal/ {print int($2 / 1024) "M"}' /proc/meminfo)"
LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if ($1) {print $1 " - "}}' /etc/locale.gen)"
CMAPS="$(find /usr/share/kbd/keymaps -name '*.map.gz' | awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " - "}' | sort)"
2019-10-01 01:09:06 -05:00
2019-02-23 21:09:47 -06:00
[[ $LINES ]] || LINES=$(tput lines)
[[ $COLUMNS ]] || COLUMNS=$(tput cols)
2019-09-24 01:39:10 -05:00
# }
2019-02-23 21:09:47 -06:00
2019-08-20 17:52:25 -05:00
# commands used to install each bootloader, however most get modified during runtime {
2019-02-23 21:09:47 -06:00
declare -A BCMDS=(
2020-04-25 22:03:14 -05:00
[efistub]='efibootmgr -v -d /dev/sda -p 1 -c -l'
[grub]='grub-install --recheck --force'
2019-09-24 01:39:10 -05:00
[refind-efi]='refind-install'
2020-04-25 22:03:14 -05:00
[syslinux]='syslinux-install_update -i -a -m'
[systemd-boot]='bootctl --path=/boot install'
2019-02-23 21:09:47 -06:00
) # }
2019-11-23 19:36:08 -06:00
# sessions that provide their own super bind and set the wallpaper {
2020-03-01 14:14:10 -06:00
declare WM_PKG_SES='openbox|bspwm|i3-gaps|fluxbox|jwm|awesome'
2019-11-23 19:36:08 -06:00
declare SELF_CONTAINED='plasma|gnome|cinnamon|deepin'
declare SELF_CONTAINED_SES='startplasma-x11|gnome-session|startdde|cinnamon-session'
# }
2019-08-20 17:52:25 -05:00
# executable name for each wm/de used in ~/.xinitrc {
2019-02-23 21:09:47 -06:00
declare -A WM_SESSIONS=(
2020-04-25 22:03:14 -05:00
[awesome]='awesome'
[bspwm]='bspwm'
[cinnamon]='cinnamon-session'
[deepin]='startdde'
[dwm]='dwm'
[fluxbox]='startfluxbox'
[gnome]='gnome-session'
[i3-gaps]='i3'
[jwm]='jwm'
2020-05-03 21:31:31 -05:00
[lxqt]='startlxqt'
2020-04-25 22:03:14 -05:00
[openbox]='openbox-session'
[plasma]='startplasma-x11'
[xfce4]='startxfce4'
2019-02-23 21:09:47 -06:00
) # }
2019-12-26 20:21:13 -06:00
# Packages installed for each wm/de, most are depends of the skel packages {
2019-02-23 21:09:47 -06:00
declare -A WM_EXT=(
2020-04-25 22:03:14 -05:00
[awesome]='archlabs-skel-awesome'
[bspwm]='archlabs-skel-bspwm'
[cinnamon]='gnome-terminal'
[deepin]='deepin-extra'
[dwm]='nitrogen polkit-gnome gnome-keyring dunst lxappearance'
[fluxbox]='archlabs-skel-fluxbox'
[gnome]='gnome-tweaks'
[i3-gaps]='archlabs-skel-i3-gaps'
[jwm]=''
2020-05-03 21:31:31 -05:00
[lxqt]='breeze-icons picom libpulse network-manager-applet'
2020-04-25 22:03:14 -05:00
[openbox]='archlabs-skel-openbox'
[plasma]='kde-applications-meta powerdevil'
[xfce4]='archlabs-skel-xfce4 xfce4-goodies'
2019-02-23 21:09:47 -06:00
) # }
2019-08-20 17:52:25 -05:00
# files offered for editing after install is complete {
2019-02-23 21:09:47 -06:00
declare -A EDIT_FILES=(
2019-08-18 15:37:49 -05:00
[login]='' # login is populated once we know the username and shell
2020-04-25 22:03:14 -05:00
[fstab]='/etc/fstab'
[sudoers]='/etc/sudoers'
[crypttab]='/etc/crypttab'
[pacman]='/etc/pacman.conf'
[console]='/etc/vconsole.conf'
[mkinitcpio]='/etc/mkinitcpio.conf'
[hostname]='/etc/hostname /etc/hosts'
2019-08-27 03:50:42 -05:00
[bootloader]="/boot/loader/entries/$DIST.conf" # ** based on bootloader
2020-04-25 22:03:14 -05:00
[locale]='/etc/locale.conf /etc/default/locale'
[keyboard]='/etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard'
2019-02-23 21:09:47 -06:00
) # }
2019-09-24 01:39:10 -05:00
# mkfs command flags for filesystem formatting {
declare -A FS_CMD_FLAGS=(
2020-05-14 23:40:59 -05:00
[btrfs]='-fq'
2020-04-25 22:03:14 -05:00
[ext2]='-q'
[ext3]='-q'
[ext4]='-q'
[f2fs]='-f'
[jfs]='-q'
[nilfs2]='-q'
[ntfs]='-q'
[reiserfs]='-q'
[vfat]='-F32'
2020-05-17 11:36:29 -05:00
[xfs]='-fq'
2019-02-23 21:09:47 -06:00
) # }
2019-08-20 17:52:25 -05:00
# mount options for each filesystem {
2019-02-23 21:09:47 -06:00
declare -A FS_OPTS=(
2020-04-25 22:03:14 -05:00
[vfat]=''
[ntfs]=''
[ext2]=''
[ext3]=''
2019-02-23 21:09:47 -06:00
[jfs]='discard errors=continue errors=panic nointegrity'
[reiserfs]='acl nolog notail replayonly user_xattr off'
[ext4]='discard dealloc nofail noacl relatime noatime nobarrier nodelalloc'
[xfs]='discard filestreams ikeep largeio noalign nobarrier norecovery noquota wsync'
[nilfs2]='discard nobarrier errors=continue errors=panic order=relaxed order=strict norecovery'
[f2fs]='discard fastboot flush_merge data_flush inline_xattr inline_data noinline_data inline_dentry no_heap noacl nobarrier norecovery noextent_cache disable_roll_forward disable_ext_identify'
2020-05-14 02:16:20 -05:00
[btrfs]='autodefrag compress=zlib compress=lzo compress=no compress-force=zlib compress-force=lzo discard noacl noatime nodatasum nospace_cache recovery skip_balance space_cache ssd ssd_spread'
2019-02-23 21:09:47 -06:00
) # }
2019-08-19 21:19:40 -05:00
# packages installed for each login option {
declare -A LOGIN_PKGS=(
2020-04-25 22:03:14 -05:00
[gdm]='gdm'
2019-08-19 21:19:40 -05:00
[lightdm]='lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice'
2020-04-25 22:03:14 -05:00
[sddm]='sddm'
[xinit]='xorg-xinit'
2019-08-19 21:19:40 -05:00
) # }
2019-08-20 17:52:25 -05:00
# extras installed for user selected packages {
# if a package requires additional packages that aren't already dependencies
2020-05-17 16:52:41 -05:00
# they can be added here e.g. [package]="extra"
2019-02-23 21:09:47 -06:00
declare -A PKG_EXT=(
2020-04-25 22:03:14 -05:00
[bluez]='bluez-libs bluez-utils bluez-tools bluez-plugins bluez-hid2hci'
[cairo-dock]='cairo-dock-plug-ins'
[kdenlive]='qt5ct qt5-styleplugins'
[mpd]='mpc'
[mupdf]='mupdf-tools'
[noto-fonts]='noto-fonts-emoji'
[pcmanfm]='tumbler'
[qbittorrent]='qt5ct qt5-styleplugins'
[qt5ct]='qt5-styleplugins'
[qutebrowser]='qt5ct qt5-styleplugins'
[thunar]='tumbler thunar-volman'
[transmission-qt]='qt5ct qt5-styleplugins'
[vlc]='qt5ct qt5-styleplugins'
[zathura]='zathura-pdf-poppler'
2019-02-23 21:09:47 -06:00
) # }
2019-09-24 01:39:10 -05:00
# dialog text variables {
2019-02-23 21:09:47 -06:00
# Basics (somewhat in order)
2020-04-25 22:03:14 -05:00
_keymap="\nSelect which keymap to use from the list below.\n\nThis will determine the installed system keymap, NOT locale which is chosen later.\n\nSystem default: us"
2019-12-22 23:52:07 -06:00
_vconsole="\nSelect the console keymap, the console is the tty shell you reach before starting a graphical environment (Xorg).\n\nIts keymap is separate from the one used by the graphical environments, though many do use the same such as 'us' English.\n\nSystem default: us"
2020-05-17 17:25:37 -05:00
_prep="\nThis is the installer main menu, once a step is complete you will return here.\n\nOn successful completion of a step the cursor will advance to the next step.\nOn failure the cursor will be placed on the step required to advance (when possible).\n\nSteps beginning with an asterisk (*) are required.\n\nOnce all required steps are complete, selecting the last step will finalize the install."
2019-02-23 21:09:47 -06:00
_device="\nSelect a device to use from the list below.\n\nDevices (/dev) are the available drives on the system. /sda, /sdb, /sdc ..."
_mount="\nUse [Space] to toggle mount options from below, press [Enter] when done to confirm selection.\n\nNot selecting any and confirming will run an automatic mount."
2020-05-03 14:47:39 -05:00
_warn="\nIMPORTANT: Choose carefully when editing, formatting, and mounting partitions or your DATA MAY BE LOST.\n\nTo mount a partition without formatting it, select 'skip' when prompted to choose a file system during the mounting stage.\nThis can only be used for partitions that already contain a file system and cannot be the root (/) partition, it needs to be formatted before install.\n"
2019-10-03 00:54:44 -05:00
_part="\nFull device auto partitioning is available for beginners otherwise cfdisk is recommended.\n\n - All systems will require a root partition (8G or greater).\n - UEFI or BIOS using LUKS without LVM require a separate boot partition (100-512M)."
2020-05-17 16:52:41 -05:00
_btrfs="\nBtrfs can be used with or without creating subvolumes.\n\nAn initial subvolume will be created and mounted with additional subvolumes branching from this created after.\n\nCreate subvolumes?\n"
2019-02-23 21:09:47 -06:00
_uefi="\nSelect the EFI boot partition (/boot), required for UEFI boot.\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as vfat/fat32 if not already."
_bios="\nDo you want to use a separate boot partition? (optional)\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as ext3/4 if not already."
_biosluks="\nSelect the boot partition (/boot), required for LUKS.\n\nIt's usually the first partition on the device, 100-512M, and will be formatted as ext3/4 if not already."
2020-04-25 13:29:49 -05:00
_format="is already formatted correctly.\n\nFor a clean install, existing partitions should be formatted, however this removes ALL data (bootloaders) on the partition so choose carefully.\n\nDo you want to format the partition?\n"
2020-05-17 16:52:41 -05:00
_swapsize="\nEnter the size of the swapfile in megabytes (M) or gigabytes (G).\n\ne.g. 100M will create a 100 megabyte swapfile, while 10G will create a 10 gigabyte swapfile.\n\nFor ease of use and as an example it is filled in to match the size of your system memory (RAM).\n\nMust be greater than 1, contain only whole numbers, and end with either M or G."
2019-03-04 23:47:24 -06:00
_expart="\nYou can now choose any additional partitions you want mounted, you'll be asked for a mountpoint after.\n\nSelect 'done' to finish the mounting step and begin unpacking the base system in the background."
2019-02-23 21:09:47 -06:00
_exmnt="\nWhere do you want the partition mounted?\n\nEnsure the name begins with a slash (/).\nExamples include: /usr, /home, /var, etc."
2020-05-17 20:29:26 -05:00
_mirrors="\nAutomatic mirror selection using reflector is preferred and should yield fast mirrors, however\nyou may want to select which countries mirrors to use for faster sorting and more control\n\nUse automatic mirrors?\n"
2020-05-17 17:25:37 -05:00
_bginstall="\nThe background base install will now start, select which base to use\n\nPacstrap - downloads all packages, avoids issues but can be slower depending on your network.\n\nCopy ISO - faster and not network dependant but can result in installation issues when using an older ISO.\n"
2019-08-23 02:15:56 -05:00
_user="\nEnter a name and password for the new user account.\n\nThe name must not use capital letters, contain any periods (.), end with a hyphen (-), or include any colons (:)\n\nNOTE: Use [Up], [Down], or [Tab] to switch between fields, and [Enter] to accept."
2019-12-22 23:52:07 -06:00
_hostname="\nEnter a hostname for the new system.\n\nA hostname is used to identify systems on the network.\n\nIt's restricted to alphanumeric characters (a-z, A-Z, 0-9).\nIt can contain hyphens (-) BUT NOT at the beginning or end."
2020-05-17 16:52:41 -05:00
_locale="\nLocale determines the system language and currency formats.\n\nThe format for locale names is languagecode_COUNTRYCODE\n\ne.g. en_US is: English United States\n en_GB is: English Great Britain"
2019-12-22 23:52:07 -06:00
_timez="\nSelect your timezone country or continent from the list below"
_timesubz="\nSelect your time zone city.\n\nTIP: Pressing a letter key repeatedly navigates between entries beginning with that letter."
2019-03-11 03:52:49 -05:00
_sessions="\nUse [Space] to toggle available sessions, use [Enter] to accept the selection and continue.\n\nA basic package set will be installed for compatibility and functionality."
_login="\nSelect which of your session choices to use for the initial login.\n\nYou can be change this later by editing your ~/.xinitrc"
2019-08-20 22:03:12 -05:00
_autologin="\nDo you want autologin enabled for USER?\n\nIf so the following two files will be created (disable autologin by removing them):\n\n - /home/USER/RC (run startx when logging in on tty1)\n - /etc/systemd/system/getty@tty1.service.d/autologin.conf (login USER without password)\n"
2019-12-22 23:52:07 -06:00
_packages="\nUse [Space] to toggle packages then press [Enter] to accept.\n\nPackages may be installed by your DE/WM (if any), or for the packages you select."
2019-10-27 15:43:20 -05:00
_usercmd="\nEnter command to be run in the newly installed system (chroot) below.\n\nAn example use case would be installing packages or editing files not offered in the menus.\n\nBecause the command will be run in a chroot not every command will function correctly, additionally the command will not be sanity checked, it's your system so exercise caution.\n\nMore than one command may be run using standard bash syntax.\n"
2019-09-30 19:41:09 -05:00
_edit="\nBefore exiting you can select configuration files to review/change.\n\nIf you need to make other changes with the drives still mounted, use Ctrl-z to pause the installer, when finished type 'fg' and [Enter] to resume the installer, if you want to avoid the automatic reboot using Ctrl-c will cleanly exit."
2019-02-23 21:09:47 -06:00
# LUKS
2019-12-22 23:52:07 -06:00
_luksmenu="\nA separate boot partition without encryption or logical volume management (LVM) is required (except BIOS systems using grub).\n\nBasic uses the default encryption settings, and is recommended for beginners. Advanced allows cypher and key size parameters to be entered manually."
_luksomenu="\nEnter a name and password for the encrypted device.\n\nIt is not necessary to prefix the name with /dev/mapper/, an example has been provided."
2019-02-23 21:09:47 -06:00
_lukskey="Once the specified flags have been amended, they will automatically be used with the 'cryptsetup -q luksFormat /dev/...' command.\n\nNOTE: Do not specify any additional flags such as -v (--verbose) or -y (--verify-passphrase)."
# LVM
_lvmmenu="\nLogical volume management (LVM) allows 'virtual' hard drives (volume groups) and partitions (logical volumes) to be created from existing device partitions.\n\nA volume group must be created first, then one or more logical volumes within it.\n\nLVM can also be used with an encrypted partition to create multiple logical volumes (e.g. root and home) within it."
_lvmvgname="\nEnter a name for the volume group (VG) being created from the partition(s) selected."
_lvmlvname="\nEnter a name for the logical volume (LV) being created.\n\nThis is similar to setting a label for a partition."
2020-05-17 16:52:41 -05:00
_lvmlvsize="\nEnter what size you want the logical volume (LV) to be in megabytes (M) or gigabytes (G).\n\ne.g. 100M will create a 100 megabyte volume, 10G will create a 10 gigabyte volume."
2019-02-23 21:09:47 -06:00
_lvmdelask="\nConfirm deletion of volume group(s) and logical volume(s).\n\nDeleting a volume group, will delete all logical volumes within it.\n"
# Errors
2019-12-22 23:52:07 -06:00
_errexpart="\nCannot mount partition due to a problem with the mountpoint.\n\nEnsure it begins with a slash (/) followed by at least one character.\n"
2020-05-17 16:16:17 -05:00
_errpart="\nYou need to create partition(s) first.\n\n\nBIOS systems require at least one partition (ROOT).\n\nUEFI systems require at least two (ROOT and EFI).\n"
2020-05-17 11:36:29 -05:00
_errchoice="\nIf you want to fix the issue yourself use Ctrl-z to pause the installer.\nFrom there you can do whatever is needed to resolve the error.\nOnce finished use the 'fg' command to resume the installer and select 'Continue'.\n"
2019-02-23 21:09:47 -06:00
_lukserr="\nA minimum of two partitions are required for encryption:\n\n 1. root (/) - standard or LVM.\n 2. boot (/boot) - standard (unless using LVM on BIOS systems).\n"
_lvmerr="\nThere are no viable partitions available to use for LVM, a minimum of one is required.\n\nIf LVM is already in use, deactivating it will allow the partition(s) to be used again.\n"
_lvmerrvgname="\nInvalid name entered.\n\nThe volume group name may be alpha-numeric, but may not contain spaces, start with a '/', or already be in use.\n"
2020-05-14 02:16:20 -05:00
_btrfserrname="\nInvalid name entered.\n\nThe subvolume name may be alpha-numeric, but may not contain spaces, start with a '/', or already be in use.\n"
2019-02-23 21:09:47 -06:00
_lvmerlvname="\nInvalid name entered.\n\nThe logical volume (LV) name may be alpha-numeric, but may not contain spaces or be preceded with a '/'\n"
2020-05-17 16:52:41 -05:00
_lvmerrlvsize="\nInvalid value Entered.\n\nMust be a numeric value with 'M' (megabytes) or 'G' (gigabytes) at the end.\n\ne.g. 400M, 10G, 250G, etc...\n\nThe value may also not be equal to or greater than the remaining size of the volume group.\n"
2019-02-23 21:09:47 -06:00
# }
###############################################################################
# selection menus
2019-08-20 17:52:25 -05:00
# main is the entry point which calls functions including outside of its block
# once those functions finished they always are returned here with the
# exception of install_main(), it exits upon completion
2019-02-23 21:09:47 -06:00
2019-08-20 17:52:25 -05:00
main()
2019-02-23 21:09:47 -06:00
{
2020-05-12 21:50:35 -05:00
if [[ $NOMOUNT ]]; then
(( SEL < 8 )) && (( SEL++ ))
tput civis
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " \
--default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \
1 "* Select bootloader" \
2 "* Username and password" \
3 "* System configuration" \
2020-05-17 16:16:17 -05:00
4 "Select WM(s) and/or DE(s)" \
2020-05-12 21:50:35 -05:00
5 "Select additional packages" \
2020-05-17 16:16:17 -05:00
6 "Enter a post-install command to run" \
7 "View installation configuration" \
8 "* Confirm choices and complete install" 2> "$ANS"
2020-05-12 21:50:35 -05:00
read -r SEL < "$ANS"
case $SEL in
1) prechecks 0 && { select_bootldr || (( SEL-- )); } ;;
2) prechecks 1 && { select_mkuser || (( SEL-- )); } ;;
3) prechecks 2 && { select_config || (( SEL-- )); } ;;
4) prechecks 3 && { select_sessions || (( SEL-- )); } ;;
5) prechecks 3 && { select_packages || (( SEL-- )); } ;;
6) prechecks 3 && select_usercmd ;;
7) prechecks 3 && select_show ;;
8) prechecks 3 && install_main ;;
*) yesno "Exit" "\nUnmount partitions (if any) and exit the installer?\n" && die 0
esac
else
(( SEL < 13 )) && (( SEL++ ))
tput civis
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " \
--default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \
2020-05-17 16:46:01 -05:00
1 "Storage device management" \
2020-05-17 16:16:17 -05:00
2 "* Mount partitions" \
3 "* Select bootloader" \
4 "* Username and password" \
5 "* System configuration" \
6 "Select WM(s) and/or DE(s)" \
7 "Select additional packages" \
8 "Enter a post-install command to run" \
9 "View installation configuration" \
10 "* Confirm choices and complete install" 2> "$ANS"
2020-05-12 21:50:35 -05:00
read -r SEL < "$ANS"
2020-05-17 16:16:17 -05:00
if [[ -z $WARN && $SEL == 2 ]]; then
msg "Data Warning" "$_warn"
WARN=true
fi
2020-05-12 21:50:35 -05:00
case $SEL in
2020-05-17 16:16:17 -05:00
1) dev_menu || (( SEL-- )) ;;
2) mount_menu || (( SEL-- )) ;;
3) prechecks 0 && { select_bootldr || (( SEL-- )); } ;;
4) prechecks 1 && { select_mkuser || (( SEL-- )); } ;;
5) prechecks 2 && { select_config || (( SEL-- )); } ;;
6) prechecks 3 && { select_sessions || (( SEL-- )); } ;;
7) prechecks 3 && { select_packages || (( SEL-- )); } ;;
8) prechecks 3 && select_usercmd ;;
9) prechecks 3 && select_show ;;
10) prechecks 3 && install_main ;;
2020-05-12 21:50:35 -05:00
*) yesno "Exit" "\nUnmount partitions (if any) and exit the installer?\n" && die 0
esac
fi
2020-05-17 16:16:17 -05:00
2019-02-23 21:09:47 -06:00
}
select_show()
{
2020-04-25 22:03:14 -05:00
local pkgs="${USER_PKGS[*]} ${SES_PKGS[*]}"
2019-03-04 23:47:24 -06:00
[[ $INSTALL_WMS == *dwm* ]] && pkgs="dwm st dmenu $pkgs"
2019-08-25 13:47:18 -05:00
pkgs="${pkgs// / }" pkgs="${pkgs# }"
2019-02-23 21:09:47 -06:00
msg "Show Configuration" "
---------- PARTITION CONFIGURATION ------------
2020-05-14 02:16:20 -05:00
Root Part: $ROOT - ${ROOTFS:-skipped}
Boot Part: ${BOOT:-none} - ${BOOTFS:-none}
2019-11-23 19:36:08 -06:00
Boot Device: ${BOOT_D:-none}
Swap Part/File: ${SWAP:-none}
Swap Size: ${SWAP_S:-none}
2019-10-18 21:47:46 -05:00
Extra Mounts: ${EXMNTS:-none}
2019-10-17 22:57:47 -05:00
Mkinit Hooks: ${HOOKS:-none}
2019-02-23 21:09:47 -06:00
2019-11-23 19:36:08 -06:00
LVM used: ${LVM:-unused}
LUKS used: ${LUKS:-unused}
2019-02-23 21:09:47 -06:00
------------ SYSTEM CONFIGURATION -------------
2019-11-23 19:36:08 -06:00
Locale: ${LOCALE:-none}
2019-02-23 21:09:47 -06:00
Keymap: ${KEYMAP:-none}
2019-11-23 19:36:08 -06:00
Hostname: ${NEWHOST:-none}
2019-02-23 21:09:47 -06:00
Timezone: ${ZONE:-none}/${SUBZ:-none}
2019-10-27 19:25:06 -05:00
Chroot cmd: ${USER_CMD:-none}
2019-08-25 13:47:18 -05:00
------------ USER CONFIGURATION ---------------
2019-02-23 21:09:47 -06:00
2019-08-25 13:47:18 -05:00
Username: ${NEWUSER:-none}
2020-04-10 18:03:28 -05:00
Login Shell: ${NEWSHELL:-none}
2019-08-25 13:47:18 -05:00
Login Session: ${LOGIN_WM:-none}
Autologin: ${AUTOLOGIN:-none}
Login Type: ${LOGIN_TYPE:-none}
2019-02-23 21:09:47 -06:00
2019-08-25 13:47:18 -05:00
----------- PACKAGE CONFIGURATION -------------
2019-02-23 21:09:47 -06:00
2019-08-25 13:47:18 -05:00
Kernel: ${KERNEL:-none}
Bootloader: ${BOOTLDR:-none}
Packages: ${pkgs:-none}
2019-02-23 21:09:47 -06:00
"
}
select_login()
{
2019-11-23 19:36:08 -06:00
AUTOLOGIN=''
2019-08-26 22:16:36 -05:00
2019-11-23 19:36:08 -06:00
dlg LOGIN_TYPE menu "Login" "\nSelect what kind of login management to use." \
2020-05-03 17:52:40 -05:00
"xinit" "Console login with no graphical display manager" \
"lightdm" "Lightweight display manager (deepin and xfce default)" \
"gdm" "Gnome display manager (gnome default, go figure)" \
2020-05-03 21:31:31 -05:00
"sddm" "Simple desktop display manager (plasma and lxqt default)" || return 1
2019-08-26 22:16:36 -05:00
case $LOGIN_TYPE in
2020-05-03 17:52:40 -05:00
gdm|sddm)
2020-05-03 22:56:06 -05:00
EDIT_FILES[login]="none"
2020-05-03 17:52:40 -05:00
;;
2019-11-23 19:36:08 -06:00
lightdm)
LIGHTDM_GREETER='gtk-greeter'
EDIT_FILES[login]="/etc/lightdm/lightdm.conf /etc/lightdm/lightdm-gtk-greeter.conf"
2020-03-07 18:58:48 -06:00
local txt="\nWith a deepin install you can choose to use their greeter for lightdm\n\nUse the deepin greeter?\n"
2019-11-23 19:36:08 -06:00
[[ $INSTALL_WMS == *deepin* ]] && yesno "Greeter" "$txt" && LIGHTDM_GREETER="deepin-greeter"
;;
2020-05-03 22:56:06 -05:00
xinit)
EDIT_FILES[login]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
2019-08-26 22:16:36 -05:00
if (( $(wc -w <<< "$INSTALL_WMS") > 1 )); then
2019-11-23 19:36:08 -06:00
dlg LOGIN_WM menu "Session" "$_login" $LOGIN_CHOICES || return 1
2019-08-26 22:16:36 -05:00
LOGIN_WM="${WM_SESSIONS[$LOGIN_WM]}"
fi
[[ -z $LOGIN_WM ]] && LOGIN_WM="${WM_SESSIONS[${INSTALL_WMS%% *}]}"
2019-11-23 19:36:08 -06:00
yesno "Autologin" "$(sed "s|USER|$NEWUSER|g; s|RC|$LOGINRC|g" <<< "$_autologin")" && AUTOLOGIN=true
2019-08-26 22:16:36 -05:00
;;
esac
2020-03-02 00:50:51 -06:00
return 0
2019-02-23 21:09:47 -06:00
}
select_config()
{
2019-04-17 20:24:09 -05:00
typeset -i i=0
2019-02-23 21:09:47 -06:00
CONFIG_DONE=''
until [[ $CONFIG_DONE ]]; do
case $i in
2020-05-03 17:52:40 -05:00
0)
dlg NEWSHELL menu "Shell" "\nChoose which shell to use." \
2019-09-15 12:30:44 -05:00
zsh 'A very advanced and programmable command interpreter (shell) for UNIX' \
bash 'The GNU Bourne Again shell, standard in many GNU/Linux distributions' \
mksh 'The MirBSD Korn Shell - an enhanced version of the public domain ksh' || return 1
2020-05-03 17:52:40 -05:00
;;
1)
dlg NEWHOST input "Hostname" "$_hostname" "${DIST,,}" limit || { i=0; continue; }
2019-02-23 21:09:47 -06:00
;;
2020-05-03 17:52:40 -05:00
2)
dlg LOCALE menu "Locale" "$_locale" $LOCALES || { i=1; continue; }
;;
3)
ZONE='' SUBZ=''
2019-02-23 21:09:47 -06:00
until [[ $ZONE && $SUBZ ]]; do
2020-04-26 10:36:33 -05:00
dlg ZONE menu "Timezone" "$_timez" \
America - \
Australia - \
Asia - \
Atlantic - \
Africa - \
Europe - \
Indian - \
Pacific - \
Arctic - \
Antarctica - || break
dlg SUBZ menu "Timezone" "$_timesubz" $(awk '/'"$ZONE"'\// {
gsub(/'"$ZONE"'\//, "")
print $3 " - "
}' /usr/share/zoneinfo/zone.tab | sort) || continue
2019-02-23 21:09:47 -06:00
done
2020-05-03 17:52:40 -05:00
[[ $ZONE && $SUBZ ]] || { i=2; continue; }
;;
4)
dlg KERNEL menu "Kernel" "\nChoose which kernel to use." \
2019-02-23 21:09:47 -06:00
linux 'Vanilla linux kernel and modules, with a few patches applied' \
linux-lts 'Long-term support (LTS) linux kernel and modules' \
linux-zen 'A effort of kernel hackers to provide the best kernel for everyday systems' \
2019-03-17 14:17:43 -05:00
linux-hardened 'A security-focused linux kernel with hardening patches to mitigate exploits' || { i=3; continue; }
2020-05-03 17:52:40 -05:00
2019-02-23 21:09:47 -06:00
CONFIG_DONE=true
;;
esac
2019-04-17 20:24:09 -05:00
(( i++ )) # progress through to the next choice
2019-02-23 21:09:47 -06:00
done
2020-04-10 18:03:28 -05:00
case $NEWSHELL in
2019-10-10 22:00:22 -05:00
bash) LOGINRC='.bash_profile' ;;
2020-05-03 17:52:40 -05:00
zsh) LOGINRC='.zprofile' ;;
2019-10-10 22:00:22 -05:00
mksh) LOGINRC='.profile' ;;
esac
2019-02-23 21:09:47 -06:00
return 0
}
select_mkuser()
{
NEWUSER=''
2019-10-06 05:26:53 -05:00
typeset -a ans
2020-04-26 10:36:33 -05:00
local rootsec="--- Root password, if left empty the user password will be used ---"
2019-02-23 21:09:47 -06:00
until [[ $NEWUSER ]]; do
tput cnorm
2020-04-26 10:36:33 -05:00
dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" \
--separator $'\n' --title " User " --mixedform "$_user" 0 0 0 \
"Username:" 1 1 "${ans[0]}" 1 11 "$COLUMNS" 0 0 \
"Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \
"Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 \
"$rootsec" 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
2019-02-23 21:09:47 -06:00
2019-10-06 05:26:53 -05:00
mapfile -t ans <"$ANS"
2019-02-23 21:09:47 -06:00
# root passwords empty, so use the user passwords
2019-10-06 05:26:53 -05:00
if [[ -z "${ans[4]}" && -z "${ans[5]}" ]]; then
ans[4]="${ans[1]}"
ans[5]="${ans[2]}"
fi
2019-02-23 21:09:47 -06:00
# make sure a username was entered and that the passwords match
2019-10-06 05:26:53 -05:00
if [[ -z ${ans[0]} || ${ans[0]} =~ \ |\' || ${ans[0]} =~ [^a-z0-9] ]]; then
2020-03-25 10:30:25 -05:00
msg "Invalid Username" "\nInvalid user name.\n\nPlease try again.\n"; ans[0]=''
2019-10-06 05:26:53 -05:00
elif [[ -z "${ans[1]}" || "${ans[1]}" != "${ans[2]}" ]]; then
2019-02-23 21:09:47 -06:00
msg "Password Mismatch" "\nThe user passwords do not match.\n\nPlease try again.\n"
2019-10-06 05:26:53 -05:00
elif [[ "${ans[4]}" != "${ans[5]}" ]]; then
2019-02-23 21:09:47 -06:00
msg "Password Mismatch" "\nThe root passwords do not match.\n\nPlease try again.\n"
else
2019-10-06 05:26:53 -05:00
NEWUSER="${ans[0]}"
USER_PASS="${ans[1]}"
ROOT_PASS="${ans[4]}"
2019-02-23 21:09:47 -06:00
fi
done
return 0
}
select_keymap()
{
2020-05-14 23:06:50 -05:00
if [[ ! -f /tmp/xkeys ]]; then
dlg KEYMAP menu "Keyboard" "$_keymap" \
2020-05-17 13:05:57 -05:00
af Afghani al Albanian am Armenian ara Arabic at German au English \
az Azerbaijani ba Bosnian bd Bangla be Belgian 'bg' Bulgarian br Portuguese \
bt Dzongkha bw Tswana by Belarusian ca French 'cd' French ch German \
cm English cn Chinese cz Czech de German dk Danish dz Berber \
ee Estonian epo Esperanto es Spanish et Amharic 'fi' Finnish fo Faroese \
fr French gb English ge Georgian gh English gn French gr Greek \
hr Croatian hu Hungarian id Indonesian ie Irish il Hebrew 'in' Indian \
iq Iraqi ir Persian is Icelandic it Italian jp Japanese ke Swahili \
kg Kyrgyz kh Khmer kr Korean kz Kazakh la Lao latam Spanish \
lk Sinhala lt Lithuanian lv Latvian ma Arabic mao Maori md Moldavian \
me Montenegrin mk Macedonian ml Bambara mm Burmese mn Mongolian mt Maltese \
'mv' Dhivehi my Malay ng English nl Dutch no Norwegian np Nepali \
ph Filipino pk Urdu pl Polish pt Portuguese ro Romanian rs Serbian \
ru Russian se Swedish si Slovenian sk Slovak sn Wolof sy Arabic \
tg French th Thai tj Tajik tm Turkmen tr Turkish tw Taiwanese \
tz Swahili ua Ukrainian us English uz Uzbek vn Vietnamese za English || return 1
2020-05-14 23:06:50 -05:00
echo "$KEYMAP" > /tmp/xkeys
2019-02-23 21:09:47 -06:00
else
2020-05-14 23:06:50 -05:00
KEYMAP="$(< /tmp/xkeys)"
fi
if [[ ! -f /tmp/ckeys ]]; then
if [[ $CMAPS == *"$KEYMAP "* ]]; then
CMAP="$KEYMAP"
else
dlg CMAP menu "Console Keymap" "$_vconsole" $CMAPS || return 1
fi
echo "$CMAP" > /tmp/ckeys
else
CMAP="$(< /tmp/ckeys)"
2019-02-23 21:09:47 -06:00
fi
2019-10-01 01:09:06 -05:00
if [[ $TERM == 'linux' ]]; then
2019-10-19 17:18:42 -05:00
loadkeys "$CMAP" > /dev/null 2>&1
2019-10-01 01:09:06 -05:00
else
2019-10-19 17:18:42 -05:00
setxkbmap "$KEYMAP" > /dev/null 2>&1
2019-02-23 21:09:47 -06:00
fi
return 0
}
2019-10-20 21:49:12 -05:00
select_usercmd()
{
2019-11-23 19:36:08 -06:00
dlg USER_CMD input "Command" "$_usercmd" "$USER_CMD" nolimit
2019-10-20 21:49:12 -05:00
}
2019-12-22 19:41:42 -06:00
select_bootldr()
{
if [[ $SYS == 'BIOS' ]]; then
dlg BOOTLDR menu "BIOS Bootloader" "\nSelect which bootloader to use." \
"grub" "The Grand Unified Bootloader, standard among many Linux distributions" \
"syslinux" "A collection of boot loaders for booting drives, CDs, or over the network" || return 1
else
dlg BOOTLDR menu "UEFI Bootloader" "\nSelect which bootloader to use." \
"systemd-boot" "A simple UEFI boot manager which executes configured EFI images" \
"grub" "The Grand Unified Bootloader, standard among many Linux distributions" \
"refind-efi" "A UEFI boot manager that aims to be platform neutral and simplify multi-boot" \
"efistub" "Boot the kernel image directly (no chainloading support)" \
"syslinux" "A collection of boot loaders for booting drives, CDs, or over the network (no chainloading support)" || return 1
fi
setup_${BOOTLDR}
2020-03-02 00:50:51 -06:00
return 0
2019-12-22 19:41:42 -06:00
}
2019-02-23 21:09:47 -06:00
select_sessions()
{
2020-05-03 21:31:31 -05:00
typeset -a pkgs
2019-02-23 21:09:47 -06:00
LOGIN_CHOICES=''
dlg INSTALL_WMS check "Sessions" "$_sessions\n" \
2020-04-26 10:36:33 -05:00
i3-gaps "A fork of i3wm with more features including gaps" "$(ofn i3-gaps "$INSTALL_WMS")" \
openbox "A lightweight, powerful, and highly configurable stacking wm" "$(ofn openbox "$INSTALL_WMS")" \
dwm "A dynamic WM for X that manages windows in tiled, floating, or monocle layouts" "$(ofn dwm "$INSTALL_WMS")" \
bspwm "A tiling wm that represents windows as the leaves of a binary tree" "$(ofn bspwm "$INSTALL_WMS")" \
2020-05-03 21:31:31 -05:00
lxqt "A port of the lightweight desktop environment (LXDE) to Qt" "$(ofn lxqt "$INSTALL_WMS")" \
2020-04-26 10:36:33 -05:00
jwm "A lightweight window manager for Xorg written in C" "$(ofn jwm "$INSTALL_WMS")" \
xfce4 "A lightweight and modular desktop environment based on gtk+2/3" "$(ofn xfce4 "$INSTALL_WMS")" \
awesome "A customized Awesome WM session created by @elanapan" "$(ofn awesome "$INSTALL_WMS")" \
fluxbox "A lightweight and highly-configurable window manager" "$(ofn fluxbox "$INSTALL_WMS")" \
plasma "A KDE software project currently comprising a full desktop environment" "$(ofn plasma "$INSTALL_WMS")" \
deepin "The desktop environment of the Chinese Deepin Linux distribution." "$(ofn deepin "$INSTALL_WMS")" \
gnome "A desktop environment that aims to be simple and easy to use" "$(ofn gnome "$INSTALL_WMS")" \
cinnamon "A desktop environment combining traditional desktop with modern effects" "$(ofn cinnamon "$INSTALL_WMS")"
2019-02-23 21:09:47 -06:00
2019-08-20 22:03:12 -05:00
[[ $INSTALL_WMS ]] || return 0
2020-04-26 10:36:33 -05:00
2020-04-23 23:03:44 -05:00
for i in ${INSTALL_WMS/dwm/}; do
2020-05-03 21:31:31 -05:00
pkgs+=("$i")
2020-04-23 23:03:44 -05:00
done
2019-02-23 21:09:47 -06:00
for i in $INSTALL_WMS; do
LOGIN_CHOICES+="$i - "
2019-12-22 23:52:07 -06:00
if [[ $i =~ (plasma|deepin) ]]; then
2020-04-26 10:36:33 -05:00
local pretxt="\nThere are some extra packages available for $i that you may want installed:"
local txt="These are larger package groups containing applications that are a part of $i"
txt+=" but are not included in the $i package group."
yesno "${i^} Extra" "$pretxt ${WM_EXT[$i]}\n\n$txt\n\nWould you like to install them?\n" || continue
2019-12-22 23:52:07 -06:00
fi
2020-04-23 23:03:44 -05:00
if [[ ${WM_EXT[$i]} ]]; then
for j in ${WM_EXT[$i]}; do
2020-05-03 21:31:31 -05:00
pkgs+=("$j")
2020-04-23 23:03:44 -05:00
done
fi
2019-02-23 21:09:47 -06:00
done
select_login || return 1
2020-05-03 21:31:31 -05:00
for pkg in "${pkgs[@]}"; do
2020-04-25 22:03:14 -05:00
[[ ${SES_PKGS[*]} != *"$pkg"* ]] && SES_PKGS+=("$pkg")
2020-04-23 23:03:44 -05:00
done
2019-04-01 21:04:42 -05:00
2020-04-25 22:03:14 -05:00
if [[ $INSTALL_WMS ]]; then
echo "$INSTALL_WMS" > /tmp/wmlist
else
rm -f /tmp/wmlist
fi
2019-02-23 21:09:47 -06:00
return 0
}
select_packages()
{
2020-04-23 23:03:44 -05:00
dlg UPKGS check " Packages " "$_packages" \
2019-03-11 03:52:49 -05:00
abiword "A Fully-featured word processor" "$(ofn abiword "${USER_PKGS[*]}")" \
alacritty "A cross-platform, GPU-accelerated terminal emulator" "$(ofn alacritty "${USER_PKGS[*]}")" \
atom "An open-source text editor developed by GitHub" "$(ofn atom "${USER_PKGS[*]}")" \
audacious "A free and advanced audio player based on GTK+" "$(ofn audacious "${USER_PKGS[*]}")" \
audacity "A program that lets you manipulate digital audio waveforms" "$(ofn audacity "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
base-devel "A group of packages required for AUR" "$(ofn base-devel "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
blueman "GUI bluetooth device manager" "$(ofn blueman "${USER_PKGS[*]}")" \
bluez "Simple CLI based bluetooth support" "$(ofn bluez "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
cairo-dock "Light eye-candy fully themable animated dock" "$(ofn cairo-dock "${USER_PKGS[*]}")" \
calligra "A set of applications for productivity" "$(ofn calligra "${USER_PKGS[*]}")" \
chromium "An open-source web browser based on the Blink rendering engine" "$(ofn chromium "${USER_PKGS[*]}")" \
clementine "A modern music player and library organizer" "$(ofn clementine "${USER_PKGS[*]}")" \
cmus "A small, fast and powerful console music player" "$(ofn cmus "${USER_PKGS[*]}")" \
deadbeef "A GTK+ audio player for GNU/Linux" "$(ofn deadbeef "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
deluge "A bittorrent client written in python" "$(ofn deluge "${USER_PKGS[*]}")" \
elinks "An advanced and well-established feature-rich text mode web browser" "$(ofn elinks "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
emacs "An extensible, customizable, self-documenting real-time display editor" "$(ofn emacs "${USER_PKGS[*]}")" \
epiphany "A GNOME web browser based on the WebKit rendering engine" "$(ofn epiphany "${USER_PKGS[*]}")" \
evince "A document viewer" "$(ofn evince "${USER_PKGS[*]}")" \
evolution "Manage your email, contacts and schedule" "$(ofn evolution "${USER_PKGS[*]}")" \
file-roller "Create and modify archives" "$(ofn file-roller "${USER_PKGS[*]}")" \
firefox "A popular open-source web browser from Mozilla" "$(ofn firefox "${USER_PKGS[*]}")" \
gcolor2 "A simple GTK+2 color selector" "$(ofn gcolor2 "${USER_PKGS[*]}")" \
geany "A fast and lightweight IDE" "$(ofn geany "${USER_PKGS[*]}")" \
geary "A lightweight email client for the GNOME desktop" "$(ofn geary "${USER_PKGS[*]}")" \
gimp "GNU Image Manipulation Program" "$(ofn gimp "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
git "The fast distributed version control system" "$(ofn git "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
gnome-calculator "GNOME Scientific calculator" "$(ofn gnome-calculator "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
gnome-disk-utility "Disk Management Utility" "$(ofn gnome-disk-utility "${USER_PKGS[*]}")" \
gnome-system-monitor "View current processes and monitor system state" "$(ofn gnome-system-monitor "${USER_PKGS[*]}")" \
gparted "A GUI frontend for creating and manipulating partition tables" "$(ofn gparted "${USER_PKGS[*]}")" \
gpick "Advanced color picker using GTK+ toolkit" "$(ofn gpick "${USER_PKGS[*]}")" \
gpicview "Lightweight image viewer" "$(ofn gpicview "${USER_PKGS[*]}")" \
guvcview "Capture video from camera devices" "$(ofn guvcview "${USER_PKGS[*]}")" \
hexchat "A popular and easy to use graphical IRC client" "$(ofn hexchat "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
htop "An interactive process viewer" "$(ofn htop "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
inkscape "Professional vector graphics editor" "$(ofn inkscape "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
irssi "A modular text mode IRC client with Perl scripting" "$(ofn irssi "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
kdenlive "A popular non-linear video editor for Linux" "$(ofn kdenlive "${USER_PKGS[*]}")" \
krita "Edit and paint images" "$(ofn krita "${USER_PKGS[*]}")" \
libreoffice-fresh "Full featured office suite" "$(ofn libreoffice-fresh "${USER_PKGS[*]}")" \
lollypop "A new music playing application" "$(ofn lollypop "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
mc "A file manager that imitates Norton Commander" "$(ofn mc "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
mousepad "A simple text editor" "$(ofn mousepad "${USER_PKGS[*]}")" \
mpd "A flexible, powerful, server-side application for playing music" "$(ofn mpd "${USER_PKGS[*]}")" \
mpv "A media player based on mplayer" "$(ofn mpv "${USER_PKGS[*]}")" \
mupdf "Lightweight PDF and XPS viewer" "$(ofn mupdf "${USER_PKGS[*]}")" \
mutt "Small but very powerful text-based mail client" "$(ofn mutt "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
nano "Pico editor clone with enhancements" "$(ofn nano "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
nautilus "The default file manager for Gnome" "$(ofn nautilus "${USER_PKGS[*]}")" \
ncmpcpp "A mpd client and almost exact clone of ncmpc with some new features" "$(ofn ncmpcpp "${USER_PKGS[*]}")" \
neovim "A fork of Vim aiming to improve user experience, plugins, and GUIs." "$(ofn neovim "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
nmap "Utility for network discovery and security auditing" "$(ofn nmap "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
noto-fonts "Google Noto fonts" "$(ofn noto-fonts "${USER_PKGS[*]}")" \
noto-fonts-cjk "Google Noto CJK fonts (Chinese, Japanese, Korean)" "$(ofn noto-fonts-cjk "${USER_PKGS[*]}")" \
2020-05-03 14:47:39 -05:00
ntfs-3g "NTFS file system driver and utilities" "$(ofn ntfs-3g "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
obs-studio "Free opensource streaming/recording software" "$(ofn obs-studio "${USER_PKGS[*]}")" \
openshot "An open-source, non-linear video editor for Linux" "$(ofn openshot "${USER_PKGS[*]}")" \
opera "A Fast and secure, free of charge web browser from Opera Software" "$(ofn opera "${USER_PKGS[*]}")" \
pcmanfm "A fast and lightweight file manager based in Lxde" "$(ofn pcmanfm "${USER_PKGS[*]}")" \
pidgin "Multi-protocol instant messaging client" "$(ofn pidgin "${USER_PKGS[*]}")" \
plank "An elegant, simple, and clean dock" "$(ofn plank "${USER_PKGS[*]}")" \
2020-04-26 10:36:33 -05:00
playerctl "Media player controller for spotify, vlc, audacious, bmp, xmms2, and others." "$(ofn playerctl "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
qbittorrent "An advanced bittorrent client" "$(ofn qbittorrent "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
qpdfview "A tabbed PDF viewer" "$(ofn qpdfview "${USER_PKGS[*]}")" \
qt5ct "GUI for managing Qt based application themes, icons, and fonts" "$(ofn qt5ct "${USER_PKGS[*]}")" \
qutebrowser "A keyboard-focused vim-like web browser based on Python and PyQt5" "$(ofn qutebrowser "${USER_PKGS[*]}")" \
rhythmbox "A Music playback and management application" "$(ofn rhythmbox "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
rsync "A file transfer program to keep remote files in sync" "$(ofn rsync "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
rxvt-unicode "A unicode enabled rxvt-clone terminal emulator" "$(ofn rxvt-unicode "${USER_PKGS[*]}")" \
sakura "A terminal emulator based on GTK and VTE" "$(ofn sakura "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
simple-scan "Simple scanning utility" "$(ofn simple-scan "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
simplescreenrecorder "A feature-rich screen recorder" "$(ofn simplescreenrecorder "${USER_PKGS[*]}")" \
steam "A popular game distribution platform by Valve" "$(ofn steam "${USER_PKGS[*]}")" \
surf "A simple web browser based on WebKit2/GTK+" "$(ofn surf "${USER_PKGS[*]}")" \
terminator "Terminal emulator that supports tabs and grids" "$(ofn terminator "${USER_PKGS[*]}")" \
termite "A minimal VTE-based terminal emulator" "$(ofn termite "${USER_PKGS[*]}")" \
thunar "A modern file manager for the Xfce Desktop Environment" "$(ofn thunar "${USER_PKGS[*]}")" \
thunderbird "Standalone mail and news reader from mozilla" "$(ofn thunderbird "${USER_PKGS[*]}")" \
tilda "A GTK based drop down terminal for Linux and Unix" "$(ofn tilda "${USER_PKGS[*]}")" \
tilix "A tiling terminal emulator for Linux using GTK+ 3" "$(ofn tilix "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
transmission-cli "Free bittorrent client CLI" "$(ofn transmission-cli "${USER_PKGS[*]}")" \
unrar "The RAR compression program" "$(ofn unrar "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
transmission-gtk "GTK+ Front end for transmission" "$(ofn transmission-gtk "${USER_PKGS[*]}")" \
transmission-qt "Qt Front end for transmission" "$(ofn transmission-qt "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
ttf-anonymous-pro "A family fixed-width fonts designed with code in mind" "$(ofn ttf-anonymous-pro "${USER_PKGS[*]}")" \
ttf-fira-code "Monospaced font with programming ligatures" "$(ofn ttf-fira-code "${USER_PKGS[*]}")" \
ttf-font-awesome "Iconic font designed for Bootstrap" "$(ofn ttf-font-awesome "${USER_PKGS[*]}")" \
ttf-hack "A hand groomed typeface based on Bitstream Vera Mono" "$(ofn ttf-hack "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
vim "Vi Improved, a highly configurable, improved version of the vi text editor" "$(ofn vim "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
vlc "A free and open source cross-platform multimedia player" "$(ofn vlc "${USER_PKGS[*]}")" \
weechat "Fast, light and extensible IRC client" "$(ofn weechat "${USER_PKGS[*]}")" \
2020-04-25 22:03:14 -05:00
wget "Network utility to retrieve files from the Web" "$(ofn wget "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
xapps "Common library for X-Apps project" "$(ofn xapps "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
xarchiver "A GTK+ frontend to various command line archivers" "$(ofn xarchiver "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
xed "A small and lightweight text editor. X-Apps Project." "$(ofn xed "${USER_PKGS[*]}")" \
2019-09-28 02:09:08 -05:00
xfce4-terminal "A terminal emulator based in the Xfce Desktop Environment" "$(ofn xfce4-terminal "${USER_PKGS[*]}")" \
2019-08-27 01:02:45 -05:00
xreader "Document viewer for files like PDF and Postscript. X-Apps Project." "$(ofn xed "${USER_PKGS[*]}")" \
2019-03-11 03:52:49 -05:00
zathura "Minimalistic document viewer" "$(ofn zathura "${USER_PKGS[*]}")"
2019-02-23 21:09:47 -06:00
2020-04-23 23:03:44 -05:00
if [[ $UPKGS ]]; then # add any needed PKG_EXT to the list
for i in $UPKGS; do
2020-04-24 02:42:30 -05:00
[[ ${USER_PKGS[*]} != *"$i"* ]] && USER_PKGS+=("$i")
2020-04-23 23:03:44 -05:00
if [[ ${PKG_EXT[$i]} ]]; then
for j in ${PKG_EXT[$i]}; do
[[ ${USER_PKGS[*]} != *"$j"* ]] && USER_PKGS+=("$j")
done
fi
2019-02-23 21:09:47 -06:00
done
fi
return 0
}
###############################################################################
2020-05-17 16:16:17 -05:00
# device management menus
# acts as an in-between function to avoid cluttering the main menu
# also called when mounting but not enough partitions are present
dev_menu()
{
local txt="$1"
local back="Return to the main menu"
[[ $txt ]] && back="Return to mounting"
while :; do
2020-05-17 16:46:01 -05:00
dlg DEVMNG_OPT menu "Device Management" "\nHere you can perform some basic operations to modify system storage devices.\n$txt" \
2020-05-17 16:16:17 -05:00
'view' 'View the device tree output from lsblk' \
2020-05-17 16:46:01 -05:00
'part' 'Modify the partition layout of a device' \
2020-05-17 16:16:17 -05:00
'luks' 'Setup LUKS encryption on a partition or LVM' \
'lvm' 'Setup logical volume management on partition(s)' \
2020-05-17 20:29:26 -05:00
'back' "$back" || return 0
2020-05-17 16:16:17 -05:00
2020-05-17 20:29:26 -05:00
if [[ $DEVMNG_OPT == 'back' ]]; then
2020-05-17 16:16:17 -05:00
return 0
elif [[ -z $WARN && $DEVMNG_OPT != 'view' ]]; then
msg "Data Warning" "$_warn"
WARN=true
fi
case $DEVMNG_OPT in
'view') part_show ;;
'part') part_menu ;;
'luks') luks_menu ;;
'lvm') lvm_menu ;;
esac
done
}
###############################################################################
# partitioning menu
2019-08-20 17:52:25 -05:00
# non-essential partitioning helpers called by the user when using the optional
# partition menu and selecting a device to edit
2019-02-23 21:09:47 -06:00
part_menu()
{
2019-11-23 19:36:08 -06:00
is_bg_install || return 0
2019-03-11 03:52:49 -05:00
local device choice devhash
devhash="$(lsblk -f | base64)"
2019-10-18 21:47:46 -05:00
umount_dir "$MNT"
2019-03-11 03:52:49 -05:00
part_device || return 1
device="$DEVICE"
2019-02-23 21:09:47 -06:00
2019-08-18 15:37:49 -05:00
while :; do
2019-03-11 03:52:49 -05:00
choice=""
2020-05-17 20:29:26 -05:00
dlg choice menu 'Modify Partitions' "$_part\n\n$(lsblk -no NAME,MODEL,SIZE,FSTYPE,LABEL "$device")" \
'auto' 'Whole device automatic partitioning' \
'cfdisk' 'Curses based variant of fdisk' \
'cgdisk' 'Curses based variant of gdisk' \
'parted' 'GNU partition editor' $([[ "$DISPLAY" ]] && hash gparted >/dev/null 2>&1 && printf \
'gparted -') \
'fdisk' 'Dialog-driven creation and manipulation of partitions' \
'gdisk' 'A text-mode partitioning tool that works on GUID Partition Table (GPT) disks' \
'back' 'Return to the device management menu'
if [[ -z $choice || $choice == 'back' ]]; then
2019-02-23 21:09:47 -06:00
return 0
elif [[ $choice == 'auto' ]]; then
2019-11-02 20:49:31 -05:00
local root_size txt label boot_fs boot_type
2019-12-22 23:52:07 -06:00
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: ALL data on $device will be destroyed and the following partitions will be created\n\n- "
2019-02-23 21:09:47 -06:00
if [[ $SYS == 'BIOS' ]]; then
2019-11-02 12:50:52 -05:00
label="msdos" boot_fs="ext4" boot_type="primary"
2020-05-17 13:05:57 -05:00
txt+="$boot_fs boot partition with the boot flag enabled (512M)\n- "
2019-02-23 21:09:47 -06:00
else
2019-11-02 12:50:52 -05:00
label="gpt" boot_fs="fat32" boot_type="ESP"
2020-05-17 13:05:57 -05:00
txt+="$boot_fs efi boot partition (512M)\n- "
2019-02-23 21:09:47 -06:00
fi
2020-05-17 13:05:57 -05:00
txt+="ext4 partition using all remaining space ($root_size)\n\nDo you want to continue?\n"
2019-11-02 20:49:31 -05:00
yesno "Auto Partition" "$txt" && part_auto "$device" "$label" "$boot_fs" "$root_size" "$boot_type"
2019-02-23 21:09:47 -06:00
else
clear
tput cnorm
$choice "$device"
fi
2019-03-17 14:17:43 -05:00
if [[ $devhash != "$(lsblk -f | base64)" ]]; then
2019-08-27 03:00:08 -05:00
msg "Probing Partitions" "\nInforming kernel of partition changes using partprobe\n" 0
2019-10-19 17:18:42 -05:00
partprobe > /dev/null 2>&1
2019-08-26 22:16:36 -05:00
[[ $choice == 'auto' ]] && return
2019-03-17 14:17:43 -05:00
fi
2019-02-23 21:09:47 -06:00
done
}
part_show()
{
2020-03-07 19:53:06 -06:00
msg "Device Tree" "\n\n$(
2020-04-25 22:03:14 -05:00
lsblk -no NAME,MODEL,SIZE,TYPE,FSTYPE,MOUNTPOINT |
awk '/disk|part|lvm|crypt/ && !'"/${IGNORE_DEV:-NONEXX}/"'{sub(/part|disk|crypt|lvm/, ""); print}'
2020-03-07 19:53:06 -06:00
)\n\n"
2019-02-23 21:09:47 -06:00
}
part_auto()
{
2019-11-02 12:50:52 -05:00
local device="$1" label="$2" boot_fs="$3" size="$4" boot_type="$5" dev_info=""
2019-02-23 21:09:47 -06:00
2019-11-02 12:50:52 -05:00
msg "Auto Partition" "\nRemoving partitions on $device and setting label to $label\n" 1
2019-02-23 21:09:47 -06:00
2019-10-28 14:16:14 -05:00
dev_info="$(parted -s "$device" print 2> /dev/null)"
2019-10-18 00:08:13 -05:00
2019-02-23 21:09:47 -06:00
swapoff -a
while read -r PART; do
2019-11-02 12:50:52 -05:00
[[ $PART ]] || continue
2019-10-28 14:16:14 -05:00
parted -s "$device" rm "$PART" > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "parted -s '$device' rm '$PART' > /dev/null" || return 1
2019-02-23 21:09:47 -06:00
done <<< "$(awk '/^ [1-9][0-9]?/ {print $1}' <<< "$dev_info" | sort -r)"
2019-11-02 12:50:52 -05:00
[[ $(awk '/Table:/ {print $3}' <<< "$dev_info") != "$label" ]] && parted -s "$device" mklabel "$label" > /dev/null 2> "$ERR"
2019-02-23 21:09:47 -06:00
msg "Auto Partition" "\nCreating a 512M $boot_fs boot partition.\n" 1
2019-11-02 12:50:52 -05:00
parted -s "$device" mkpart "$boot_type" "$boot_fs" 1MiB 513MiB > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "parted -s '$device' mkpart '$boot_type' '$boot_fs' 1MiB 513MiB > /dev/null" || return 1
2019-02-23 21:09:47 -06:00
sleep 0.5
2019-11-23 19:36:08 -06:00
BOOT_D="$device"
AUTO_BOOT=$(lsblk -lno NAME,TYPE "$device" | awk 'NR==2 {print "/dev/" $1}')
2019-02-23 21:09:47 -06:00
if [[ $SYS == "BIOS" ]]; then
2019-11-23 19:36:08 -06:00
mkfs.ext4 -q "$AUTO_BOOT" > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "mkfs.ext4 -q '$AUTO_BOOT' > /dev/null" || return 1
2019-02-23 21:09:47 -06:00
else
2019-11-23 19:36:08 -06:00
mkfs.vfat -F32 "$AUTO_BOOT" > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "mkfs.vfat -F32 '$AUTO_BOOT' > /dev/null" || return 1
2019-02-23 21:09:47 -06:00
fi
msg "Auto Partition" "\nCreating a $size ext4 root partition.\n" 0
2019-10-28 14:16:14 -05:00
parted -s "$device" mkpart primary ext4 513MiB 100% > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "parted -s '$device' mkpart primary ext4 513MiB 100% > /dev/null" || return 1
2019-02-23 21:09:47 -06:00
sleep 0.5
2019-11-23 19:36:08 -06:00
AUTO_ROOT="$(lsblk -lno NAME,TYPE "$device" | awk 'NR==3 {print "/dev/" $1}')"
mkfs.ext4 -q "$AUTO_ROOT" > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "mkfs.ext4 -q '$AUTO_ROOT' > /dev/null" || return 1
2019-02-23 21:09:47 -06:00
sleep 0.5
2019-03-11 03:52:49 -05:00
msg "Auto Partition" "\nProcess complete.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$device")\n"
2019-02-23 21:09:47 -06:00
}
2019-08-20 17:52:25 -05:00
###############################################################################
# partition management functions
2020-03-07 17:10:17 -06:00
# these are helpers used by other functions to do essential setup/teardown
2019-08-20 17:52:25 -05:00
2019-02-23 21:09:47 -06:00
part_find()
{
2019-03-11 03:52:49 -05:00
local regexp="$1" err=''
2020-03-07 19:07:27 -06:00
local s dev size isize model
2019-10-27 19:25:06 -05:00
2020-04-25 13:29:49 -05:00
PARTS="$(part_pretty "" "$regexp")"
PART_COUNT=$(wc -l <<< "$PARTS")
2019-10-27 19:25:06 -05:00
2019-10-18 21:47:46 -05:00
case "$regexp" in
2020-05-03 17:52:40 -05:00
'part|lvm|crypt')
[[ $PART_COUNT -lt 1 || ($SYS == 'UEFI' && $PART_COUNT -lt 2) ]] && err="$_errpart"
;;
'part|crypt')
(( PART_COUNT < 1 )) && err="$_lvmerr"
;;
'part|lvm')
(( PART_COUNT < 2 )) && err="$_lukserr"
;;
2019-02-23 21:09:47 -06:00
esac
2019-10-18 21:47:46 -05:00
if [[ $err ]]; then
2020-04-25 13:29:49 -05:00
msg "Not Enough Partitions" "$err" 0
2019-10-18 21:47:46 -05:00
return 1
fi
2019-02-23 21:09:47 -06:00
return 0
}
2019-08-26 22:16:36 -05:00
part_swap()
{
2020-03-07 17:10:17 -06:00
local swp="$1"
if [[ $swp == "$MNT/swapfile" && $SWAP_S ]]; then
2020-04-25 13:29:49 -05:00
msg "Swap Setup" "\nActivating $SWAP_S swapfile at /swapfile\n" 1
2020-03-07 17:10:17 -06:00
fallocate -l $SWAP_S "$swp" 2> "$ERR"
errshow 0 "fallocate -l '$SWAP_S' '$swp'"
chmod 600 "$swp" 2> "$ERR"
errshow 0 "chmod 600 '$swp'"
2020-04-25 13:29:49 -05:00
else
2020-05-14 13:25:10 -05:00
msg "Swap Setup" "\nActivating swap partition $SWAP\n" 1
2019-08-26 22:16:36 -05:00
fi
2020-03-07 17:10:17 -06:00
mkswap "$swp" > /dev/null 2> "$ERR"
errshow 0 "mkswap '$swp' > /dev/null"
swapon "$swp" > /dev/null 2> "$ERR"
errshow 0 "swapon '$swp' > /dev/null"
2019-08-26 22:16:36 -05:00
return 0
}
2019-02-23 21:09:47 -06:00
part_mount()
{
2019-11-23 19:36:08 -06:00
local part="$1"
2020-05-17 11:36:29 -05:00
local mntp="${MNT}$2"
2020-03-25 10:30:25 -05:00
local fs
fs="$(lsblk -lno FSTYPE "$part")"
2019-02-23 21:09:47 -06:00
2020-05-17 11:36:29 -05:00
mkdir -p "$mntp"
2019-11-23 19:36:08 -06:00
2020-05-17 17:51:20 -05:00
# skipped formatting on existing btrfs partition?
if [[ $fs == 'btrfs' && $BTRFS -eq 0 ]] && yesno "Btrfs Subvolume Mount" "\nDo you have a subvolume on $part that should be mounted at $mntp?\n"; then
btrfs_name "\nEnter the name of initial subvolume on $part to be mounted at $mntp.\n\ne.g. mount -o subvol=YOUR_SUBVOL $part $mntp\n" || return 1
btrfs_mount "$part" "$mntp" "$SUBVOL" || return 1
2019-02-23 21:09:47 -06:00
else
2020-05-17 17:51:20 -05:00
if [[ $BTRFS -ne 2 && $fs && ${FS_OPTS[$fs]} && $part != "$BOOT" && $part != "$AUTO_ROOT" ]] && select_mntopts "$part" "$fs"; then
mount -o $MNT_OPTS "$part" "$mntp" > /dev/null 2> "$ERR"
errshow 0 "mount -o $MNT_OPTS $part $mntp" || return 1
else
MNT_OPTS=''
mount "$part" "$mntp" > /dev/null 2> "$ERR"
errshow 0 "mount $part $mntp" || return 1
fi
msg "Mount Complete" "\nMounted $part at $mntp\n" 1
2019-02-23 21:09:47 -06:00
fi
2020-05-17 11:36:29 -05:00
part_countdec "$part"
part_cryptlv "$part"
2019-02-23 21:09:47 -06:00
return 0
}
2020-04-25 13:29:49 -05:00
part_pretty()
{
local part="$1"
local regexp="$2"
local s dev size isize model
# invalid block device passed in
[[ $part && ! -b $part ]] && return
2020-04-26 10:36:33 -05:00
# full search when not given a regex
[[ $regexp == "" ]] && regexp="part|crypt|lvm"
2020-04-25 13:29:49 -05:00
# string of partitions >= 80M
# format: /dev/sda1 447.1G__ext4__unlabeled__Sandisk_SDSSDXP480G
while read -r dev size; do
[[ $dev && $size ]] || continue
s=${size%%__*}
size_t="${s: -1:1}"
2020-05-12 21:50:35 -05:00
isize=${s:0: -1}
2020-04-25 13:29:49 -05:00
isize=${isize%.*}
if [[ $dev = /dev/nvme* ]]; then
2020-04-26 10:36:33 -05:00
model=$(lsblk -lno MODEL "${dev%p[1-9]}" | awk '{gsub(/ |\t/, "_"); print}')
2020-04-25 13:29:49 -05:00
else
2020-04-26 10:36:33 -05:00
model=$(lsblk -lno MODEL "${dev%[1-9]}" | awk '{gsub(/ |\t/, "_"); print}')
2020-04-25 13:29:49 -05:00
fi
[[ $size_t == 'K' || ($size_t == 'M' && $isize -lt 80) ]] || printf "%s\n" "$dev ${size}__$model"
done < <(lsblk -lno TYPE,PATH,SIZE,FSTYPE,LABEL $part |
awk "/$regexp/"' && !'"/${IGNORE_DEV:-NONEXX}/"' {
2020-05-17 13:05:57 -05:00
if ($4 == "") {
$4 = "unformatted"
}
if ($5 == "") {
$5 = "unlabeled"
}
2020-04-25 13:29:49 -05:00
print $2, $3 "__" $4 "__" $5
}')
}
2019-02-23 21:09:47 -06:00
part_format()
{
2019-11-23 19:36:08 -06:00
local part="$1"
local fs="$2"
local delay="$3"
2019-02-23 21:09:47 -06:00
2020-05-15 02:50:53 -05:00
if [[ $fs == 'f2fs' && -z $PF2FS ]]; then
modprobe f2fs
PF2FS=true
sleep 1
elif [[ $fs == 'btrfs' && -z $PBTRFS ]]; then
modprobe btrfs
PBTRFS=true
sleep 1
fi
2020-05-14 23:40:59 -05:00
2020-05-15 02:50:53 -05:00
msg "File System 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 0 "mkfs.$fs ${FS_CMD_FLAGS[$fs]} $part" || return 1
2020-03-25 10:30:25 -05:00
sleep "$delay"
2019-03-11 03:52:49 -05:00
}
2019-02-23 21:09:47 -06:00
part_device()
{
2020-04-25 13:29:49 -05:00
if [[ $DEV_COUNT -eq 1 && $DEVS ]]; then
DEVICE="$(awk '{print $1}' <<< "$DEVS")"
2019-02-23 21:09:47 -06:00
elif (( DEV_COUNT > 1 )); then
if [[ $1 ]]; then
2020-04-25 13:29:49 -05:00
dlg DEVICE menu "Boot Device" "\nSelect the device to use for bootloader install." $DEVS
2019-02-23 21:09:47 -06:00
else
2020-04-25 13:29:49 -05:00
dlg DEVICE menu "Select Device" "$_device" $DEVS
2019-02-23 21:09:47 -06:00
fi
[[ $DEVICE ]] || return 1
elif [[ $DEV_COUNT -lt 1 && ! $1 ]]; then
2019-08-20 22:03:12 -05:00
msg "Device Error" "\nNo available devices.\n\nExiting..\n" 2
die 1
2019-02-23 21:09:47 -06:00
fi
2019-11-23 19:36:08 -06:00
[[ $1 ]] && BOOT_D="$DEVICE"
2019-02-23 21:09:47 -06:00
return 0
}
part_bootdev()
{
2019-11-23 19:36:08 -06:00
BOOT_D="${BOOT%[1-9]}"
BOOT_NUM="${BOOT: -1}"
[[ $BOOT = /dev/nvme* ]] && BOOT_D="${BOOT%p[1-9]}"
2019-02-23 21:09:47 -06:00
if [[ $SYS == 'UEFI' ]]; then
2019-11-23 19:36:08 -06:00
parted -s $BOOT_D set $BOOT_NUM esp on > /dev/null 2>&1
2019-02-23 21:09:47 -06:00
else
2019-11-23 19:36:08 -06:00
parted -s $BOOT_D set $BOOT_NUM boot on > /dev/null 2>&1
2019-02-23 21:09:47 -06:00
fi
return 0
}
part_cryptlv()
{
2019-03-11 03:52:49 -05:00
local part="$1" devs=""
devs="$(lsblk -lno NAME,FSTYPE,TYPE)"
2019-02-23 21:09:47 -06:00
# Identify if $part is LUKS+LVM, LVM+LUKS, LVM alone, or LUKS alone
if lsblk -lno TYPE "$part" | grep -q 'crypt'; then
LUKS='encrypted'
LUKS_NAME="${part#/dev/mapper/}"
2020-05-17 20:29:26 -05:00
for dev in $(awk '/lvm/ && /crypto_LUKS/ {print "/dev/mapper/"$1}' <<< "$devs" | sort | uniq); do
2019-02-23 21:09:47 -06:00
if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
2020-03-01 14:14:10 -06:00
LUKS_DEV="${LUKS_DEV}cryptdevice=$dev:$LUKS_NAME "
2019-02-23 21:09:47 -06:00
LVM='logical volume'
break
fi
done
2020-05-17 20:29:26 -05:00
for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | sort | uniq); do
2019-02-23 21:09:47 -06:00
if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
2020-03-01 14:14:10 -06:00
LUKS_DEV="${LUKS_DEV}cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME "
2019-02-23 21:09:47 -06:00
break
fi
done
elif lsblk -lno TYPE "$part" | grep -q 'lvm'; then
LVM='logical volume'
VNAME="${part#/dev/mapper/}"
2020-05-17 20:29:26 -05:00
for dev in $(awk '/crypt/ && /lvm2_member/ {print "/dev/mapper/"$1}' <<< "$devs" | sort | uniq); do
2019-02-23 21:09:47 -06:00
if lsblk -lno NAME "$dev" | grep -q "$VNAME"; then
LUKS_NAME="${dev/\/dev\/mapper\//}"
break
fi
done
2020-05-17 20:29:26 -05:00
for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | sort | uniq); do
2019-02-23 21:09:47 -06:00
if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
2020-03-01 14:14:10 -06:00
LUKS_DEV="${LUKS_DEV}cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME "
2019-02-23 21:09:47 -06:00
LUKS='encrypted'
break
fi
done
fi
}
part_countdec()
{
2019-08-18 16:22:41 -05:00
for pt; do
2020-04-25 13:29:49 -05:00
if (( PART_COUNT )); then
2019-08-18 16:22:41 -05:00
PARTS="$(sed "/${pt//\//\\/}/d" <<< "$PARTS")"
2020-04-25 13:29:49 -05:00
(( PART_COUNT-- ))
2019-02-23 21:09:47 -06:00
fi
done
}
###############################################################################
# mounting menus
2019-08-20 17:52:25 -05:00
# mount_menu is the entry point which calls all other functions
# once finished it returns to the main menu: main()
2019-02-23 21:09:47 -06:00
2019-08-20 17:52:25 -05:00
mount_menu()
2019-02-23 21:09:47 -06:00
{
2019-11-23 19:36:08 -06:00
is_bg_install || return 0
2020-05-12 21:50:35 -05:00
msg "Mount Menu" "\nGathering device and partition information.\n" 1
2019-02-23 21:09:47 -06:00
lvm_detect
2019-10-18 21:47:46 -05:00
umount_dir "$MNT"
2020-05-17 16:16:17 -05:00
if ! part_find 'part|lvm|crypt'; then
dev_menu "$_errpart"
if ! part_find 'part|lvm|crypt'; then
SEL=0
return 1
fi
fi
2019-02-23 21:09:47 -06:00
[[ $LUKS && $LUKS_PART ]] && part_countdec $LUKS_PART
[[ $LVM && $LVM_PARTS ]] && part_countdec $LVM_PARTS
2019-11-23 19:36:08 -06:00
select_root || { ROOT=''; return 1; }
select_boot || { BOOT=''; return 1; }
if [[ $BOOT ]]; then
part_mount "$BOOT" "/boot" || return 1
2019-02-23 21:09:47 -06:00
part_bootdev
2019-11-23 19:36:08 -06:00
SEP_BOOT=true
2019-02-23 21:09:47 -06:00
fi
select_swap || return 1
2019-11-23 19:36:08 -06:00
select_extra || return 1
2019-08-25 02:16:21 -05:00
install_background
2019-02-23 21:09:47 -06:00
return 0
}
2019-11-23 19:36:08 -06:00
select_boot()
2019-02-23 21:09:47 -06:00
{
2020-03-07 17:10:17 -06:00
local s pts dev size isize ptcount=0
2019-02-23 21:09:47 -06:00
2019-11-23 19:36:08 -06:00
if [[ -z $BOOT ]]; then
if [[ $AUTO_BOOT && -z $LVM && -z $LUKS ]]; then
BOOT="$AUTO_BOOT"
return 0
2019-02-23 21:09:47 -06:00
fi
2019-09-30 19:41:09 -05:00
2020-04-25 13:29:49 -05:00
if (( PART_COUNT )); then
2019-11-23 19:36:08 -06:00
while read -r dev size; do # walk partition list and skip ones that are too small/big for boot
2020-03-07 17:10:17 -06:00
s=${size%%__*}
size_t="${s: -1:1}"
isize=${s:0:-1}
2019-11-23 19:36:08 -06:00
isize=${isize%.*}
2020-03-07 17:10:17 -06:00
if ! [[ $size_t == 'T' || ($size_t == 'G' && $isize -gt 2) ]]; then
pts+="$dev $size "
(( ptcount++ ))
fi
2019-11-23 19:36:08 -06:00
done <<< "$PARTS"
2019-02-23 21:09:47 -06:00
fi
2020-03-07 17:10:17 -06:00
local txt="\nNo partitions available that meet size requirements!!\n\nReturning to the main menu.\n"
2019-11-23 19:36:08 -06:00
case "$SYS" in
UEFI)
case "$ptcount" in
2020-03-07 17:10:17 -06:00
0)
msg "EFI Boot Partition" "$txt" 2
return 1
;;
1)
2020-04-25 13:29:49 -05:00
msg "EFI Boot Partition" "\nOnly one partition that meets size requirements for boot (/boot).\n" 1
2020-03-07 17:10:17 -06:00
BOOT="$(awk 'NF > 0 {print $1}' <<< "$pts")"
;;
*)
dlg BOOT menu "EFI Partition" "$_uefi" $pts
;;
2019-11-23 19:36:08 -06:00
esac
[[ $BOOT ]] || return 1
;;
BIOS)
if [[ $LUKS && ! $LVM ]]; then
2019-10-18 21:47:46 -05:00
case "$ptcount" in
2020-03-07 17:10:17 -06:00
0)
txt="\nLUKS without LVM requires a separate boot partition.$txt"
msg "Boot Partition" "$txt" 2
return 1
;;
1)
2020-04-25 13:29:49 -05:00
msg "Boot Partition" "\nOnly one partition that meets size requirements for boot (/boot).\n" 1
2020-03-07 17:10:17 -06:00
BOOT="$(awk 'NF > 0 {print $1}' <<< "$pts")"
;;
*)
dlg BOOT menu "Boot Partition" "$_biosluks" $pts
;;
2019-10-18 21:47:46 -05:00
esac
2019-11-23 19:36:08 -06:00
[[ $BOOT ]] || return 1
else
(( ptcount == 0 )) && return 0
dlg BOOT menu "Boot Partition" "$_bios" "skip" "no separate boot" $pts
2020-03-07 17:10:17 -06:00
if [[ -z $BOOT || $BOOT == "skip" ]]; then
BOOT=''
return 0
fi
2019-11-23 19:36:08 -06:00
fi
;;
esac
2019-02-23 21:09:47 -06:00
fi
2020-03-25 10:30:25 -05:00
local fs
fs="$(fsck -N "$BOOT")"
2020-05-17 17:25:37 -05:00
BOOTFS="$fs"
2020-03-07 17:10:17 -06:00
if ([[ $SYS == 'BIOS' ]] && grep -q 'ext[34]' <<< "$fs") || ([[ $SYS == 'UEFI' ]] && grep -q 'fat' <<< "$fs"); then
2020-05-14 13:25:10 -05:00
yesno "Format Boot Partition" "\nIMPORTANT: $BOOT $_format" "Format" "Do Not Format" 1 || return 0
2019-02-23 21:09:47 -06:00
fi
2019-10-18 21:47:46 -05:00
case "$SYS" in
2020-05-14 02:16:20 -05:00
UEFI)
BOOTFS='vfat'
part_format "$BOOT" "vfat" 2 || return 1
;;
BIOS)
BOOTFS='ext4'
part_format "$BOOT" "ext4" 2 || return 1
;;
2019-10-18 21:47:46 -05:00
esac
2019-02-23 21:09:47 -06:00
return 0
}
2019-11-23 19:36:08 -06:00
select_root()
2019-02-23 21:09:47 -06:00
{
2020-05-17 11:36:29 -05:00
local pts dev size isize ptcount=0
2019-11-23 19:36:08 -06:00
if [[ -z $ROOT ]]; then
if [[ $AUTO_ROOT && -z $LVM && -z $LUKS ]]; then
ROOT="$AUTO_ROOT"
2019-10-17 19:19:00 -05:00
msg "Mount Menu" "\nUsing partitions created during automatic format.\n" 2
2020-05-17 11:36:29 -05:00
part_mount "$ROOT" || { AUTO_ROOT='' ROOT=''; return 1; }
2019-10-17 19:19:00 -05:00
return 0 # we're done here
2020-05-17 11:36:29 -05:00
else # walk partition list and skip ones that are < 8G
2019-10-17 19:19:00 -05:00
while read -r dev size; do
2020-03-07 17:10:17 -06:00
s=${size%%__*}
size_t="${s: -1:1}"
2020-05-12 21:50:35 -05:00
isize=${s:0: -1}
2020-03-07 17:10:17 -06:00
isize=${isize%.*}
2020-03-07 18:24:38 -06:00
if ! [[ $size_t == 'M' || ($size_t == 'G' && $isize -lt 8) ]]; then
2020-03-07 17:10:17 -06:00
pts+="$dev $size "
(( ptcount++ ))
fi
2019-10-17 19:19:00 -05:00
done <<< "$PARTS"
if (( ptcount == 1 )); then # only one available device
2020-04-25 13:29:49 -05:00
msg "Root Partition (/)" "\nOnly one that meets size requirements for root (/).\n" 2
2019-11-23 19:36:08 -06:00
ROOT="$(awk 'NF > 0 {print $1}' <<< "$pts")"
2019-10-17 19:19:00 -05:00
else
2020-03-07 17:10:17 -06:00
local txt="\nSelect the root (/) partition, this is where $DIST will be installed."
2020-03-07 18:24:38 -06:00
txt+="\n\nDevices smaller than 8G will not be shown here."
2019-11-23 19:36:08 -06:00
dlg ROOT menu "Mount Root" "$txt" $pts
2019-10-17 19:19:00 -05:00
fi
2019-08-18 16:22:41 -05:00
fi
2019-02-23 21:09:47 -06:00
fi
2020-05-14 02:16:20 -05:00
if [[ $ROOT ]]; then
select_filesystem "$ROOT" || return 1
2020-05-17 11:36:29 -05:00
part_mount "$ROOT" || return 1
2020-05-14 02:16:20 -05:00
if (( BTRFS == 2 )); then
2020-05-14 13:25:10 -05:00
btrfs_subvols "$ROOT" || return 1
2020-05-14 02:16:20 -05:00
fi
2020-05-16 18:05:01 -05:00
BTRFS=0
2020-05-14 23:25:14 -05:00
return 0
2020-05-14 02:16:20 -05:00
fi
2020-05-17 11:36:29 -05:00
2019-11-23 19:36:08 -06:00
# should never reach here unless an error occurred
ROOT=''
return 1
}
select_swap()
{
local pts dev size isize
2020-04-25 13:29:49 -05:00
if (( PART_COUNT )) ; then
2020-03-07 17:10:17 -06:00
while read -r dev size; do # walk partition list and skip ones that are > 64G
s=${size%%__*}
size_t="${s: -1:1}"
2020-05-12 21:50:35 -05:00
isize=${s:0: -1}
2019-11-23 19:36:08 -06:00
isize=${isize%.*}
2020-03-07 17:10:17 -06:00
if ! [[ $size_t == 'T' || ($size_t == 'G' && $isize -gt 64) ]]; then
pts+="$dev $size "
fi
2019-11-23 19:36:08 -06:00
done <<< "$PARTS"
fi
dlg SWAP menu "Swap Setup" "\nSelect whether to use a swapfile, swap partition, or none." \
2020-03-07 17:10:17 -06:00
"none" "No swap space" \
2020-03-07 18:24:38 -06:00
"swapfile" "/swapfile (editable size)" \
2019-11-23 19:36:08 -06:00
$pts
if [[ -z $SWAP || $SWAP == "none" ]]; then
SWAP=''
return 0
elif [[ $SWAP == "swapfile" ]]; then
local i=0
until [[ ${SWAP_S:0:1} =~ [1-9] && ${SWAP_S: -1} =~ (M|G) ]]; do
2020-03-07 17:10:17 -06:00
if (( i > 0 )); then
msg "Swap Size Error" \
"\nSwap size must be 1(M|G) or greater, and can only contain whole numbers\n\nSize entered: $SWAP_S\n" 2
fi
if ! dlg SWAP_S input "Swap Setup" "$_swapsize" "$SYS_MEM"; then
SWAP=''
SWAP_S=''
return 1
fi
2019-11-23 19:36:08 -06:00
(( i++ ))
done
part_swap "$MNT/$SWAP"
SWAP="/$SWAP"
else
part_swap "$SWAP"
part_countdec "$SWAP"
SWAP_S="$(lsblk -lno SIZE $SWAP)"
2019-09-30 19:41:09 -05:00
fi
2019-02-23 21:09:47 -06:00
return 0
}
2019-11-23 19:36:08 -06:00
select_extra()
2019-02-23 21:09:47 -06:00
{
2019-10-18 21:47:46 -05:00
local part dev size
2019-08-18 15:37:49 -05:00
2020-03-07 17:10:17 -06:00
# walk partition list and skip ones that are < 1G
2020-04-25 13:29:49 -05:00
if (( PART_COUNT )); then
2019-10-27 16:13:56 -05:00
while read -r dev size; do
2020-03-07 17:10:17 -06:00
s=${size%%__*}
[[ ${s: -1:1} == 'M' ]] && part_countdec "$dev"
2019-10-27 16:13:56 -05:00
done <<< "$PARTS"
fi
2019-08-18 15:37:49 -05:00
2020-04-25 13:29:49 -05:00
if (( PART_COUNT == 0 )); then
2020-03-07 17:10:17 -06:00
msg "Mount Extra" "\nMounting Finished\n\nNo more partitions to mount, returning to main menu.\n" 2
2020-05-16 18:05:01 -05:00
else
while (( PART_COUNT )); do
part=''
dlg part menu 'Mount Extra' "$_expart" 'done' 'finish mounting step' $PARTS || break
if [[ $part == 'done' ]]; then
break
2020-05-17 11:36:29 -05:00
elif select_filesystem "$part" && select_mountpoint && part_mount "$part" "$EXMNT"; then
2020-05-16 18:05:01 -05:00
if (( BTRFS == 2 )); then
btrfs_subvols "$part" "$EXMNT" || return 1
fi
EXMNTS+="$part: $EXMNT "
[[ $EXMNT == '/usr' && $HOOKS != *usr* ]] && HOOKS+=" usr"
BTRFS=0
else
return 1
fi
done
2020-03-07 17:10:17 -06:00
fi
2019-02-23 21:09:47 -06:00
return 0
}
2019-11-23 19:36:08 -06:00
select_mntopts()
{
2020-05-17 11:36:29 -05:00
local part="$1"
local fs="$2"
2019-11-23 19:36:08 -06:00
local opts=''
local title="${fs^} Mount Options"
2020-05-17 11:36:29 -05:00
yesno "$title" "\nMount $part with default mount options?\n" && return 1
2019-11-23 19:36:08 -06:00
for i in ${FS_OPTS[$fs]}; do
opts+="$i - off "
done
until [[ $MNT_OPTS ]]; do
2020-05-17 13:05:57 -05:00
dlg MNT_OPTS check "$title" "$_mount" $opts || return 1 # no options is auto mount
2019-11-23 19:36:08 -06:00
MNT_OPTS="${MNT_OPTS// /,}"
2020-05-17 11:36:29 -05:00
yesno "$title" "\nConfirm mount options: $MNT_OPTS\n" || MNT_OPTS=''
2019-11-23 19:36:08 -06:00
done
return 0
}
select_filesystem()
{
local part="$1"
local fs=''
2020-05-03 14:47:39 -05:00
local cur txt pt
2020-03-25 10:30:25 -05:00
cur="$(lsblk -lno FSTYPE "$part" 2> /dev/null)"
2020-05-14 23:40:59 -05:00
txt="\nSelect which file system to use for $(part_pretty "$part")\n\ndefault: ext4"
2019-11-23 19:36:08 -06:00
2020-05-03 14:47:39 -05:00
if [[ $cur ]]; then
2020-05-14 13:25:10 -05:00
txt+="\nexisting: $cur"
2020-05-03 14:47:39 -05:00
# bail early if the partition was created in part_auto()
[[ $part == "$AUTO_ROOT" ]] && return 0
fi
2019-11-23 19:36:08 -06:00
2020-05-14 02:16:20 -05:00
BTRFS=0
2019-11-23 19:36:08 -06:00
until [[ $fs ]]; do
2020-05-17 17:34:18 -05:00
dlg fs menu "File System" "$txt" $([[ $cur ]] && printf "skip -") \
2020-05-03 14:47:39 -05:00
ext4 "The evolution of the most used Linux file system, successor to Ext3" \
ext3 "Third extended file system, successor to Ext2" \
ext2 "Second extended file system, unlike 3/4 it is not journaled and obsolete" \
vfat "File allocation table, a legacy file system which is simple and robust" \
2020-05-14 02:16:20 -05:00
btrfs "A modern copy on write file system with advanced features, fault tolerance, repair, and easy administration" \
2020-05-03 14:47:39 -05:00
ntfs "NT file system, a journaling file system created by Microsoft" \
f2fs "Flash-friendly file system, intended for NAND-based flash memory" \
jfs "Journaled file system created by IBM and open-sourced in 1999" \
xfs "Journaled file system created by Silicon Graphics Inc. (SGI)" \
nilfs2 "A log-structured file system implementation for the Linux kernel" \
reiserfs "Journaled file system created by a team at Namesys led by Hans Reiser" || return 1
2020-05-14 02:16:20 -05:00
2019-11-23 19:36:08 -06:00
[[ $fs == 'skip' ]] && return 0
2020-05-14 13:25:10 -05:00
yesno "File System" "\nFormat $part as $fs?\n" || fs=''
2019-11-23 19:36:08 -06:00
done
2020-05-14 02:16:20 -05:00
[[ $part == "$ROOT" ]] && ROOTFS=$fs
2020-05-15 02:50:53 -05:00
part_format "$part" "$fs" 1
if [[ $fs == 'btrfs' ]]; then
BTRFS=1
yesno "Btrfs Subvolumes" "$_btrfs" && BTRFS=2
fi
2019-11-23 19:36:08 -06:00
}
select_mountpoint()
{
EXMNT=''
until [[ $EXMNT ]]; do
2020-04-25 13:29:49 -05:00
dlg EXMNT input "Extra Mount $(part_pretty "$part")" "$_exmnt" "/" || return 1
2019-11-23 19:36:08 -06:00
if [[ ${EXMNT:0:1} != "/" || ${#EXMNT} -le 1 || $EXMNT =~ \ |\' || $EXMNTS == *"$EXMNT"* ]]; then
msg "Mountpoint Error" "$_errexpart"
EXMNT=''
fi
done
return 0
}
2019-02-23 21:09:47 -06:00
###############################################################################
# installation
2019-08-20 17:52:25 -05:00
# main is the entry point which calls all other install functions, once
# complete it shows a dialog to edit files on the new system before reboot
2019-02-23 21:09:47 -06:00
install_main()
{
install_base
2019-10-27 16:56:08 -05:00
genfstab -U "$MNT" > "$MNT/etc/fstab" 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 1 "genfstab -U '$MNT' > '$MNT/etc/fstab'"
2019-10-18 21:47:46 -05:00
[[ -f $MNT/swapfile ]] && sed -i "s~${MNT}~~" "$MNT/etc/fstab"
2019-02-23 21:09:47 -06:00
install_packages
2019-11-23 19:36:08 -06:00
install_tearfree "$MNT/etc/X11/xorg.conf.d"
2019-02-23 21:09:47 -06:00
install_mkinitcpio
2019-12-22 19:41:42 -06:00
install_bootldr
2019-02-23 21:09:47 -06:00
chrun "hwclock --systohc --utc" || chrun "hwclock --systohc --utc --directisa"
install_user
2019-04-21 14:32:42 -05:00
install_login
2020-05-03 14:47:39 -05:00
2020-05-14 02:16:20 -05:00
# changing distro name?
2020-05-17 16:16:17 -05:00
if grep -q 'ArchLabs' "$MNT/etc/lsb-release" && [[ $DIST != 'ArchLabs' ]]; then
2020-05-14 02:16:20 -05:00
sed -i "s/ArchLabs/$DIST/g" "$MNT/etc/lsb-release"
sed -i "s/ArchLabs/$DIST/g" "$MNT/etc/os-release"
2020-05-17 11:36:29 -05:00
else
sed -i "s/Arch/$DIST/g" "$MNT/etc/lsb-release"
sed -i "s/Arch/$DIST/g" "$MNT/etc/os-release"
2020-05-14 02:16:20 -05:00
fi
2020-05-03 14:47:39 -05:00
# allow members of the wheel group to run commands as root
sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" "$MNT/etc/sudoers"
2019-02-23 21:09:47 -06:00
chrun "chown -Rf $NEWUSER:users /home/$NEWUSER"
2020-05-03 14:47:39 -05:00
2019-10-20 21:49:12 -05:00
if [[ "$USER_CMD" ]]; then
2019-10-27 17:16:24 -05:00
chrun "$USER_CMD" 2> "$ERR" 2>&1
2019-12-20 12:05:03 -06:00
errshow 0 "chrun '$USER_CMD'"
2019-10-20 21:49:12 -05:00
fi
2019-02-23 21:09:47 -06:00
2019-08-18 15:37:49 -05:00
while :; do
2019-02-23 21:09:47 -06:00
dlg choice menu "Finalization" "$_edit" \
finished "exit the installer and reboot" \
keyboard "${EDIT_FILES[keyboard]}" \
console "${EDIT_FILES[console]}" \
locale "${EDIT_FILES[locale]}" \
hostname "${EDIT_FILES[hostname]}" \
sudoers "${EDIT_FILES[sudoers]}" \
mkinitcpio "${EDIT_FILES[mkinitcpio]}" \
fstab "${EDIT_FILES[fstab]}" \
crypttab "${EDIT_FILES[crypttab]}" \
bootloader "${EDIT_FILES[bootloader]}" \
pacman "${EDIT_FILES[pacman]}" \
login "${EDIT_FILES[login]}"
2019-03-11 03:52:49 -05:00
if [[ -z $choice || $choice == 'finished' ]]; then
2019-10-20 21:49:12 -05:00
[[ $DEBUG == true && -r $DBG ]] && ${EDITOR:-vim} "$DBG"
clear
die 127
2019-02-23 21:09:47 -06:00
else
for f in ${EDIT_FILES[$choice]}; do
2019-10-20 21:49:12 -05:00
if [[ -e ${MNT}$f ]]; then
${EDITOR:-vim} "${MNT}$f"
else
2020-04-25 13:29:49 -05:00
msg "File Missing" "\nOne or more of the files selected do not exist:\n\n${MNT}$f\n"
2019-10-20 21:49:12 -05:00
fi
2019-02-23 21:09:47 -06:00
done
fi
done
}
install_base()
{
2019-09-15 18:59:17 -05:00
clear
tput cnorm
2019-11-23 19:36:08 -06:00
if [[ $BG_PID ]] && kill -0 $BG_PID 2> /dev/null; then
2020-05-03 01:25:41 -05:00
[[ -e /tmp/wmlist ]] && rm /tmp/wmlist
2019-11-23 19:36:08 -06:00
printf "\nA background install process is still running, tailing the output...\n"
tail -f --pid=$BG_PID "$BG"
trap - EXIT
unset BG_PID
fi
2019-02-23 21:09:47 -06:00
2020-05-03 14:47:39 -05:00
mkdir -pv "$MNT/etc/default"
mkdir -pv "$MNT/etc/X11/xorg.conf.d/"
2020-05-17 16:16:17 -05:00
if [[ $PACSTRAP == 0 ]]; then
2020-04-25 22:03:14 -05:00
# remove archiso files when copying iso
2020-04-18 16:37:22 -05:00
rm -rf "$MNT/etc/mkinitcpio-archiso.conf"
find "$MNT/usr/lib/initcpio" -name 'archiso*' -type f -delete
2020-04-25 22:03:14 -05:00
# vmlinuz, if this isn't copied the vanilla kernel may fail mkinitcpio
2020-04-18 16:37:22 -05:00
cp -vf "$RUN/x86_64/vmlinuz" "$MNT/boot/vmlinuz-linux" 2> "$ERR"
errshow 1 "cp -vf '$RUN/x86_64/vmlinuz' '$MNT/boot/vmlinuz-linux'"
2019-10-19 17:18:42 -05:00
2020-04-23 23:03:44 -05:00
# 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/\(HandleLidSwitch=\)ignore/#\1suspend/' "$MNT/etc/systemd/logind.conf"
sed -i 's/\(HandleSuspendKey=\)ignore/#\1suspend/' "$MNT/etc/systemd/logind.conf"
sed -i 's/\(HandleHibernateKey=\)ignore/#\1hibernate/' "$MNT/etc/systemd/logind.conf"
find "$MNT/boot" -name '*-ucode.img' -delete
2020-05-17 16:16:17 -05:00
elif [[ $DIST == "ArchLabs" ]]; then
# we have some customizations in /etc on the iso we want to preserve
cp -vf /etc/modprobe.d/* "$MNT/etc/modprobe.d/" # */
cp -vf /etc/X11/xorg.conf.d/* "$MNT/etc/X11/xorg.conf.d/" # */
cp -vf /etc/dialogrc "$MNT/etc/dialogrc"
cp -vf /etc/os-release "$MNT/etc/os-release"
cp -vf /etc/lsb-release "$MNT/etc/lsb-release"
cp -vf /etc/skel/.zshrc "$MNT/etc/skel/.zshrc"
2020-04-23 23:03:44 -05:00
fi
2019-03-11 03:52:49 -05:00
2019-10-19 17:18:42 -05:00
# copy network settings
2019-10-18 21:47:46 -05:00
[[ -f /etc/resolv.conf ]] && cp -fv /etc/resolv.conf "$MNT/etc/"
2020-04-25 22:03:14 -05:00
[[ -d /etc/netctl/interfaces ]] && cp -rfv /etc/netctl/interfaces "$MNT/etc/netctl/"
[[ -d /etc/NetworkManager/system-connections ]] && cp -rvf /etc/NetworkManager/system-connections "$MNT/etc/NetworkManager/"
2019-02-23 21:09:47 -06:00
2020-05-17 16:16:17 -05:00
# stop pacman complaining
2020-05-14 02:16:20 -05:00
chrun 'mkdir -p /var/lib/pacman/sync'
chrun 'touch /var/lib/pacman/sync/{core.db,extra.db,community.db}'
2019-11-23 19:36:08 -06:00
echo "LANG=$LOCALE" > "$MNT/etc/locale.conf"
2019-10-18 21:47:46 -05:00
cp -fv "$MNT/etc/locale.conf" "$MNT/etc/default/locale"
2019-11-23 19:36:08 -06:00
sed -i "s/#en_US.UTF-8/en_US.UTF-8/g; s/#${LOCALE}/${LOCALE}/g" "$MNT/etc/locale.gen"
2019-02-23 21:09:47 -06:00
chrun "locale-gen"
chrun "ln -svf /usr/share/zoneinfo/$ZONE/$SUBZ /etc/localtime"
2019-10-18 21:47:46 -05:00
cat > "$MNT/etc/X11/xorg.conf.d/00-keyboard.conf" <<- EOF
2019-08-20 17:52:25 -05:00
# Use localectl(1) to instruct systemd-localed to update it.
Section "InputClass"
Identifier "system-keyboard"
MatchIsKeyboard "on"
Option "XkbLayout" "$KEYMAP"
EndSection
EOF
2019-10-18 21:47:46 -05:00
cat > "$MNT/etc/default/keyboard" <<- EOF
2019-08-20 17:52:25 -05:00
# KEYBOARD CONFIGURATION FILE
# Consult the keyboard(5) manual page.
XKBMODEL=""
XKBLAYOUT="$KEYMAP"
XKBVARIANT=""
XKBOPTIONS=""
BACKSPACE="guess"
EOF
2019-10-18 21:47:46 -05:00
printf "KEYMAP=%s\nFONT=%s\n" "$CMAP" "$FONT" > "$MNT/etc/vconsole.conf"
2019-10-19 17:18:42 -05:00
2019-11-23 19:36:08 -06:00
echo "$NEWHOST" > "$MNT/etc/hostname"
2019-10-18 21:47:46 -05:00
cat > "$MNT/etc/hosts" <<- EOF
2019-08-20 17:52:25 -05:00
127.0.0.1 localhost
2019-11-23 19:36:08 -06:00
127.0.1.1 $NEWHOST
2019-08-20 17:52:25 -05:00
::1 localhost ip6-localhost ip6-loopback
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
EOF
2019-02-23 21:09:47 -06:00
}
install_user()
{
2020-05-04 01:02:31 -05:00
local i=0
2019-10-19 17:18:42 -05:00
local groups='audio,video,floppy,log,network,rfkill,scanner,storage,optical,power,wheel'
2019-10-20 21:49:12 -05:00
[[ -e $MNT/etc/X11/xorg.conf.d/20-nvida.conf && -e $MNT/usr/bin/optirun ]] && groups+=',bumblebee'
2019-10-17 21:53:32 -05:00
2019-10-19 17:18:42 -05:00
rm -f "$MNT/root/.zlogin" # remove welcome message
2019-08-21 01:39:09 -05:00
2019-10-27 17:16:24 -05:00
chrun "chpasswd <<< 'root:$ROOT_PASS'" 2> "$ERR" 2>&1
2019-12-20 12:05:03 -06:00
errshow 1 "chrun 'chpasswd <<< \"root:$ROOT_PASS\"'"
2020-04-10 18:03:28 -05:00
if [[ $NEWSHELL != 'zsh' ]]; then # root uses zsh by default
chrun "usermod -s /bin/$NEWSHELL root" 2> "$ERR" 2>&1
errshow 1 "chrun 'usermod -s /bin/$NEWSHELL root'"
2019-09-15 18:59:17 -05:00
# copy the default mkshrc to /root if it was selected
2020-04-10 18:03:28 -05:00
[[ $NEWSHELL == 'mksh' ]] && cp -fv "$MNT/etc/skel/.mkshrc" "$MNT/root/.mkshrc"
2019-02-23 21:09:47 -06:00
fi
2019-08-30 20:59:30 -05:00
echo "Creating new user $NEWUSER and setting password"
2020-05-04 01:02:31 -05:00
# check if there's an existing user home for new user (separate /home)
[[ -d "$MNT/home/$NEWUSER" ]] && i=1
2020-04-10 18:03:28 -05:00
chrun "useradd -m -u 1000 -g users -G $groups -s /bin/$NEWSHELL $NEWUSER" 2> "$ERR" 2>&1
errshow 1 "chrun 'useradd -m -u 1000 -g users -G $groups -s /bin/$NEWSHELL $NEWUSER'"
2019-10-27 17:16:24 -05:00
chrun "chpasswd <<< '$NEWUSER:$USER_PASS'" 2> "$ERR" 2>&1
2019-12-20 12:05:03 -06:00
errshow 1 "chrun 'chpasswd <<< \"$NEWUSER:$USER_PASS\"'"
2019-10-19 02:24:24 -05:00
2019-11-23 19:36:08 -06:00
[[ $INSTALL_WMS == *dwm* ]] && install_suckless "/home/$NEWUSER" chroot
2019-08-01 12:59:16 -05:00
2020-05-04 01:02:31 -05:00
# upgrade existing home with new skeleton configs
[[ $i == 1 ]] && cp -aT "$MNT/etc/skel/" "$MNT/home/$NEWUSER"
2019-11-23 19:36:08 -06:00
install_cleanup "$NEWUSER"
2019-08-26 22:16:36 -05:00
2019-02-23 21:09:47 -06:00
return 0
}
2019-04-21 14:32:42 -05:00
install_login()
{
2019-11-23 19:36:08 -06:00
AUTOLOGIN_SERV="$MNT/etc/systemd/system/getty@tty1.service.d"
if [[ -z $LOGIN_TYPE ]]; then
rm -rf "$AUTOLOGIN_SERV"
return 0
fi
echo "Setting up $LOGIN_TYPE"
if [[ $LOGIN_TYPE != 'xinit' ]]; then
[[ $INSTALL_WMS == *dwm* ]] && dwm_xsession
rm -rf "$AUTOLOGIN_SERV" "$MNT/home/$NEWUSER/.xinitrc"
2019-12-20 12:05:03 -06:00
chrun "systemctl enable $LOGIN_TYPE.service" 2> "$ERR"
errshow 1 "chrun 'systemctl enable $LOGIN_TYPE.service'"
2019-11-23 19:36:08 -06:00
fi
2019-12-22 19:41:42 -06:00
config_${LOGIN_TYPE}
2019-11-23 19:36:08 -06:00
}
install_cleanup()
{
local user="$1"
2020-04-10 18:03:28 -05:00
# remove tint2 configs if bspwm and openbox aren't being installed
[[ $INSTALL_WMS =~ (bspwm|openbox) ]] || rm -rf "$MNT/home/$user/.config/tint2"
# remove jgmenu configs if bspwm, fluxbox, and openbox aren't being installed
[[ $INSTALL_WMS =~ (fluxbox|bspwm|openbox) ]] || rm -rf "$MNT/home/$user/.config/jgmenu"
2019-11-23 19:36:08 -06:00
# remove geany configs if it wasn't installed
2020-04-23 23:03:44 -05:00
[[ ${USER_PKGS[*]} != *geany* ]] && rm -rf "$MNT/home/$user/.config/geany"
2019-11-23 19:36:08 -06:00
# remove shell stuff for unused shells
2020-04-10 18:03:28 -05:00
[[ $NEWSHELL != 'bash' ]] && rm -rf "$MNT/home/$user/.bash"*
[[ $NEWSHELL != 'zsh' ]] && rm -rf "$MNT/home/$user/.z"*
2019-11-23 19:36:08 -06:00
# cleanup default jwmrc
if [[ $INSTALL_WMS == *jwm* ]]; then
sed '7,14d; s/xlock -mode blank/i3-lock-fancy -p/g; s/root:1/rofi_run/g' "$MNT/etc/system.jwmrc" > "$MNT/home/$user/.jwmrc"
fi
2020-03-01 14:14:10 -06:00
# no picom (compton) or ksuperkey in dwm login
2019-11-23 19:36:08 -06:00
[[ $LOGIN_WM == 'dwm' ]] && sed -i '/super/d; /picom/d' "$MNT/home/$user/.xprofile" "$MNT/root/.xprofile"
# remove some commands from ~/.xprofile when using self contained sessions
2020-05-03 21:31:31 -05:00
if [[ $LOGIN_WM =~ ($SELF_CONTAINED_SES) || ($LOGIN_TYPE != 'xinit' && $INSTALL_WMS =~ ($SELF_CONTAINED)) ]]; then
2019-11-23 19:36:08 -06:00
sed -i '/super/d; /nitrogen/d; /picom/d' "$MNT/home/$user/.xprofile" "$MNT/root/.xprofile"
fi
2019-11-13 21:47:53 -06:00
2019-04-21 14:32:42 -05:00
}
2019-12-22 23:52:07 -06:00
install_bootldr()
{
2020-03-01 14:14:10 -06:00
local uuid_type="UUID"
2019-12-22 23:52:07 -06:00
echo "Installing $BOOTLDR"
if [[ $ROOT == /dev/mapper* ]]; then
ROOT_ID="$ROOT"
else
[[ $BOOTLDR =~ (systemd-boot|refind-efi|efistub) ]] && uuid_type="PARTUUID"
ROOT_ID="$uuid_type=$(blkid -s $uuid_type -o value $ROOT)"
fi
if [[ $SYS == 'UEFI' ]]; then
# remove our old install and generic BOOT/ dir
echo "Removing conflicting boot directories"
2020-05-14 02:16:20 -05:00
if [[ -d "$MNT/boot/EFI/$DIST" ]]; then
find "$MNT/boot/EFI/" -maxdepth 1 -mindepth 1 -iname "$DIST" -type d -delete -printf "remove %p\n"
find "$MNT/boot/EFI/" -maxdepth 1 -mindepth 1 -iname 'BOOT' -type d -delete -printf "remove %p\n"
fi
2019-12-22 23:52:07 -06:00
fi
2020-03-01 14:14:10 -06:00
if [[ $SWAP ]]; then # attempt to setup swap space for suspend/resume
if [[ $SWAP == /dev/mapper* ]]; then
RESUME="resume=$SWAP "
elif [[ $SWAP == "/swapfile" ]]; then
2020-05-17 16:16:17 -05:00
RESUME="resume=$ROOT_ID resume_offset=$(filefrag -v "${MNT}$SWAP" | awk '{if ($1=="0:") {gsub(/\./, ""); print $4}}') "
2020-03-01 14:14:10 -06:00
else
RESUME="resume=$uuid_type=$(blkid -s $uuid_type -o value "$SWAP") "
fi
fi
2019-12-22 23:52:07 -06:00
prerun_$BOOTLDR
chrun "${BCMDS[$BOOTLDR]}" 2> "$ERR" 2>&1
errshow 1 "chrun '${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
fi
if [[ $SYS == 'UEFI' ]]; then
# some UEFI firmware requires a generic esp/BOOT/BOOTX64.EFI
mkdir -pv "$MNT/boot/EFI/BOOT"
case "$BOOTLDR" in
2020-05-03 17:52:40 -05:00
grub)
cp -fv "$MNT/boot/EFI/$DIST/grubx64.efi" "$MNT/boot/EFI/BOOT/BOOTX64.EFI"
;;
syslinux)
cp -rf "$MNT/boot/EFI/syslinux/"* "$MNT/boot/EFI/BOOT/"
cp -f "$MNT/boot/EFI/syslinux/syslinux.efi" "$MNT/boot/EFI/BOOT/BOOTX64.EFI"
;;
2019-12-22 23:52:07 -06:00
refind-efi)
2020-05-03 17:52:40 -05:00
k="linux-hardened,linux-zen,linux-lts,linux"
sed -i "/#extra_kernel_version_strings/ c extra_kernel_version_strings $k" "$MNT/boot/EFI/refind/refind.conf"
cp -fv "$MNT/boot/EFI/refind/refind_x64.efi" "$MNT/boot/EFI/BOOT/BOOTX64.EFI"
;;
2019-12-22 23:52:07 -06:00
esac
fi
return 0
}
2019-02-23 21:09:47 -06:00
install_packages()
{
2020-04-23 23:03:44 -05:00
typeset -a inpkg rmpkg loginpkg
2019-08-17 23:10:51 -05:00
2020-04-25 22:03:14 -05:00
inpkg=("${SES_PKGS[@]}" "${USER_PKGS[@]}")
if [[ $INSTALL_WMS ]]; then
inpkg+=("${BASE_PKGS[@]}")
[[ $INSTALL_WMS =~ ($WM_PKG_SES) ]] && inpkg+=("${WM_PKGS[@]}")
fi
2020-04-23 23:03:44 -05:00
for i in ${LOGIN_PKGS[$LOGIN_TYPE]}; do
loginpkg+=("$i")
done
2020-05-04 01:02:31 -05:00
2020-04-26 10:36:33 -05:00
if [[ $PACSTRAP -eq 1 ]]; then
2020-05-17 16:16:17 -05:00
blk="$(lsblk -f)"
lspci | grep -qi 'broadcom' && inpkg+=('b43-firmware' 'b43-fwcutter' 'broadcom-wl')
grep -qi 'ntfs' <<< "$blk" && inpkg+=('ntfs-3g')
grep -qi 'jfs' <<< "$blk" && inpkg+=('jfsutils')
grep -qi 'xfs' <<< "$blk" && inpkg+=('xfsprogs')
grep -qi 'reiserfs' <<< "$blk" && inpkg+=('reiserfsprogs')
[[ $LVM ]] && inpkg+=('lvm2')
2020-05-14 02:16:20 -05:00
if [[ $BTRFS_MNT ]] || grep -qi 'btrfs' <<< "$blk"; then
2020-05-17 16:16:17 -05:00
inpkg+=('btrfs-progs')
2020-05-14 02:16:20 -05:00
fi
2020-05-17 17:25:37 -05:00
else
[[ $NEWSHELL == 'zsh' ]] || rmpkg+=('zsh')
2020-05-17 16:16:17 -05:00
if pacman -Qq archlabs-installer >/dev/null 2>&1; then
rmpkg+=('archlabs-installer')
else
rm -fv "$MNT/usr/bin/installer"
fi
2020-04-23 23:03:44 -05:00
fi
2019-10-18 21:47:46 -05:00
2020-05-17 16:16:17 -05:00
[[ $INSTALL_WMS =~ dwm ]] && inpkg+=('git')
[[ $NEWSHELL == 'zsh' ]] && inpkg+=('zsh-completions')
[[ $NEWSHELL =~ (bash|zsh) ]] && inpkg+=('bash-completion')
2020-04-24 02:42:30 -05:00
2020-04-25 22:03:14 -05:00
# remove the packages we don't want on the installed system
[[ ${rmpkg[*]} ]] && chrun "pacman -Rnsc ${rmpkg[*]} --noconfirm"
2019-08-26 22:16:36 -05:00
2020-05-04 11:56:06 -05:00
# install crucial packages first to avoid issues, reinstalling iputils fixes network issues for non-root users
chrun "pacman -S $KERNEL $UCODE iputils --noconfirm" 2> "$ERR" 2>&1
errshow 1 "chrun 'pacman -S $KERNEL $UCODE iputils --noconfirm'"
2020-04-18 19:11:19 -05:00
2020-05-04 11:56:06 -05:00
# install the packages chosen throughout the install plus any extras added
chrun "pacman -S ${inpkg[*]} ${loginpkg[*]} $NEWSHELL --needed --noconfirm" 2> "$ERR" 2>&1
errshow 1 "chrun 'pacman -S ${inpkg[*]}${loginpkg[*]} $NEWSHELL --needed --noconfirm'"
2019-02-23 21:09:47 -06:00
2019-08-19 21:19:40 -05:00
# bootloader packages
2019-02-23 21:09:47 -06:00
if [[ $BOOTLDR == 'grub' ]]; then
2020-04-25 22:03:14 -05:00
chrun "pacman -S os-prober grub --needed --noconfirm" 2> "$ERR" 2>&1
errshow 1 "chrun 'pacman -S os-prober grub --needed --noconfirm'"
2019-02-23 21:09:47 -06:00
elif [[ $BOOTLDR == 'refind-efi' ]]; then
2020-04-25 22:03:14 -05:00
chrun "pacman -S refind-efi --needed --noconfirm" 2> "$ERR" 2>&1
errshow 1 "chrun 'pacman -S refind-efi --needed --noconfirm'"
elif [[ $BOOTLDR == 'syslinux' ]]; then
chrun "pacman -S syslinux --needed --noconfirm" 2> "$ERR" 2>&1
errshow 1 "chrun 'pacman -S syslinux --needed --noconfirm'"
fi
if [[ $SYS == 'UEFI' ]]; then
2019-10-27 17:16:24 -05:00
chrun "pacman -S efibootmgr --needed --noconfirm" 2> "$ERR" 2>&1
2019-12-20 12:05:03 -06:00
errshow 1 "chrun 'pacman -S efibootmgr --needed --noconfirm'"
2019-02-23 21:09:47 -06:00
fi
2019-08-17 19:39:19 -05:00
2020-05-03 01:25:41 -05:00
if [[ $VM == 'oracle' ]]; then
2020-05-03 22:56:06 -05:00
chrun "pacman -S ${KERNEL}-headers virtualbox-guest-utils virtualbox-guest-dkms --needed --noconfirm"
2019-10-20 21:49:12 -05:00
fi
2019-02-23 21:09:47 -06:00
return 0
}
2019-10-19 17:18:42 -05:00
install_suckless()
{
local dir="$1/suckless"
shift
2019-10-28 14:16:14 -05:00
if [[ $1 == 'chroot' ]]; then
2019-10-19 17:18:42 -05:00
chrun "mkdir -pv '$dir'"
for i in dwm dmenu st; do
if chrun "git clone 'https://git.suckless.org/$i' '$dir/$i'"; then
chrun "cd '$dir/$i' && make PREFIX=/usr install"
else
printf "failed to clone %s repo\n" "$i"
fi
done
else
mkdir -pv "$dir"
for i in dwm dmenu st; do
if git clone "https://git.suckless.org/$i" "$dir/$i"; then
cd "$dir/$i" && make PREFIX=/usr install
else
printf "failed to clone %s repo\n" "$i"
fi
done
fi
}
2019-11-23 19:36:08 -06:00
install_tearfree()
{
local xpath="$1"
2020-05-03 01:25:41 -05:00
if [[ $VM != 'none' ]]; then
2020-05-05 17:48:11 -05:00
[[ -e "$xpath/40-touchpad.conf" ]] && rm -fv "$xpath/40-touchpad.conf"
2019-11-23 19:36:08 -06:00
elif [[ $TEARFREE ]]; then
if 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
cat "$xpath/20-intel.conf"
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
cat "$xpath/20-amdgpu.conf"
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
cat "$xpath/20-radeon.conf"
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
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
2019-12-23 12:17:01 -06:00
cat "$xpath/20-nvidia.conf"
2019-11-23 19:36:08 -06:00
echo
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
fi
if lspci | grep ' VGA ' | grep -q 'Intel\|AMD/ATI'; then
if [[ $xpath == *"$MNT"* ]]; then
sed -i 's/xrender/glx/g' "$MNT/etc/skel/.config/picom.conf"
else
sed -i 's/xrender/glx/g' /etc/skel/.config/picom.conf
fi
fi
fi
2020-04-18 16:37:22 -05:00
if [[ $PACSTRAP != 1 ]]; then
# remove nvidia installer from installed system
[[ $xpath == *"$MNT"* ]] && rm -rf "$MNT/usr/bin/nvidia-installer" "$MNT/var/lib/nvidia-installer"
fi
2019-11-23 19:36:08 -06:00
}
2019-02-23 21:09:47 -06:00
install_mkinitcpio()
{
local add=''
2019-11-23 19:36:08 -06:00
[[ $LUKS ]] && add+=" encrypt"
[[ $LVM ]] && add+=" lvm2"
2020-05-04 01:02:31 -05:00
[[ $SWAP ]] && add+=" resume"
2019-11-23 19:36:08 -06:00
sed -i "s/block filesystems/block${add} filesystems ${HOOKS}/g" "$MNT/etc/mkinitcpio.conf"
2019-10-27 17:16:24 -05:00
chrun "mkinitcpio -p $KERNEL" 2> "$ERR" 2>&1
2019-12-20 12:05:03 -06:00
errshow 1 "chrun 'mkinitcpio -p $KERNEL'"
2019-02-23 21:09:47 -06:00
}
2019-03-04 23:47:24 -06:00
install_mirrorlist()
{
2020-05-17 13:05:57 -05:00
if [[ $AUTO_MIR ]]; then
2020-05-02 14:16:56 -05:00
timedatectl set-ntp 1 && timedatectl > /dev/null 2>&1
2020-05-17 13:05:57 -05:00
reflector --verbose --score 80 -l 40 -f 5 --sort rate --save /etc/pacman.d/mirrorlist
else
echo "ranking mirrorlist, this may take a while..."
cp -f /etc/pacman.d/mirrorlist /tmp/mirrors
rankmirrors -n 6 /tmp/mirrors > /etc/pacman.d/mirrorlist
2019-03-04 23:47:24 -06:00
fi
}
2019-02-23 21:09:47 -06:00
install_background()
{
2020-05-17 20:29:26 -05:00
local luks='' net='networkmanager'
2020-05-03 01:25:41 -05:00
2020-05-17 20:29:26 -05:00
[[ ! -d /etc/NetworkManager/system-connections ]] && net='netctl'
[[ $LUKS ]] && luks='cryptsetup'
2020-04-25 22:03:14 -05:00
2020-05-17 20:29:26 -05:00
if hash reflector > /dev/null 2>&1 && yesno 'Mirrorlist' "$_mirrors"; then
2020-05-17 13:05:57 -05:00
AUTO_MIR=true
else
AUTO_MIR=''
install_mirror_country
fi
2020-05-17 14:04:37 -05:00
if hash rsync > /dev/null 2>&1; then
2020-05-17 20:29:26 -05:00
yesno 'Background Install' "$_bginstall" 'Pacstrap' 'Copy ISO' || PACSTRAP=0
2020-05-17 14:04:37 -05:00
fi
2020-05-03 01:25:41 -05:00
(
2020-05-17 13:05:57 -05:00
install_mirrorlist > /tmp/bgout 2>&1
2020-05-04 11:56:06 -05:00
2020-05-03 14:47:39 -05:00
if [[ $PACSTRAP == 1 ]]; then
2020-05-04 11:56:06 -05:00
pacman -Sy >> /tmp/bgout 2>&1
2020-05-03 01:25:41 -05:00
pacstrap /mnt >> /tmp/bgout 2>&1
else
rsync -avh /run/archiso/sfs/airootfs/ "$MNT/" >> /tmp/bgout 2>&1
fi
cp /etc/pacman.conf "$MNT/etc/pacman.conf"
cp /etc/pacman.d/mirrorlist "$MNT/etc/pacman.d/mirrorlist"
al_repo "$MNT/etc/pacman.conf"
2020-05-03 14:47:39 -05:00
if [[ $PACSTRAP == 1 ]]; then
2020-05-03 01:25:41 -05:00
chrun "pacman -S ${ISO_PKGS[*]} $net $luks --noconfirm --needed" >> /tmp/bgout 2>&1
else
2020-05-17 20:29:26 -05:00
chrun 'pacman -Sy' >> /tmp/bgout 2>&1
2020-05-04 11:56:06 -05:00
chrun "pacman -S $net --noconfirm --needed" >> /tmp/bgout 2>&1
2020-05-03 01:25:41 -05:00
fi
if [[ $net == "networkmanager" ]]; then
2020-05-17 20:29:26 -05:00
chrun 'systemctl enable NetworkManager.service' >> /tmp/bgout 2>&1
2020-05-03 01:25:41 -05:00
else
2020-05-17 20:29:26 -05:00
chrun 'systemctl enable netctl.service' >> /tmp/bgout 2>&1
2020-05-03 01:25:41 -05:00
fi
if [[ -e /tmp/wmlist ]]; then
chrun "pacman -S ${BASE_PKGS[*]} --noconfirm --needed" >> /tmp/bgout 2>&1
fi
) &
BG_PID=$!
2020-03-25 10:30:25 -05:00
# shellcheck disable=SC2064
2019-10-19 17:18:42 -05:00
trap "kill $BG_PID 2> /dev/null" EXIT
2019-02-23 21:09:47 -06:00
}
2020-05-17 13:05:57 -05:00
install_mirror_country()
{
local conf='' tmp=''
until [[ $conf ]]; do
local url=''
dlg CODES check "Mirror Country" "\nSelect which countries to use for mirrors from the list below." \
AU Australia "$(ofn AU "$CODES")" AT Austria "$(ofn AT "$CODES")" \
BA "Bosnia Herzegovina" "$(ofn BA "$CODES")" BY Belarus "$(ofn BY "$CODES")" \
BE Belgium "$(ofn BE "$CODES")" BR Brazil "$(ofn BR "$CODES")" \
BG Bulgaria "$(ofn BG "$CODES")" CA Canada "$(ofn CA "$CODES")" \
CL Chile "$(ofn CL "$CODES")" CN China "$(ofn CN "$CODES")" \
CO Colombia "$(ofn CO "$CODES")" CZ "Czech Republic" "$(ofn CZ "$CODES")" \
DK Denmark "$(ofn DK "$CODES")" EE Estonia "$(ofn EE "$CODES")" \
FI Finland "$(ofn FI "$CODES")" FR France "$(ofn FR "$CODES")" \
DE Germany "$(ofn DE "$CODES")" GB "United Kingdom" "$(ofn GB "$CODES")" \
GR Greece "$(ofn GR "$CODES")" HU Hungary "$(ofn HU "$CODES")" \
IN India "$(ofn IN "$CODES")" IE Ireland "$(ofn IE "$CODES")" \
IL Israel "$(ofn IL "$CODES")" IT Italy "$(ofn IT "$CODES")" \
JP Japan "$(ofn JP "$CODES")" KZ Kazakhstan "$(ofn KZ "$CODES")" \
KR Korea "$(ofn KR "$CODES")" LT Lithuania "$(ofn LT "$CODES")" \
LV Latvia "$(ofn LV "$CODES")" LU Luxembourg "$(ofn LU "$CODES")" \
MK Macedonia "$(ofn MK "$CODES")" NL Netherlands "$(ofn NL "$CODES")" \
NC "New Caledonia" "$(ofn NC "$CODES")" NZ "New Zealand" "$(ofn NZ "$CODES")" \
NO Norway "$(ofn NO "$CODES")" PL Poland "$(ofn PL "$CODES")" \
PT Portugal "$(ofn PT "$CODES")" RO Romania "$(ofn RO "$CODES")" \
RU Russia "$(ofn RU "$CODES")" RS Serbia "$(ofn RS "$CODES")" \
SG Singapore "$(ofn SG "$CODES")" SK Slovakia "$(ofn SK "$CODES")" \
ZA "South Africa" "$(ofn ZA "$CODES")" ES Spain "$(ofn ES "$CODES")" \
LK "Sri Lanka" "$(ofn LK "$CODES")" SE Sweden "$(ofn SE "$CODES")" \
CH Switzerland "$(ofn CH "$CODES")" TW Taiwan "$(ofn TW "$CODES")" \
TR Turkey "$(ofn TR "$CODES")" UA Ukraine "$(ofn UA "$CODES")" \
US "United States" "$(ofn US "$CODES")" UZ Uzbekistan "$(ofn UZ "$CODES")" \
VN Vietnam "$(ofn VN "$CODES")" || return 1
# build the url to use
for i in $CODES; do
if [[ $url ]]; then
url+="&country=$i"
else
url="https://www.archlinux.org/mirrorlist/?country=$i"
fi
done
url+="&use_mirror_status=on"
msg "Mirror Country" "\nDownloading the latest mirrorlist for the chosen countries.\n\n$url\n" 0
tmp="$(mktemp --suffix=-mirrorlist)"
curl -fsSL $url -o $tmp 2> "$ERR"
errshow 0 "curl -fsSL $url -o $tmp" || return 1
sed -i 's/^#Server/Server/g' "$tmp"
# let the user edit and confirm it
$EDITOR "$tmp"
if yesno "Mirror Country" "\nUse the newly created mirrorlist for installation?\n"; then
conf=true
else
rm -f "$tmp"
fi
done
cp -f "$tmp" /etc/pacman.d/mirrorlist
chmod +r /etc/pacman.d/mirrorlist
}
2019-10-01 01:09:06 -05:00
###############################################################################
# display manager config
# these are called based on which DM is chosen after it is installed
2019-11-23 19:36:08 -06:00
# additional config can be handled here, for now only lightdm and xinit.
2019-10-01 01:09:06 -05:00
2019-12-22 19:41:42 -06:00
config_gdm()
2019-10-01 01:09:06 -05:00
{
2019-10-19 17:18:42 -05:00
: #TODO
2019-10-01 01:09:06 -05:00
}
2019-12-22 19:41:42 -06:00
config_sddm()
2019-10-01 01:09:06 -05:00
{
2019-10-19 17:18:42 -05:00
: #TODO
2019-10-01 01:09:06 -05:00
}
2019-12-22 19:41:42 -06:00
config_xinit()
2019-11-23 19:36:08 -06:00
{
if [[ $INSTALL_WMS ]]; then
sed -i "/exec/ c exec ${LOGIN_WM}" "$MNT/home/$NEWUSER/.xinitrc"
if [[ $LOGIN_WM == 'gnome-session' ]]; then
# see https://wiki.archlinux.org/index.php/GNOME#Manually
sed -i '/exec/ i export XDG_SESSION_TYPE=x11' "$MNT/home/$NEWUSER/.xinitrc"
sed -i '/exec/ i export GDK_BACKEND=x11' "$MNT/home/$NEWUSER/.xinitrc"
fi
else
rm -rf "$MNT/home/$NEWUSER/.xinitrc" "$MNT/root/.xinitrc"
return 0
fi
if [[ $AUTOLOGIN ]]; then
mkdir -p "$AUTOLOGIN_SERV"
cat > "$AUTOLOGIN_SERV/autologin.conf" <<- EOF
[Service]
ExecStart=
ExecStart=-/sbin/agetty --autologin $NEWUSER --noclear %I 38400 linux
EOF
else
rm -rf "$AUTOLOGIN_SERV"
fi
2019-12-21 18:29:17 -06:00
# run `startx` after logging in regardless of autologin
cat > "$MNT/home/$NEWUSER/$LOGINRC" <<- EOF
# automatically run startx when logging in on tty1
[ -z "\$DISPLAY" ] && [ \$XDG_VTNR -eq 1 ] && startx
EOF
2019-11-23 19:36:08 -06:00
}
2019-12-22 19:41:42 -06:00
config_lightdm()
2019-10-20 21:49:12 -05:00
{
2019-11-23 19:36:08 -06:00
sed -i "/greeter-session=/ c greeter-session=lightdm-$LIGHTDM_GREETER" "$MNT/etc/lightdm/lightdm.conf"
if [[ $LIGHTDM_GREETER == 'gtk-greeter' ]]; then
cat > "$MNT/etc/lightdm/lightdm-gtk-greeter.conf" <<- EOF
[greeter]
default-user-image=/usr/share/icons/ArchLabs-Dark/64x64/places/distributor-logo-archlabs.png
background=/usr/share/backgrounds/archlabs/archlabs.jpg
theme-name=Adwaita-dark
icon-theme-name=Adwaita
font-name=DejaVu Sans Mono 11
position=30%,end 50%,end
EOF
fi
2019-10-20 21:49:12 -05:00
}
2019-02-23 21:09:47 -06:00
###############################################################################
# bootloader setup
2019-08-20 17:52:25 -05:00
# prerun_* set up the configs needed before actually running the commands
# setup_* are run after selecting a bootloader and build the command used later
# they can also be used for further user input as these run before control is taken away
2019-02-23 21:09:47 -06:00
setup_grub()
{
EDIT_FILES[bootloader]="/etc/default/grub"
if [[ $SYS == 'BIOS' ]]; then
2019-11-23 19:36:08 -06:00
[[ $BOOT_D ]] || { part_device 1 || return 1; }
2019-12-22 23:52:07 -06:00
BCMDS[grub]="grub-install --verbose --recheck --force --target=i386-pc $BOOT_D"
2019-02-23 21:09:47 -06:00
else
2019-10-19 17:18:42 -05:00
BCMDS[grub]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1
2019-12-22 23:52:07 -06:00
grub-install --verbose --recheck --force --target=x86_64-efi --efi-directory=/boot --bootloader-id='$DIST'"
2019-10-19 17:18:42 -05:00
grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1
2019-02-23 21:09:47 -06:00
fi
2019-12-22 23:52:07 -06:00
BCMDS[grub]="mkdir -p /run/udev /run/lvm && mount --bind /hostrun/udev /run/udev && mount --bind /hostrun/lvm /run/lvm &&
${BCMDS[grub]} && grub-mkconfig -o /boot/grub/grub.cfg && sleep 1 && umount /run/udev /run/lvm"
2019-02-23 21:09:47 -06:00
return 0
}
prerun_grub()
{
2019-10-18 21:47:46 -05:00
sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g; s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" "$MNT/etc/default/grub"
2019-02-23 21:09:47 -06:00
if [[ $LUKS_DEV ]]; then
2019-12-22 23:52:07 -06:00
sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g; s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" "$MNT/etc/default/grub"
2019-02-23 21:09:47 -06:00
fi
if [[ $SYS == 'BIOS' && $LVM && -z $SEP_BOOT ]]; then
2019-12-22 23:52:07 -06:00
sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" "$MNT/etc/default/grub"
2019-02-23 21:09:47 -06:00
fi
# setup for os-prober module
2019-10-18 21:47:46 -05:00
mkdir -p /run/{lvm,udev} "$MNT/hostrun/"{lvm,udev}
mount --bind /run/lvm "$MNT/hostrun/lvm"
mount --bind /run/udev "$MNT/hostrun/udev"
2019-02-23 21:09:47 -06:00
return 0
}
setup_efistub()
{
EDIT_FILES[bootloader]=""
}
prerun_efistub()
{
2019-10-28 23:34:23 -05:00
BCMDS[efistub]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1
2019-11-23 19:36:08 -06:00
efibootmgr -v -d $BOOT_D -p $BOOT_NUM -c -L '${DIST} Linux' -l /vmlinuz-${KERNEL} \
2020-05-14 02:16:20 -05:00
-u 'root=$ROOT_ID rw $(
[[ $BTRFS_MNT ]] && printf '%s ' "$BTRFS_MNT"
[[ $UCODE ]] && printf 'initrd=\%s.img ' "$UCODE"
)initrd=\initramfs-${KERNEL}.img'"
2019-02-23 21:09:47 -06:00
}
setup_syslinux()
{
if [[ $SYS == 'BIOS' ]]; then
EDIT_FILES[bootloader]="/boot/syslinux/syslinux.cfg"
else
EDIT_FILES[bootloader]="/boot/EFI/syslinux/syslinux.cfg"
2019-10-19 17:18:42 -05:00
BCMDS[syslinux]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1
2019-11-23 19:36:08 -06:00
efibootmgr -v -c -d $BOOT_D -p $BOOT_NUM -l /EFI/syslinux/syslinux.efi -L $DIST"
2019-02-23 21:09:47 -06:00
fi
}
prerun_syslinux()
{
2020-03-01 14:14:10 -06:00
local c="$MNT/boot/syslinux" s="/usr/lib/syslinux/bios"
local d=".." # for non-UEFI systems we need to use ../path
2019-12-22 23:52:07 -06:00
2019-10-18 21:47:46 -05:00
if [[ $SYS == 'UEFI' ]]; then
2019-12-22 23:52:07 -06:00
c="$MNT/boot/EFI/syslinux" s="/usr/lib/syslinux/efi64" d='';
2019-10-18 21:47:46 -05:00
fi
2019-12-22 23:52:07 -06:00
mkdir -pv "$c"
cp -rfv "$s/"* "$c/"
cp -fv "$RUN/syslinux/splash.png" "$c/"
2019-08-20 17:52:25 -05:00
cat > "$c/syslinux.cfg" <<- EOF
2019-10-18 21:47:46 -05:00
UI vesamenu.c32
2019-08-20 17:52:25 -05:00
MENU TITLE $DIST Boot Menu
2019-10-18 21:47:46 -05:00
MENU BACKGROUND splash.png
2019-08-20 17:52:25 -05:00
TIMEOUT 50
DEFAULT $DIST
2019-10-18 21:47:46 -05:00
# see: https://www.syslinux.org/wiki/index.php/Comboot/menu.c32
MENU WIDTH 78
MENU MARGIN 4
MENU ROWS 4
MENU VSHIFT 10
MENU TIMEOUTROW 13
MENU TABMSGROW 14
MENU CMDLINEROW 14
MENU HELPMSGROW 16
MENU HELPMSGENDROW 29
MENU COLOR border 30;44 #40ffffff #a0000000 std
MENU COLOR title 1;36;44 #9033ccff #a0000000 std
MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all
MENU COLOR unsel 37;44 #50ffffff #a0000000 std
MENU COLOR help 37;40 #c0ffffff #a0000000 std
MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std
MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std
MENU COLOR msg07 37;40 #90ffffff #a0000000 std
MENU COLOR tabmsg 31;40 #30ffffff #00000000 std
2019-08-20 17:52:25 -05:00
LABEL $DIST
MENU LABEL $DIST Linux
LINUX $d/vmlinuz-$KERNEL
2020-05-14 02:16:20 -05:00
APPEND root=$ROOT_ID ${LUKS_DEV}${RESUME}rw$([[ $BTRFS_MNT ]] && printf ' %s' "$BTRFS_MNT")
2019-08-20 17:52:25 -05:00
INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL.img
LABEL ${DIST}fallback
MENU LABEL $DIST Linux Fallback
LINUX $d/vmlinuz-$KERNEL
2020-05-14 02:16:20 -05:00
APPEND root=$ROOT_ID ${LUKS_DEV}${RESUME}rw$([[ $BTRFS_MNT ]] && printf ' %s' "$BTRFS_MNT")
2019-08-20 17:52:25 -05:00
INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL-fallback.img
EOF
2019-02-23 21:09:47 -06:00
return 0
}
setup_refind-efi()
{
EDIT_FILES[bootloader]="/boot/refind_linux.conf"
2019-10-19 17:18:42 -05:00
BCMDS[refind-efi]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1; refind-install"
2019-02-23 21:09:47 -06:00
}
prerun_refind-efi()
{
2019-10-18 21:47:46 -05:00
cat > "$MNT/boot/refind_linux.conf" <<- EOF
2020-05-14 02:16:20 -05:00
"$DIST Linux" "root=$ROOT_ID ${LUKS_DEV}${RESUME}rw$([[ $BTRFS_MNT ]] && printf ' %s' "$BTRFS_MNT") add_efi_memmap $([[ $UCODE ]] &&
2019-12-26 20:21:13 -06:00
printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-%v.img"
2020-05-14 02:16:20 -05:00
"$DIST Linux Fallback" "root=$ROOT_ID ${LUKS_DEV}${RESUME}rw$([[ $BTRFS_MNT ]] && printf ' %s' "$BTRFS_MNT") add_efi_memmap $([[ $UCODE ]] &&
2019-12-26 20:21:13 -06:00
printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-%v-fallback.img"
2019-08-20 17:52:25 -05:00
EOF
2019-12-22 23:52:07 -06:00
2019-10-18 21:47:46 -05:00
mkdir -p "$MNT/etc/pacman.d/hooks"
2019-12-22 23:52:07 -06:00
2019-10-18 21:47:46 -05:00
cat > "$MNT/etc/pacman.d/hooks/refind.hook" <<- EOF
2019-08-20 17:52:25 -05:00
[Trigger]
Operation = Upgrade
Type = Package
Target = refind-efi
2019-02-23 21:09:47 -06:00
2019-08-20 17:52:25 -05:00
[Action]
Description = Updating rEFInd on ESP
When = PostTransaction
Exec = /usr/bin/refind-install
EOF
2019-02-23 21:09:47 -06:00
}
setup_systemd-boot()
{
EDIT_FILES[bootloader]="/boot/loader/entries/$DIST.conf"
2019-12-22 23:52:07 -06:00
BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars > /dev/null 2>&1; systemd-machine-id-setup && bootctl --path=/boot install"
2019-02-23 21:09:47 -06:00
}
prerun_systemd-boot()
{
2019-12-22 23:52:07 -06:00
mkdir -pv "$MNT/boot/loader/entries"
2019-10-18 21:47:46 -05:00
cat > "$MNT/boot/loader/loader.conf" <<- EOF
2020-05-03 14:47:39 -05:00
default $DIST.conf
2019-08-20 17:52:25 -05:00
timeout 5
editor no
EOF
2019-12-22 23:52:07 -06:00
2019-10-18 21:47:46 -05:00
cat > "$MNT/boot/loader/entries/$DIST.conf" <<- EOF
2019-08-20 17:52:25 -05:00
title $DIST Linux
linux /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd %s" "/$UCODE.img")
initrd /initramfs-$KERNEL.img
2020-05-14 02:16:20 -05:00
options root=$ROOT_ID ${LUKS_DEV}${RESUME}rw$([[ $BTRFS_MNT ]] && printf ' %s' "$BTRFS_MNT")
2019-08-20 17:52:25 -05:00
EOF
2019-12-22 23:52:07 -06:00
2019-10-18 21:47:46 -05:00
cat > "$MNT/boot/loader/entries/$DIST-fallback.conf" <<- EOF
2019-08-20 17:52:25 -05:00
title $DIST Linux Fallback
linux /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd %s" "/$UCODE.img")
initrd /initramfs-$KERNEL-fallback.img
2020-05-14 02:16:20 -05:00
options root=$ROOT_ID ${LUKS_DEV}${RESUME}rw$([[ $BTRFS_MNT ]] && printf ' %s' "$BTRFS_MNT")
2019-08-20 17:52:25 -05:00
EOF
2019-12-22 23:52:07 -06:00
mkdir -pv "$MNT/etc/pacman.d/hooks"
2019-10-18 21:47:46 -05:00
cat > "$MNT/etc/pacman.d/hooks/systemd-boot.hook" <<- EOF
2019-08-20 17:52:25 -05:00
[Trigger]
Type = Package
Operation = Upgrade
Target = systemd
[Action]
Description = Updating systemd-boot
When = PostTransaction
Exec = /usr/bin/bootctl update
EOF
2019-02-23 21:09:47 -06:00
return 0
}
2020-05-14 02:16:20 -05:00
###############################################################################
# btrfs functions
btrfs_name()
{
local txt="$1"
2020-05-17 16:16:17 -05:00
local exists="$2"
2020-05-14 02:16:20 -05:00
SUBVOL=''
until [[ $SUBVOL ]]; do
2020-05-17 11:36:29 -05:00
dlg SUBVOL input "Subvolume Name" "$txt" || return 1
2020-05-14 02:16:20 -05:00
if [[ -z $SUBVOL ]]; then
return 1
2020-05-17 16:16:17 -05:00
elif [[ $SUBVOL =~ \ |\' || $exists == *"$SUBVOL"* ]]; then
2020-05-16 18:05:01 -05:00
msg "Subvolume Name Error" "$_btrfserrname"
2020-05-14 02:16:20 -05:00
SUBVOL=''
fi
done
return 0
}
2020-05-17 17:51:20 -05:00
btrfs_mount()
{
local part="$1"
local mntp="$2"
local subvol="$3"
[[ $mntp == "$MNT" ]] && BTRFS_MNT="rootflags=subvol=$subvol"
select_mntopts "$part" 'btrfs' && [[ $MNT_OPTS ]] && MNT_OPTS+=','
mount -o ${MNT_OPTS}subvol="$subvol" "$part" "$mntp" 2> "$ERR"
errshow 0 "mount -o ${MNT_OPTS}subvol=$subvol $part $mntp" || return 1
msg "Mount Complete" "\nMounted $part subvol=$subvol at $mntp\n" 1
}
2020-05-17 14:04:37 -05:00
btrfs_subvols()
{
local part="$1"
local mntp="${MNT}$2"
local mvol=''
2020-05-17 16:52:41 -05:00
btrfs_name "\nEnter a name for the initial subvolume on $part e.g. 'subvol_root'." || return 1
2020-05-17 14:04:37 -05:00
mvol="$SUBVOL"
btrfs subvolume create "$mntp/$mvol" > /dev/null 2> "$ERR"
errshow 0 "btrfs subvolume create $mntp/$mvol" || return 1
2020-05-17 16:16:17 -05:00
2020-05-17 14:04:37 -05:00
umount_dir "$mntp" || return 1
2020-05-17 17:51:20 -05:00
btrfs_mount "$part" "$mntp" "$mvol" || return 1
2020-05-17 16:16:17 -05:00
2020-05-17 14:04:37 -05:00
btrfs_extsubvols "$mntp" "$mvol" || return 1
2020-05-17 17:25:37 -05:00
msg "Btrfs Setup" "\nSubvolume(s) created successfully.\n\nSubvolume root '$mvol' mounted at $mntp\n$([[ $SUBVOL_COUNT -gt 0 ]] && ls -R "$mntp")"
2020-05-17 14:04:37 -05:00
}
2020-05-17 11:36:29 -05:00
btrfs_extsubvols()
2020-05-14 02:16:20 -05:00
{
2020-05-17 11:36:29 -05:00
local mntp="$1"
local mvol="$2"
local list=''
local n=0
2020-05-14 02:16:20 -05:00
2020-05-17 11:36:29 -05:00
SUBVOL_COUNT=0
dlg SUBVOL_COUNT menu "Subvolume Count" "\nSelect the number of subvolumes to create in: $mvol" \
0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -
while (( ++n <= SUBVOL_COUNT )); do
local txt="\nEnter a name for subvolume $n within '$mvol'."
if (( n > 1 )); then
btrfs_name "$txt\n\nCreated subvolumes: $list" "$list $mvol" || return 1
else
btrfs_name "$txt" "$mvol" || return 1
fi
btrfs subvolume create "$mntp/$SUBVOL" > /dev/null 2> "$ERR"
errshow 0 "btrfs subvolume create $mntp/$SUBVOL" || return 1
2020-05-14 02:16:20 -05:00
list+="$SUBVOL "
done
2020-05-17 11:36:29 -05:00
return 0
}
2020-05-14 02:16:20 -05:00
2019-02-23 21:09:47 -06:00
###############################################################################
# lvm functions
lvm_menu()
{
2019-11-23 19:36:08 -06:00
is_bg_install || return 1
2019-02-23 21:09:47 -06:00
lvm_detect
local choice
2019-08-27 02:24:03 -05:00
while :; do
dlg choice menu "Logical Volume Management" "$_lvmmenu" \
2020-05-17 20:29:26 -05:00
'create' "Create a new volume group and volumes" \
'remove' "Delete an existing volume group" \
'remove_all' "Delete ALL volume groups and volumes" \
"back" "Return to the device management menu"
2019-08-27 02:24:03 -05:00
case "$choice" in
2020-05-17 20:29:26 -05:00
'create') lvm_create && break ;;
'remove') lvm_delgroup && yesno "Remove Volume Group" "$_lvmdelask" && vgremove -f "$DEL_VG" > /dev/null 2>&1 ;;
'remove_all') lvm_del_all ;;
2019-08-27 02:24:03 -05:00
*) break ;;
esac
done
2019-02-23 21:09:47 -06:00
return 0
}
lvm_detect()
{
2019-10-27 19:25:06 -05:00
if [[ $(vgs -o vg_name --noheading 2> /dev/null) ]]; then
if [[ $(lvs -o vg_name,lv_name --noheading --separator - 2> /dev/null) && $(pvs -o pv_name --noheading 2> /dev/null) ]]; then
msg "LVM Setup" "\nActivating existing logical volume management.\n" 0
modprobe dm-mod > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 'modprobe dm-mod > /dev/null'
2019-10-27 19:25:06 -05:00
vgscan > /dev/null 2>&1
vgchange -ay > /dev/null 2>&1
fi
2019-02-23 21:09:47 -06:00
fi
}
lvm_create()
{
2020-05-17 11:36:29 -05:00
VGROUP='' LVM_PARTS='' VOL_COUNT=0 VGROUP_MB=0
2019-10-18 21:47:46 -05:00
umount_dir "$MNT"
2019-02-23 21:09:47 -06:00
lvm_mkgroup || return 1
2020-05-17 11:36:29 -05:00
2019-02-23 21:09:47 -06:00
local txt="\nThe last (or only) logical volume will automatically use all remaining space in the volume group."
2020-05-17 20:29:26 -05:00
dlg VOL_COUNT menu "Create Volume Group" "\nSelect the number of logical volumes (LVs) to create in: $VGROUP\n$txt" \
2020-05-17 11:36:29 -05:00
1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 -
2019-02-23 21:09:47 -06:00
[[ $VOL_COUNT ]] || return 1
lvm_extra_lvs || return 1
2020-05-17 16:16:17 -05:00
2019-02-23 21:09:47 -06:00
lvm_volume_name "$_lvmlvname\nNOTE: This LV will use up all remaining space in the volume group (${VGROUP_MB}MB)" || return 1
2020-05-17 20:29:26 -05:00
msg "Create Volume Group (LV:$VOL_COUNT)" "\nCreating volume $VNAME from remaining space in $VGROUP\n" 0
2019-10-27 16:56:08 -05:00
lvcreate -l +100%FREE "$VGROUP" -n "$VNAME" > /dev/null 2> "$ERR"
2020-05-17 11:36:29 -05:00
errshow 0 "lvcreate -l +100%FREE $VGROUP -n $VNAME" || return 1
2020-05-17 16:16:17 -05:00
2020-05-17 11:36:29 -05:00
LVM='logical volume'
sleep 0.5
2019-02-23 21:09:47 -06:00
txt="\nDone, volume: $VGROUP-$VNAME (${VOLUME_SIZE:-${VGROUP_MB}MB}) has been created.\n"
2020-05-17 20:29:26 -05:00
msg "Create Volume Group (LV:$VOL_COUNT)" "$txt\n$(lsblk -o NAME,SIZE $LVM_PARTS)\n"
2019-02-23 21:09:47 -06:00
return 0
}
2019-08-27 03:00:08 -05:00
lvm_lv_size()
2019-02-23 21:09:47 -06:00
{
local txt="${VGROUP}: ${SIZE}$SIZE_UNIT (${VGROUP_MB}MB remaining).$_lvmlvsize"
2019-03-11 03:52:49 -05:00
2019-08-18 15:37:49 -05:00
while :; do
2019-02-23 21:09:47 -06:00
ERR_SIZE=0
2020-05-17 20:29:26 -05:00
dlg VOLUME_SIZE input "Create Volume Group (LV:$VOL_COUNT)" "$txt"
2019-02-23 21:09:47 -06:00
if [[ -z $VOLUME_SIZE ]]; then
ERR_SIZE=1
break # allow bailing with escape or an empty choice
elif (( ${VOLUME_SIZE:0:1} == 0 )); then
ERR_SIZE=1 # size values can't begin with '0'
else
# walk the string and make sure all but the last char are digits
local lv=$((${#VOLUME_SIZE} - 1))
for (( i=0; i<lv; i++ )); do
[[ ${VOLUME_SIZE:$i:1} =~ [0-9] ]] || { ERR_SIZE=1; break; }
done
if (( ERR_SIZE != 1 )); then
case ${VOLUME_SIZE:$lv:1} in
2019-11-23 19:36:08 -06:00
[mMgG])
local s=${VOLUME_SIZE:0:$lv} m=$((s * 1000))
2019-02-23 21:09:47 -06:00
case ${VOLUME_SIZE:$lv:1} in
2019-11-23 19:36:08 -06:00
[Gg])
if (( m >= VGROUP_MB )); then
ERR_SIZE=1
else
VGROUP_MB=$((VGROUP_MB - m))
fi
;;
[Mm])
if (( ${VOLUME_SIZE:0:$lv} >= VGROUP_MB )); then
ERR_SIZE=1
else
VGROUP_MB=$((VGROUP_MB - s))
fi
;;
2019-02-23 21:09:47 -06:00
*) ERR_SIZE=1
2019-11-23 19:36:08 -06:00
esac
;;
2019-02-23 21:09:47 -06:00
*) ERR_SIZE=1
esac
fi
fi
2019-12-22 19:41:42 -06:00
(( ERR_SIZE )) || break
2020-04-25 13:29:49 -05:00
msg "Invalid Logical Volume Size" "$_lvmerrlvsize" 2
2019-02-23 21:09:47 -06:00
done
return $ERR_SIZE
}
lvm_mkgroup()
{
local named=''
until [[ $named ]]; do
lvm_partitions || return 1
lvm_group_name || return 1
2020-05-17 20:29:26 -05:00
yesno "Create Volume Group" "\nCreate volume group: $VGROUP\n\nusing these partition(s): $LVM_PARTS\n" && named=true
2019-02-23 21:09:47 -06:00
done
2020-05-17 20:29:26 -05:00
msg "Create Volume Group" "\nCreating volume group: $VGROUP\n" 0
2019-10-27 16:56:08 -05:00
vgcreate -f "$VGROUP" $LVM_PARTS > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "vgcreate -f '$VGROUP' $LVM_PARTS >/dev/null" || return 1
2019-02-23 21:09:47 -06:00
SIZE=$(vgdisplay "$VGROUP" | awk '/VG Size/ { gsub(/[^0-9.]/, ""); print int($0) }')
SIZE_UNIT="$(vgdisplay "$VGROUP" | awk '/VG Size/ { print substr($NF, 0, 1) }')"
if [[ $SIZE_UNIT == 'G' ]]; then
VGROUP_MB=$((SIZE * 1000))
else
VGROUP_MB=$SIZE
fi
2020-05-17 20:29:26 -05:00
msg "Create Volume Group" "\nVolume group $VGROUP (${SIZE}$SIZE_UNIT) successfully created\n" 2
2019-02-23 21:09:47 -06:00
}
lvm_del_all()
{
2019-03-11 03:52:49 -05:00
local v pv
2019-10-19 17:18:42 -05:00
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)"
2019-02-23 21:09:47 -06:00
if [[ $VGROUP || $v || $pv ]]; then
2020-05-17 20:29:26 -05:00
if yesno "Remove All Volume Groups" "$_lvmdelask"; then
2019-10-19 17:18:42 -05:00
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
2019-02-23 21:09:47 -06:00
LVM=''
fi
2020-05-14 02:16:20 -05:00
for i in $(lvmdiskscan | grep 'LVM physical volume' | grep 'sd[a-z]' | sed 's/\/dev\///' | awk '{print $1}'); do
dd if=/dev/zero bs=512 count=512 of=/dev/${i} >/dev/null 2>&1
done
2019-02-23 21:09:47 -06:00
else
2020-04-25 13:29:49 -05:00
msg "Delete LVM" "\nNo available LVM to remove...\n" 2
2019-02-23 21:09:47 -06:00
LVM=''
fi
}
lvm_delgroup()
{
DEL_VG=''
VOL_GROUP_LIST=''
2020-05-17 20:29:26 -05:00
for i in $(lvs --noheadings | awk '{print $2}' | sort | uniq); do
2019-02-23 21:09:47 -06:00
VOL_GROUP_LIST+="$i $(vgdisplay "$i" | awk '/VG Size/ {print $3$4}') "
done
2019-08-27 02:24:03 -05:00
2019-03-11 03:52:49 -05:00
[[ $VOL_GROUP_LIST ]] || { msg "No Groups" "\nNo volume groups found."; return 1; }
2019-02-23 21:09:47 -06:00
dlg DEL_VG menu "Logical Volume Management" "\nSelect volume group to delete.\n\nAll logical volumes within will also be deleted." $VOL_GROUP_LIST
[[ $DEL_VG ]]
}
lvm_extra_lvs()
{
while (( VOL_COUNT > 1 )); do
2019-12-22 19:41:42 -06:00
lvm_volume_name "$_lvmlvname" || return 1
lvm_lv_size || return 1
2020-05-17 16:16:17 -05:00
2020-05-17 20:29:26 -05:00
msg "Create Volume Group (LV:$VOL_COUNT)" "\nCreating a $VOLUME_SIZE volume $VNAME in $VGROUP\n" 0
2019-10-27 16:56:08 -05:00
lvcreate -L "$VOLUME_SIZE" "$VGROUP" -n "$VNAME" > /dev/null 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "lvcreate -L '$VOLUME_SIZE' '$VGROUP' -n '$VNAME'" || return 1
2020-05-17 16:16:17 -05:00
2020-05-17 20:29:26 -05:00
msg "Create Volume Group (LV:$VOL_COUNT)" "\nDone, logical volume (LV) $VNAME ($VOLUME_SIZE) has been created.\n"
2019-02-23 21:09:47 -06:00
(( VOL_COUNT-- ))
done
return 0
}
lvm_partitions()
{
part_find 'part|crypt' || return 1
PARTS="$(awk 'NF > 0 {print $0 " off"}' <<< "$PARTS")"
2020-05-12 21:50:35 -05:00
[[ $LUKS && $LUKS_PART ]] && part_countdec $LUKS_PART
2020-05-17 20:29:26 -05:00
dlg LVM_PARTS check "Create Volume Group" "\nSelect the partition(s) to use for the physical volume (PV)." $PARTS
2019-02-23 21:09:47 -06:00
}
lvm_group_name()
{
VGROUP=''
until [[ $VGROUP ]]; do
2020-05-17 20:29:26 -05:00
dlg VGROUP input "Create Volume Group" "$_lvmvgname"
2019-02-23 21:09:47 -06:00
if [[ -z $VGROUP ]]; then
return 1
2019-08-27 02:00:12 -05:00
elif [[ ${VGROUP:0:1} == "/" || $VGROUP =~ \ |\' ]] || vgdisplay | grep -q "$VGROUP"; then
2019-03-11 03:52:49 -05:00
msg "LVM Name Error" "$_lvmerrvgname"
2019-02-23 21:09:47 -06:00
VGROUP=''
fi
done
return 0
}
lvm_volume_name()
{
VNAME=''
2020-05-17 11:36:29 -05:00
local txt="$1"
2019-02-23 21:09:47 -06:00
until [[ $VNAME ]]; do
2020-05-17 20:29:26 -05:00
dlg VNAME input "Create Volume Group (LV:$VOL_COUNT)" "\n$txt"
2019-02-23 21:09:47 -06:00
if [[ -z $VNAME ]]; then
return 1
2019-03-11 03:52:49 -05:00
elif [[ ${VNAME:0:1} == "/" || $VNAME =~ \ |\' ]] || lsblk | grep -q "$VNAME"; then
msg "LVM Name Error" "$_lvmerlvname"
2019-02-23 21:09:47 -06:00
VNAME=''
fi
done
return 0
}
###############################################################################
# luks functions
luks_menu()
{
local choice
2019-11-23 19:36:08 -06:00
is_bg_install || return 1
2020-05-17 20:29:26 -05:00
while :; do
dlg choice menu 'LUKS Encryption' "$_luksmenu" \
'basic' 'LUKS setup with default settings' \
'open' 'Open an existing LUKS partition' \
'advanced' 'Specify cypher type and other flags for cryptsetup' \
'back' 'Return to the device management menu'
case "$choice" in
'basic') luks_basic || return 1 ;;
'open') luks_open || return 1 ;;
'advanced') luks_advanced || return 1 ;;
*) break ;;
esac
done
2019-02-23 21:09:47 -06:00
return 0
}
luks_open()
{
2019-10-19 17:18:42 -05:00
modprobe -a dm-mod dm_crypt > /dev/null 2>&1
2019-10-18 21:47:46 -05:00
umount_dir "$MNT"
2019-02-23 21:09:47 -06:00
part_find 'part|crypt|lvm' || return 1
2020-04-25 13:29:49 -05:00
if (( PART_COUNT == 1 )); then
2019-02-23 21:09:47 -06:00
LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
else
2020-05-12 21:50:35 -05:00
[[ $LVM && $LVM_PARTS ]] && part_countdec $LVM_PARTS
2020-05-17 20:29:26 -05:00
dlg LUKS_PART menu "LUKS Open" "\nSelect which partition to open." $PARTS
2019-02-23 21:09:47 -06:00
fi
[[ $LUKS_PART ]] || return 1
2020-05-17 20:29:26 -05:00
luks_pass "LUKS Open" || return 1
msg "LUKS Open" "\nOpening encryption: $LUKS_NAME\n\nUsing device/volume: $(part_pretty "$LUKS_PART")\n" 0
2019-10-27 16:56:08 -05:00
cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "cryptsetup open --type luks '$LUKS_PART' '$LUKS_NAME' <<< '$LUKS_PASS'" || return 1
2020-04-25 13:29:49 -05:00
LUKS='encrypted'
luks_show
2019-02-23 21:09:47 -06:00
return 0
}
luks_pass()
{
LUKS_PASS=''
2019-10-06 05:26:53 -05:00
local t="$1"
typeset -a ans=(cryptroot) # default name to start
2019-02-23 21:09:47 -06:00
until [[ $LUKS_PASS ]]; do
tput cnorm
2020-03-03 00:14:19 -06:00
dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" \
--separator $'\n' --title " $t " --mixedform "$_luksomenu" 0 0 0 \
2019-10-06 05:26:53 -05:00
"Name:" 1 1 "${ans[0]}" 1 7 "$COLUMNS" 0 0 \
"Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \
2019-10-19 17:18:42 -05:00
"Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 2> "$ANS" || return 1
2019-10-06 05:26:53 -05:00
mapfile -t ans <"$ANS"
2019-02-23 21:09:47 -06:00
2019-10-06 05:26:53 -05:00
if [[ -z "${ans[0]}" ]]; then
2019-02-23 21:09:47 -06:00
msg "Name Empty" "\nEncrypted device name cannot be empty.\n\nPlease try again.\n" 2
2019-10-06 05:26:53 -05:00
elif [[ -z "${ans[1]}" || "${ans[1]}" != "${ans[2]}" ]]; then
LUKS_NAME="${ans[0]}"
2019-02-23 21:09:47 -06:00
msg "Password Mismatch" "\nThe passwords entered do not match.\n\nPlease try again.\n" 2
else
2019-10-06 05:26:53 -05:00
LUKS_NAME="${ans[0]}"
LUKS_PASS="${ans[1]}"
2019-02-23 21:09:47 -06:00
fi
done
return 0
}
luks_show()
{
sleep 0.5
2020-05-17 20:29:26 -05:00
msg "LUKS Encryption" "\nEncrypted partition ready for mounting.\n\n$(lsblk -o NAME,SIZE,FSTYPE "$LUKS_PART")\n\n"
2019-02-23 21:09:47 -06:00
}
luks_setup()
{
2019-10-19 17:18:42 -05:00
modprobe -a dm-mod dm_crypt > /dev/null 2>&1
2019-10-18 21:47:46 -05:00
umount_dir "$MNT"
2019-02-23 21:09:47 -06:00
part_find 'part|lvm' || return 1
2019-11-23 19:36:08 -06:00
if [[ $AUTO_ROOT ]]; then
LUKS_PART="$AUTO_ROOT"
2020-04-25 13:29:49 -05:00
elif (( PART_COUNT == 1 )); then
2019-02-23 21:09:47 -06:00
LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
else
2020-05-12 21:50:35 -05:00
[[ $LVM && $LVM_PARTS ]] && part_countdec $LVM_PARTS
2020-05-17 20:29:26 -05:00
dlg LUKS_PART menu "LUKS Encryption" "\nSelect the partition you want to encrypt." $PARTS
2019-02-23 21:09:47 -06:00
fi
[[ $LUKS_PART ]] || return 1
2020-05-17 20:29:26 -05:00
luks_pass "LUKS Encryption"
2019-02-23 21:09:47 -06:00
}
luks_basic()
{
luks_setup || return 1
2020-05-17 20:29:26 -05:00
msg "LUKS Encryption" "\nCreating encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0
2019-10-27 16:56:08 -05:00
cryptsetup -q luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "cryptsetup -q luksFormat '$LUKS_PART' <<< '$LUKS_PASS'" || return 1
2019-10-27 16:56:08 -05:00
cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> "$ERR"
2019-12-20 12:05:03 -06:00
errshow 0 "cryptsetup open '$LUKS_PART' '$LUKS_NAME' <<< '$LUKS_PASS'" || return 1
2020-03-03 00:14:19 -06:00
LUKS='encrypted'
luks_show
2019-02-23 21:09:47 -06:00
return 0
}
luks_advanced()
{
2020-03-03 00:14:19 -06:00
luks_setup || return 1
local cipher
dlg cipher input "LUKS Encryption" "$_lukskey" "-s 512 -c aes-xts-plain64"
[[ $cipher ]] || return 1
2020-05-17 20:29:26 -05:00
msg "LUKS Encryption" "\nCreating encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0
2020-03-03 00:14:19 -06:00
cryptsetup -q $cipher luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2> "$ERR"
errshow 0 "cryptsetup -q $cipher luksFormat '$LUKS_PART' <<< '$LUKS_PASS'" || return 1
cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2> "$ERR"
errshow 0 "cryptsetup open '$LUKS_PART' '$LUKS_NAME' <<< '$LUKS_PASS'" || return 1
LUKS='encrypted'
luks_show
return 0
2019-02-23 21:09:47 -06:00
}
###############################################################################
2019-08-20 17:52:25 -05:00
# simple functions
# some help avoid repetition and improve usability of some commands
# others are initial setup functions used before reaching the main loop
2019-02-23 21:09:47 -06:00
ofn()
{
[[ "$2" == *"$1"* ]] && printf "on" || printf "off"
}
die()
{
2020-05-16 18:05:01 -05:00
# exit cleanly with exit code $1 or the last command's exit code
# when $1 == 127 we unmount and reboot
local e="${1:-$?}"
2019-08-17 19:39:19 -05:00
2019-02-23 21:09:47 -06:00
trap - INT
tput cnorm
2020-04-25 22:25:21 -05:00
(( e == 0 )) && clear
2019-09-15 18:59:17 -05:00
if [[ -d $MNT ]]; then
2019-10-18 21:47:46 -05:00
umount_dir "$MNT"
2019-10-20 21:49:12 -05:00
(( e == 127 )) && umount_dir /run/archiso/bootmnt && sleep 0.5 && reboot -f
2019-02-23 21:09:47 -06:00
fi
2019-09-15 18:59:17 -05:00
exit $e
2019-02-23 21:09:47 -06:00
}
dlg()
{
2019-08-20 22:03:12 -05:00
local var="$1" # assign output from dialog to var
2019-08-25 03:28:30 -05:00
local dlg_t="$2" # dialog type (menu, check, input)
2019-08-20 22:03:12 -05:00
local title="$3" # dialog title
local body="$4" # dialog message
2019-08-27 02:52:10 -05:00
local n=0 # number of items to display for menu and check dialogs
2019-08-20 22:03:12 -05:00
shift 4 # shift off args assigned above
2019-09-02 18:36:57 -05:00
# adjust n when passed a large list
2019-08-27 02:52:10 -05:00
local l=$((LINES - 20))
(( ($# / 2) > l )) && n=$l
2019-10-10 22:00:22 -05:00
2019-08-20 22:03:12 -05:00
case "$dlg_t" in
2020-04-26 10:36:33 -05:00
menu)
2020-05-17 11:36:29 -05:00
tput civis
2020-04-26 10:36:33 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--menu "$body" 0 0 $n "$@" 2> "$ANS" || return 1
;;
check)
2020-05-17 11:36:29 -05:00
tput civis
2020-04-26 10:36:33 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--checklist "$body" 0 0 $n "$@" 2> "$ANS" || return 1
;;
2019-02-23 21:09:47 -06:00
input)
tput cnorm
2020-05-17 11:36:29 -05:00
if [[ $1 && $1 != 'limit' ]]; then
local def="$1" # assign default value for input
shift
fi
2019-02-23 21:09:47 -06:00
if [[ $1 == 'limit' ]]; then
2020-04-26 10:36:33 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 \
--title " $title " --inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1
2019-02-23 21:09:47 -06:00
else
2020-04-26 10:36:33 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--inputbox "$body" 0 0 "$def" 2> "$ANS" || return 1
2019-02-23 21:09:47 -06:00
fi
;;
esac
2019-08-20 22:03:12 -05:00
# if answer file isn't empty read from it into $var
2019-03-11 03:52:49 -05:00
[[ -s "$ANS" ]] && printf -v "$var" "%s" "$(< "$ANS")"
2019-02-23 21:09:47 -06:00
}
msg()
{
2019-08-20 22:03:12 -05:00
# displays a message dialog
# when more than 2 args the message will disappear after sleep time ($3)
local title="$1"
local body="$2"
shift 2
2019-02-23 21:09:47 -06:00
tput civis
2019-08-20 22:03:12 -05:00
if (( $# )); then
dialog --backtitle "$DIST Installer - $SYS - v$VER" --sleep "$1" --title " $title " --infobox "$body\n" 0 0
2019-02-23 21:09:47 -06:00
else
2019-03-11 03:52:49 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --msgbox "$body\n" 0 0
2019-02-23 21:09:47 -06:00
fi
}
2019-08-27 03:50:42 -05:00
live()
{
2019-10-19 01:07:40 -05:00
local ses="$1"
2019-09-16 19:43:28 -05:00
2019-10-19 01:07:40 -05:00
if ! select_keymap; then
2019-09-15 18:59:17 -05:00
clear
2019-09-16 19:43:28 -05:00
die 0
2019-09-15 18:59:17 -05:00
elif ! net_connect; then
2019-10-19 17:18:42 -05:00
msg "Not Connected" "\nRunning live requires an active internet connection to install packages.\n\nExiting..\n" 2
2019-09-16 19:43:28 -05:00
die 1
2020-03-01 14:14:10 -06:00
elif (( $(awk '/MemTotal/ {print int($2 * 1024 / 1000 / 1000)}' /proc/meminfo) < 4704)); then
msg "Not Enough Memory" "\nLive session requires at least 4.5G of system memory for installing packages.\n\nExiting..\n" 2
2019-10-19 01:07:40 -05:00
die 1
2019-09-15 18:59:17 -05:00
fi
2019-10-19 17:18:42 -05:00
clear
echo "Sorting mirrorlist"
2020-03-01 14:14:10 -06:00
if ! mount /run/archiso/cowspace -o remount,size=4G; then
msg "Remount Fail" "\nUnable to remount root with a larger copy-on-write space, this is needed for installing packages.\n\nExiting..\n" 2
die 1
fi
2020-05-17 13:05:57 -05:00
install_mirrorlist
2019-11-23 19:36:08 -06:00
al_repo "/etc/pacman.conf"
2019-10-19 17:18:42 -05:00
pacman -Syyu --noconfirm || die 1
2020-05-17 16:16:17 -05:00
rm -rf /var/cache/pacman/pkg/* # */
2020-04-25 22:03:14 -05:00
pacman -S ${BASE_PKGS[*]} xorg-xinit --needed --noconfirm || die 1
2020-05-17 16:16:17 -05:00
rm -rf /var/cache/pacman/pkg/* # */
2019-10-19 17:18:42 -05:00
case "$ses" in
2020-05-03 17:52:40 -05:00
$WM_PKG_SES)
pacman -S "$ses" ${WM_PKGS[*]} ${WM_EXT[$ses]} --needed --noconfirm || die 1
;;
$SELF_CONTAINED)
pacman -S "$ses" ${WM_EXT[$ses]} --needed --noconfirm || die 1
;;
dwm)
pacman -S git --needed --noconfirm || die 1
install_suckless "/root" nochroot
;;
2019-10-19 17:18:42 -05:00
esac
pacman -Scc --noconfirm
2020-05-17 16:16:17 -05:00
rm -rf /var/cache/pacman/pkg/* # */
2019-10-19 17:18:42 -05:00
cp -rfT /etc/skel /root
2019-11-23 19:36:08 -06:00
install_tearfree "/etc/X11/xorg.conf.d"
2019-10-19 17:18:42 -05:00
case "$ses" in
2020-05-03 17:52:40 -05:00
$SELF_CONTAINED)
sed -i '/super/d; /nitrogen/d; /picom/d' /root/.xprofile
;;
dwm)
sed -i '/super/d; /picom/d' /root/.xprofile
;;
2019-10-19 17:18:42 -05:00
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
2019-09-15 18:59:17 -05:00
}
usage()
{
2019-10-19 17:18:42 -05:00
cat <<- EOF
2020-05-16 18:05:01 -05:00
usage: $1 [-hDn] [-r ROOT] [-b BOOT] [-l SESSION] [-d DISTRO] [-m MOUNTPOINT]
2019-09-15 18:59:17 -05:00
options:
2020-05-17 11:36:29 -05:00
-h print this message and exit
-l install and setup a live session
-D enable xtrace and log output to $DBG
-m set the mountpoint used for the new installation
-d set the distribution name for the installed system
-n no partitioning, mounting, or formatting (self mount)
-r root partition to use for install, required when using -n
-b boot partition to use for install, required on UEFI systems when using -n
-t install and setup drivers for nvidia or tearfree xorg configs for other vendors
if you experience boot issues with this option, remove /etc/X11/xorg.conf.d/20-*.conf
2019-09-15 18:59:17 -05:00
sessions:
2020-05-17 11:36:29 -05:00
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
lxqt - A port of the lightweight desktop environment (LXDE) to Qt
bspwm - A tiling wm that represents windows as the leaves of a binary tree
fluxbox - A lightweight and highly-configurable window manager
jwm - A lightweight window manager for Xorg written in C
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
2019-09-15 18:59:17 -05:00
EOF
2019-09-16 19:43:28 -05:00
exit 0
2019-08-27 03:50:42 -05:00
}
2019-02-23 21:09:47 -06:00
yesno()
{
2020-04-26 10:36:33 -05:00
local title="$1"
local body="$2"
local yes='Yes'
local no='No'
2019-08-17 19:39:19 -05:00
(( $# >= 3 )) && yes="$3"
(( $# >= 4 )) && no="$4"
2019-02-23 21:09:47 -06:00
tput civis
if (( $# == 5 )); then
2020-04-26 10:36:33 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --defaultno \
--title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
2019-02-23 21:09:47 -06:00
else
2020-04-26 10:36:33 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " \
--yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
2019-02-23 21:09:47 -06:00
fi
}
chrun()
{
arch-chroot "$MNT" bash -c "$1"
}
debug()
{
export PS4='| ${BASH_SOURCE} LINE:${LINENO} FUNC:${FUNCNAME[0]:+ ${FUNCNAME[0]}()} |> '
set -x
exec 3>| $DBG
BASH_XTRACEFD=3
DEBUG=true
}
2019-12-20 12:05:03 -06:00
errmsg()
{
local err=""
err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")"
2020-05-16 18:05:01 -05:00
[[ -z $err ]] && err="no error message was output"
2019-12-20 12:05:03 -06:00
printf "%s" "$err"
}
2019-11-23 19:36:08 -06:00
al_repo()
{
local conf="$1"
2019-12-22 23:52:07 -06:00
grep -q 'archlabs_repo' "$conf" && return 0
2019-11-23 19:36:08 -06:00
2019-12-22 23:52:07 -06:00
cat >> "$conf" <<- EOF
2019-11-23 19:36:08 -06:00
2019-12-22 23:52:07 -06:00
[archlabs_unstable]
Server = https://bitbucket.org/archlabslinux/\$repo/raw/master/\$arch
2019-11-23 19:36:08 -06:00
2019-12-22 23:52:07 -06:00
[archlabs_repo]
Server = https://bitbucket.org/archlabslinux/\$repo/raw/master/\$arch
Server = https://sourceforge.net/projects/archlabs-repo/files/\$repo/\$arch
Server = https://github.com/ARCHLabs/\$repo/raw/master/\$arch
EOF
2019-11-23 19:36:08 -06:00
}
2019-08-17 19:39:19 -05:00
termcol()
{
local colors=(
"\e]P0191919" # #191919
"\e]P1D15355" # #D15355
"\e]P2609960" # #609960
"\e]P3FFCC66" # #FFCC66
"\e]P4255A9B" # #255A9B
"\e]P5AF86C8" # #AF86C8
"\e]P62EC8D3" # #2EC8D3
"\e]P7949494" # #949494
"\e]P8191919" # #191919
"\e]P9D15355" # #D15355
"\e]PA609960" # #609960
"\e]PBFF9157" # #FF9157
"\e]PC4E88CF" # #4E88CF
"\e]PDAF86C8" # #AF86C8
"\e]PE2ec8d3" # #2ec8d3
"\e]PFE1E1E1" # #E1E1E1
)
[[ $TERM == 'linux' ]] && printf "%b" "${colors[@]}" && clear
}
2019-02-23 21:09:47 -06:00
errshow()
{
2020-03-25 10:30:25 -05:00
# shellcheck disable=SC2181
2019-08-17 19:39:19 -05:00
[ $? -eq 0 ] && return 0
2019-02-23 21:09:47 -06:00
2019-11-02 12:50:52 -05:00
local fatal=$1
2020-05-14 23:40:59 -05:00
shift 1 # always shift off the fatal level arg
2020-05-17 17:25:37 -05:00
if [[ $1 == *chrun* ]]; then
local cmd="arch-chroot $MNT bash -c ${1##chrun }"
else
local cmd="$1"
fi
2020-03-25 10:30:25 -05:00
local txt
2020-05-17 17:25:37 -05:00
txt="\nCommand: $cmd\n\n$(errmsg)\n\n"
2019-12-26 20:21:13 -06:00
tput cnorm
2019-08-17 19:39:19 -05:00
if (( fatal )); then
2020-05-14 23:40:59 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Install Error " --yes-label "Abort" --no-label "Continue" \
--yesno "${txt}Errors at this stage must be fixed before the install can continue.\n$_errchoice\n" 0 0 || return 0
2019-02-23 21:09:47 -06:00
[[ -r $DBG && $TERM == 'linux' ]] && less "$DBG"
die 1
fi
2020-05-15 02:50:53 -05:00
dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Install Error " --yes-label "Abort" --no-label "Continue" \
--yesno "${txt}Errors at this stage may not be serious depending on the command and error type.\n$_errchoice\n" 0 0 || return 0
2020-05-14 23:40:59 -05:00
tput civis
return 1
2019-02-23 21:09:47 -06:00
}
prechecks()
{
2019-08-17 19:39:19 -05:00
local i=1
2020-05-16 18:05:01 -05:00
if (( $1 >= 0 )) && ! grep -q " $MNT " /proc/mounts; then
2019-02-23 21:09:47 -06:00
msg "Not Mounted" "\nPartition(s) must be mounted first.\n" 2
2020-05-17 16:16:17 -05:00
if [[ $NOMOUNT ]]; then
die 1
else
SEL=1
fi
i=0
2019-02-23 21:09:47 -06:00
elif [[ $1 -ge 1 && -z $BOOTLDR ]]; then
msg "No Bootloader" "\nBootloader must be selected first.\n" 2
2020-05-17 16:16:17 -05:00
if [[ $NOMOUNT ]]; then
SEL=0
else
SEL=2
fi
i=0
2019-02-23 21:09:47 -06:00
elif [[ $1 -ge 2 && (-z $NEWUSER || -z $USER_PASS) ]]; then
msg "No User" "\nA user must be created first.\n" 2
2020-05-17 16:16:17 -05:00
if [[ $NOMOUNT ]]; then
SEL=1
else
SEL=3
fi
i=0
2019-02-23 21:09:47 -06:00
elif [[ $1 -ge 3 && -z $CONFIG_DONE ]]; then
2020-05-16 18:05:01 -05:00
msg "No Config" "\nSystem configuration must be done first.\n" 2
2020-05-17 16:16:17 -05:00
if [[ $NOMOUNT ]]; then
SEL=2
else
SEL=4
fi
i=0
2019-02-23 21:09:47 -06:00
fi
2019-08-17 19:39:19 -05:00
(( i )) # return code
2019-02-23 21:09:47 -06:00
}
umount_dir()
{
2019-08-17 19:39:19 -05:00
mount | grep -q 'swap' && swapoff -a
for dir; do
2020-05-16 18:05:01 -05:00
if [[ -d $dir ]] && grep -q " $dir " /proc/mounts; then
2019-10-19 17:18:42 -05:00
if ! umount "$dir" 2> /dev/null; then
2019-09-15 18:59:17 -05:00
sleep 0.5
2019-10-19 17:18:42 -05:00
umount -f "$dir" 2> /dev/null || umount -l "$dir"
2019-09-15 18:59:17 -05:00
fi
fi
2019-08-17 19:39:19 -05:00
done
2019-02-23 21:09:47 -06:00
}
chk_connect()
{
2020-05-15 18:19:27 -05:00
if [[ ! -f /tmp/new ]]; then
msg "Network Connect" "\nVerifying network connection\n" 0
if [[ $VM != 'none' ]] && hash nm-online > /dev/null 2>&1; then
nm-online > /dev/null 2>&1
else
ping -qc1 'archlinux.org' > /dev/null 2>&1
fi
2020-03-07 14:27:42 -06:00
fi
2019-02-23 21:09:47 -06:00
}
net_connect()
{
if chk_connect; then
return 0
2019-10-19 17:18:42 -05:00
elif hash nmtui > /dev/null 2>&1; then
2019-08-30 20:59:30 -05:00
tput civis
if [[ $TERM == 'linux' ]]; then
2020-01-10 14:08:42 -06:00
printf "%b" "\e]P1191919" "\e]P4191919" # fix up the nasty default colours of nmtui
2019-08-30 20:59:30 -05:00
nmtui-connect
2020-01-10 14:08:42 -06:00
printf "%b" "\e]P1D15355" "\e]P4255a9b" # restore defaults
2019-02-23 21:09:47 -06:00
else
2019-08-30 20:59:30 -05:00
nmtui-connect
2019-02-23 21:09:47 -06:00
fi
2019-10-19 17:18:42 -05:00
elif hash wifi-menu > /dev/null 2>&1; then
2019-08-30 20:59:30 -05:00
wifi-menu
else
return 1
2019-02-23 21:09:47 -06:00
fi
2019-12-21 07:29:03 -06:00
chk_connect
2019-02-23 21:09:47 -06:00
}
2019-11-23 19:36:08 -06:00
dwm_xsession()
{
mkdir -p "$MNT/usr/share/xsessions"
cat > "$MNT/usr/share/xsessions/dwm.desktop" <<- EOF
[Desktop Entry]
Encoding=UTF-8
Name=Dwm
Comment=Dynamic Window Manager
Exec=dwm
2020-04-10 18:03:28 -05:00
TryExec=dwm
Type=Application
2019-11-23 19:36:08 -06:00
EOF
}
is_bg_install()
2019-08-17 19:39:19 -05:00
{
2019-09-24 01:39:10 -05:00
[[ $BG_PID ]] || return 0
2019-08-17 19:39:19 -05:00
msg "Install Running" "\nA background install process is currently running.\n" 2
return 1
}
2019-02-23 21:09:47 -06:00
system_devices()
{
IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
2020-04-25 13:29:49 -05:00
DEVS="$(lsblk -lno TYPE,PATH,SIZE,MODEL | awk '/disk/ && !'"/${IGNORE_DEV:-NONEXX}/"' {print $2, $3 "__" $4}')"
DEV_COUNT=$(wc -l <<< "$DEVS")
2019-02-23 21:09:47 -06:00
2020-04-25 13:29:49 -05:00
if [[ -z $DEVS ]]; then
2019-03-11 03:52:49 -05:00
msg "Device Error" "\nNo available devices...\n\nExiting..\n" 2
2019-02-23 21:09:47 -06:00
die 1
fi
}
system_identify()
{
2020-05-03 01:25:41 -05:00
if [[ $VM != 'none' ]]; then
2019-02-23 21:09:47 -06:00
UCODE=''
2020-05-03 01:25:41 -05:00
elif grep -q 'AuthenticAMD' /proc/cpuinfo; then
UCODE="amd-ucode"
2019-02-23 21:09:47 -06:00
elif grep -q 'GenuineIntel' /proc/cpuinfo; then
UCODE="intel-ucode"
fi
2019-10-19 17:18:42 -05:00
modprobe -q efivarfs > /dev/null 2>&1
2019-02-23 21:09:47 -06:00
if [[ -d /sys/firmware/efi/efivars ]]; then
2020-05-16 18:05:01 -05:00
SYS="UEFI"
2019-02-23 21:09:47 -06:00
grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars
else
2020-05-16 18:05:01 -05:00
SYS="BIOS"
2019-02-23 21:09:47 -06:00
fi
}
###############################################################################
# entry point
2019-08-17 19:39:19 -05:00
termcol
2020-05-17 16:46:01 -05:00
MISSING=""
2020-05-17 14:04:37 -05:00
for i in dialog find parted curl arch-chroot; do
2020-05-17 16:46:01 -05:00
hash $i >/dev/null 2>&1 || MISSING+="$i "
2020-05-17 14:04:37 -05:00
done
2020-05-17 16:46:01 -05:00
if [[ $MISSING ]]; then
printf "This installer requires the following package(s) to be installed:\n\n\t%s" "$MISSING"
2019-11-23 19:36:08 -06:00
die 1
elif (( UID != 0 )); then
2020-05-17 14:34:28 -05:00
msg "Not Root" "\nThis installer must be run as root.\n\nExiting..\n" 2
2019-02-23 21:09:47 -06:00
die 1
2020-05-17 14:34:28 -05:00
elif ! grep -qm 1 ' lm ' /proc/cpuinfo; then
msg "Not x86_64" "\nThis installer only supports x86_64 architectures.\n\nExiting..\n" 2
2019-02-23 21:09:47 -06:00
die 1
fi
2019-09-15 18:59:17 -05:00
trap 'printf "\n^C\n" && die 1' INT
2019-04-17 20:24:09 -05:00
2020-05-15 18:19:27 -05:00
while getopts ":htl:Dnr:b:m:d:" OPT; do
2019-10-19 17:18:42 -05:00
case "$OPT" in
2020-05-16 18:05:01 -05:00
D) debug ;;
h) usage "$0" ;;
n) NOMOUNT=true ;;
t) TEARFREE=true ;;
m) MNT="$OPTARG" ;;
d) DIST="$OPTARG" ;;
2020-05-15 18:19:27 -05:00
r)
2020-05-16 18:05:01 -05:00
[[ -b $OPTARG ]] || { msg "Invalid Root" "\nThe installer expects a full path to a block device for root.\n\nExiting..\n" 2; die 1; }
2020-05-15 18:19:27 -05:00
ROOT="$OPTARG"
;;
b)
2020-05-16 18:05:01 -05:00
[[ -b $OPTARG ]] || { msg "Invalid Boot" "\nThe installer expects a full path to a block device for boot.\n\nExiting..\n" 2; die 1; }
2020-05-15 18:19:27 -05:00
BOOT="$OPTARG"
;;
2019-10-19 17:18:42 -05:00
l)
2020-05-16 18:05:01 -05:00
[[ "${!WM_SESSIONS[*]}" =~ $OPTARG ]] || { echo "error: invalid session for -l, see -h for help"; die 1; }
live "$OPTARG"
2019-10-19 17:18:42 -05:00
;;
2020-05-12 21:50:35 -05:00
\?)
echo "invalid option: $OPTARG"
2020-05-17 16:46:01 -05:00
die 2
2020-05-12 21:50:35 -05:00
;;
2019-10-19 17:18:42 -05:00
esac
done
2020-05-15 18:19:27 -05:00
if [[ ! -d $MNT ]]; then
msg "Invalid Mountpoint" "\nThe installer expects an existing directory for mounting.\n\nExiting..\n" 2
2020-05-17 16:46:01 -05:00
die 2
2020-05-15 18:19:27 -05:00
elif [[ -z $DIST ]]; then
msg "Invalid Distribution" "\nThe distribution name cannot be empty.\n\nExiting..\n" 2
2020-05-17 16:46:01 -05:00
die 2
2020-05-15 18:19:27 -05:00
fi
2019-02-23 21:09:47 -06:00
system_identify
system_devices
2020-05-12 21:50:35 -05:00
if [[ $NOMOUNT ]]; then
2020-05-15 18:19:27 -05:00
if [[ -z $ROOT || ($SYS == 'UEFI' && -z $BOOT) ]]; then
msg "Invalid Partitions" "$_errpart" 0
2020-05-17 16:46:01 -05:00
die 2
2020-05-12 21:50:35 -05:00
fi
if [[ $BOOT ]]; then
part_bootdev
2020-05-14 02:16:20 -05:00
[[ $BOOT != "$ROOT" ]] && SEP_BOOT=true
2020-05-12 21:50:35 -05:00
fi
fi
2019-12-21 07:29:03 -06:00
2020-05-16 18:05:01 -05:00
if [[ $TERM == 'linux' ]]; then
if [[ -f /tmp/font ]]; then
FONT="$(< /tmp/font)"
2020-05-12 21:50:35 -05:00
setfont "$FONT"
2020-05-16 18:05:01 -05:00
else
fontsize=16
while [[ $TERM == 'linux' && ! -f /tmp/font ]]; do
dlg fontsize menu "Font Size" "\nSelect a font size from the list below.\n\nDefault: 16" \
12 "setfont ter-i12n" 14 "setfont ter-i14n" 16 "setfont ter-i16n" 18 "setfont ter-i18n" \
20 "setfont ter-i20n" 22 "setfont ter-i22n" 24 "setfont ter-i24n" 28 "setfont ter-i28n" \
32 "setfont ter-i32n" || break
FONT="ter-i${fontsize}n"
setfont "$FONT"
yesno "Font Size" "\nKeep the currently set font size?\n" && echo "ter-i${fontsize}n" > /tmp/font
done
fi
2020-05-12 21:50:35 -05:00
fi
2019-12-21 07:29:03 -06:00
2020-05-16 18:05:01 -05:00
if [[ ! -f /tmp/weld ]]; then
2020-05-17 14:34:28 -05:00
msg "Welcome to the $DIST Installer" "\nThis will help you get $DIST installed and setup on your system.\n\nIf you are unsure about an option, the default or most common\nwill be mentioned or the first selected entry will be the default.\n\n\nMenu Navigation:\n\n - Select items with the arrow keys or the option number.\n - Use [Space] to toggle check boxes and [Enter] to accept.\n - Switch between fields using [Tab] or the arrow keys.\n - Use [Page Up] and [Page Down] to jump whole pages\n - Press the highlighted key of an option to select it.\n"
2020-05-16 18:05:01 -05:00
touch /tmp/weld
2020-05-14 23:06:50 -05:00
fi
2019-08-27 03:50:42 -05:00
2019-09-15 18:59:17 -05:00
if ! select_keymap; then
2019-11-23 19:36:08 -06:00
clear
die 0
2019-09-15 18:59:17 -05:00
elif ! net_connect; then
msg "Not Connected" "\nThis installer requires an active internet connection.\n\nExiting..\n" 2
die 1
fi
2019-09-30 19:41:09 -05:00
2020-05-15 18:19:27 -05:00
if [[ ! -f /tmp/new ]]; then
2020-05-16 18:05:01 -05:00
msg "Installer Update" "\nChecking for newer installer versions.\n" 1
2020-05-17 16:16:17 -05:00
if curl -fsSL 'https://bitbucket.org/archlabslinux/installer/raw/master/installer' -o /tmp/new; then
2020-05-17 11:36:29 -05:00
if (( $(vercmp "$(awk -F= '/^VER=/ {print $2}' /tmp/new)" "$VER") > 0 )); then
2020-05-17 16:16:17 -05:00
cp /tmp/new /usr/bin/installer
chmod +x /usr/bin/installer
exec /usr/bin/installer "$@"
2020-05-15 18:19:27 -05:00
fi
else
msg "Download Failed" "\nUnable to download the latest version, continuing with the current.\n" 2
fi
fi
2020-05-16 18:05:01 -05:00
# warn before starting the background process
2020-05-12 21:50:35 -05:00
if [[ $NOMOUNT ]]; then
wrn="\nA background install process will begin early when using -n flag\n\nSome files may be overwritten during the process\n"
yesno "Data Warning" "$wrn\nProceed?\n" || die 0
install_background
fi
2019-09-16 19:43:28 -05:00
while :; do
main
done
2019-02-23 21:09:47 -06:00
# vim:fdm=marker:fmr={,}