karbs

my fork of LARBS with my builds of suckless and dotfiles
git clone git://git.kocotian.pl/karbs.git
Log | Files | Refs | README | LICENSE

larbs.sh (11904B)


      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 1 ;;
     10 	r) dotfilesrepo=${OPTARG} && git ls-remote "$dotfilesrepo" || exit 1 ;;
     11 	b) repobranch=${OPTARG} ;;
     12 	p) progsfile=${OPTARG} ;;
     13 	a) aurhelper=${OPTARG} ;;
     14 	*) printf "Invalid option: -%s\\n" "$OPTARG" && exit 1 ;;
     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 installpkg(){ pacman --noconfirm --needed -S "$1" >/dev/null 2>&1 ;}
     25 
     26 error() { clear; printf "ERROR:\\n%s\\n" "$1" >&2; exit 1;}
     27 
     28 welcomemsg() { \
     29 	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
     30 
     31 	dialog --colors --title "Important Note!" --yes-label "All ready!" --no-label "Return..." --yesno "Be sure the computer you are using has current pacman updates and refreshed Arch keyrings.\\n\\nIf it does not, the installation of some programs might fail." 8 70
     32 	}
     33 
     34 getuserandpass() { \
     35 	# Prompts user for new username an password.
     36 	name=$(dialog --inputbox "First, please enter a name for the user account." 10 60 3>&1 1>&2 2>&3 3>&1) || exit 1
     37 	while ! echo "$name" | grep -q "^[a-z_][a-z0-9_-]*$"; do
     38 		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)
     39 	done
     40 	pass1=$(dialog --no-cancel --passwordbox "Enter a password for that user." 10 60 3>&1 1>&2 2>&3 3>&1)
     41 	pass2=$(dialog --no-cancel --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1)
     42 	while ! [ "$pass1" = "$pass2" ]; do
     43 		unset pass2
     44 		pass1=$(dialog --no-cancel --passwordbox "Passwords do not match.\\n\\nEnter password again." 10 60 3>&1 1>&2 2>&3 3>&1)
     45 		pass2=$(dialog --no-cancel --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1)
     46 	done ;}
     47 
     48 usercheck() { \
     49 	! { id -u "$name" >/dev/null 2>&1; } ||
     50 	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
     51 	}
     52 
     53 preinstallmsg() { \
     54 	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 1; }
     55 	}
     56 
     57 adduserandpass() { \
     58 	# Adds user `$name` with password $pass1.
     59 	dialog --infobox "Adding user \"$name\"..." 4 50
     60 	useradd -m -g wheel -s /bin/zsh "$name" >/dev/null 2>&1 ||
     61 	usermod -a -G wheel "$name" && mkdir -p /home/"$name" && chown "$name":wheel /home/"$name"
     62 	repodir="/home/$name/.local/src"; mkdir -p "$repodir"; chown -R "$name":wheel "$(dirname "$repodir")"
     63 	echo "$name:$pass1" | chpasswd
     64 	unset pass1 pass2 ;}
     65 
     66 refreshkeys() { \
     67 	dialog --infobox "Refreshing Arch Keyring..." 4 40
     68 	pacman -Q artix-keyring >/dev/null 2>&1 && pacman --noconfirm -S artix-keyring >/dev/null 2>&1
     69 	pacman --noconfirm -S archlinux-keyring >/dev/null 2>&1
     70 	}
     71 
     72 newperms() { # Set special sudoers settings for install (or after).
     73 	sed -i "/#LARBS/d" /etc/sudoers
     74 	echo "$* #LARBS" >> /etc/sudoers ;}
     75 
     76 manualinstall() { # Installs $1 manually if not installed. Used only for AUR helper here.
     77 	[ -f "/usr/bin/$1" ] || (
     78 	dialog --infobox "Installing \"$1\", an AUR helper..." 4 50
     79 	cd /tmp || exit 1
     80 	rm -rf /tmp/"$1"*
     81 	curl -sO https://aur.archlinux.org/cgit/aur.git/snapshot/"$1".tar.gz &&
     82 	sudo -u "$name" tar -xvf "$1".tar.gz >/dev/null 2>&1 &&
     83 	cd "$1" &&
     84 	sudo -u "$name" makepkg --noconfirm -si >/dev/null 2>&1
     85 	cd /tmp || return 1) ;}
     86 
     87 maininstall() { # Installs all needed programs from main repo.
     88 	dialog --title "LARBS Installation" --infobox "Installing \`$1\` ($n of $total). $1 $2" 5 70
     89 	installpkg "$1"
     90 	}
     91 
     92 gitmakeinstall() {
     93 	progname="$(basename "$1" .git)"
     94 	dir="$repodir/$progname"
     95 	dialog --title "LARBS Installation" --infobox "Installing \`$progname\` ($n of $total) via \`git\` and \`make\`. $(basename "$1") $2" 5 70
     96 	sudo -u "$name" git clone --depth 1 "$1" "$dir" >/dev/null 2>&1 || { cd "$dir" || return 1 ; sudo -u "$name" git pull --force origin master;}
     97 	cd "$dir" || exit 1
     98 	make >/dev/null 2>&1
     99 	make install >/dev/null 2>&1
    100 	cd /tmp || return 1 ;}
    101 
    102 aurinstall() { \
    103 	dialog --title "LARBS Installation" --infobox "Installing \`$1\` ($n of $total) from the AUR. $1 $2" 5 70
    104 	echo "$aurinstalled" | grep -q "^$1$" && return 1
    105 	sudo -u "$name" $aurhelper -S --noconfirm "$1" >/dev/null 2>&1
    106 	}
    107 
    108 pipinstall() { \
    109 	dialog --title "LARBS Installation" --infobox "Installing the Python package \`$1\` ($n of $total). $1 $2" 5 70
    110 	[ -x "$(command -v "pip")" ] || installpkg python-pip >/dev/null 2>&1
    111 	yes | pip install "$1"
    112 	}
    113 
    114 installationloop() { \
    115 	([ -f "$progsfile" ] && cp "$progsfile" /tmp/progs.csv) || curl -Ls "$progsfile" | sed '/^#/d' > /tmp/progs.csv
    116 	total=$(wc -l < /tmp/progs.csv)
    117 	aurinstalled=$(pacman -Qqm)
    118 	while IFS=, read -r tag program comment; do
    119 		n=$((n+1))
    120 		echo "$comment" | grep -q "^\".*\"$" && comment="$(echo "$comment" | sed "s/\(^\"\|\"$\)//g")"
    121 		case "$tag" in
    122 			"A") aurinstall "$program" "$comment" ;;
    123 			"G") gitmakeinstall "$program" "$comment" ;;
    124 			"P") pipinstall "$program" "$comment" ;;
    125 			*) maininstall "$program" "$comment" ;;
    126 		esac
    127 	done < /tmp/progs.csv ;}
    128 
    129 putgitrepo() { # Downloads a gitrepo $1 and places the files in $2 only overwriting conflicts
    130 	dialog --infobox "Downloading and installing config files..." 4 60
    131 	[ -z "$3" ] && branch="master" || branch="$repobranch"
    132 	dir=$(mktemp -d)
    133 	[ ! -d "$2" ] && mkdir -p "$2"
    134 	chown -R "$name":wheel "$dir" "$2"
    135 	sudo -u "$name" git clone --recursive -b "$branch" --depth 1 "$1" "$dir" >/dev/null 2>&1
    136 	sudo -u "$name" cp -rfT "$dir" "$2"
    137 	}
    138 
    139 systembeepoff() { dialog --infobox "Getting rid of that retarded error beep sound..." 10 50
    140 	rmmod pcspkr
    141 	echo "blacklist pcspkr" > /etc/modprobe.d/nobeep.conf ;}
    142 
    143 finalize(){ \
    144 	dialog --infobox "Preparing welcome message..." 4 50
    145 	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
    146 	}
    147 
    148 ### THE ACTUAL SCRIPT ###
    149 
    150 ### This is how everything happens in an intuitive format and order.
    151 
    152 # Check if user is root on Arch distro. Install dialog.
    153 pacman --noconfirm --needed -Sy dialog || error "Are you sure you're running this as the root user, are on an Arch-based distribution and have an internet connection?"
    154 
    155 # Welcome user and pick dotfiles.
    156 welcomemsg || error "User exited."
    157 
    158 # Get and verify username and password.
    159 getuserandpass || error "User exited."
    160 
    161 # Give warning if user already exists.
    162 usercheck || error "User exited."
    163 
    164 # Last chance for user to back out before install.
    165 preinstallmsg || error "User exited."
    166 
    167 ### The rest of the script requires no user input.
    168 
    169 # Refresh Arch keyrings.
    170 refreshkeys || error "Error automatically refreshing Arch keyring. Consider doing so manually."
    171 
    172 for x in curl base-devel git ntp zsh; do
    173 	dialog --title "LARBS Installation" --infobox "Installing \`$x\` which is required to install and configure other programs." 5 70
    174 	installpkg "$x"
    175 done
    176 
    177 dialog --title "LARBS Installation" --infobox "Synchronizing system time to ensure successful and secure installation of software..." 4 70
    178 ntpdate 0.us.pool.ntp.org >/dev/null 2>&1
    179 
    180 adduserandpass || error "Error adding username and/or password."
    181 
    182 [ -f /etc/sudoers.pacnew ] && cp /etc/sudoers.pacnew /etc/sudoers # Just in case
    183 
    184 # Allow user to run sudo without password. Since AUR programs must be installed
    185 # in a fakeroot environment, this is required for all builds with AUR.
    186 newperms "%wheel ALL=(ALL) NOPASSWD: ALL"
    187 
    188 # Make pacman and yay colorful and adds eye candy on the progress bar because why not.
    189 grep -q "^Color" /etc/pacman.conf || sed -i "s/^#Color$/Color/" /etc/pacman.conf
    190 grep -q "ILoveCandy" /etc/pacman.conf || sed -i "/#VerbosePkgLists/a ILoveCandy" /etc/pacman.conf
    191 
    192 # Use all cores for compilation.
    193 sed -i "s/-j2/-j$(nproc)/;s/^#MAKEFLAGS/MAKEFLAGS/" /etc/makepkg.conf
    194 
    195 manualinstall $aurhelper || error "Failed to install AUR helper."
    196 
    197 # The command that does all the installing. Reads the progs.csv file and
    198 # installs each needed program the way required. Be sure to run this only after
    199 # the user has been created and has priviledges to run sudo without a password
    200 # and all build dependencies are installed.
    201 installationloop
    202 
    203 dialog --title "LARBS Installation" --infobox "Finally, installing \`libxft-bgra\` to enable color emoji in suckless software without crashes." 5 70
    204 yes | sudo -u "$name" $aurhelper -S libxft-bgra-git >/dev/null 2>&1
    205 
    206 # Install the dotfiles in the user's home directory
    207 putgitrepo "$dotfilesrepo" "/home/$name" "$repobranch"
    208 rm -f "/home/$name/README.md" "/home/$name/LICENSE" "/home/$name/FUNDING.yml"
    209 # make git ignore deleted LICENSE & README.md files
    210 git update-index --assume-unchanged "/home/$name/README.md" "/home/$name/LICENSE" "/home/$name/FUNDING.yml"
    211 
    212 # Most important command! Get rid of the beep!
    213 systembeepoff
    214 
    215 # Make zsh the default shell for the user.
    216 chsh -s /bin/zsh "$name" >/dev/null 2>&1
    217 sudo -u "$name" mkdir -p "/home/$name/.cache/zsh/"
    218 
    219 # dbus UUID must be generated for Artix runit.
    220 dbus-uuidgen > /var/lib/dbus/machine-id
    221 
    222 # Tap to click
    223 [ ! -f /etc/X11/xorg.conf.d/40-libinput.conf ] && printf 'Section "InputClass"
    224         Identifier "libinput touchpad catchall"
    225         MatchIsTouchpad "on"
    226         MatchDevicePath "/dev/input/event*"
    227         Driver "libinput"
    228 	# Enable left mouse button by tapping
    229 	Option "Tapping" "on"
    230 EndSection' > /etc/X11/xorg.conf.d/40-libinput.conf
    231 
    232 # Fix fluidsynth/pulseaudio issue.
    233 grep -q "OTHER_OPTS='-a pulseaudio -m alsa_seq -r 48000'" /etc/conf.d/fluidsynth ||
    234 	echo "OTHER_OPTS='-a pulseaudio -m alsa_seq -r 48000'" >> /etc/conf.d/fluidsynth
    235 
    236 # Start/restart PulseAudio.
    237 killall pulseaudio; sudo -u "$name" pulseaudio --start
    238 
    239 # This line, overwriting the `newperms` command above will allow the user to run
    240 # serveral important commands, `shutdown`, `reboot`, updating, etc. without a password.
    241 newperms "%wheel ALL=(ALL) ALL #LARBS
    242 %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"
    243 
    244 # Last message! Install complete!
    245 finalize
    246 clear