3 # This program is free software, provided under the GNU GPL
4 # Written by Nathaniel Maia for use in Archlabs
5 # Some ideas and code reworked from other resources
6 # AIF, Cnichi, Calamares, Arch Wiki.. Credit where credit is due
8 VER="2.0.47" # installer version
9 DIST="ArchLabs" # linux distributor
10 MNT="/mnt" # install mountpoint
11 ANS="/tmp/ans" # dialog answer file
14 # ------------------------------------------------------ #
15 # When manually mounting your partitions, you need
16 # to set these values to avoid using the mount menu.
17 # ------------------------------------------------------ #
19 # root partition, eg. /dev/sda2
22 # boot partition, required on UEFI eg. /dev/sda1
25 # boot device, used for some bootloaders eg. /dev/sda
28 # bootloader to use, can be:
29 # UEFI: grub, syslinux, efistub, systemd-boot, refind-efi
30 # BIOS: grub, syslinux
33 # directory to mount the boot partition (if any) for most bootloaders
34 # this will need to be 'boot' however a popular one for grub is 'boot/efi'
37 # ------------------------------------------------------ #
39 # bulk default values {
41 # these values will be selected during the install, it is not recommended
42 # to edit them here unless you know what you're doing.
44 UCODE='' # cpu microcode (if any), can be: amd-ucode, intel-ucode
45 KERNEL='' # linux kernel, can be: linux, linux-lts, linux-zen, or linux-hardened
46 MYSHELL='' # full path for the shell, eg. /usr/bin/zsh
48 SWAP_PART='' # swap partition or file path
49 SWAP_SIZE='' # swap size, only used when creating a swapfile
51 EXMNT='' # holder for additional partitions while mounting
52 EXMNTS='' # when an extra partition is mounted append it's info
54 FONT="ter-i16n" # font used for the linux console
55 HOOKS="shutdown" # list of additional HOOKS to add in /etc/mkinitcpio.conf
57 LOGIN_TYPE='' # login manager can be: lightdm, xinit
58 LOGIN_WM='' # default login session to be placed in ~/.xinitrc
59 LOGINRC='' # login shell rc file, eg. .zprofile, .bash_profile, .profile
61 INSTALL_WMS='' # space separated list of chosen wm/de
63 WM_PKGS='' # full list of packages added during wm/de choice (not user edited)
64 PACKAGES='' # list of all packages to install including WM_PKGS (not user edited)
65 USER_PKGS='' # packages selected by the user during install
67 NEWUSER='' # username for the new user
68 USER_PASS='' # new user's password
69 ROOT_PASS='' # root password
71 LUKS='' # empty when not using encryption
72 LUKS_DEV='' # boot parameter string for LUKS
73 LUKS_PART='' # partition used for encryption
74 LUKS_PASS='' # encryption password
75 LUKS_UUID='' # encrypted partition UUID
76 LUKS_NAME='' # name used for encryption
78 LVM='' # empty when not using lvm
79 LVM_PARTS='' # partitions used for volume group
80 VGROUP_MB=0 # available space in volume group
82 WARN='' # issued mounting/partitioning warning
83 SEP_BOOT='' # separate boot partition for BIOS
84 AUTOLOGIN='' # enable autologin for xinit
85 CONFIG_DONE='' # basic configuration is finished
86 BROADCOM_WL='' # fixes for broadcom cards eg. BCM4352
88 FORMATTED='' # partitions we formatted and should allow skipping
89 AUTO_ROOT_PART='' # root value from auto partition
90 AUTO_BOOT_PART='' # boot value from auto partition
92 # iso base, pacstrap when running the installer from a stock arch iso
93 ISO_BASE="b43-firmware b43-fwcutter broadcom-wl clonezilla dhclient dhcpcd ethtool wpa_supplicant "
94 ISO_BASE+="exfat-utils f2fs-tools gptfdisk vim hdparm ipw2100-fw ipw2200-fw nfs-utils nilfs-utils ntfs-3g "
95 ISO_BASE+="pacman-contrib parted rsync sdparm smartmontools wget wireless_tools wpa_actiond xl2tpd dialog parted "
96 ISO_BASE+="alsa-firmware alsa-lib alsa-plugins pulseaudio pulseaudio-alsa networkmanager w3m htop wireless-regdb "
97 ISO_BASE+="lm_sensors lsb-release p7zip pamixer reflector unrar ranger terminus-font ttf-dejavu archlabs-keyring"
99 # archlabs base packages
100 AL_BASE_PKGS="archlabs-skel-base archlabs-fonts archlabs-themes archlabs-dARK archlabs-icons archlabs-wallpapers archlabs-scripts"
102 # baseline (usually installed in the background)
103 BASE_PKGS="base-devel xorg xorg-drivers xorg-xinit sudo git gvfs gtk3 gtk-engines gtk-engine-murrine pavucontrol tumbler "
104 BASE_PKGS+="playerctl ffmpeg gstreamer libmad libmatroska gst-libav gst-plugins-base gst-plugins-good scrot"
106 # extras for window managers
107 WM_BASE_PKGS="arandr archlabs-networkmanager-dmenu xdg-user-dirs nitrogen polkit-gnome volumeicon xclip exo "
108 WM_BASE_PKGS+="xdotool compton wmctrl gnome-keyring dunst feh gsimplecal xfce4-power-manager xfce4-settings laptop-detect"
111 SEL=0 # currently selected menu item
112 ERR="/tmp/errlog" # error log used internally
113 DBG="/tmp/debuglog" # debug log when passed -d
114 RUN="/run/archiso/bootmnt/arch/boot" # path for live /boot
115 VM="$(dmesg | grep -i "hypervisor")" # is the system a vm
118 export DIALOGOPTS="--cr-wrap"
122 # giant ugly variable container :P {
124 # RAM in the system in MB
125 SYS_MEM="$(awk '/MemTotal/ {print int($2 / 1024) "M"}' /proc/meminfo)"
127 # locales from /etc/locale.gen
128 LOCALES="$(awk '/\.UTF-8/ {gsub(/# .*|#/, ""); if ($1) {print $1 " - "}}' /etc/locale.gen)"
130 # linux console keyboard mappings
131 CMAPS="$(find /usr/share/kbd/keymaps -name '*.map.gz' | awk '{gsub(/\.map\.gz|.*\//, ""); print $1 " - "}' | sort)"
133 # terminal size definitions
134 [[ $LINES ]] || LINES=$(tput lines)
135 [[ $COLUMNS ]] || COLUMNS=$(tput cols)
141 # commands used to install each bootloader (most get modified during runtime) {
143 [refind-efi]='refind-install'
144 [grub]='grub-install --recheck --force'
145 [syslinux]='syslinux-install_update -i -a -m'
146 [efistub]='efibootmgr -v -d /dev/sda -p 1 -c -l'
147 [systemd-boot]='bootctl --path=/boot install'
150 # executable name for each wm/de {
151 declare -A WM_SESSIONS=(
158 [gnome]='gnome-session'
159 [fluxbox]='startfluxbox'
160 [openbox]='openbox-session'
161 [cinnamon]='cinnamon-session'
164 # packages installed for each wm/de {
169 [plasma]='kdebase-meta'
170 [bspwm]='sxhkd archlabs-skel-bspwm rofi archlabs-polybar'
171 [fluxbox]='archlabs-skel-fluxbox archlabs-polybar jgmenu rofi lxmenu-data'
172 [i3-gaps]='i3status perl-anyevent-i3 archlabs-skel-i3-gaps rofi archlabs-polybar'
173 [openbox]='obconf archlabs-skel-openbox jgmenu archlabs-polybar tint2 conky rofi lxmenu-data'
174 [xfce4]='xfce4-goodies xfce4-pulseaudio-plugin network-manager-applet volumeicon rofi archlabs-skel-xfce4'
177 # files that can be edited after install is complete {
178 declare -A EDIT_FILES=(
181 [sudoers]='/etc/sudoers'
182 [crypttab]='/etc/crypttab'
183 [pacman]='/etc/pacman.conf'
184 [console]='/etc/vconsole.conf'
185 [mkinitcpio]='/etc/mkinitcpio.conf'
186 [hostname]='/etc/hostname /etc/hosts'
187 [bootloader]="/boot/loader/entries/$DIST.conf"
188 [locale]='/etc/locale.conf /etc/default/locale'
189 [keyboard]='/etc/X11/xorg.conf.d/00-keyboard.conf /etc/default/keyboard'
192 # mkfs command for formatting each offered filesystem {
197 [ntfs]='mkfs.ntfs -q'
198 [ext2]='mkfs.ext2 -q'
199 [ext3]='mkfs.ext3 -q'
200 [ext4]='mkfs.ext4 -q'
201 [vfat]='mkfs.vfat -F32'
202 [nilfs2]='mkfs.nilfs2 -q'
203 [reiserfs]='mkfs.reiserfs -q'
206 # mount options for each offered filesystem (if any {
212 [jfs]='discard errors=continue errors=panic nointegrity'
213 [reiserfs]='acl nolog notail replayonly user_xattr off'
214 [ext4]='discard dealloc nofail noacl relatime noatime nobarrier nodelalloc'
215 [xfs]='discard filestreams ikeep largeio noalign nobarrier norecovery noquota wsync'
216 [nilfs2]='discard nobarrier errors=continue errors=panic order=relaxed order=strict norecovery'
217 [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'
220 # PKG_EXT: if you add a package to $PACKAGES in any dialog {
221 # and it uses/requires some additional packages,
222 # you can add them here to keep it simple: [package]="extra"
223 # duplicates are removed with `uniq` before install
227 [mupdf]='mupdf-tools'
228 [qt5ct]='qt5-styleplugins'
229 [vlc]='qt5ct qt5-styleplugins'
230 [zathura]='zathura-pdf-poppler'
231 [noto-fonts]='noto-fonts-emoji'
232 [cairo-dock]='cairo-dock-plug-ins'
233 [qutebrowser]='qt5ct qt5-styleplugins'
234 [qbittorrent]='qt5ct qt5-styleplugins'
235 [transmission-qt]='qt5ct qt5-styleplugins'
236 [kdenlive]='kdebase-meta dvdauthor frei0r-plugins breeze breeze-gtk qt5ct qt5-styleplugins'
244 # Basics (somewhat in order)
245 _keymap="\nPick which keymap to use for the system from the list below\n\nThis is used once a graphical environment is running (Xorg).\n\nSystem default: us"
246 _vconsole="\nSelect the console keymap, the console is the tty shell you reach before starting a graphical environment (Xorg).\n\nIts keymap is seperate from the one used by the graphical environments, though many do use the same such as 'us' English.\n\nSystem default: us"
247 _device="\nSelect a device to use from the list below.\n\nDevices (/dev) are the available drives on the system. /sda, /sdb, /sdc ..."
248 _resize="\nSelect a new filesystem size in MB, a new partition will be created from the free space but will be left unformatted.\nThe lowest size is just enough to fit the currently in use space on the partition while the default is set to split the free space evenly.\n\nUse Tab or the arrow keys move the cursor between the buttons and the value, when the cursor is on the value, you can edit it by:\n\n - left/right cursor movement to select a digit to modify\n - +/- characters to increment/decrement the digit by one\n - 0 through 9 to set the digit to the given value\n\nSome keys are also recognized in all cursor positions:\n\n - Home/End set the value to its maximum or minimum\n - Pageup/Pagedown increment the value so that the slider moves by one column."
249 _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."
250 _warn="\nIMPORTANT:\n\nChoose 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 filesystem during the mounting stage.\nThis can only be used for partitions that already contain a filesystem and cannot be the root (/) partition, it needs to be formatted before install.\n"
251 _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 (and BIOS using LUKS without LVM) require a separate boot partition (100-512M)."
252 _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."
253 _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."
254 _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."
255 _format="is already formatted correctly.\n\nFor a clean install, previously existing partitions should be reformatted, however this removes ALL data (bootloaders) on the partition so choose carefully.\n\nDo you want to reformat the partition?\n"
256 _swapsize="\nEnter the size of the swapfile in megabytes (M) or gigabytes (G).\n\neg. 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."
257 _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."
258 _exmnt="\nWhere do you want the partition mounted?\n\nEnsure the name begins with a slash (/).\nExamples include: /usr, /home, /var, etc."
259 _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 the [Up] and [Down] arrows to switch between input fields, [Tab] to toggle between input fields and the buttons, and [Enter] to accept."
260 _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 beggining or end."
261 _locale="\nLocale determines the system language and currency formats.\n\nThe format for locale names is languagecode_COUNTRYCODE\n\neg. en_US is: english United States\n en_GB is: english Great Britain"
262 _timez="\nThe time zone is used to set the system clock.\n\nSelect your country or continent from the list below"
263 _timesubz="\nSelect the nearest city to you or one with the same time zone.\n\nTIP: Pressing the first letter of the city name repeatedly will navigate between entries beggining with that letter."
264 _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."
265 _login="\nSelect which of your session choices to use for the initial login.\n\nYou can be change this later by editing your ~/.xinitrc"
266 _packages="\nUse [Space] to move a package into the selected area and press [Enter] to accept the selection.\n\nPackages may be installed by your DE/WM (if any), or for the packages you select."
267 _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] or Ctrl-z again to resume the installer, if you want to avoid the automatic reboot using Ctrl-c will cleanly exit."
270 _luksnew="Basic LUKS Encryption"
271 _luksadv="Advanced LUKS Encryption"
272 _luksopen="Open Existing LUKS Partition"
273 _luksmenu="\nA seperate 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."
274 _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."
275 _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)."
278 _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."
279 _lvmnew="Create Volume Group and Volume(s)"
280 _lvmdel="Delete an Existing Volume Group"
281 _lvmdelall="Delete ALL Volume Group(s) and Volume(s)"
282 _lvmvgname="\nEnter a name for the volume group (VG) being created from the partition(s) selected."
283 _lvmlvname="\nEnter a name for the logical volume (LV) being created.\n\nThis is similar to setting a label for a partition."
284 _lvmlvsize="\nEnter what size you want the logical volume (LV) to be in megabytes (M) or gigabytes (G).\n\neg. 100M will create a 100 megabyte volume, 10G will create a 10 gigabyte volume."
285 _lvmdelask="\nConfirm deletion of volume group(s) and logical volume(s).\n\nDeleting a volume group, will delete all logical volumes within it.\n"
288 _errexpart="\nCannot mount partition due to a problem with the mountpoint.\n\nEnsure it begins with a slash (/) followed by atleast one character.\n"
289 _errpart="\nYou need create the partiton(s) first.\n\n\nBIOS systems require at least one partition (ROOT).\n\nUEFI systems require at least two (ROOT and EFI).\n"
290 _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"
291 _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"
292 _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"
293 _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"
294 _lvmerrlvsize="\nInvalid value Entered.\n\nMust be a numeric value with 'M' (megabytes) or 'G' (gigabytes) at the end.\n\neg. 400M, 10G, 250G, etc...\n\nThe value may also not be equal to or greater than the remaining size of the volume group.\n"
300 ###############################################################################
305 (( SEL < 12 )) && (( SEL++ ))
307 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " --default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \
308 1 "Device tree (optional)" \
309 2 "Partitioning (optional)" \
310 3 "LUKS setup (optional)" \
311 4 "LVM setup (optional)" \
312 5 "Mount partitions" \
313 6 "System bootloader" \
314 7 "User and password" \
315 8 "System configuration" \
316 9 "Select WM/DE (optional)" \
317 10 "Select Packages (optional)" \
318 11 "View configuration (optional)" \
319 12 "Start the installation" 2>"$ANS"
322 [[ -z $WARN && $SEL =~ (2|5) ]] && { msg "Data Warning" "$_warn"; WARN=true; }
325 2) part_menu || (( SEL-- )) ;;
326 3) luks_menu || (( SEL-- )) ;;
327 4) lvm_menu || (( SEL-- )) ;;
328 5) select_menu || (( SEL-- )) ;;
329 6) prechecks 0 && { select_boot || (( SEL-- )); } ;;
330 7) prechecks 1 && { select_mkuser || (( SEL-- )); } ;;
331 8) prechecks 2 && { select_config || (( SEL-- )); } ;;
332 9) prechecks 3 && { select_sessions || (( SEL-- )); } ;;
333 10) prechecks 3 && { select_packages || (( SEL-- )); } ;;
334 11) prechecks 3 && select_show ;;
335 12) prechecks 3 && install_main ;;
336 *) yesno "Exit" "\nUnmount partitions (if any) and exit the installer?\n" && die 0
342 if [[ $SYS == 'BIOS' ]]; then
343 dlg BOOTLDR menu "BIOS Bootloader" "\nSelect which bootloader to use." \
344 "grub" "The Grand Unified Bootloader, standard among many Linux distributions" \
345 "syslinux" "A collection of boot loaders for booting drives, CDs, or over the network" || return 1
347 dlg BOOTLDR menu "UEFI Bootloader" "\nSelect which bootloader to use." \
348 "systemd-boot" "A simple UEFI boot manager which executes configured EFI images" \
349 "grub" "The Grand Unified Bootloader, standard among many Linux distributions" \
350 "refind-efi" "A UEFI boot manager that aims to be platform neutral and simplify multi-boot" \
351 "efistub" "Boot the kernel image directly (no chainloading support)" \
352 "syslinux" "A collection of boot loaders for booting drives, CDs, or over the network (no chainloading support)" || return 1
360 local cmd="${BCMDS[$BOOTLDR]}"
361 local pkgs="${USER_PKGS// / } ${PACKAGES// / }"
362 [[ $BOOT_PART ]] && mnt="/$BOOTDIR"
363 [[ $INSTALL_WMS == *dwm* ]] && pkgs="dwm st dmenu $pkgs"
365 msg "Show Configuration" "
367 ---------- PARTITION CONFIGURATION ------------
369 Root: ${ROOT_PART:-none}
370 Boot: ${BOOT_PART:-${BOOT_DEV:-none}}
372 Swap: ${SWAP_PART:-none}
373 Size: ${SWAP_SIZE:-none}
378 Extra: ${EXMNTS:-${EXMNT:-none}}
379 Hooks: ${HOOKS:-none}
382 ---------- BOOTLOADER CONFIGURATION -----------
384 Bootloader: ${BOOTLDR:-none}
385 Mountpoint: ${mnt:-none}
386 Command: ${cmd:-none}
389 ------------ SYSTEM CONFIGURATION -------------
391 Locale: ${MYLOCALE:-none}
392 Keymap: ${KEYMAP:-none}
393 Hostname: ${MYHOST:-none}
394 Timezone: ${ZONE:-none}/${SUBZ:-none}
397 ------------ USER CONFIGURATION --------------
399 User: ${NEWUSER:-none}
400 Shell: ${MYSHELL:-none}
401 Session: ${LOGIN_WM:-none}
402 Autologin: ${AUTOLOGIN:-none}
403 Login Method: ${LOGIN_TYPE:-none}
406 ------------ PACKAGES AND MIRRORS -------------
408 Kernel: ${KERNEL:-none}
409 Sessions: ${INSTALL_WMS:-none}
410 Packages: $(print4 "${pkgs:-none}")
416 if [[ -z $LOGIN_TYPE ]]; then
417 dlg LOGIN_TYPE menu "Login Management" "\nSelect what kind of login management to use." \
418 "xinit" "Console login without a display manager" \
419 "lightdm" "Lightweight display manager with a gtk greeter" || return 1
422 if [[ $LOGIN_TYPE == 'lightdm' ]]; then
423 LOGIN_PKGS="lightdm lightdm-gtk-greeter lightdm-gtk-greeter-settings accountsservice"
424 EDIT_FILES[login]="/etc/lightdm/lightdm.conf /etc/lightdm/lightdm-gtk-greeter.conf"
427 if (( WM_NUM == 1 )); then
428 LOGIN_WM="${WM_SESSIONS[$INSTALL_WMS]}"
430 dlg LOGIN_WM menu "Login Management" "$_login" $LOGIN_CHOICES || return 1
431 LOGIN_WM="${WM_SESSIONS[$LOGIN_WM]}"
434 local txt="\nDo you want autologin enabled for $NEWUSER?\n\nIf so the following two files will be created (disable autologin by removing them):\n\n - /home/$NEWUSER/$LOGINRC (this runs startx when logging in on tty1)\n - /etc/systemd/system/getty@tty1.service.d/autologin.conf (this logs in $NEWUSER without a password)\n"
435 yesno "Autologin" "$txt" && AUTOLOGIN=true || AUTOLOGIN=''
436 LOGIN_PKGS="xorg-xinit"
437 EDIT_FILES[login]="/home/$NEWUSER/.xinitrc /home/$NEWUSER/.xprofile"
446 until [[ $CONFIG_DONE ]]; do
449 dlg MYSHELL menu "Shell" "\nChoose which shell to use." \
450 /usr/bin/zsh 'A very advanced and programmable command interpreter (shell) for UNIX' \
451 /bin/bash 'The GNU Bourne Again shell, standard in many GNU/Linux distributions' \
452 /usr/bin/mksh 'The MirBSD Korn Shell - an enhanced version of the public domain ksh' || return 1
455 1) dlg MYHOST input "Hostname" "$_hostname" "${DIST,,}" limit || { i=0; continue; } ;;
456 2) dlg MYLOCALE menu "Locale" "$_locale" $LOCALES || { i=1; continue; } ;;
458 until [[ $ZONE && $SUBZ ]]; do
459 dlg ZONE menu "Timezone" "$_timez" America - Australia - Asia - Atlantic - Africa - Europe - Indian - Pacific - Arctic - Antarctica - || break
460 dlg SUBZ menu "Timezone" "$_timesubz" $(awk '/'"$ZONE"'\// {gsub(/'"$ZONE"'\//, ""); print $3 " - "}' /usr/share/zoneinfo/zone.tab | sort) || continue
461 yesno "Timezone" "\nConfirm time zone: $ZONE/$SUBZ\n" || unset ZONE
463 [[ $ZONE && $SUBZ ]] || { i=2; continue; } ;;
465 dlg KERNEL menu "Kernel" "\nChoose which kernel to use." \
466 linux 'Vanilla linux kernel and modules, with a few patches applied' \
467 linux-lts 'Long-term support (LTS) linux kernel and modules' \
468 linux-zen 'A effort of kernel hackers to provide the best kernel for everyday systems' \
469 linux-hardened 'A security-focused linux kernel with hardening patches to mitigate exploits' || { i=3; continue; }
474 (( i++ )) # progress through to the next choice
478 '/bin/bash') LOGINRC='.bash_profile' ;;
479 '/usr/bin/zsh') LOGINRC='.zprofile' ;;
480 '/usr/bin/mksh') LOGINRC='.profile' ;;
489 local v='' u='' p='' p2='' rp='' rp2=''
491 until [[ $NEWUSER ]]; do
494 dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " User " --mixedform "$_user" 0 0 0 \
495 "Username:" 1 1 "$u" 1 11 "$COLUMNS" 0 0 \
496 "Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \
497 "Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 \
498 "--- Root password, if left empty the user password will be used ---" 6 1 '' 6 68 "$COLUMNS" 0 2 \
499 "Password:" 8 1 '' 8 11 "$COLUMNS" 0 1 \
500 "Password2:" 9 1 '' 9 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
502 while read -r line; do
513 # root passwords empty, so use the user passwords
514 [[ -z $rp && -z $rp2 ]] && { rp="$p"; rp2="$p2"; }
516 # make sure a username was entered and that the passwords match
517 if [[ ${#u} -eq 0 || $u =~ \ |\' || $u =~ [^a-z0-9] ]]; then
518 msg "Invalid Username" "\nIncorrect user name.\n\nPlease try again.\n"; u=''
519 elif [[ -z $p ]]; then
520 msg "Empty Password" "\nThe user password cannot be left empty.\n\nPlease try again.\n"
521 elif [[ "$p" != "$p2" ]]; then
522 msg "Password Mismatch" "\nThe user passwords do not match.\n\nPlease try again.\n"
523 elif [[ "$rp" != "$rp2" ]]; then
524 msg "Password Mismatch" "\nThe root passwords do not match.\n\nPlease try again.\n"
536 dlg KEYMAP menu "Keyboard Layout" "$_keymap" \
537 us English cm English gb English au English gh English \
538 za English ng English ca French 'cd' French gn French \
539 tg French fr French de German at German ch German \
540 es Spanish latam Spanish br Portuguese pt Portuguese ma Arabic \
541 sy Arabic ara Arabic ua Ukrainian cz Czech ru Russian \
542 sk Slovak nl Dutch it Italian hu Hungarian cn Chinese \
543 tw Taiwanese vn Vietnamese kr Korean jp Japanese th Thai \
544 la Lao pl Polish se Swedish is Icelandic 'fi' Finnish \
545 dk Danish be Belgian in Indian al Albanian am Armenian \
546 bd Bangla ba Bosnian 'bg' Bulgarian dz Berber mm Burmese \
547 hr Croatian gr Greek il Hebrew ir Persian iq Iraqi \
548 af Afghani fo Faroese ge Georgian ee Estonian kg Kyrgyz \
549 kz Kazakh lt Lithuanian mt Maltese mn Mongolian ro Romanian \
550 no Norwegian rs Serbian si Slovenian tj Tajik lk Sinhala \
551 tr Turkish uz Uzbek ie Irish pk Urdu 'mv' Dhivehi \
552 np Nepali et Amharic sn Wolof ml Bambara tz Swahili \
553 ke Swahili bw Tswana ph Filipino my Malay tm Turkmen \
554 id Indonesian bt Dzongkha lv Latvian md Moldavian mao Maori \
555 by Belarusian az Azerbaijani mk Macedonian kh Khmer epo Esperanto \
556 me Montenegrin || return 1
558 if [[ $CMAPS == *"$KEYMAP"* ]]; then
561 dlg CMAP menu "Console Keymap" "$_vconsole" $CMAPS || return 1
564 if [[ $DISPLAY && $TERM != 'linux' ]]; then
565 setxkbmap "$KEYMAP" >/dev/null 2>&1
567 loadkeys "$CMAP" >/dev/null 2>&1
577 dlg INSTALL_WMS check "Sessions" "$_sessions\n" \
578 i3-gaps "A fork of i3wm with more features including gaps" "$(ofn i3-gaps "${INSTALL_WMS[*]}")" \
579 openbox "A lightweight, powerful, and highly configurable stacking wm" "$(ofn openbox "${INSTALL_WMS[*]}")" \
580 awesome "A customized Awesome WM session created by @elanapan" "$(ofn awesome "${INSTALL_WMS[*]}")" \
581 dwm "A dynamic WM for X that manages windows in tiled, floating, or monocle layouts" "$(ofn dwm "${INSTALL_WMS[*]}")" \
582 bspwm "A tiling wm that represents windows as the leaves of a binary tree" "$(ofn bspwm "${INSTALL_WMS[*]}")" \
583 fluxbox "A lightweight and highly-configurable window manager" "$(ofn fluxbox "${INSTALL_WMS[*]}")" \
584 gnome "A desktop environment that aims to be simple and easy to use" "$(ofn gnome "${INSTALL_WMS[*]}")" \
585 cinnamon "A desktop environment combining traditional desktop with modern effects" "$(ofn cinnamon "${INSTALL_WMS[*]}")" \
586 plasma "A kde software project currently comprising a full desktop environment" "$(ofn plasma "${INSTALL_WMS[*]}")" \
587 xfce4 "A lightweight and modular desktop environment based on gtk+2/3" "$(ofn xfce4 "${INSTALL_WMS[*]}")" || return 1
590 while IFS=' ' read -r i; do
592 done <<< "$INSTALL_WMS"
595 WM_PKGS="${INSTALL_WMS/dwm/}" # remove dwm from package list
596 WM_PKGS="${WM_PKGS// / }" # remove double spaces
597 WM_PKGS="${WM_PKGS# }" # remove leading space
599 # add archlabs base when choosing any session
600 [[ $WM_PKGS ]] && WM_PKGS+=" $AL_BASE_PKGS"
602 for i in $INSTALL_WMS; do
603 LOGIN_CHOICES+="$i - "
604 [[ ${WM_EXT[$i]} && $WM_PKGS != *"${WM_EXT[$i]}"* ]] && WM_PKGS+=" ${WM_EXT[$i]}"
607 select_login || return 1
608 [[ $WM_PKGS != *"$LOGIN_PKGS"* ]] && WM_PKGS+=" $LOGIN_PKGS"
610 while IFS=' ' read -r pkg; do
611 [[ $PACKAGES != *"$pkg"* ]] && PACKAGES+=" $pkg"
619 dlg USER_PKGS check " Packages " "$_packages" \
620 abiword "A Fully-featured word processor" "$(ofn abiword "${USER_PKGS[*]}")" \
621 alacritty "A cross-platform, GPU-accelerated terminal emulator" "$(ofn alacritty "${USER_PKGS[*]}")" \
622 atom "An open-source text editor developed by GitHub" "$(ofn atom "${USER_PKGS[*]}")" \
623 audacious "A free and advanced audio player based on GTK+" "$(ofn audacious "${USER_PKGS[*]}")" \
624 audacity "A program that lets you manipulate digital audio waveforms" "$(ofn audacity "${USER_PKGS[*]}")" \
625 cairo-dock "Light eye-candy fully themable animated dock" "$(ofn cairo-dock "${USER_PKGS[*]}")" \
626 calligra "A set of applications for productivity" "$(ofn calligra "${USER_PKGS[*]}")" \
627 chromium "An open-source web browser based on the Blink rendering engine" "$(ofn chromium "${USER_PKGS[*]}")" \
628 clementine "A modern music player and library organizer" "$(ofn clementine "${USER_PKGS[*]}")" \
629 cmus "A small, fast and powerful console music player" "$(ofn cmus "${USER_PKGS[*]}")" \
630 deadbeef "A GTK+ audio player for GNU/Linux" "$(ofn deadbeef "${USER_PKGS[*]}")" \
631 deluge "A BitTorrent client written in python" "$(ofn deluge "${USER_PKGS[*]}")" \
632 docky "Full fledged dock for opening applications and managing windows" "$(ofn docky "${USER_PKGS[*]}")" \
633 emacs "An extensible, customizable, self-documenting real-time display editor" "$(ofn emacs "${USER_PKGS[*]}")" \
634 epiphany "A GNOME web browser based on the WebKit rendering engine" "$(ofn epiphany "${USER_PKGS[*]}")" \
635 evince "A document viewer" "$(ofn evince "${USER_PKGS[*]}")" \
636 evolution "Manage your email, contacts and schedule" "$(ofn evolution "${USER_PKGS[*]}")" \
637 file-roller "Create and modify archives" "$(ofn file-roller "${USER_PKGS[*]}")" \
638 firefox "A popular open-source web browser from Mozilla" "$(ofn firefox "${USER_PKGS[*]}")" \
639 gcolor2 "A simple GTK+2 color selector" "$(ofn gcolor2 "${USER_PKGS[*]}")" \
640 geany "A fast and lightweight IDE" "$(ofn geany "${USER_PKGS[*]}")" \
641 geary "A lightweight email client for the GNOME desktop" "$(ofn geary "${USER_PKGS[*]}")" \
642 gimp "GNU Image Manipulation Program" "$(ofn gimp "${USER_PKGS[*]}")" \
643 gnome-disk-utility "Disk Management Utility" "$(ofn gnome-disk-utility "${USER_PKGS[*]}")" \
644 gnome-system-monitor "View current processes and monitor system state" "$(ofn gnome-system-monitor "${USER_PKGS[*]}")" \
645 gparted "A GUI frontend for creating and manipulating partition tables" "$(ofn gparted "${USER_PKGS[*]}")" \
646 gpick "Advanced color picker using GTK+ toolkit" "$(ofn gpick "${USER_PKGS[*]}")" \
647 gpicview "Lightweight image viewer" "$(ofn gpicview "${USER_PKGS[*]}")" \
648 guvcview "Capture video from camera devices" "$(ofn guvcview "${USER_PKGS[*]}")" \
649 hexchat "A popular and easy to use graphical IRC client" "$(ofn hexchat "${USER_PKGS[*]}")" \
650 inkscape "Professional vector graphics editor" "$(ofn inkscape "${USER_PKGS[*]}")" \
651 irssi "Modular text mode IRC client" "$(ofn irssi "${USER_PKGS[*]}")" \
652 kdenlive "A popular non-linear video editor for Linux" "$(ofn kdenlive "${USER_PKGS[*]}")" \
653 krita "Edit and paint images" "$(ofn krita "${USER_PKGS[*]}")" \
654 libreoffice-fresh "Full featured office suite" "$(ofn libreoffice-fresh "${USER_PKGS[*]}")" \
655 lollypop "A new music playing application" "$(ofn lollypop "${USER_PKGS[*]}")" \
656 mousepad "A simple text editor" "$(ofn mousepad "${USER_PKGS[*]}")" \
657 mpd "A flexible, powerful, server-side application for playing music" "$(ofn mpd "${USER_PKGS[*]}")" \
658 mpv "A media player based on mplayer" "$(ofn mpv "${USER_PKGS[*]}")" \
659 mupdf "Lightweight PDF and XPS viewer" "$(ofn mupdf "${USER_PKGS[*]}")" \
660 mutt "Small but very powerful text-based mail client" "$(ofn mutt "${USER_PKGS[*]}")" \
661 nautilus "The default file manager for Gnome" "$(ofn nautilus "${USER_PKGS[*]}")" \
662 ncmpcpp "A mpd client and almost exact clone of ncmpc with some new features" "$(ofn ncmpcpp "${USER_PKGS[*]}")" \
663 neovim "A fork of Vim aiming to improve user experience, plugins, and GUIs." "$(ofn neovim "${USER_PKGS[*]}")" \
664 nicotine+ "A graphical client for Soulseek" "$(ofn nicotine+ "${USER_PKGS[*]}")" \
665 noto-fonts "Google Noto fonts" "$(ofn noto-fonts "${USER_PKGS[*]}")" \
666 noto-fonts-cjk "Google Noto CJK fonts (Chinese, Japanese, Korean)" "$(ofn noto-fonts-cjk "${USER_PKGS[*]}")" \
667 obs-studio "Free opensource streaming/recording software" "$(ofn obs-studio "${USER_PKGS[*]}")" \
668 openshot "An open-source, non-linear video editor for Linux" "$(ofn openshot "${USER_PKGS[*]}")" \
669 opera "A Fast and secure, free of charge web browser from Opera Software" "$(ofn opera "${USER_PKGS[*]}")" \
670 pcmanfm "A fast and lightweight file manager based in Lxde" "$(ofn pcmanfm "${USER_PKGS[*]}")" \
671 pidgin "Multi-protocol instant messaging client" "$(ofn pidgin "${USER_PKGS[*]}")" \
672 plank "An elegant, simple, and clean dock" "$(ofn plank "${USER_PKGS[*]}")" \
673 qbittorrent "An advanced BitTorrent client" "$(ofn qbittorrent "${USER_PKGS[*]}")" \
674 qpdfview "A tabbed PDF viewer" "$(ofn qpdfview "${USER_PKGS[*]}")" \
675 qt5ct "GUI for managing Qt based application themes, icons, and fonts" "$(ofn qt5ct "${USER_PKGS[*]}")" \
676 qutebrowser "A keyboard-focused vim-like web browser based on Python and PyQt5" "$(ofn qutebrowser "${USER_PKGS[*]}")" \
677 rhythmbox "A Music playback and management application" "$(ofn rhythmbox "${USER_PKGS[*]}")" \
678 rxvt-unicode "A unicode enabled rxvt-clone terminal emulator" "$(ofn rxvt-unicode "${USER_PKGS[*]}")" \
679 sakura "A terminal emulator based on GTK and VTE" "$(ofn sakura "${USER_PKGS[*]}")" \
680 simplescreenrecorder "A feature-rich screen recorder" "$(ofn simplescreenrecorder "${USER_PKGS[*]}")" \
681 steam "A popular game distribution platform by Valve" "$(ofn steam "${USER_PKGS[*]}")" \
682 surf "A simple web browser based on WebKit2/GTK+" "$(ofn surf "${USER_PKGS[*]}")" \
683 terminator "Terminal emulator that supports tabs and grids" "$(ofn terminator "${USER_PKGS[*]}")" \
684 termite "A minimal VTE-based terminal emulator" "$(ofn termite "${USER_PKGS[*]}")" \
685 thunar "A modern file manager for the Xfce Desktop Environment" "$(ofn thunar "${USER_PKGS[*]}")" \
686 thunderbird "Standalone mail and news reader from mozilla" "$(ofn thunderbird "${USER_PKGS[*]}")" \
687 tilda "A GTK based drop down terminal for Linux and Unix" "$(ofn tilda "${USER_PKGS[*]}")" \
688 tilix "A tiling terminal emulator for Linux using GTK+ 3" "$(ofn tilix "${USER_PKGS[*]}")" \
689 transmission-cli "Free BitTorrent client CLI" "$(ofn transmission-cli "${USER_PKGS[*]}")" \
690 transmission-gtk "Free BitTorrent client GTK+ GUI" "$(ofn transmission-gtk "${USER_PKGS[*]}")" \
691 transmission-qt "Free BitTorrent client Qt GUI" "$(ofn transmission-qt "${USER_PKGS[*]}")" \
692 ttf-anonymous-pro "A family fixed-width fonts designed with code in mind" "$(ofn ttf-anonymous-pro "${USER_PKGS[*]}")" \
693 ttf-fira-code "Monospaced font with programming ligatures" "$(ofn ttf-fira-code "${USER_PKGS[*]}")" \
694 ttf-font-awesome "Iconic font designed for Bootstrap" "$(ofn ttf-font-awesome "${USER_PKGS[*]}")" \
695 ttf-hack "A hand groomed typeface based on Bitstream Vera Mono" "$(ofn ttf-hack "${USER_PKGS[*]}")" \
696 vlc "A free and open source cross-platform multimedia player" "$(ofn vlc "${USER_PKGS[*]}")" \
697 weechat "Fast, light and extensible IRC client" "$(ofn weechat "${USER_PKGS[*]}")" \
698 xarchiver "A GTK+ frontend to various command line archivers" "$(ofn xarchiver "${USER_PKGS[*]}")" \
699 xfce-terminal "A terminal emulator based in the Xfce Desktop Environment" "$(ofn xfce-terminal "${USER_PKGS[*]}")" \
700 xterm "The standard terminal emulator for the X window system" "$(ofn xterm "${USER_PKGS[*]}")" \
701 zathura "Minimalistic document viewer" "$(ofn zathura "${USER_PKGS[*]}")"
703 if [[ $USER_PKGS ]]; then
704 for i in $USER_PKGS; do
705 [[ ${PKG_EXT[$i]} && $USER_PKGS != *"${PKG_EXT[$i]}"* ]] && USER_PKGS+=" ${PKG_EXT[$i]}"
712 ###############################################################################
717 check_background_install || return 0
718 local device choice devhash
719 devhash="$(lsblk -f | base64)"
721 part_device || return 1
726 if [[ $DISPLAY && $TERM != 'linux' ]] && hash gparted >/dev/null 2>&1; then
727 dlg choice menu "Edit Partitions" "$_part" \
728 "auto" "Whole device automatic partitioning" \
729 "shrink" "Shrink an existing ext2/3/4 or ntfs partition to make room for a new partition" \
730 "gparted" "GUI front end to parted" \
731 "cfdisk" "Curses based variant of fdisk" \
732 "parted" "GNU partition editor" \
733 "fdisk" "Dialog-driven creation and manipulation of partitions" \
734 "done" "Return to the main menu" || return 0
736 dlg choice menu "Edit Partitions" "$_part" \
737 "auto" "Whole device automatic partitioning" \
738 "shrink" "Shrink an existing ext2/3/4 or ntfs partition to make room for a new partition" \
739 "cfdisk" "Curses based variant of fdisk" \
740 "parted" "GNU partition editor" \
741 "fdisk" "Dialog-driven creation and manipulation of partitions" \
742 "done" "Return to the main menu" || return 0
745 if [[ $choice == 'done' ]]; then
747 elif [[ $choice == 'shrink' ]]; then
748 part_shrink "$device"
749 elif [[ $choice == 'auto' ]]; then
750 local root_size txt table boot_fs
751 root_size=$(lsblk -lno SIZE "$device" | awk 'NR == 1 {
754 print ($1 * 1000 - 512) / 1000 "G"
760 txt="\nWARNING:\n\nALL data on $device will be destroyed and the following partitions will be created\n\n- "
761 if [[ $SYS == 'BIOS' ]]; then
762 table="msdos" boot_fs="ext4"
763 txt+="An $boot_fs boot partition with the boot flag enabled (512M)\n- "
765 table="gpt" boot_fs="fat32"
766 txt+="A $boot_fs efi boot partition (512M)\n- "
768 txt+="An ext4 partition using all remaining space ($root_size)\n\nDo you want to continue?\n"
769 yesno "Auto Partition" "$txt" && part_auto "$device" "$table" "$boot_fs" "$root_size"
775 if [[ $devhash != "$(lsblk -f | base64)" ]]; then
776 msg "Probing Partitions" "\nInforming the kernel of partition changes using partprobe.\n" 0
777 partprobe >/dev/null 2>&1
785 if [[ $IGNORE_DEV ]]; then
786 txt="$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE,MOUNTPOINT | awk "!/$IGNORE_DEV/"' && /disk|part|lvm|crypt|NAME/')"
788 txt="$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE,MOUNTPOINT | awk '/disk|part|lvm|crypt|NAME/')"
790 msg "Device Tree" "\n\n$txt\n\n"
795 if [[ $1 == "$MNT/swapfile" && $SWAP_SIZE ]]; then
796 fallocate -l $SWAP_SIZE "$1" 2>$ERR
797 errshow "fallocate -l $SWAP_SIZE $1"
798 chmod 600 "$1" 2>$ERR
799 errshow "chmod 600 $1"
801 mkswap "$1" >/dev/null 2>$ERR
803 swapon "$1" >/dev/null 2>$ERR
810 local device="$1" table="$2" boot_fs="$3" size="$4" dev_info=""
811 dev_info="$(parted -s "$device" print)"
813 msg "Auto Partition" "\nRemoving partitions on $device and setting table to $table\n" 1
816 while read -r PART; do
817 parted -s "$device" rm "$PART" >/dev/null 2>&1
818 done <<< "$(awk '/^ [1-9][0-9]?/ {print $1}' <<< "$dev_info" | sort -r)"
820 [[ $(awk '/Table:/ {print $3}' <<< "$dev_info") != "$table" ]] && parted -s "$device" mklabel "$table" >/dev/null 2>&1
822 msg "Auto Partition" "\nCreating a 512M $boot_fs boot partition.\n" 1
823 if [[ $SYS == "BIOS" ]]; then
824 parted -s "$device" mkpart primary "$boot_fs" 1MiB 513MiB >/dev/null 2>&1
826 parted -s "$device" mkpart ESP "$boot_fs" 1MiB 513MiB >/dev/null 2>&1
831 AUTO_BOOT_PART=$(lsblk -lno NAME,TYPE "$device" | awk 'NR==2 {print "/dev/" $1}')
833 if [[ $SYS == "BIOS" ]]; then
834 mkfs.ext4 -q "$AUTO_BOOT_PART" >/dev/null 2>&1
836 mkfs.vfat -F32 "$AUTO_BOOT_PART" >/dev/null 2>&1
839 msg "Auto Partition" "\nCreating a $size ext4 root partition.\n" 0
840 parted -s "$device" mkpart primary ext4 513MiB 100% >/dev/null 2>&1
842 AUTO_ROOT_PART="$(lsblk -lno NAME,TYPE "$device" | awk 'NR==3 {print "/dev/" $1}')"
843 mkfs.ext4 -q "$AUTO_ROOT_PART" >/dev/null 2>&1
845 FORMATTED+="$AUTO_BOOT_PART $AUTO_ROOT_PART "
846 msg "Auto Partition" "\nProcess complete.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$device")\n"
851 local regexp="$1" err=''
853 # string of partitions as /TYPE/PART SIZE
854 if [[ $IGNORE_DEV ]]; then
855 PARTS="$(lsblk -lno TYPE,NAME,SIZE |
856 awk "/$regexp/"' && !'"/$IGNORE_DEV/"' {
857 sub(/^part/, "/dev/")
858 sub(/^lvm|^crypt/, "/dev/mapper/")
862 PARTS="$(lsblk -lno TYPE,NAME,SIZE |
864 sub(/^part/, "/dev/")
865 sub(/^lvm|^crypt/, "/dev/mapper/")
870 # number of partitions total
872 while read -r line; do
876 # ensure we have enough partitions for the system and action type
878 'part|lvm|crypt') [[ $COUNT -lt 1 || ($SYS == 'UEFI' && $COUNT -lt 2) ]] && err="$_errpart" ;;
879 'part|crypt') (( COUNT < 1 )) && err="$_lvmerr" ;;
880 'part|lvm') (( COUNT < 2 )) && err="$_lukserr" ;;
883 # if there aren't enough partitions show the relevant error message
884 [[ $err ]] && { msg "Not Enough Partitions" "$err" 2; return 1; }
891 local part="$1" mountp="${MNT}$2" fs=""
892 fs="$(lsblk -lno FSTYPE "$part")"
895 if [[ $fs && ${FS_OPTS[$fs]} && $part != "$BOOT_PART" ]] && select_mntopts "$fs"; then
896 mount -o "$MNT_OPTS" "$part" "$mountp" >/dev/null 2>&1
898 mount "$part" "$mountp" >/dev/null 2>&1
901 part_mountconf "$part" "$mountp" || return 1
909 local part="$1" fs="$2" delay="$3"
911 msg "Format" "\nFormatting $part as $fs\n" 0
912 ${FS_CMDS[$fs]} "$part" >/dev/null 2>$ERR
913 errshow "${FS_CMDS[$fs]} $part" || return 1
922 local device="$1" fs=""
924 part_find "${device##*/}[^ ]" || return 1
925 (( COUNT == 1 )) && part="$(awk '{print $1}' <<< "${PARTS[@]}" )"
927 if (( COUNT == 1 )) || dlg part menu "Resize" "\nWhich partition on $device do you want to resize?" $PARTS; then
928 fs=$(lsblk -lno FSTYPE "$part")
931 msg "Resize" "\nGathering device size info.\n" 0
933 end=$(parted -s "$device" unit KiB print | awk '/^\s*'"$num"'/ {print $3}') # part size in KiB
934 devsize=$(parted -s "$device" unit KiB print | awk '/Disk '"${device//\//\\/}"':/ {print $3}') # whole device size in KiB
935 mount "$part" $MNT >/dev/null 2>&1; sleep 0.5
936 min=$(df --output=used --block-size=MiB "$part" | awk 'NR == 2 {print int($1) + 256}')
937 max=$(df --output=avail --block-size=MiB "$part" | awk 'NR == 2 {print int($1)}')
938 umount $MNT >/dev/null 2>&1
940 if dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Resize: $part " --rangebox "$_resize" 17 "$COLUMNS" "$min" "$max" $((max / 2)) 2>$ANS; then
942 size=$((size * 1024))
949 if ntfsresize -fc "$part"; then
950 ntfsresize -ff --size $(( (size * 1024) / 1000 ))k "$part" 2>$ERR # k=10^3 bytes
951 errshow "ntfsresize -f -s $(( (size * 1024) / 1000 ))k $part" || return 1
953 msg "Resize" "\nThe ntfs partition $part cannot be resized because it is scheduled for a consistency check.\n\nTo do a consistency check in windows open command prompt as admin and run:\n\n\tchkdsk /f /r /x\n"
958 e2fsck -f "$part"; sleep 0.5
959 resize2fs -f "$part" ${size}K 2>$ERR # K=2^10 bytes
960 errshow "resize2fs -f $part ${size}K" || return 1
964 parted "$device" resizepart "$num" ${size}KiB || return 1
967 if [[ $devsize == "$end" ]]; then
968 parted -s "$device" mkpart primary ext4 ${size}KiB 100% 2>$ERR
969 errshow "parted -s $device mkpart primary ext4 ${size}KiB 100%" || return 1
971 parted -s "$device" mkpart primary ext4 ${size}KiB ${end}KiB 2>$ERR
972 errshow "parted -s $device mkpart primary ext4 ${size}KiB ${end}KiB" || return 1
974 msg "Resize Complete" "\n$part has been successfully resized to $((size / 1024))M.\n" 1
976 "") msg "No Filesystem" "\nFor unformatted partitions, cfdisk can be used in the partition menu.\n" ;;
977 *) msg "Invalid Filesystem: $fs" "\nResizing only supports ext and ntfs.\n" ;;
984 if [[ $DEV_COUNT -eq 1 && $SYS_DEVS ]]; then
985 DEVICE="$(awk '{print $1}' <<< "$SYS_DEVS")"
986 elif (( DEV_COUNT > 1 )); then
988 dlg DEVICE menu "Boot Device" "\nSelect the device to use for bootloader install." $SYS_DEVS
990 dlg DEVICE menu "Select Device" "$_device" $SYS_DEVS
992 [[ $DEVICE ]] || return 1
993 elif [[ $DEV_COUNT -lt 1 && ! $1 ]]; then
994 msg "Device Error" "\nNo available devices.\n\nExiting..\n" 2; die 1
997 [[ $1 ]] && BOOT_DEV="$DEVICE"
1004 BOOT_DEV="${BOOT_PART%[1-9]}"
1005 BOOT_PART_NUM="${BOOT_PART: -1}"
1006 [[ $BOOT_PART = /dev/nvme* ]] && BOOT_DEV="${BOOT_PART%p[1-9]}"
1007 if [[ $SYS == 'UEFI' ]]; then
1008 parted -s $BOOT_DEV set $BOOT_PART_NUM esp on >/dev/null 2>&1
1010 parted -s $BOOT_DEV set $BOOT_PART_NUM boot on >/dev/null 2>&1
1017 local part="$1" devs=""
1018 devs="$(lsblk -lno NAME,FSTYPE,TYPE)"
1020 # Identify if $part is LUKS+LVM, LVM+LUKS, LVM alone, or LUKS alone
1021 if lsblk -lno TYPE "$part" | grep -q 'crypt'; then
1023 LUKS_NAME="${part#/dev/mapper/}"
1025 for dev in $(awk '/lvm/ && /crypto_LUKS/ {print "/dev/mapper/"$1}' <<< "$devs" | uniq); do
1026 if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
1027 LUKS_DEV="$LUKS_DEV cryptdevice=$dev:$LUKS_NAME"
1028 LVM='logical volume'
1033 for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | uniq); do
1034 if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
1035 LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
1036 LUKS_DEV="$LUKS_DEV cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME"
1041 elif lsblk -lno TYPE "$part" | grep -q 'lvm'; then
1042 LVM='logical volume'
1043 VNAME="${part#/dev/mapper/}"
1045 for dev in $(awk '/crypt/ && /lvm2_member/ {print "/dev/mapper/"$1}' <<< "$devs" | uniq); do
1046 if lsblk -lno NAME "$dev" | grep -q "$VNAME"; then
1047 LUKS_NAME="${dev/\/dev\/mapper\//}"
1052 for dev in $(awk '/part/ && /crypto_LUKS/ {print "/dev/"$1}' <<< "$devs" | uniq); do
1053 if lsblk -lno NAME "$dev" | grep -q "$LUKS_NAME"; then
1054 LUKS_UUID="$(lsblk -lno UUID,TYPE,FSTYPE "$dev" | awk '/part/ && /crypto_LUKS/ {print $1}')"
1055 LUKS_DEV="$LUKS_DEV cryptdevice=UUID=$LUKS_UUID:$LUKS_NAME"
1066 if (( COUNT > 0 )); then
1067 PARTS="$(sed "/${i//\//\\/}/d" <<< "$PARTS")"
1075 if grep -qw "$1" /proc/mounts; then
1076 msg "Mount Success" "\nPartition $1 mounted at $2\n" 1
1080 msg "Mount Fail" "\nPartition $1 failed to mount at $2\n" 2
1085 ###############################################################################
1090 check_background_install || return 0
1093 part_find 'part|lvm|crypt' || { SEL=2; return 1; }
1095 [[ $LUKS && $LUKS_PART ]] && part_countdec $LUKS_PART
1096 [[ $LVM && $LVM_PARTS ]] && part_countdec $LVM_PARTS
1098 select_root_partition || return 1
1100 if [[ $SYS == 'UEFI' ]]; then
1101 select_efi_partition || { BOOT_PART=''; return 1; }
1102 elif (( COUNT > 0 )); then
1103 select_boot_partition || { BOOT_PART=''; return 1; }
1106 if [[ $BOOT_PART ]]; then
1107 part_mount "$BOOT_PART" "/$BOOTDIR" && SEP_BOOT=true || return 1
1111 select_swap || return 1
1112 select_extra_partitions || return 1
1113 install_background || return 1
1120 dlg SWAP_PART menu "Swap Setup" "\nSelect whether to use a swapfile, swap partition, or none." \
1121 "none" "Don't allocate any swap space" \
1122 "swapfile" "Allocate $SYS_MEM at /swapfile" \
1125 if [[ -z $SWAP_PART || $SWAP_PART == "none" ]]; then
1128 elif [[ $SWAP_PART == "swapfile" ]]; then
1130 until [[ ${SWAP_SIZE:0:1} =~ [1-9] && ${SWAP_SIZE: -1} =~ (M|G) ]]; do
1131 (( i > 0 )) && msg "Swap Size Error" "\nSwap size must be 1(M|G) or greater, and can only contain whole numbers\n\nSize entered: $SWAP_SIZE\n" 2
1132 dlg SWAP_SIZE input "Swap Setup" "$_swapsize" "$SYS_MEM" || { SWAP_PART=''; SWAP_SIZE=''; return 1; }
1135 part_swap "$MNT/$SWAP_PART"
1136 SWAP_PART="/$SWAP_PART"
1137 elif [[ $PARTS == *"$SWAP_PART"* ]]; then
1138 part_swap $SWAP_PART
1139 part_countdec $SWAP_PART
1140 SWAP_SIZE="$(lsblk -lno SIZE $SWAP_PART)"
1150 local fs="$1" opts=''
1151 local title="${fs^} Mount Options"
1153 for i in ${FS_OPTS[$fs]}; do
1157 until [[ $MNT_OPTS ]]; do
1158 dlg MNT_OPTS check "$title" "$_mount" $opts
1159 [[ $MNT_OPTS ]] || return 1
1160 MNT_OPTS="${MNT_OPTS// /,}"
1161 yesno "$title" "\nConfirm the following options: $MNT_OPTS\n" || MNT_OPTS=''
1170 until [[ $EXMNT ]]; do
1171 dlg EXMNT input "Extra Mount $part" "$_exmnt" "/" || return 1
1172 if [[ ${EXMNT:0:1} != "/" || ${#EXMNT} -le 1 || $EXMNT =~ \ |\' || $EXMNTS == *"$EXMNT"* ]]; then
1173 msg "Mountpoint Error" "$_errexpart"
1182 local part="$1" fs='' cur=''
1183 local txt="\nSelect which filesystem to use for: $part\n\nDefault: ext4"
1184 cur="$(lsblk -lno FSTYPE "$part" 2>/dev/null)"
1187 if [[ $cur && ($part != "$ROOT_PART" || $FORMATTED == *"$part"*) ]]; then
1188 dlg fs menu "Filesystem" "$txt\nCurrent: $cur" skip - ext4 - ext3 - ext2 - vfat - ntfs - f2fs - jfs - xfs - nilfs2 - reiserfs - || return 1
1190 dlg fs menu "Filesystem" "$txt" ext4 - ext3 - ext2 - vfat - ntfs - f2fs - jfs - xfs - nilfs2 - reiserfs - || return 1
1192 [[ $fs == 'skip' ]] && return 0
1193 yesno "Filesystem" "\nFormat $part as $fs?\n" || fs=''
1195 part_format "$part" "$fs"
1198 select_efi_partition()
1200 if (( COUNT == 1 )); then
1201 BOOT_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
1202 elif [[ $AUTO_BOOT_PART ]]; then
1203 BOOT_PART="$AUTO_BOOT_PART"
1204 return 0 # were done here
1206 dlg BOOT_PART menu "EFI Partition" "$_uefi" $PARTS
1209 [[ $BOOT_PART ]] || return 1
1211 if grep -q 'fat' <<< "$(fsck -N "$BOOT_PART")"; then
1212 local txt="\nIMPORTANT:\n\nThe EFI partition $BOOT_PART $_format"
1213 if yesno "Format EFI Partition" "$txt" "Format $BOOT_PART" "Skip Formatting" 1; then
1214 part_format "$BOOT_PART" "vfat" 2
1217 part_format "$BOOT_PART" "vfat" 2
1223 select_boot_partition()
1225 if [[ $AUTO_BOOT_PART && ! $LVM ]]; then
1226 BOOT_PART="$AUTO_BOOT_PART"; return 0 # were done here
1227 elif [[ $LUKS && ! $LVM ]]; then
1228 dlg BOOT_PART menu "Boot Partition" "$_biosluks" $PARTS
1229 [[ $BOOT_PART ]] || return 1
1231 dlg BOOT_PART menu "Boot Partition" "$_bios" "skip" "don't use a separate boot" $PARTS
1232 [[ -z $BOOT_PART || $BOOT_PART == "skip" ]] && { BOOT_PART=''; return 0; }
1235 if grep -q 'ext[34]' <<< "$(fsck -N "$BOOT_PART")"; then
1236 local txt="\nIMPORTANT:\n\nThe boot partition $BOOT_PART $_format"
1237 if yesno "Format Boot Partition" "$txt" "Format $BOOT_PART" "Skip Formatting" 1; then
1238 part_format "$BOOT_PART" "ext4" 2
1241 part_format "$BOOT_PART" "ext4" 2
1246 select_root_partition()
1248 if [[ $AUTO_ROOT_PART && -z $LVM && -z $LUKS ]]; then
1249 ROOT_PART="$AUTO_ROOT_PART"
1250 elif (( COUNT == 1 )); then
1251 ROOT_PART="$(awk 'NR==1 {print $1}' <<< "$PARTS")"
1253 dlg ROOT_PART menu "Mount Root" "\nSelect the root (/) partition, this is where $DIST will be installed.\n\nDevices smaller than 8G will not be shown here." $PARTS
1255 [[ $ROOT_PART ]] || return 1
1257 select_filesystem "$ROOT_PART" || { ROOT_PART=''; return 1; }
1258 part_mount "$ROOT_PART" || { ROOT_PART=''; return 1; }
1263 select_extra_partitions()
1266 while (( COUNT > 0 )); do
1268 dlg part menu 'Mount Extra' "$_expart" 'done' 'finish mounting step' $PARTS || break
1269 if [[ $part == 'done' ]]; then
1271 elif select_filesystem "$part" && select_mountpoint && part_mount "$part" "$EXMNT"; then
1272 EXMNTS+="$part: $EXMNT "
1273 [[ $EXMNT == '/usr' && $HOOKS != *usr* ]] && HOOKS="usr $HOOKS"
1281 ###############################################################################
1289 genfstab -U $MNT >$MNT/etc/fstab 2>$ERR
1290 errshow 1 "genfstab -U $MNT >$MNT/etc/fstab"
1291 [[ -f $MNT/swapfile ]] && sed -i "s~${MNT}~~" $MNT/etc/fstab
1295 chrun "hwclock --systohc --utc" || chrun "hwclock --systohc --utc --directisa"
1298 chrun "chown -Rf $NEWUSER:users /home/$NEWUSER"
1302 dlg choice menu "Finalization" "$_edit" \
1303 finished "exit the installer and reboot" \
1304 keyboard "${EDIT_FILES[keyboard]}" \
1305 console "${EDIT_FILES[console]}" \
1306 locale "${EDIT_FILES[locale]}" \
1307 hostname "${EDIT_FILES[hostname]}" \
1308 sudoers "${EDIT_FILES[sudoers]}" \
1309 mkinitcpio "${EDIT_FILES[mkinitcpio]}" \
1310 fstab "${EDIT_FILES[fstab]}" \
1311 crypttab "${EDIT_FILES[crypttab]}" \
1312 bootloader "${EDIT_FILES[bootloader]}" \
1313 pacman "${EDIT_FILES[pacman]}" \
1314 login "${EDIT_FILES[login]}"
1316 if [[ -z $choice || $choice == 'finished' ]]; then
1317 [[ $DEBUG == true && -r $DBG ]] && vim $DBG
1321 for f in ${EDIT_FILES[$choice]}; do
1322 [[ -e ${MNT}$f ]] && exists+=" ${MNT}$f"
1324 if [[ $exists ]]; then
1327 msg "File Missing" "\nThe file(s) selected do not exist:\n\n${EDIT_FILES[$choice]}\n"
1335 if [[ $RSYNC_PID || $MIRROR_PID ]]; then
1337 printf "\nOne or more background install processes are still running, grabbing their output...\n"
1339 while kill -0 "$RSYNC_PID" 2>/dev/null || kill -0 "$MIRROR_PID" 2>/dev/null; do
1340 tail -n 1 /tmp/bg_out
1344 unset RSYNC_PID MIRROR_PID
1345 elif [[ -d /run/archiso/sfs/airootfs/etc/skel ]]; then
1346 rsync -ahv /run/archiso/sfs/airootfs/ $MNT/ 2>$ERR
1347 errshow 1 "rsync -ahv /run/archiso/sfs/airootfs/ $MNT/"
1348 install_mirrorlist "$MNT/etc/pacman.d/mirrorlist"
1349 chrun "pacman -Syyu --noconfirm && pacman -S $BASE_PKGS --needed --noconfirm"
1351 mkdir -p /etc/pacman.d/mirrorlist
1352 install_mirrorlist "/etc/pacman.d/mirrorlist"
1353 pacstrap "$MNT" base $ISO_BASE 2>$ERR
1354 errshow 1 "pacstrap $MNT base $KERNEL $ISO_BASE"
1355 mkdir -p "$MNT/etc/pacman.d/mirrorlist"
1356 cp -f /etc/pacman.d/mirrorlist "$MNT/etc/pacman.d/mirrorlist"
1357 chrun "pacman -Syyu --noconfirm && pacman -S $BASE_PKGS --needed --noconfirm"
1360 rm -rf $MNT/etc/mkinitcpio-archiso.conf
1361 find $MNT/usr/lib/initcpio -name 'archiso*' -type f -delete
1362 sed -i 's/volatile/auto/g' $MNT/etc/systemd/journald.conf
1363 find $MNT/boot -name '*-ucode.img' -delete
1366 find $MNT/etc/X11/xorg.conf.d/ -name '*.conf' -delete
1367 elif lspci | grep ' VGA ' | grep -q 'Intel'; then
1368 cat > $MNT/etc/X11/xorg.conf.d/20-intel.conf << EOF
1370 Identifier "Intel Graphics"
1372 Option "TearFree" "true"
1377 [[ -e /run/archiso/sfs/airootfs && $KERNEL == 'linux' ]] && cp -vf $RUN/x86_64/vmlinuz $MNT/boot/vmlinuz-linux
1379 cp -fv /etc/resolv.conf $MNT/etc/
1380 [[ -e /etc/NetworkManager/system-connections ]] && cp -rvf /etc/NetworkManager/system-connections $MNT/etc/NetworkManager/
1382 echo "LANG=$MYLOCALE" > $MNT/etc/locale.conf
1383 cp -f $MNT/etc/locale.conf $MNT/etc/default/locale
1384 sed -i "s/#en_US.UTF-8/en_US.UTF-8/g; s/#${MYLOCALE}/${MYLOCALE}/g" $MNT/etc/locale.gen
1386 chrun "ln -svf /usr/share/zoneinfo/$ZONE/$SUBZ /etc/localtime"
1388 if [[ $BROADCOM_WL ]]; then
1389 echo 'blacklist bcma' >> $MNT/etc/modprobe.d/blacklist.conf
1390 rm -f $MNT/etc/modprobe/
1393 cat > $MNT/etc/X11/xorg.conf.d/00-keyboard.conf << EOF
1394 # Use localectl(1) to instruct systemd-localed to update it.
1395 Section "InputClass"
1396 Identifier "system-keyboard"
1397 MatchIsKeyboard "on"
1398 Option "XkbLayout" "$KEYMAP"
1401 cat > $MNT/etc/default/keyboard << EOF
1402 # KEYBOARD CONFIGURATION FILE
1403 # Consult the keyboard(5) manual page.
1410 printf "KEYMAP=%s\nFONT=%s\n" "$CMAP" "$FONT" > $MNT/etc/vconsole.conf
1411 echo "$MYHOST" > $MNT/etc/hostname
1412 cat > $MNT/etc/hosts << EOF
1415 ::1 localhost ip6-localhost ip6-loopback
1416 ff02::1 ip6-allnodes
1417 ff02::2 ip6-allrouters
1423 if [[ $ROOT_PART == /dev/mapper* ]]; then
1424 ROOT_PART_ID="$ROOT_PART"
1426 local uuid_type="UUID"
1427 [[ $BOOTLDR =~ (systemd-boot|refind-efi|efistub) ]] && uuid_type="PARTUUID"
1428 ROOT_PART_ID="$uuid_type=$(blkid -s $uuid_type -o value $ROOT_PART)"
1431 if [[ $SYS == 'UEFI' ]]; then
1432 find $MNT/$BOOTDIR/EFI/ -maxdepth 1 -mindepth 1 -iname "$DIST" -type d -delete
1433 find $MNT/$BOOTDIR/EFI/ -maxdepth 1 -mindepth 1 -iname 'boot' -type d -delete
1437 chrun "${BCMDS[$BOOTLDR]}" 2>$ERR
1438 errshow 1 "${BCMDS[$BOOTLDR]}"
1440 if [[ -d $MNT/hostrun ]]; then
1441 umount $MNT/hostrun/udev >/dev/null 2>&1
1442 umount $MNT/hostrun/lvm >/dev/null 2>&1
1443 rm -rf $MNT/hostrun >/dev/null 2>&1
1446 if [[ $SYS == 'UEFI' ]]; then
1447 # some UEFI firmware requires a generic esp/BOOT/BOOTX64.EFI
1448 mkdir -pv $MNT/$BOOTDIR/EFI/BOOT
1449 if [[ $BOOTLDR == 'grub' ]]; then
1450 cp -fv $MNT/$BOOTDIR/EFI/$DIST/grubx64.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI
1451 elif [[ $BOOTLDR == 'syslinux' ]]; then
1452 cp -rf $MNT/$BOOTDIR/EFI/syslinux/* $MNT/$BOOTDIR/EFI/BOOT/
1453 cp -f $MNT/$BOOTDIR/EFI/syslinux/syslinux.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI
1454 elif [[ $BOOTLDR == 'refind-efi' ]]; then
1455 sed -i '/#extra_kernel_version_strings/ c extra_kernel_version_strings linux-hardened,linux-zen,linux-lts,linux' $MNT/$BOOTDIR/EFI/refind/refind.conf
1456 cp -fv $MNT/$BOOTDIR/EFI/refind/refind_x64.efi $MNT/$BOOTDIR/EFI/BOOT/BOOTX64.EFI
1465 chrun "chpasswd <<< 'root:$ROOT_PASS'" 2>$ERR
1466 errshow 1 "set root password"
1467 if [[ $MYSHELL != *zsh ]]; then
1468 chrun "usermod -s $MYSHELL root" 2>$ERR
1469 errshow 1 "usermod -s $MYSHELL root"
1470 [[ $MYSHELL == "/usr/bin/mksh" ]] && cp -fv $MNT/etc/skel/.mkshrc /root/.mkshrc
1473 local groups='audio,autologin,floppy,log,network,rfkill,scanner,storage,optical,power,wheel'
1475 chrun "groupadd -r autologin" 2>$ERR
1476 errshow 1 "groupadd -r autologin"
1477 chrun "useradd -m -u 1000 -g users -G $groups -s $MYSHELL $NEWUSER" 2>$ERR
1478 errshow 1 "useradd -m -u 1000 -g users -G $groups -s $MYSHELL $NEWUSER"
1479 chrun "chpasswd <<< '$NEWUSER:$USER_PASS'" 2>$ERR
1480 errshow 1 "set $NEWUSER password"
1482 if [[ $USER_PKGS == *neovim* && -d $MNT/home/$NEWUSER/.vim ]]; then
1483 mkdir -p $MNT/home/$NEWUSER/.config/nvim
1484 cp -fv $MNT/home/$NEWUSER/.vimrc $MNT/home/$NEWUSER/.config/nvim/init.vim
1485 cp -rfv $MNT/home/$NEWUSER/.vim/colors $MNT/home/$NEWUSER/.config/nvim/colors
1488 [[ $INSTALL_WMS == *dwm* ]] && install_suckless
1489 [[ $INSTALL_WMS == *awesome* ]] && install_awesome
1491 # remove some commands from ~/.xprofile when using KDE or Gnome as the login session
1492 if [[ $LOGIN_WM =~ (startkde|gnome-session) ]]; then
1493 sed -i '/super/d' $MNT/home/$NEWUSER/.xprofile $MNT/root/.xprofile
1494 sed -i '/nitrogen/d' $MNT/home/$NEWUSER/.xprofile $MNT/root/.xprofile
1495 sed -i '/al-compositor/d' $MNT/home/$NEWUSER/.xprofile $MNT/root/.xprofile
1496 sed -i '/compton/d' $MNT/home/$NEWUSER/.xprofile $MNT/root/.xprofile
1504 if [[ -e $MNT/home/$NEWUSER/.xinitrc ]] && grep -q 'exec' $MNT/home/$NEWUSER/.xinitrc; then
1505 sed -i "/exec/ c exec ${LOGIN_WM}" $MNT/home/$NEWUSER/.xinitrc
1507 printf "exec %s\n" "$LOGIN_WM" >> $MNT/home/$NEWUSER/.xinitrc
1510 [[ ${EDIT_FILES[login]} == *"$LOGINRC"* ]] || EDIT_FILES[login]+=" /home/$NEWUSER/$LOGINRC"
1512 if [[ $AUTOLOGIN ]]; then
1513 sed -i "s/root/${NEWUSER}/g" $SERVICE/autologin.conf
1514 cat > $MNT/home/$NEWUSER/$LOGINRC <<EOF
1516 # sourced by ${MYSHELL##*/} when used as a login shell
1518 # automatically run startx when logging in on tty1
1519 [[ -z \$DISPLAY && \$XDG_VTNR -eq 1 ]] && exec startx -- vt1
1523 rm -rf $MNT/home/$NEWUSER/.{profile,zprofile,bash_profile}
1529 SERVICE="$MNT/etc/systemd/system/getty@tty1.service.d"
1530 sed -i '/printf/d' $MNT/root/.zshrc
1531 install_${LOGIN_TYPE:-xinit}
1537 rm -rf $MNT/home/$NEWUSER/.{xinitrc,profile,zprofile,bash_profile}
1538 chrun 'systemctl set-default graphical.target && systemctl enable lightdm.service' 2>$ERR
1539 errshow 1 "systemctl set-default graphical.target && systemctl enable lightdm.service"
1540 cat > $MNT/etc/lightdm/lightdm-gtk-greeter.conf << EOF
1541 # LightDM GTK+ Configuration
1544 default-user-image=/usr/share/icons/ArchLabs-Dark/64x64/places/distributor-logo-archlabs.png
1545 background=/usr/share/backgrounds/archlabs/archlabs.jpg
1546 theme-name=Adwaita-dark
1547 icon-theme-name=Adwaita
1548 font-name=DejaVu Sans Mono 11
1549 position=30%,end 50%,end
1555 if chrun "git clone https://github.com/elenapan/archlabs-awesome /home/$NEWUSER/archlabs-awesome"; then
1556 cp -rT "/mnt/home/$NEWUSER/archlabs-awesome" "/mnt/home/$NEWUSER"
1557 cp -rT "/mnt/home/$NEWUSER/archlabs-awesome" /mnt/etc/skel
1558 rm -rf "/home/$NEWUSER/"{.git,archlabs-awesome,screenshots}
1559 printf "You will need to instal pamac seperately if needed using: 'baph -i pamac-aur'\n"
1562 printf "failed to clone awesome config repo\n"
1569 local inpkg="$PACKAGES $USER_PKGS"
1571 if pacman -Qsq 'archlabs-installer' >/dev/null 2>&1; then
1572 rmpkg+=" archlabs-installer"
1573 elif [[ -e "$MNT/usr/bin/archlabs-installer" ]]; then
1574 rm -f "$MNT/usr/bin/archlabs-installer"
1577 [[ $UCODE ]] && inpkg+=" $UCODE"
1578 [[ $MYSHELL == *mksh ]] && inpkg+=" mksh"
1579 [[ $KERNEL == 'linux' ]] || { inpkg+=" $KERNEL"; rmpkg+=" linux"; }
1580 [[ $inpkg =~ (term|urxvt|tilix|alacritty|sakura|tilda|plasma|cinnamon) || $INSTALL_WMS == *dwm* ]] || inpkg+=" xterm"
1581 [[ $MYSHELL == '/usr/bin/zsh' ]] && inpkg+=" zsh-completions"
1582 [[ $INSTALL_WMS =~ ^(plasma|gnome|cinnamon)$ ]] || inpkg+=" archlabs-ksuperkey"
1583 [[ $INSTALL_WMS =~ (openbox|bspwm|i3-gaps|dwm|fluxbox) ]] && inpkg+=" $WM_BASE_PKGS"
1585 chrun "pacman -Syyu --noconfirm"
1586 [[ $rmpkg ]] && chrun "pacman -Rns $rmpkg --noconfirm"
1587 chrun "pacman -S iputils --noconfirm"
1588 chrun "pacman -S $inpkg --needed --noconfirm" 2>$ERR
1589 errshow 1 "pacman -S $inpkg --needed --noconfirm"
1591 if [[ $BOOTLDR == 'grub' ]]; then
1592 if [[ $SYS == 'BIOS' ]]; then
1593 chrun "pacman -S grub os-prober --needed --noconfirm" 2>$ERR
1594 errshow 1 "pacman -S grub os-prober --needed --noconfirm"
1596 chrun "pacman -S grub os-prober efibootmgr --needed --noconfirm" 2>$ERR
1597 errshow 1 "pacman -S grub os-prober efibootmgr --needed --noconfirm"
1599 elif [[ $BOOTLDR == 'refind-efi' ]]; then
1600 chrun "pacman -S refind-efi efibootmgr --needed --noconfirm" 2>$ERR
1601 errshow 1 "pacman -S refind-efi efibootmgr --needed --noconfirm"
1602 elif [[ $SYS == 'UEFI' ]]; then
1603 chrun "pacman -S efibootmgr --needed --noconfirm" 2>$ERR
1604 errshow 1 "pacman -S efibootmgr --needed --noconfirm"
1606 sed -i "s/# %wheel ALL=(ALL) ALL/%wheel ALL=(ALL) ALL/g" $MNT/etc/sudoers
1612 mkdir -pv $MNT/home/$NEWUSER/suckless
1613 for i in dwm dmenu st; do
1614 if chrun "git clone https://git.suckless.org/$i /home/$NEWUSER/suckless/$i"; then
1615 chrun "cd /home/$NEWUSER/suckless/$i; make PREFIX=/usr install; make clean; rm config.h"
1617 printf "failed to clone %s repo\n" "$i"
1621 if [[ -d $MNT/home/$NEWUSER/suckless/dwm && -x $MNT/usr/bin/dwm ]]; then
1622 printf "To configure dwm edit %s\n" "/home/$NEWUSER/suckless/dwm/config.h"
1623 printf "You can then recompile it with 'sudo make clean install'\n"
1628 install_mkinitcpio()
1632 # luks keyfile creation
1633 # currently not used due to not prompting for passphrase on startup
1634 # [[ $LUKS_UUID && $LUKS_PASS && $SYS == 'UEFI' && $BOOTLDR == 'grub' ]] && luks_keyfile
1636 [[ $LUKS ]] && add="encrypt"
1637 [[ $LVM ]] && { [[ $add ]] && add+=" lvm2" || add+="lvm2"; }
1638 sed -i "s/block filesystems/block ${add} filesystems ${HOOKS}/g" $MNT/etc/mkinitcpio.conf
1639 chrun "mkinitcpio -p $KERNEL" 2>$ERR
1640 errshow 1 "mkinitcpio -p $KERNEL"
1643 install_mirrorlist()
1647 if hash reflector >/dev/null 2>&1; then
1648 reflector --score 120 -l 50 -f 5 --sort rate --save "$mfile"
1649 elif hash rankmirrors >/dev/null 2>&1; then
1650 ip_add="$(curl -fsSL "http://api.ipstack.com/check&?access_key=5f29642060ab983b31fdf4c2935d8c56&fields=ip" |
1651 python -c "import sys, json; print(json.load(sys.stdin)['ip'])")"
1653 country="$(curl -fsSL "http://api.ipstack.com/${ip_add}?access_key=5f29642060ab983b31fdf4c2935d8c56&fields=country_code" |
1654 python -c "import sys, json; print(json.load(sys.stdin)['country_code'])")"
1656 if [[ "$country" ]]; then
1657 if [[ $country =~ (CA|US) ]]; then
1658 mirror="https://www.archlinux.org/mirrorlist/?country=US&country=CA&use_mirror_status=on"
1659 elif [[ $country =~ (AU|NZ) ]]; then
1660 mirror="https://www.archlinux.org/mirrorlist/?country=AU&country=NZ&use_mirror_status=on"
1662 mirror="https://www.archlinux.org/mirrorlist/?country=${country}&use_mirror_status=on"
1665 mirror="https://www.archlinux.org/mirrorlist/?country=all&use_mirror_status=on"
1668 curl -fsSL "$mirror" | sed -e 's/^#Server/Server/' -e '/^#/d' | rankmirrors -n 6 - >/etc/pacman.d/mirrorlist
1674 install_background()
1676 if [[ -d /run/archiso/sfs/airootfs/etc/skel ]] && grep -qw "$MNT" /proc/mounts && (grep -qw "$MNT/$BOOTDIR" /proc/mounts || [[ $SYS == 'BIOS' && -z $LUKS ]]); then
1677 yesno "Background Install" "\nSome parts of the install can be done in the background now, base unpack, mirrorlist sort, system update, and base packages.\n\nDo you want to start the background process?\n" || return 0
1678 rsync -a /run/archiso/sfs/airootfs/ $MNT/ &
1680 ( install_mirrorlist "$MNT/etc/pacman.d/mirrorlist" && chrun "pacman -Syyu $BASE_PKGS --needed --noconfirm" >> /tmp/bg_out 2>&1 ) &
1682 trap "kill $RSYNC_PID 2>/dev/null; kill $MIRROR_PID 2>/dev/null" EXIT
1687 ###############################################################################
1692 EDIT_FILES[bootloader]="/etc/default/grub"
1694 if [[ $SYS == 'BIOS' ]]; then
1695 [[ $BOOT_DEV ]] || { part_device 1 || return 1; }
1696 BCMDS[grub]="grub-install --recheck --force --target=i386-pc $BOOT_DEV"
1698 if [[ $ROOT_PART == */dev/mapper/* && -z $LVM && -z $LUKS_PASS ]]; then
1699 luks_pass "$_luksopen" 1 || return 1
1701 BCMDS[grub]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
1702 grub-install --recheck --force --target=x86_64-efi --efi-directory=/$BOOTDIR --bootloader-id=$DIST"
1703 grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
1706 BCMDS[grub]="mkdir -p /run/udev /run/lvm &&
1707 mount --bind /hostrun/udev /run/udev &&
1708 mount --bind /hostrun/lvm /run/lvm &&
1710 grub-mkconfig -o /boot/grub/grub.cfg &&
1711 sleep 1 && umount /run/udev /run/lvm"
1718 sed -i "s/GRUB_DISTRIBUTOR=.*/GRUB_DISTRIBUTOR=\"${DIST}\"/g;
1719 s/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT=\"\"/g" $MNT/etc/default/grub
1721 if [[ $LUKS_DEV ]]; then
1722 sed -i "s~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
1723 s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g" $MNT/etc/default/grub 2>$ERR
1724 errshow 1 "sed -i 's~#GRUB_ENABLE_CRYPTODISK~GRUB_ENABLE_CRYPTODISK~g;
1725 s~GRUB_CMDLINE_LINUX=.*~GRUB_CMDLINE_LINUX=\"${LUKS_DEV}\"~g' $MNT/etc/default/grub"
1728 if [[ $SYS == 'BIOS' && $LVM && -z $SEP_BOOT ]]; then
1729 sed -i "s/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g" $MNT/etc/default/grub 2>$ERR
1730 errshow 1 "sed -i 's/GRUB_PRELOAD_MODULES=.*/GRUB_PRELOAD_MODULES=\"lvm\"/g' $MNT/etc/default/grub"
1733 # setup for os-prober module
1734 mkdir -p /run/{lvm,udev}
1735 mkdir -p $MNT/hostrun/{lvm,udev}
1736 mount --bind /run/lvm $MNT/hostrun/lvm
1737 mount --bind /run/udev $MNT/hostrun/udev
1744 EDIT_FILES[bootloader]=""
1749 BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
1750 efibootmgr -v -d $BOOT_DEV -p $BOOT_PART_NUM -c -L '${DIST} Linux' -l /vmlinuz-${KERNEL} \
1751 -u 'root=$ROOT_PART_ID rw $([[ $UCODE ]] && printf 'initrd=\%s.img ' "$UCODE")initrd=\initramfs-${KERNEL}.img'"
1757 if [[ $SYS == 'BIOS' ]]; then
1758 EDIT_FILES[bootloader]="/boot/syslinux/syslinux.cfg"
1760 EDIT_FILES[bootloader]="/boot/EFI/syslinux/syslinux.cfg"
1761 BCMDS[syslinux]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
1762 efibootmgr -v -c -d $BOOT_DEV -p $BOOT_PART_NUM -l /EFI/syslinux/syslinux.efi -L $DIST"
1769 local c="$MNT/boot/syslinux" s="/usr/lib/syslinux/bios" d=".."
1770 [[ $SYS == 'UEFI' ]] && { c="$MNT/boot/EFI/syslinux"; s="/usr/lib/syslinux/efi64/"; d=''; }
1772 mkdir -pv "$c" && cp -rfv $s/* "$c/" && cp -f "$RUN/syslinux/splash.png" "$c/"
1773 cat > "$c/syslinux.cfg" << EOF
1775 MENU TITLE $DIST Boot Menu
1776 MENU BACKGROUND splash.png
1780 # see: https://www.syslinux.org/wiki/index.php/Comboot/menu.c32
1789 MENU HELPMSGENDROW 29
1790 MENU COLOR border 30;44 #40ffffff #a0000000 std
1791 MENU COLOR title 1;36;44 #9033ccff #a0000000 std
1792 MENU COLOR sel 7;37;40 #e0ffffff #20ffffff all
1793 MENU COLOR unsel 37;44 #50ffffff #a0000000 std
1794 MENU COLOR help 37;40 #c0ffffff #a0000000 std
1795 MENU COLOR timeout_msg 37;40 #80ffffff #00000000 std
1796 MENU COLOR timeout 1;37;40 #c0ffffff #00000000 std
1797 MENU COLOR msg07 37;40 #90ffffff #a0000000 std
1798 MENU COLOR tabmsg 31;40 #30ffffff #00000000 std
1801 MENU LABEL $DIST Linux
1802 LINUX $d/vmlinuz-$KERNEL
1803 APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
1804 INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL.img
1806 LABEL ${DIST}fallback
1807 MENU LABEL $DIST Linux Fallback
1808 LINUX $d/vmlinuz-$KERNEL
1809 APPEND root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
1810 INITRD $([[ $UCODE ]] && printf "%s" "$d/$UCODE.img,")$d/initramfs-$KERNEL-fallback.img
1811 $([[ $SYS == 'BIOS' ]] && printf "\n%s" "# examples of chainloading other bootloaders
1816 #APPEND file=$d/grub/boot.img
1828 EDIT_FILES[bootloader]="/boot/refind_linux.conf"
1829 BCMDS[refind-efi]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
1835 cat > $MNT/boot/refind_linux.conf << EOF
1836 "$DIST Linux" "root=$ROOT_PART_ID $([[ $LUKS_DEV ]] &&
1837 printf "%s " "$LUKS_DEV")rw add_efi_memmap $([[ $UCODE ]] &&
1838 printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-$KERNEL.img"
1839 "$DIST Linux Fallback" "root=$ROOT_PART_ID $([[ $LUKS_DEV ]] &&
1840 printf "%s " "$LUKS_DEV")rw add_efi_memmap $([[ $UCODE ]] &&
1841 printf "initrd=%s " "/$UCODE.img")initrd=/initramfs-$KERNEL-fallback.img"
1843 mkdir -p $MNT/etc/pacman.d/hooks
1844 cat > $MNT/etc/pacman.d/hooks/refind.hook << EOF
1851 Description = Updating rEFInd on ESP
1852 When = PostTransaction
1853 Exec = /usr/bin/refind-install
1857 setup_systemd-boot()
1859 EDIT_FILES[bootloader]="/boot/loader/entries/$DIST.conf"
1860 BCMDS[systemd-boot]="mount -t efivarfs efivarfs /sys/firmware/efi/efivars >/dev/null 2>&1
1861 bootctl --path=/boot install"
1864 prerun_systemd-boot()
1866 mkdir -p $MNT/boot/loader/entries
1867 cat > $MNT/boot/loader/loader.conf << EOF
1872 cat > $MNT/boot/loader/entries/$DIST.conf << EOF
1874 linux /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd %s" "/$UCODE.img")
1875 initrd /initramfs-$KERNEL.img
1876 options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
1878 cat > $MNT/boot/loader/entries/$DIST-fallback.conf << EOF
1879 title $DIST Linux Fallback
1880 linux /vmlinuz-${KERNEL}$([[ $UCODE ]] && printf "\ninitrd %s" "/$UCODE.img")
1881 initrd /initramfs-$KERNEL-fallback.img
1882 options root=$ROOT_PART_ID $([[ $LUKS_DEV ]] && printf "%s " "$LUKS_DEV")rw
1884 mkdir -p $MNT/etc/pacman.d/hooks
1885 cat > $MNT/etc/pacman.d/hooks/systemd-boot.hook << EOF
1892 Description = Updating systemd-boot
1893 When = PostTransaction
1894 Exec = /usr/bin/bootctl update
1896 systemd-machine-id-setup --root="$MNT"
1900 ###############################################################################
1905 check_background_install || return 1
1908 dlg choice menu "Logical Volume Management" "$_lvmmenu" \
1909 "$_lvmnew" "vgcreate -f, lvcreate -L -n" \
1910 "$_lvmdel" "vgremove -f" \
1911 "$_lvmdelall" "lvrmeove, vgremove, pvremove -f" \
1912 "back" "return to the main menu"
1915 "$_lvmnew") lvm_create || return 1 ;;
1916 "$_lvmdel") lvm_delgroup && yesno "$_lvmdel" "$_lvmdelask" && vgremove -f "$DEL_VG" >/dev/null 2>&1 ;;
1917 "$_lvmdelall") lvm_del_all ;;
1926 pv="$(pvs -o pv_name --noheading 2>/dev/null)"
1927 v="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)"
1928 VGROUP="$(vgs -o vg_name --noheading 2>/dev/null)"
1930 if [[ $VGROUP && $v && $pv ]]; then
1931 msg "Logical Volume Management" "\nActivating existing logical volume management (LVM).\n\n" 1
1932 modprobe dm-mod >/dev/null 2>$ERR
1933 errshow 'modprobe dm-mod'
1934 vgscan >/dev/null 2>&1
1935 vgchange -ay >/dev/null 2>&1
1941 VGROUP='' LVM_PARTS='' VGROUP_MB=0
1943 lvm_mkgroup || return 1
1944 local txt="\nThe last (or only) logical volume will automatically use all remaining space in the volume group."
1945 dlg VOL_COUNT menu "$_lvmnew" "\nSelect the number of logical volumes (LVs) to create in: $VGROUP\n$txt" 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9
1946 [[ $VOL_COUNT ]] || return 1
1947 lvm_extra_lvs || return 1
1948 lvm_volume_name "$_lvmlvname\nNOTE: This LV will use up all remaining space in the volume group (${VGROUP_MB}MB)" || return 1
1949 lvcreate -l +100%FREE "$VGROUP" -n "$VNAME" >/dev/null 2>$ERR
1950 errshow "lvcreate -l +100%FREE $VGROUP -n $VNAME" || return 1
1951 LVM='logical volume'; sleep 0.5
1952 txt="\nDone, volume: $VGROUP-$VNAME (${VOLUME_SIZE:-${VGROUP_MB}MB}) has been created.\n"
1953 msg "$_lvmnew (LV:$VOL_COUNT)" "$txt\n$(lsblk -o NAME,MODEL,TYPE,FSTYPE,SIZE $LVM_PARTS)\n"
1959 local txt="${VGROUP}: ${SIZE}$SIZE_UNIT (${VGROUP_MB}MB remaining).$_lvmlvsize"
1963 dlg VOLUME_SIZE input "$_lvmnew (LV:$VOL_COUNT)" "$txt" ''
1964 if [[ -z $VOLUME_SIZE ]]; then
1966 break # allow bailing with escape or an empty choice
1967 elif (( ${VOLUME_SIZE:0:1} == 0 )); then
1968 ERR_SIZE=1 # size values can't begin with '0'
1970 # walk the string and make sure all but the last char are digits
1971 local lv=$((${#VOLUME_SIZE} - 1))
1972 for (( i=0; i<lv; i++ )); do
1973 [[ ${VOLUME_SIZE:$i:1} =~ [0-9] ]] || { ERR_SIZE=1; break; }
1975 if (( ERR_SIZE != 1 )); then
1976 case ${VOLUME_SIZE:$lv:1} in
1977 [mMgG]) local s=${VOLUME_SIZE:0:$lv} m=$((s * 1000))
1978 case ${VOLUME_SIZE:$lv:1} in
1979 [Gg]) (( m >= VGROUP_MB )) && ERR_SIZE=1 || VGROUP_MB=$((VGROUP_MB - m)) ;;
1980 [Mm]) (( ${VOLUME_SIZE:0:$lv} >= VGROUP_MB )) && ERR_SIZE=1 || VGROUP_MB=$((VGROUP_MB - s)) ;;
1987 if (( ERR_SIZE )); then
1988 msg "Invalid Logical Volume Size" "$_lvmerrlvsize"
2000 local txt="\nConfirm creation of volume group: $VGROUP\n\nwith the following partition(s):"
2002 until [[ $named ]]; do
2003 lvm_partitions || return 1
2004 lvm_group_name || return 1
2005 yesno "$_lvmnew" "$txt $LVM_PARTS\n" && named=true
2008 vgcreate -f "$VGROUP" $LVM_PARTS >/dev/null 2>$ERR
2009 errshow "vgcreate -f $VGROUP $LVM_PARTS" || return 1
2011 SIZE=$(vgdisplay "$VGROUP" | awk '/VG Size/ { gsub(/[^0-9.]/, ""); print int($0) }')
2012 SIZE_UNIT="$(vgdisplay "$VGROUP" | awk '/VG Size/ { print substr($NF, 0, 1) }')"
2014 if [[ $SIZE_UNIT == 'G' ]]; then
2015 VGROUP_MB=$((SIZE * 1000))
2020 msg "$_lvmnew" "\nVolume group: $VGROUP ($SIZE $SIZE_UNIT) has been created\n"
2027 pv="$(pvs -o pv_name --noheading 2>/dev/null)"
2028 v="$(lvs -o vg_name,lv_name --noheading --separator - 2>/dev/null)"
2029 VGROUP="$(vgs -o vg_name --noheading 2>/dev/null)"
2031 if [[ $VGROUP || $v || $pv ]]; then
2032 if yesno "$_lvmdelall" "$_lvmdelask"; then
2033 for i in $v; do lvremove -f "/dev/mapper/$i" >/dev/null 2>&1; done
2034 for i in $VGROUP; do vgremove -f "$i" >/dev/null 2>&1; done
2035 for i in $pv; do pvremove -f "$i" >/dev/null 2>&1; done
2039 msg "Delete LVM" "\nNo LVMs to remove...\n" 2
2049 for i in $(lvs --noheadings | awk '{print $2}' | uniq); do
2050 VOL_GROUP_LIST+="$i $(vgdisplay "$i" | awk '/VG Size/ {print $3$4}') "
2052 [[ $VOL_GROUP_LIST ]] || { msg "No Groups" "\nNo volume groups found."; return 1; }
2054 dlg DEL_VG menu "Logical Volume Management" "\nSelect volume group to delete.\n\nAll logical volumes within will also be deleted." $VOL_GROUP_LIST
2060 while (( VOL_COUNT > 1 )); do
2061 lvm_volume_name "$_lvmlvname" && get_lv_size || return 1
2062 lvcreate -L "$VOLUME_SIZE" "$VGROUP" -n "$VNAME" >/dev/null 2>$ERR
2063 errshow "lvcreate -L $VOLUME_SIZE $VGROUP -n $VNAME" || return 1
2064 msg "$_lvmnew (LV:$VOL_COUNT)" "\nDone, logical volume (LV) $VNAME ($VOLUME_SIZE) has been created.\n"
2072 part_find 'part|crypt' || return 1
2073 PARTS="$(awk 'NF > 0 {print $0 " off"}' <<< "$PARTS")"
2074 dlg LVM_PARTS check "$_lvmnew" "\nSelect the partition(s) to use for the physical volume (PV)." $PARTS
2081 until [[ $VGROUP ]]; do
2082 dlg VGROUP input "$_lvmnew" "$_lvmvgname" "mygroup"
2083 if [[ -z $VGROUP ]]; then
2085 elif [[ ${VGROUP:0:1} == "/" || $VGROUP =~ \ |\' ]] || lsblk | grep -q "$VGROUP"; then
2086 msg "LVM Name Error" "$_lvmerrvgname"
2096 local txt="$1" default="mainvolume"
2097 (( VOL_COUNT > 1 )) && default="extravolume$VOL_COUNT"
2098 until [[ $VNAME ]]; do
2099 dlg VNAME input "$_lvmnew (LV:$VOL_COUNT)" "\n$txt" "$default"
2100 if [[ -z $VNAME ]]; then
2102 elif [[ ${VNAME:0:1} == "/" || $VNAME =~ \ |\' ]] || lsblk | grep -q "$VNAME"; then
2103 msg "LVM Name Error" "$_lvmerlvname"
2110 ###############################################################################
2116 check_background_install || return 1
2117 dlg choice menu "LUKS Encryption" "$_luksmenu" \
2118 "$_luksnew" "cryptsetup -q luksFormat" \
2119 "$_luksopen" "cryptsetup open --type luks" \
2120 "$_luksadv" "cryptsetup -q -s -c luksFormat" \
2121 "back" "Return to the main menu"
2124 "$_luksnew") luks_basic || return 1 ;;
2125 "$_luksopen") luks_open || return 1 ;;
2126 "$_luksadv") luks_advanced || return 1 ;;
2134 modprobe -a dm-mod dm_crypt >/dev/null 2>&1
2136 part_find 'part|crypt|lvm' || return 1
2138 if (( COUNT == 1 )); then
2139 LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
2141 dlg LUKS_PART menu "$_luksopen" "\nSelect which partition to open." $PARTS
2144 [[ $LUKS_PART ]] || return 1
2146 luks_pass "$_luksopen" || return 1
2147 msg "$_luksopen" "\nOpening encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0
2148 cryptsetup open --type luks "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR
2149 errshow "cryptsetup open --type luks $LUKS_PART $LUKS_NAME" || return 1
2150 LUKS='encrypted'; luks_show
2157 local t="$1" op="$2" v='' p='' p2=''
2159 until [[ $LUKS_PASS ]]; do
2163 dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " $t " \
2164 --mixedform "\nEnter the password to decrypt $ROOT_PART\n\nThis is needed to create a keyfile." 0 0 0 \
2165 "Password:" 1 1 '' 1 11 "$COLUMNS" 0 1 \
2166 "Password2:" 2 1 '' 2 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
2169 dialog --insecure --backtitle "$DIST Installer - $SYS - v$VER" --separator $'\n' --title " $t " --mixedform "$_luksomenu" 0 0 0 \
2170 "Name:" 1 1 "${LUKS_NAME:-cryptroot}" 1 7 "$COLUMNS" 0 0 \
2171 "Password:" 2 1 '' 2 11 "$COLUMNS" 0 1 \
2172 "Password2:" 3 1 '' 3 12 "$COLUMNS" 0 1 2>"$ANS" || return 1
2176 while read -r line; do
2192 if [[ -z $op && -z $n ]]; then
2193 msg "Name Empty" "\nEncrypted device name cannot be empty.\n\nPlease try again.\n" 2
2194 elif [[ -z $p || "$p" != "$p2" ]]; then
2195 [[ $op ]] || LUKS_NAME="$n"
2196 msg "Password Mismatch" "\nThe passwords entered do not match.\n\nPlease try again.\n" 2
2198 [[ $op ]] || LUKS_NAME="$n"
2209 msg "$_luksnew" "\nEncrypted partition opened and ready for mounting.\n\n$(lsblk -o NAME,MODEL,SIZE,TYPE,FSTYPE "$LUKS_PART")\n\n"
2214 modprobe -a dm-mod dm_crypt >/dev/null 2>&1
2216 part_find 'part|lvm' || return 1
2218 if [[ $AUTO_ROOT_PART ]]; then
2219 LUKS_PART="$AUTO_ROOT_PART"
2220 elif (( COUNT == 1 )); then
2221 LUKS_PART="$(awk 'NF > 0 {print $1}' <<< "$PARTS")"
2223 dlg LUKS_PART menu "$_luksnew" "\nSelect the partition you want to encrypt." $PARTS
2226 [[ $LUKS_PART ]] || return 1
2227 luks_pass "$_luksnew"
2232 luks_setup || return 1
2233 msg "$_luksnew" "\nCreating encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0
2234 cryptsetup -q luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2>$ERR
2235 errshow "cryptsetup -q luksFormat $LUKS_PART" || return 1
2236 cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR
2237 errshow "cryptsetup open $LUKS_PART $LUKS_NAME" || return 1
2238 LUKS='encrypted'; luks_show
2244 if [[ ! -e $MNT/crypto_keyfile.bin ]]; then
2245 # printf "Creating LUKS keyfile /crypto_keyfile.bin\n"
2247 n="$(lsblk -lno NAME,UUID,TYPE | awk "/$LUKS_UUID/"' && /part|crypt|lvm/ {print $1}')"
2248 local mkkey="dd bs=512 count=8 if=/dev/urandom of=/crypto_keyfile.bin"
2249 mkkey="$mkkey && chmod 000 /crypto_keyfile.bin"
2250 mkkey="$mkkey && cryptsetup luksAddKey /dev/$n /crypto_keyfile.bin <<< '$LUKS_PASS'"
2252 sed -i 's/FILES=()/FILES=(\/crypto_keyfile.bin)/g' $MNT/etc/mkinitcpio.conf 2>$ERR
2262 dlg cipher input "LUKS Encryption" "$_lukskey" "-s 512 -c aes-xts-plain64"
2263 [[ $cipher ]] || return 1
2264 msg "$_luksadv" "\nCreating encrypted partition: $LUKS_NAME\n\nDevice or volume used: $LUKS_PART\n" 0
2265 cryptsetup -q $cipher luksFormat "$LUKS_PART" <<< "$LUKS_PASS" 2>$ERR
2266 errshow "cryptsetup -q $cipher luksFormat $LUKS_PART" || return 1
2267 cryptsetup open "$LUKS_PART" "$LUKS_NAME" <<< "$LUKS_PASS" 2>$ERR
2268 errshow "cryptsetup open $LUKS_PART $LUKS_NAME" || return 1
2275 ###############################################################################
2280 [[ "$2" == *"$1"* ]] && printf "on" || printf "off"
2289 if [[ -d $MNT ]] && command cd /; then
2291 if (( exitcode == 127 )); then
2292 umount -l /run/archiso/bootmnt
2298 # restore custom linux console 0-15 colors when not rebooting
2299 if [[ $TERM == 'linux' ]]; then
2300 colors=("\e]P0191919" "\e]P1D15355" "\e]P2609960" "\e]P3FFCC66"
2301 "\e]P4255A9B" "\e]P5AF86C8" "\e]P62EC8D3" "\e]P7949494" "\e]P8191919" "\e]P9D15355"
2302 "\e]PA609960" "\e]PBFF9157" "\e]PC4E88CF" "\e]PDAF86C8" "\e]PE2ec8d3" "\e]PFE1E1E1")
2303 printf "%b" "${colors[@]}" && clear && unset col
2311 local var="$1" dialog_type="$2" title="$3" body="$4" n=0
2313 (( ($# / 2) > SHL )) && n=$SHL
2316 case "$dialog_type" in
2318 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --menu "$body" 0 0 $n "$@" 2>"$ANS" || return 1
2321 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --checklist "$body" 0 0 $n "$@" 2>"$ANS" || return 1
2327 if [[ $1 == 'limit' ]]; then
2328 dialog --backtitle "$DIST Installer - $SYS - v$VER" --max-input 63 --title " $title " --inputbox "$body" 0 0 "$def" 2>"$ANS" || return 1
2330 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --inputbox "$body" 0 0 "$def" 2>"$ANS" || return 1
2334 [[ -s "$ANS" ]] && printf -v "$var" "%s" "$(< "$ANS")"
2339 local title="$1" body="$2"
2341 if (( $# == 3 )); then
2342 dialog --backtitle "$DIST Installer - $SYS - v$VER" --sleep "$3" --title " $title " --infobox "$body\n" 0 0
2344 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --msgbox "$body\n" 0 0
2350 local title="$1" body="$2" yes='Yes' no='No'
2351 (( $# >= 3 )) && local yes="$3"
2352 (( $# >= 4 )) && local no="$4"
2354 if (( $# == 5 )); then
2355 dialog --backtitle "$DIST Installer - $SYS - v$VER" --defaultno --title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
2357 dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " $title " --yes-label "$yes" --no-label "$no" --yesno "$body\n" 0 0
2363 arch-chroot "$MNT" bash -c "$1"
2368 export PS4='| ${BASH_SOURCE} LINE:${LINENO} FUNC:${FUNCNAME[0]:+ ${FUNCNAME[0]}()} |> '
2377 printf "\n^C caught, cleaning up...\n"
2384 if [[ $COLUMNS -ge 110 && ${#str} -gt $((COLUMNS - 30)) ]]; then
2386 i = 2; p1 = p2 = p3 = p4 = ""; p1 = $1; q = int(NF / 4)
2387 for (; i <= q; i++) { p1 = p1 " " $i }
2388 for (; i <= q * 2; i++) { p2 = p2 " " $i }
2389 for (; i <= q * 3; i++) { p3 = p3 " " $i }
2390 for (; i <= NF; i++) { p4 = p4 " " $i }
2391 printf "%s\n %s\n %s\n %s", p1, p2, p3, p4
2393 printf "%s\n" "$str"
2394 elif [[ $str ]]; then
2395 printf "%s\n" "$str"
2402 (( exit_code == 0 )) && return 0
2404 local fatal=0 err=""
2405 err="$(sed 's/[^[:print:]]//g; s/\[[0-9\;:]*\?m//g; s/==> //g; s/] ERROR:/]\nERROR:/g' "$ERR")"
2406 (( $1 == 1 )) && { fatal=1; shift; }
2407 local txt="\nThe command exited abnormally:\n\n$1\n\n"
2410 txt+="With the following message:\n\n$err\n\n"
2412 txt+="With no error message:\n\n"
2415 if (( fatal == 1 )); then
2416 txt+="Errors at this stage are fatal and the install cannot continue.\n"
2418 txt+="Errors at this stage are non-fatal and can be either fixed or ignored depending on the error.\n"
2421 msg "Install Error" "$txt"
2423 if (( fatal == 1 )); then
2424 [[ -r $DBG && $TERM == 'linux' ]] && less "$DBG"
2433 msg "Broadcom Wireless Setup" "\nDetected chipset is Broadcom BCM4352\n\nDisabling bcma/b43 modules and loading wl module.\n" 1
2434 { rmmod wl; rmmod bcma; rmmod b43; rmmod ssb; modprobe wl; depmod -a; } >/dev/null 2>&1
2440 if [[ $1 -ge 0 ]] && ! grep -qw "$MNT" /proc/mounts; then
2441 msg "Not Mounted" "\nPartition(s) must be mounted first.\n" 2
2444 elif [[ $1 -ge 1 && -z $BOOTLDR ]]; then
2445 msg "No Bootloader" "\nBootloader must be selected first.\n" 2
2448 elif [[ $1 -ge 2 && (-z $NEWUSER || -z $USER_PASS) ]]; then
2449 msg "No User" "\nA user must be created first.\n" 2
2452 elif [[ $1 -ge 3 && -z $CONFIG_DONE ]]; then
2453 msg "Not Configured" "\nSystem configuration must be done first.\n" 2
2463 [[ -d $1 ]] && umount -R "$1" >/dev/null 2>&1
2469 msg "Network Connect" "\nVerifying network connection\n" 1
2470 curl -sIN --connect-timeout 5 'https://www.archlinux.org/' | sed '1q' | grep -q '200'
2475 if chk_connect; then
2478 if hash nmtui >/dev/null 2>&1; then
2480 [[ $TERM == 'linux' ]] && printf "%b" "\e]P1191919" "\e]P4191919"
2482 [[ $TERM == 'linux' ]] && printf "%b" "\e]P1D15355" "\e]P4255a9b"
2492 IGNORE_DEV="$(lsblk -lno NAME,MOUNTPOINT | awk '/\/run\/archiso\/bootmnt/ {sub(/[1-9]/, ""); print $1}')"
2494 if [[ $IGNORE_DEV ]]; then
2495 SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ && !'"/$IGNORE_DEV/"' {print "/dev/" $1 " " $2}')"
2497 SYS_DEVS="$(lsblk -lno NAME,SIZE,TYPE | awk '/disk/ {print "/dev/" $1 " " $2}')"
2500 if [[ -z $SYS_DEVS ]]; then
2501 msg "Device Error" "\nNo available devices...\n\nExiting..\n" 2
2506 while read -r line; do
2508 done <<< "$SYS_DEVS"
2515 elif grep -q 'AuthenticAMD' /proc/cpuinfo; then
2517 elif grep -q 'GenuineIntel' /proc/cpuinfo; then
2521 modprobe -q efivarfs >/dev/null 2>&1
2523 _prep="\nOnce a step is finished a step you will be returned here, if the step was successful the cursor will be advanced to the next step.\nIf a step is unsuccessful the cursor will be placed on the step required to advance (when possible).\n\nTo begin the install you should have:\n\n - A root (/) partition mounted."
2524 if [[ -d /sys/firmware/efi/efivars ]]; then
2526 grep -q /sys/firmware/efi/efivars /proc/mounts || mount -t efivarfs efivarfs /sys/firmware/efi/efivars
2527 _prep+="\n - An EFI boot partition mounted."
2531 _prep+="\n\nOnce finished mounting, a portion of the install can be done in the background while you continue configuring the system:\n"
2532 _prep+="\n - Choose the system bootloader.\n - Create a user and password."
2533 _prep+="\n - Basic system configuration, kernel, shell, login, packages, etc..\n\nOnce you're happy with the choices and the required steps are complete, the main install can be started."
2536 check_background_install()
2538 [[ $RSYNC_PID || $MIRROR_PID ]] || return 0
2539 msg "Install Running" "\nA background install process is currently running.\n" 2
2543 ###############################################################################
2546 if (( UID != 0 )); then
2547 msg "Not Root" "\nThis installer must be run as root or using sudo.\n\nExiting..\n" 2
2549 elif ! grep -qwm 1 'lm' /proc/cpuinfo; then
2550 msg "Not x86_64 Architecture" "\nThis installer only supports x86_64 architectures.\n\nExiting..\n" 2
2552 elif [[ $1 =~ (-d|--debug) ]]; then
2556 # trap ^C to perform cleanup
2562 msg "Welcome to the $DIST Installer" "\nThis will help you get $DIST setup on your system.\nHaving previous GNU/Linux and shell experience will be an asset, however we try our best to keep things simple.\n\nIf you are unsure about an option, a default will be listed or\nthe first selected option will usually be the default (excluding language and timezone).\n\n\nMenu Navigation:\n\n - Select items with the arrow keys or the option number.\n - Use [Space] to toggle options and [Enter] to confirm.\n - Switch between buttons 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"
2564 select_keymap || { clear; die 0; }
2566 if lspci -vnn -d 14e4: | grep -q 'BCM4352'; then
2570 if ! net_connect; then
2571 msg "Not Connected" "\nThis installer requires an active internet connection.\n\nExiting..\n" 2
2579 # vim:fdm=marker:fmr={,}