larbs

Luke's Auto-Rice Bootstrapping Scripts: Auto-Setup & Configure Arch Linux
Log | Files | Refs | README | LICENSE

larbs.sh (11055B)


      1 #!/bin/sh
      2 # Luke's Auto Rice Boostrapping Script (LARBS)
      3 # by Luke Smith <luke@lukesmith.xyz>
      4 # License: GNU GPLv3
      5 
      6 ### OPTIONS AND VARIABLES ###
      7 
      8 while getopts ":a:r:b:p:h" o; do case "${o}" in
      9 	h) printf "Optional arguments for custom use:\\n  -r: Dotfiles repository (local file or url)\\n  -p: Dependencies and programs csv (local file or url)\\n  -a: AUR helper (must have pacman-like syntax)\\n  -h: Show this message\\n" && exit ;;
     10 	r) dotfilesrepo=${OPTARG} && git ls-remote "$dotfilesrepo" || exit ;;
     11 	b) repobranch=${OPTARG} ;;
     12 	p) progsfile=${OPTARG} ;;
     13 	a) aurhelper=${OPTARG} ;;
     14 	*) printf "Invalid option: -%s\\n" "$OPTARG" && exit ;;
     15 esac done
     16 
     17 [ -z "$dotfilesrepo" ] && dotfilesrepo="https://github.com/lukesmithxyz/voidrice.git"
     18 [ -z "$progsfile" ] && progsfile="https://raw.githubusercontent.com/LukeSmithxyz/LARBS/master/progs.csv"
     19 [ -z "$aurhelper" ] && aurhelper="yay"
     20 [ -z "$repobranch" ] && repobranch="master"
     21 
     22 ### FUNCTIONS ###
     23 
     24 if type xbps-install >/dev/null 2>&1; then
     25 	installpkg(){ xbps-install -y "$1" >/dev/null 2>&1 ;}
     26 	grepseq="\"^[PGV]*,\""
     27 elif type apt >/dev/null 2>&1; then
     28 	installpkg(){ apt-get install -y "$1" >/dev/null 2>&1 ;}
     29 	grepseq="\"^[PGU]*,\""
     30 else
     31 	installpkg(){ pacman --noconfirm --needed -S "$1" >/dev/null 2>&1 ;}
     32 	grepseq="\"^[PGA]*,\""
     33 fi
     34 
     35 error() { clear; printf "ERROR:\\n%s\\n" "$1"; exit;}
     36 
     37 welcomemsg() { \
     38 	dialog --title "Welcome!" --msgbox "Welcome to Luke's Auto-Rice Bootstrapping Script!\\n\\nThis script will automatically install a fully-featured Linux desktop, which I use as my main machine.\\n\\n-Luke" 10 60
     39 	}
     40 
     41 selectdotfiles() { \
     42 	edition="$(dialog --title "Select LARBS version." --menu "Select which version of LARBS you wish to have as default:" 10 70 2 i3 "The classic version of LARBS using i3." dwm "The version of LARBS using suckless's dwm." custom "If you are supplying commandline options for LARBS." 3>&1 1>&2 2>&3 3>&1)" || error "User exited."
     43 	}
     44 
     45 getuserandpass() { \
     46 	# Prompts user for new username an password.
     47 	name=$(dialog --inputbox "First, please enter a name for the user account." 10 60 3>&1 1>&2 2>&3 3>&1) || exit
     48 	while ! echo "$name" | grep "^[a-z_][a-z0-9_-]*$" >/dev/null 2>&1; do
     49 		name=$(dialog --no-cancel --inputbox "Username not valid. Give a username beginning with a letter, with only lowercase letters, - or _." 10 60 3>&1 1>&2 2>&3 3>&1)
     50 	done
     51 	pass1=$(dialog --no-cancel --passwordbox "Enter a password for that user." 10 60 3>&1 1>&2 2>&3 3>&1)
     52 	pass2=$(dialog --no-cancel --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1)
     53 	while ! [ "$pass1" = "$pass2" ]; do
     54 		unset pass2
     55 		pass1=$(dialog --no-cancel --passwordbox "Passwords do not match.\\n\\nEnter password again." 10 60 3>&1 1>&2 2>&3 3>&1)
     56 		pass2=$(dialog --no-cancel --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1)
     57 	done ;}
     58 
     59 usercheck() { \
     60 	! (id -u "$name" >/dev/null) 2>&1 ||
     61 	dialog --colors --title "WARNING!" --yes-label "CONTINUE" --no-label "No wait..." --yesno "The user \`$name\` already exists on this system. LARBS can install for a user already existing, but it will \\Zboverwrite\\Zn any conflicting settings/dotfiles on the user account.\\n\\nLARBS will \\Zbnot\\Zn overwrite your user files, documents, videos, etc., so don't worry about that, but only click <CONTINUE> if you don't mind your settings being overwritten.\\n\\nNote also that LARBS will change $name's password to the one you just gave." 14 70
     62 	}
     63 
     64 preinstallmsg() { \
     65 	dialog --title "Let's get this party started!" --yes-label "Let's go!" --no-label "No, nevermind!" --yesno "The rest of the installation will now be totally automated, so you can sit back and relax.\\n\\nIt will take some time, but when done, you can relax even more with your complete system.\\n\\nNow just press <Let's go!> and the system will begin installation!" 13 60 || { clear; exit; }
     66 	}
     67 
     68 adduserandpass() { \
     69 	# Adds user `$name` with password $pass1.
     70 	dialog --infobox "Adding user \"$name\"..." 4 50
     71 	useradd -m -g wheel -s /bin/bash "$name" >/dev/null 2>&1 ||
     72 	usermod -a -G wheel "$name" && mkdir -p /home/"$name" && chown "$name":wheel /home/"$name"
     73 	echo "$name:$pass1" | chpasswd
     74 	unset pass1 pass2 ;}
     75 
     76 refreshkeys() { \
     77 	dialog --infobox "Refreshing Arch Keyring..." 4 40
     78 	pacman --noconfirm -Sy archlinux-keyring >/dev/null 2>&1
     79 	}
     80 
     81 newperms() { # Set special sudoers settings for install (or after).
     82 	sed -i "/#LARBS/d" /etc/sudoers
     83 	echo "$* #LARBS" >> /etc/sudoers ;}
     84 
     85 manualinstall() { # Installs $1 manually if not installed. Used only for AUR helper here.
     86 	[ -f "/usr/bin/$1" ] || (
     87 	dialog --infobox "Installing \"$1\", an AUR helper..." 4 50
     88 	cd /tmp || exit
     89 	rm -rf /tmp/"$1"*
     90 	curl -sO https://aur.archlinux.org/cgit/aur.git/snapshot/"$1".tar.gz &&
     91 	sudo -u "$name" tar -xvf "$1".tar.gz >/dev/null 2>&1 &&
     92 	cd "$1" &&
     93 	sudo -u "$name" makepkg --noconfirm -si >/dev/null 2>&1
     94 	cd /tmp || return) ;}
     95 
     96 maininstall() { # Installs all needed programs from main repo.
     97 	dialog --title "LARBS Installation" --infobox "Installing \`$1\` ($n of $total). $1 $2" 5 70
     98 	installpkg "$1"
     99 	}
    100 
    101 gitmakeinstall() {
    102 	dir=$(mktemp -d)
    103 	dialog --title "LARBS Installation" --infobox "Installing \`$(basename "$1")\` ($n of $total) via \`git\` and \`make\`. $(basename "$1") $2" 5 70
    104 	git clone --depth 1 "$1" "$dir" >/dev/null 2>&1
    105 	cd "$dir" || exit
    106 	make >/dev/null 2>&1
    107 	make install >/dev/null 2>&1
    108 	cd /tmp || return ;}
    109 
    110 aurinstall() { \
    111 	dialog --title "LARBS Installation" --infobox "Installing \`$1\` ($n of $total) from the AUR. $1 $2" 5 70
    112 	echo "$aurinstalled" | grep "^$1$" >/dev/null 2>&1 && return
    113 	sudo -u "$name" $aurhelper -S --noconfirm "$1" >/dev/null 2>&1
    114 	}
    115 
    116 pipinstall() { \
    117 	dialog --title "LARBS Installation" --infobox "Installing the Python package \`$1\` ($n of $total). $1 $2" 5 70
    118 	command -v pip || installpkg python-pip >/dev/null 2>&1
    119 	yes | pip install "$1"
    120 	}
    121 
    122 installationloop() { \
    123 	([ -f "$progsfile" ] && cp "$progsfile" /tmp/progs.csv) || curl -Ls "$progsfile" | sed '/^#/d' | eval grep "$grepseq" > /tmp/progs.csv
    124 	total=$(wc -l < /tmp/progs.csv)
    125 	aurinstalled=$(pacman -Qm | awk '{print $1}')
    126 	while IFS=, read -r tag program comment; do
    127 		n=$((n+1))
    128 		echo "$comment" | grep "^\".*\"$" >/dev/null 2>&1 && comment="$(echo "$comment" | sed "s/\(^\"\|\"$\)//g")"
    129 		case "$tag" in
    130 			"A") aurinstall "$program" "$comment" ;;
    131 			"G") gitmakeinstall "$program" "$comment" ;;
    132 			"P") pipinstall "$program" "$comment" ;;
    133 			*) maininstall "$program" "$comment" ;;
    134 		esac
    135 	done < /tmp/progs.csv ;}
    136 
    137 putgitrepo() { # Downlods a gitrepo $1 and places the files in $2 only overwriting conflicts
    138 	dialog --infobox "Downloading and installing config files..." 4 60
    139 	[ -z "$3" ] && branch="master" || branch="$repobranch"
    140 	dir=$(mktemp -d)
    141 	[ ! -d "$2" ] && mkdir -p "$2" && chown -R "$name:wheel" "$2"
    142 	chown -R "$name:wheel" "$dir"
    143 	sudo -u "$name" git clone -b "$branch" --depth 1 "$1" "$dir/gitrepo" >/dev/null 2>&1 &&
    144 	sudo -u "$name" cp -rfT "$dir/gitrepo" "$2"
    145 	}
    146 
    147 systembeepoff() { dialog --infobox "Getting rid of that retarded error beep sound..." 10 50
    148 	rmmod pcspkr
    149 	echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf ;}
    150 
    151 finalize(){ \
    152 	dialog --infobox "Preparing welcome message..." 4 50
    153 	echo "exec_always --no-startup-id notify-send -i ~/.local/share/larbs/larbs.png 'Welcome to LARBS:' 'Press Super+F1 for the manual.' -t 10000"  >> "/home/$name/.config/i3/config"
    154 	dialog --title "All done!" --msgbox "Congrats! Provided there were no hidden errors, the script completed successfully and all the programs and configuration files should be in place.\\n\\nTo run the new graphical environment, log out and log back in as your new user, then run the command \"startx\" to start the graphical environment (it will start automatically in tty1).\\n\\n.t Luke" 12 80
    155 	}
    156 
    157 ### THE ACTUAL SCRIPT ###
    158 
    159 ### This is how everything happens in an intuitive format and order.
    160 
    161 # Check if user is root on Arch distro. Install dialog.
    162 installpkg dialog ||  error "Are you sure you're running this as the root user and have an internet connection?"
    163 
    164 # Welcome user and pick dotfiles.
    165 welcomemsg || error "User exited."
    166 selectdotfiles || error "User exited."
    167 
    168 # Get and verify username and password.
    169 getuserandpass || error "User exited."
    170 
    171 # Give warning if user already exists.
    172 usercheck || error "User exited."
    173 
    174 # Last chance for user to back out before install.
    175 preinstallmsg || error "User exited."
    176 
    177 ### The rest of the script requires no user input.
    178 
    179 adduserandpass || error "Error adding username and/or password."
    180 
    181 # Refresh Arch keyrings.
    182 # refreshkeys || error "Error automatically refreshing Arch keyring. Consider doing so manually."
    183 
    184 dialog --title "LARBS Installation" --infobox "Installing \`basedevel\` and \`git\` for installing other software." 5 70
    185 installpkg base-devel
    186 installpkg git
    187 [ -f /etc/sudoers.pacnew ] && cp /etc/sudoers.pacnew /etc/sudoers # Just in case
    188 
    189 # Allow user to run sudo without password. Since AUR programs must be installed
    190 # in a fakeroot environment, this is required for all builds with AUR.
    191 newperms "%wheel ALL=(ALL) NOPASSWD: ALL"
    192 
    193 # Make pacman and yay colorful and adds eye candy on the progress bar because why not.
    194 grep "^Color" /etc/pacman.conf >/dev/null || sed -i "s/^#Color/Color/" /etc/pacman.conf
    195 grep "ILoveCandy" /etc/pacman.conf >/dev/null || sed -i "/#VerbosePkgLists/a ILoveCandy" /etc/pacman.conf
    196 
    197 # Use all cores for compilation.
    198 sed -i "s/-j2/-j$(nproc)/;s/^#MAKEFLAGS/MAKEFLAGS/" /etc/makepkg.conf
    199 
    200 manualinstall $aurhelper || error "Failed to install AUR helper."
    201 
    202 # The command that does all the installing. Reads the progs.csv file and
    203 # installs each needed program the way required. Be sure to run this only after
    204 # the user has been created and has priviledges to run sudo without a password
    205 # and all build dependencies are installed.
    206 installationloop
    207 
    208 # Install the dotfiles in the user's home directory
    209 putgitrepo "$dotfilesrepo" "/home/$name" "$repobranch"
    210 rm -f "/home/$name/README.md" "/home/$name/LICENSE"
    211 
    212 # Most important command! Get rid of the beep!
    213 systembeepoff
    214 
    215 # This line, overwriting the `newperms` command above will allow the user to run
    216 # serveral important commands, `shutdown`, `reboot`, updating, etc. without a password.
    217 newperms "%wheel ALL=(ALL) ALL #LARBS
    218 %wheel ALL=(ALL) NOPASSWD: /usr/bin/shutdown,/usr/bin/reboot,/usr/bin/systemctl suspend,/usr/bin/wifi-menu,/usr/bin/mount,/usr/bin/umount,/usr/bin/pacman -Syu,/usr/bin/pacman -Syyu,/usr/bin/packer -Syu,/usr/bin/packer -Syyu,/usr/bin/systemctl restart NetworkManager,/usr/bin/rc-service NetworkManager restart,/usr/bin/pacman -Syyu --noconfirm,/usr/bin/loadkeys,/usr/bin/yay,/usr/bin/pacman -Syyuw --noconfirm"
    219 
    220 # Make zsh the default shell for the user
    221 sed -i "s/^$name:\(.*\):\/bin\/.*/$name:\1:\/bin\/zsh/" /etc/passwd
    222 
    223 # dbus UUID must be generated for Artix runit
    224 dbus-uuidgen > /var/lib/dbus/machine-id
    225 
    226 # Let LARBS know the WM it's supposed to run.
    227 echo "$edition" > "/home/$name/.local/share/larbs/wm"; chown "$name:wheel" "/home/$name/.local/share/larbs/wm"
    228 
    229 # Last message! Install complete!
    230 finalize
    231 clear