diff --git a/installer b/installer index 65e9cd3..9207585 100755 --- a/installer +++ b/installer @@ -160,17 +160,6 @@ typeset -a ISO_PKGS=( "wireless_tools" "wpa_supplicant" "wvdial" - -# are these needed? -# "xl2tpd" -# "vpnc" -# "smartmontools" -# "geoclue2" -# "clonezilla" -# "darkhttpd" -# "linux-atm" -# "ndisc6" -# "netctl" ) # } SYS_MEM="$(awk '/MemTotal/ {print int($2 / 1024) "M"}' /proc/meminfo)" @@ -308,7 +297,7 @@ declare -A PKG_EXT=( # Basics (somewhat in order) _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" _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" -_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 be advanced 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 you're happy with the choices and the required steps are complete, selecting the final step will begin the install." +_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 mounting is complete a background process will install the base system while you continue.\nOnce all required steps are complete, selecting the last step will finalize the install." _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." _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" @@ -354,7 +343,7 @@ _lvmdelask="\nConfirm deletion of volume group(s) and logical volume(s).\n\nDele # Errors _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" -_errpart="\nYou need to create the partition(s) first.\n\n\nBIOS systems require at least one partition (ROOT).\n\nUEFI systems require at least two (ROOT and EFI).\n" +_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" _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" _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" @@ -381,11 +370,11 @@ main() 1 "* Select bootloader" \ 2 "* Username and password" \ 3 "* System configuration" \ - 4 "Select window manager or desktop" \ + 4 "Select WM(s) and/or DE(s)" \ 5 "Select additional packages" \ - 6 "Run a command on the installed system" \ - 7 "View configuration and command selections" \ - 8 "* Confirm choices and finish installation" 2> "$ANS" + 6 "Enter a post-install command to run" \ + 7 "View installation configuration" \ + 8 "* Confirm choices and complete install" 2> "$ANS" read -r SEL < "$ANS" case $SEL in @@ -404,39 +393,37 @@ main() tput civis dialog --backtitle "$DIST Installer - $SYS - v$VER" --title " Prepare " \ --default-item $SEL --cancel-label 'Exit' --menu "$_prep" 0 0 0 \ - 1 "Device tree" \ - 2 "Partitioning" \ - 3 "LUKS encryption" \ - 4 "Logical volume management" \ - 5 "* Mount partitions" \ - 6 "* Select bootloader" \ - 7 "* Username and password" \ - 8 "* System configuration" \ - 9 "Select window manager or desktop" \ - 10 "Select additional packages" \ - 11 "Run a command on the installed system" \ - 12 "View configuration and command selections" \ - 13 "* Confirm choices and finish installation" 2> "$ANS" + 1 "Device management" \ + 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" read -r SEL < "$ANS" - [[ -z $WARN && $SEL =~ (2|5) ]] && { msg "Data Warning" "$_warn"; WARN=true; } + if [[ -z $WARN && $SEL == 2 ]]; then + msg "Data Warning" "$_warn" + WARN=true + fi case $SEL in - 1) part_show ;; - 2) part_menu || (( SEL-- )) ;; - 3) luks_menu || (( SEL-- )) ;; - 4) lvm_menu || (( SEL-- )) ;; - 5) mount_menu || (( SEL-- )) ;; - 6) prechecks 0 && { select_bootldr || (( SEL-- )); } ;; - 7) prechecks 1 && { select_mkuser || (( SEL-- )); } ;; - 8) prechecks 2 && { select_config || (( SEL-- )); } ;; - 9) prechecks 3 && { select_sessions || (( SEL-- )); } ;; - 10) prechecks 3 && { select_packages || (( SEL-- )); } ;; - 11) prechecks 3 && select_usercmd ;; - 12) prechecks 3 && select_show ;; - 13) prechecks 3 && install_main ;; + 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 ;; *) yesno "Exit" "\nUnmount partitions (if any) and exit the installer?\n" && die 0 esac fi + } select_show() @@ -864,7 +851,41 @@ select_packages() } ############################################################################### -# partitioning menus +# 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 + dlg DEVMNG_OPT menu "Device Management" "\nSelect an operation from the list below.$txt" \ + 'view' 'View the device tree output from lsblk' \ + 'part' 'Change the partition layout of a device' \ + 'luks' 'Setup LUKS encryption on a partition or LVM' \ + 'lvm' 'Setup logical volume management on partition(s)' \ + 'Back' "$back" || return 0 + + if [[ $DEVMNG_OPT == 'Back' ]]; then + 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 # non-essential partitioning helpers called by the user when using the optional # partition menu and selecting a device to edit @@ -879,7 +900,7 @@ part_menu() while :; do choice="" - dlg choice menu "Edit Partitions" "$_part\n\n$(lsblk -no NAME,MODEL,SIZE,FSTYPE,LABEL "$device")" \ + 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" \ @@ -887,7 +908,7 @@ part_menu() "gparted 'A gui front end to parted'") \ "fdisk" "Dialog-driven creation and manipulation of partitions" \ "gdisk" "A text-mode partitioning tool that works on GUID Partition Table (GPT) disks" \ - "done" "Return to the main menu" + "Back" "Return to the device management menu" if [[ -z $choice || $choice == 'done' ]]; then return 0 @@ -1209,7 +1230,13 @@ mount_menu() msg "Mount Menu" "\nGathering device and partition information.\n" 1 lvm_detect umount_dir "$MNT" - part_find 'part|lvm|crypt' || { SEL=2; return 1; } + if ! part_find 'part|lvm|crypt'; then + dev_menu "$_errpart" + if ! part_find 'part|lvm|crypt'; then + SEL=0 + return 1 + fi + fi [[ $LUKS && $LUKS_PART ]] && part_countdec $LUKS_PART [[ $LVM && $LVM_PARTS ]] && part_countdec $LVM_PARTS select_root || { ROOT=''; return 1; } @@ -1540,7 +1567,7 @@ install_main() install_login # changing distro name? - if grep -q 'ArchLabs' "$MNT/etc/lsb-release"; then + if grep -q 'ArchLabs' "$MNT/etc/lsb-release" && [[ $DIST != 'ArchLabs' ]]; then sed -i "s/ArchLabs/$DIST/g" "$MNT/etc/lsb-release" sed -i "s/ArchLabs/$DIST/g" "$MNT/etc/os-release" else @@ -1604,17 +1631,7 @@ install_base() mkdir -pv "$MNT/etc/default" mkdir -pv "$MNT/etc/X11/xorg.conf.d/" - if [[ $PACSTRAP == 1 ]]; then - cp -vf /etc/modprobe.d/* "$MNT/etc/modprobe.d/" - cp -vf /etc/X11/xorg.conf.d/* "$MNT/etc/X11/xorg.conf.d/" - # we have some customizations in /etc on the iso we want to preserve - if [[ $DIST == "ArchLabs" ]]; then - 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" - fi - else + if [[ $PACSTRAP == 0 ]]; then # remove archiso files when copying iso rm -rf "$MNT/etc/mkinitcpio-archiso.conf" find "$MNT/usr/lib/initcpio" -name 'archiso*' -type f -delete @@ -1632,6 +1649,14 @@ install_base() 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 + 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" fi # copy network settings @@ -1639,13 +1664,10 @@ install_base() [[ -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/" - # Stop pacman complaining + # stop pacman complaining chrun 'mkdir -p /var/lib/pacman/sync' chrun 'touch /var/lib/pacman/sync/{core.db,extra.db,community.db}' - # 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" - echo "LANG=$LOCALE" > "$MNT/etc/locale.conf" cp -fv "$MNT/etc/locale.conf" "$MNT/etc/default/locale" sed -i "s/#en_US.UTF-8/en_US.UTF-8/g; s/#${LOCALE}/${LOCALE}/g" "$MNT/etc/locale.gen" @@ -1798,7 +1820,7 @@ install_bootldr() if [[ $SWAP == /dev/mapper* ]]; then RESUME="resume=$SWAP " elif [[ $SWAP == "/swapfile" ]]; then - RESUME="resume=$ROOT_ID resume_offset=$(filefrag -v "${MNT}$SWAP" | awk '{ if ($1=="0:") { gsub(/\./, ""); print $4 } }') " + RESUME="resume=$ROOT_ID resume_offset=$(filefrag -v "${MNT}$SWAP" | awk '{if ($1=="0:") {gsub(/\./, ""); print $4}}') " else RESUME="resume=$uuid_type=$(blkid -s $uuid_type -o value "$SWAP") " fi @@ -1853,27 +1875,27 @@ install_packages() done if [[ $PACSTRAP -eq 1 ]]; then - 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") + 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') if [[ $BTRFS_MNT ]] || grep -qi 'btrfs' <<< "$blk"; then - inpkg+=("btrfs-progs") + inpkg+=('btrfs-progs') fi + if pacman -Qq archlabs-installer >/dev/null 2>&1; then + rmpkg+=('archlabs-installer') + else + rm -fv "$MNT/usr/bin/installer" + fi + [[ $NEWSHELL == 'zsh' ]] || rmpkg+=('zsh') fi - [[ $INSTALL_WMS =~ dwm ]] && inpkg+=("git") - [[ $NEWSHELL == "bash" ]] && inpkg+=("bash-completion") - [[ $PACSTRAP != 1 ]] && pacman -Qq archlabs-installer >/dev/null 2>&1 && rmpkg+=("archlabs-installer") - - if [[ $NEWSHELL == 'zsh' ]]; then - inpkg+=("zsh-completions" "bash-completion") - elif [[ $PACSTRAP != 1 ]]; then - rmpkg+=("zsh") - fi + [[ $INSTALL_WMS =~ dwm ]] && inpkg+=('git') + [[ $NEWSHELL == 'zsh' ]] && inpkg+=('zsh-completions') + [[ $NEWSHELL =~ (bash|zsh) ]] && inpkg+=('bash-completion') # remove the packages we don't want on the installed system [[ ${rmpkg[*]} ]] && chrun "pacman -Rnsc ${rmpkg[*]} --noconfirm" @@ -2430,14 +2452,14 @@ prerun_systemd-boot() btrfs_name() { local txt="$1" - local match="$2" + local exists="$2" SUBVOL='' until [[ $SUBVOL ]]; do dlg SUBVOL input "Subvolume Name" "$txt" || return 1 if [[ -z $SUBVOL ]]; then return 1 - elif [[ $SUBVOL =~ \ |\' || $match == *"$SUBVOL"* ]]; then + elif [[ $SUBVOL =~ \ |\' || $exists == *"$SUBVOL"* ]]; then msg "Subvolume Name Error" "$_btrfserrname" SUBVOL='' fi @@ -2456,10 +2478,12 @@ btrfs_subvols() [[ $mntp == "$MNT" ]] && BTRFS_MNT="rootflags=subvol=$mvol" btrfs subvolume create "$mntp/$mvol" > /dev/null 2> "$ERR" errshow 0 "btrfs subvolume create $mntp/$mvol" || return 1 + umount_dir "$mntp" || return 1 select_mntopts 'btrfs' && [[ $MNT_OPTS ]] && MNT_OPTS+=',' - mount -o ${MNT_OPTS}subvol=${mvol} "$part" "$mntp" 2> "$ERR" - errshow 0 "mount -o ${MNT_OPTS}subvol=${mvol} $part $mntp" || return 1 + mount -o ${MNT_OPTS}subvol="$mvol" "$part" "$mntp" 2> "$ERR" + errshow 0 "mount -o ${MNT_OPTS}subvol=$mvol $part $mntp" || return 1 + btrfs_extsubvols "$mntp" "$mvol" || return 1 msg "Btrfs Setup Complete" "\nCreated subvolumes:\n\n$(ls -R "$mntp/$mvol")" } @@ -2501,7 +2525,7 @@ lvm_menu() "$_lvmnew" "vgcreate -f, lvcreate -L -n" \ "$_lvmdel" "vgremove -f" \ "$_lvmdelall" "lvrmeove, vgremove, pvremove -f" \ - "Back" "Return to the main menu" + "Back" "Return to the device management menu" case "$choice" in "$_lvmnew") lvm_create && break ;; "$_lvmdel") lvm_delgroup && yesno "$_lvmdel" "$_lvmdelask" && vgremove -f "$DEL_VG" > /dev/null 2>&1 ;; @@ -2537,10 +2561,12 @@ lvm_create() 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - [[ $VOL_COUNT ]] || return 1 lvm_extra_lvs || return 1 + lvm_volume_name "$_lvmlvname\nNOTE: This LV will use up all remaining space in the volume group (${VGROUP_MB}MB)" || return 1 msg "$_lvmnew (LV:$VOL_COUNT)" "\nCreating volume $VNAME from remaining space in $VGROUP\n" 0 lvcreate -l +100%FREE "$VGROUP" -n "$VNAME" > /dev/null 2> "$ERR" errshow 0 "lvcreate -l +100%FREE $VGROUP -n $VNAME" || return 1 + LVM='logical volume' sleep 0.5 txt="\nDone, volume: $VGROUP-$VNAME (${VOLUME_SIZE:-${VGROUP_MB}MB}) has been created.\n" @@ -2668,9 +2694,11 @@ lvm_extra_lvs() while (( VOL_COUNT > 1 )); do lvm_volume_name "$_lvmlvname" || return 1 lvm_lv_size || return 1 + msg "$_lvmnew (LV:$VOL_COUNT)" "\nCreating a $VOLUME_SIZE volume $VNAME in $VGROUP\n" 0 lvcreate -L "$VOLUME_SIZE" "$VGROUP" -n "$VNAME" > /dev/null 2> "$ERR" errshow 0 "lvcreate -L '$VOLUME_SIZE' '$VGROUP' -n '$VNAME'" || return 1 + msg "$_lvmnew (LV:$VOL_COUNT)" "\nDone, logical volume (LV) $VNAME ($VOLUME_SIZE) has been created.\n" (( VOL_COUNT-- )) done @@ -2727,12 +2755,12 @@ luks_menu() "$_luksnew" "cryptsetup -q luksFormat" \ "$_luksopen" "cryptsetup open --type luks" \ "$_luksadv" "cryptsetup -q -s -c luksFormat" \ - "Back" "Return to the main menu" + "Back" "Return to the device management menu" case "$choice" in - "$_luksnew") luks_basic || return 1 ;; - "$_luksopen") luks_open || return 1 ;; - "$_luksadv") luks_advanced || return 1 ;; + "$_luksnew") luks_basic || return 1 ;; + "$_luksopen") luks_open || return 1 ;; + "$_luksadv") luks_advanced || return 1 ;; esac return 0 @@ -2955,9 +2983,9 @@ live() install_mirrorlist al_repo "/etc/pacman.conf" pacman -Syyu --noconfirm || die 1 - rm -rf /var/cache/pacman/pkg/* + rm -rf /var/cache/pacman/pkg/* # */ pacman -S ${BASE_PKGS[*]} xorg-xinit --needed --noconfirm || die 1 - rm -rf /var/cache/pacman/pkg/* + rm -rf /var/cache/pacman/pkg/* # */ case "$ses" in $WM_PKG_SES) pacman -S "$ses" ${WM_PKGS[*]} ${WM_EXT[$ses]} --needed --noconfirm || die 1 @@ -2970,10 +2998,8 @@ live() install_suckless "/root" nochroot ;; esac - rm -rf /var/cache/pacman/pkg/* - [[ $VM == 'oracle' ]] && pacman -S virtualbox-guest-utils virtualbox-guest-modules-arch --needed --noconfirm pacman -Scc --noconfirm - rm -rf /var/cache/pacman/pkg/* + rm -rf /var/cache/pacman/pkg/* # */ cp -rfT /etc/skel /root install_tearfree "/etc/X11/xorg.conf.d" case "$ses" in @@ -3140,16 +3166,36 @@ prechecks() if (( $1 >= 0 )) && ! grep -q " $MNT " /proc/mounts; then msg "Not Mounted" "\nPartition(s) must be mounted first.\n" 2 - SEL=4 i=0 + if [[ $NOMOUNT ]]; then + die 1 + else + SEL=1 + fi + i=0 elif [[ $1 -ge 1 && -z $BOOTLDR ]]; then msg "No Bootloader" "\nBootloader must be selected first.\n" 2 - SEL=5 i=0 + if [[ $NOMOUNT ]]; then + SEL=0 + else + SEL=2 + fi + i=0 elif [[ $1 -ge 2 && (-z $NEWUSER || -z $USER_PASS) ]]; then msg "No User" "\nA user must be created first.\n" 2 - SEL=6 i=0 + if [[ $NOMOUNT ]]; then + SEL=1 + else + SEL=3 + fi + i=0 elif [[ $1 -ge 3 && -z $CONFIG_DONE ]]; then msg "No Config" "\nSystem configuration must be done first.\n" 2 - SEL=7 i=0 + if [[ $NOMOUNT ]]; then + SEL=2 + else + SEL=4 + fi + i=0 fi (( i )) # return code } @@ -3367,9 +3413,11 @@ fi # check for update once if [[ ! -f /tmp/new ]]; then msg "Installer Update" "\nChecking for newer installer versions.\n" 1 - if curl -fsSL https://bitbucket.org/archlabslinux/installer/raw/master/installer -o /tmp/new; then + if curl -fsSL 'https://bitbucket.org/archlabslinux/installer/raw/master/installer' -o /tmp/new; then if (( $(vercmp "$(awk -F= '/^VER=/ {print $2}' /tmp/new)" "$VER") > 0 )); then - cp /tmp/new /usr/bin/installer && exec installer "$@" + cp /tmp/new /usr/bin/installer + chmod +x /usr/bin/installer + exec /usr/bin/installer "$@" die fi else