#!/bin/sh # Soomin's Auto Rice Bootstrapping Script (THESIAH) adapted for debian # Adaptation by: Soomin Im # License: GNU GPLv3 ### VARIABLES ### dotfilesrepo="https://github.com/TheSiahxyz/.dotfiles.git" progsfile="thesiah.xyz/debianprogs.csv" repobranch="master" export TERM=ansi ### FUNCTIONS ### installpkg() { DEBIAN_FRONTEND=noninteractive apt-get install -y "$1" >/dev/null 2>&1 || error "Failed to install $1" } error() { whiptail --title "Error" --msgbox "An error occurred: $1" 8 78 printf "%s\n" "$1" >&2 exit 1 } welcomemsg() { whiptail --title "Welcome!" \ --msgbox "Welcome to Soomin's Auto-Rice Bootstrapping Script for Debian! This script will automatically install a fully-featured Linux desktop, which I use as my main machine." 12 60 whiptail --title "Important Note!" --yes-button "All ready!" \ --no-button "Return..." \ --yesno "Be sure the computer you are using has current pacman updates and refreshed Debian keyrings.\\n\\nIf it does not, the installation of some programs might fail." 8 70 } getuserandpass() { name=$(whiptail --inputbox "Please enter a name for the user account." 10 60 3>&1 1>&2 2>&3 3>&1) || error "User exited." pass1=$(whiptail --passwordbox "Enter a password for the user." 10 60 3>&1 1>&2 2>&3 3>&1) || error "User exited." pass2=$(whiptail --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1) || error "User exited." while ! [ "$pass1" = "$pass2" ]; do pass1=$(whiptail --passwordbox "Passwords do not match.\\n\\nEnter password again." 10 60 3>&1 1>&2 2>&3 3>&1) pass2=$(whiptail --passwordbox "Retype password." 10 60 3>&1 1>&2 2>&3 3>&1) done } usercheck() { if id "$name" &>/dev/null; then whiptail --yesno "The user $name already exists. Do you want to continue?" 8 78 || error "User exited." fi } preinstallmsg() { whiptail --title "Ready to start?" --yesno "The rest of the installation will now be totally automated. Press Yes to continue." 8 78 || error "User exited." } adduserandpass() { whiptail --infobox "Adding user \"$name\"..." 7 50 adduser --ingroup sudo --shell /bin/zsh "$name" >/dev/null 2>&1 || usermod -a -G sudo "$name" && mkdir -p \ "/home/$name/Desktop" \ "/home/$name/Documents" \ "/home/$name/Downloads" \ "/home/$name/Music" \ "/home/$name/Pictures" \ "/home/$name/Private/git" \ "/home/$name/Public" \ "/home/$name/Torrent/complete" \ "/home/$name/Torrent/incomplete" \ "/media/$name/flash" \ "/mnt/second" \ "/home/$name" && chown -R "$name":sudo /home/"$name" echo "$name:$pass1" | chpasswd >/dev/null 2>&1 export repodir="/home/$name/.local/src" mkdir -p "$repodir" chown -R "$name":sudo "$(dirname "$repodir")" unset pass1 pass2 } installationloop() { ([ -f "$progsfile" ] && cp "$progsfile" /tmp/progs.csv) || curl -Ls "$progsfile" | sed '/^#/d' >/tmp/progs.csv total=$(wc -l /dev/null 2>&1 || { cd "$dir" || return 1 sudo -u "$name" git pull --force origin master >/dev/null 2>&1 } # Check the repository name and act accordingly for suckless case "$progname" in "suckless") for sub in "${dir}/"*; do cd "$sub" || continue make >/dev/null 2>&1 make install >/dev/null 2>&1 done ;; *) cd "$dir" || exit 1 make >/dev/null 2>&1 make install >/dev/null 2>&1 ;; esac cd /tmp || return 1 } pipinstall() { whiptail --title "SI Installation" \ --infobox "Installing the Python package \`$1\` ($n of $total). $1 $2" 9 70 [ -x "$(command -v "pip")" ] || installpkg python3-pip >/dev/null 2>&1 [ -x "$(command -v "pipx")" ] || installpkg pipx >/dev/null 2>&1 yes | pip install "$1" || yes | pipx install "$1" } vimplugininstall() { # Installs vim plugins. whiptail --infobox "Installing vim plugins..." 7 60 mkdir -p "/home/$name/.config/vim/autoload" curl -Ls "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim" >"/home/$name/.config/vim/autoload/plug.vim" chown -R "$name:$name" "/home/$name/.config/vim" # Changed to use user's group sudo -u "$name" vim -c "PlugInstall|q|q" } atuininstall() { whiptail --infobox "Installing atuin..." 7 60 cd /home/"$name" curl --proto '=https' --tlsv1.2 -LsSf https://setup.atuin.sh | sh cd /tmp || return } lfinstall() { whiptail --infobox "Installing lf..." 7 60 download_url=$(curl -s https://api.github.com/repos/gokcehan/lf/releases/latest | jq -r '.assets[] | select(.name == "lf-linux-amd64.tar.gz") | .browser_download_url') cd /home/"$name" curl -LO "$download_url" tar xzf lf-linux-amd64.tar.gz mv lf /usr/bin/lf cd /tmp || return } zoxideinstall() { whiptail --infobox "Installing zoxide..." 7 60 sudo -u "$name" git -C "/home/$name" clone --depth 1 --single-branch \ --no-tags -q https://github.com/ajeetdsouza/zoxide.git zoxide || { cd zoxide || return 1 sudo -u "$name" git pull --force origin master } cd /home/"$name"/zoxide ./install.sh cd /tmp && rm -rf /home/"$name"/zoxide || return } nviminstall() { whiptail --infobox "Installing neovim..." 7 60 latest_version=$(curl -s https://api.github.com/repos/neovim/neovim/releases/latest | grep -o '"tag_name": ".*"' | cut -d'"' -f4) download_url="https://github.com/neovim/neovim/releases/download/$latest_version/nvim.appimage" cd /home/"$name" curl -LO "$download_url" mv nvim.appimage /usr/bin/nvim || return cd /tmp || return } addsudo() { echo "$name ALL=(ALL:ALL) ALL" >/etc/sudoers.d/00-thesiah-user-can-sudo echo "$name ALL=(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/apt update,/usr/bin/apt upgrade,/usr/bin/apt upgrade -y,/usr/bin/loadkeys,/usr/bin/apt-get --download-only upgrade" >/etc/sudoers.d/01-thesiah-cmds-without-password echo "Defaults editor=/usr/bin/nvim" >/etc/sudoers.d/02-thesiah-visudo-editor mkdir -p /etc/sysctl.d echo "kernel.dmesg_restrict = 0" >/etc/sysctl.d/dmesg.conf } checksystem() { whiptail --infobox "Setting ufw and samba..." 7 60 if [ "$1" = "ufw" ]; then ufw --force reload >/dev/null 2>&1 ufw default deny incoming >/dev/null 2>&1 ufw allow 80 >/dev/null 2>&1 ufw allow 443 >/dev/null 2>&1 ufw allow 25/tcp >/dev/null 2>&1 ufw allow 587/tcp >/dev/null 2>&1 ufw allow 3478/udp >/dev/null 2>&1 ufw allow 5349/tcp >/dev/null 2>&1 ufw allow 10000/udp >/dev/null 2>&1 ufw allow in ssh >/dev/null 2>&1 ufw allow in IMAPS >/dev/null 2>&1 ufw allow in POP3 >/dev/null 2>&1 ufw allow in SMTP >/dev/null 2>&1 ufw allow in 'WWW Full' >/dev/null 2>&1 ufw allow in 'Postfix SMTPS' >/dev/null 2>&1 ufw allow in 'Mail Submission' >/dev/null 2>&1 ufw enable >/dev/null 2>&1 || ufw --force enable >/dev/null 2>&1 fi if [ "$1" = "smbd" ]; then ufw --force reload >/dev/null 2>&1 ufw allow 137/tcp >/dev/null 2>&1 ufw allow 137/udp >/dev/null 2>&1 ufw allow 138/tcp >/dev/null 2>&1 ufw allow 138/udp >/dev/null 2>&1 ufw allow 139/tcp >/dev/null 2>&1 ufw allow 445/tcp >/dev/null 2>&1 [ -f /etc/samba/smb.conf ] && touch /etc/samba/smb.conf sleep 1 printf "$pass1" | smbpasswd -a "$name" >/dev/null 2>&1 fi if ! systemctl is-active --quiet "$1"; then systemctl enable "$1" systemctl start "$1" fi } gnupginstall() { whiptail --infobox "Installing gnupg..." 7 60 gpgerror="http://mirrors.dotsrc.org/gcrypt/libgpg-error/libgpg-error-1.50.tar.gz" npth="http://mirrors.dotsrc.org/gcrypt/npth/npth-1.7.tar.bz2" assuan="http://mirrors.dotsrc.org/gcrypt/libassuan/libassuan-3.0.1.tar.bz2" ksba="http://mirrors.dotsrc.org/gcrypt/libksba/libksba-1.6.7.tar.bz2" gcrypt="http://mirrors.dotsrc.org/gcrypt/libgcrypt/libgcrypt-1.11.0.tar.gz" gpglibs="$gpgerror $npth $assuan $ksba $gcrypt" cd /home/"$name" for lib in "$gpglibs"; do curl -LO "$lib" filename=$(basename "$lib") case "$filename" in *.tar.bz2) tar -xjf "$filename" ;; *.tar.gz) tar -xzf "$filename" ;; *) exit 1 ;; esac dirname="${filename%.tar.*}" cd "$dirname" mkdir -p build cd build ../configure [ $? -ne 0 ] && exit 1 make [ $? -ne 0 ] && exit 1 make install [ $? -ne 0 ] && exit 1 cd ../.. rm -rf "$dirname" rm "$filename" done cd /tmp || return 1 } finalize() { ln -sf /home/"$name"/.dotfiles/default/Pictures/wallpaper/bg.png /home/"$name"/.local/share/bg chown -h "$name":sudo /home/"$name"/.local/share/bg whiptail --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 Soomin" 13 80 } ### MAIN SCRIPT ### if [ "$(id -u)" -ne 0 ]; then echo "This script must be run as root." >&2 exit 1 fi essential_packages="curl ca-certificates build-essential git network-manager ntp zsh stow" whiptail --title "SI Installation" --infobox "Installing essential packages required to install and configure other programs." 8 70 for package in $essential_packages; do installpkg $package || error "Failed to install $package" done welcomemsg || error "User exited." getuserandpass || error "User exited." usercheck || error "User exited." preinstallmsg || error "User exited." adduserandpass || error "Error adding username and/or password." trap 'rm -f /etc/sudoers.d/thesiah-temp' HUP INT QUIT TERM PWR EXIT echo "%sudo ALL=(ALL) NOPASSWD: ALL Defaults:sudo,root runcwd=*" >/etc/sudoers.d/thesiah-temp installationloop putgitrepo "$dotfilesrepo" "/home/$name/.dotfiles" "$repobranch" rm -rf "/home/$name/.git/" "/home/$name/README.md" "/home/$name/LICENSE" "/home/$name/FUNDING.yml" cd "/home/$name/.dotfiles" && stow --no-folding -S debian && stow --no-folding -S default || exit 1 sudo -u "$name" ln -sf "/home/$name/.dotfiles/debian/.config/shell/profile" "/home/$name/.zprofile" sudo -u "$name" ln -sf "/home/$name/.dotfiles/debian/.config/x11/xprofile" "/home/$name/.xprofile" sudo -u "$name" ln -sf "/home/$name/.dotfiles/debian/.config/bash/bash_profile" "/home/$name/.bash_profile" sudo -u "$name" ln -sf "/home/$name/.dotfiles/debian/.config/bash/bashrc" "/home/$name/.bashrc" [ ! -f "/home/$name/.config/vim/autoload/plug.vim" ] && vimplugininstall rmmod pcspkr echo "blacklist pcspkr" >/etc/modprobe.d/nobeep.conf chsh -s /bin/zsh "$name" >/dev/null 2>&1 sudo -u "$name" mkdir -p "/home/$name/.cache/zsh/" sudo -u "$name" mkdir -p "/home/$name/.config/mpd/playlists/" # dbus UUID must be generated for Artix runit. dbus-uuidgen >/var/lib/dbus/machine-id # Use system notifications for Brave on Artix echo "export \$(dbus-launch)" >/etc/profile.d/dbus.sh # Enable tap to click [ ! -f /etc/X11/xorg.conf.d/40-libinput.conf ] && printf 'Section "InputClass" Identifier "libinput touchpad catchall" MatchIsTouchpad "on" MatchDevicePath "/dev/input/event*" Driver "libinput" # Enable left mouse button by tapping Option "Tapping" "on" EndSection' >/etc/X11/xorg.conf.d/40-libinput.conf # Allow wheel users to sudo with password and allow several system commands # (like `shutdown` to run without password). addsudo systems="NetworkManager ssh bluetooth ufw" for system in $systems; do checksystem $system || error "Failed to start $system" done atuininstall || error "User exited." lfinstall || error "User exited." zoxideinstall || error "User exited." nviminstall || error "User exited." ln -s /usr/bin/batcat /home/"$name"/.local/bin/bat gnupginstall || error "User exited." finalize