1
0
Fork 0

refactor bootstrap.sh

This commit is contained in:
Luca Bilke 2024-05-25 00:04:59 +02:00
parent 02f3e1b7d5
commit 9b6eee78f3
No known key found for this signature in database
GPG Key ID: C9E851809C1A5BDE
1 changed files with 110 additions and 110 deletions

View File

@ -15,90 +15,90 @@ BLUE="$(tput setaf 4)"
RESET="$(tput sgr0)" RESET="$(tput sgr0)"
error() { error() {
printf "%b\n" "${RED}${BOLD}${1}${RESET}" >&2 printf "%b\n" "${RED}${BOLD}${1}${RESET}" >&2
exit 1 exit 1
} }
prompt() { prompt() {
message=$1 message=$1
printf "%b" "${BLUE}${message}${RESET}" >"$(tty)" printf "%b" "${BLUE}${message}${RESET}" >"$(tty)"
# shellcheck disable=SC3037,SC2046 # shellcheck disable=SC3037,SC2046
read -r x read -r x
echo "$x" echo "$x"
unset x unset x
} }
emphasize() { emphasize() {
printf "%b\n" "${GREEN}${BOLD}${1}${RESET}" printf "%b\n" "${GREEN}${BOLD}${1}${RESET}"
} }
info() { info() {
printf "%b\n" "${1}" printf "%b\n" "${1}"
} }
warn() { warn() {
printf "%b\n" "${YELLOW}${BOLD}${1}${RESET}" printf "%b\n" "${YELLOW}${BOLD}${1}${RESET}"
} }
_loop_wrapper() { _loop_wrapper() {
unset n unset n
unset total unset total
file=$1 file=$1
message=$2 message=$2
command=$3 command=$3
skip_regex="^(#.*)?$" skip_regex="^(#.*)?$"
total=$(grep -cvP "$skip_regex" "$file") total=$(grep -cvP "$skip_regex" "$file")
while read -r x; do while read -r x; do
echo "$x" | grep -qvP "$skip_regex" || continue echo "$x" | grep -qvP "$skip_regex" || continue
n=$((n + 1)) n=$((n + 1))
eval "info \"(${n}/${total}) $message\"" eval "info \"(${n}/${total}) $message\""
eval "$command" eval "$command"
done <"$file" done <"$file"
} }
check_root() { check_root() {
[ "$(id -u)" != "0" ] && [ "$(id -u)" != "0" ] &&
error "This script needs root!" error "This script needs root!"
} }
setup() { setup() {
info "Synchronizing XBPS index..." info "Synchronizing XBPS index..."
xbps-install -S >/dev/null 2>&1 || error "Failed to synchronize XBPS index! (Try manually running xbps-install -S)" xbps-install -S xbps void-repo-nonfree >/dev/null 2>&1 || error "Failed to synchronize XBPS index! (Try manually running xbps-install -S)"
if ! xbps-query ntp >/dev/null 2>&1; then if ! xbps-query ntp >/dev/null 2>&1; then
info "Installing ntp..." info "Installing ntp..."
xbps-install -y ntp >/dev/null 2>&1 xbps-install -y ntp >/dev/null 2>&1
info "Synchronizing time..." info "Synchronizing time..."
ntpdate "pool.ntp.org" >/dev/null 2>&1 || warn "Failed to synchronize time!" ntpdate "pool.ntp.org" >/dev/null 2>&1 || warn "Failed to synchronize time!"
fi fi
info "Done!" info "Done!"
} }
install_packages() { install_packages() {
#shellcheck disable=SC2016,SC2046 #shellcheck disable=SC2016,SC2046
xbps-install -y $(sed '/^[[:space:]]*#/d;/^$/d' "${SCRIPT_DIR}/packages.txt" | xargs) 2>&1 | grep -q "not found in repository pool." && error "Invalid package in packages.txt, run validate.sh" { sed '/^[[:space:]]*#/d;/^$/d' "${SCRIPT_DIR}/packages.txt" | xargs -r xbps-install -y || error "Invalid package in packages.txt"; } | grep -v 'already installed'
info "Done!" info "Done!"
command -v git 1>/dev/null 2>&1 || error "git isn't installed even though it should be!" command -v git 1>/dev/null 2>&1 || error "git isn't installed even though it should be!"
command -v stow 1>/dev/null 2>&1 || error "stow isn't installed even though it should be!" command -v stow 1>/dev/null 2>&1 || error "stow isn't installed even though it should be!"
} }
install_files() { install_files() {
( (
cd "${SCRIPT_DIR}/files" || exit 1 cd "${SCRIPT_DIR}/files" || exit 1
find . -type f,l -exec install -Dm 644 -o root -g root "{}" "/{}" \; find . -type f,l -exec install -Dm 644 -o root -g root "{}" "/{}" \;
) )
info "Done!" info "Done!"
} }
create_symlinks() { create_symlinks() {
#shellcheck disable=SC2016 #shellcheck disable=SC2016
_loop_wrapper "${SCRIPT_DIR}/symlinks.txt" \ _loop_wrapper "${SCRIPT_DIR}/symlinks.txt" \
'Creating symlink $(echo $x | cut -d',' -f1) -> $(echo $x | cut -d',' -f2)' \ 'Creating symlink $(echo $x | cut -d',' -f1) -> $(echo $x | cut -d',' -f2)' \
' '
source=$(echo $x | cut -d"," -f2) source=$(echo $x | cut -d"," -f2)
target=$(echo $x | cut -d"," -f1) target=$(echo $x | cut -d"," -f1)
[ -L $target ] && rm $target [ -L $target ] && rm $target
@ -108,91 +108,91 @@ create_symlinks() {
} }
create_user() { create_user() {
failed=false failed=false
while ! echo "$username" | grep "^[a-z_][a-z0-9_-]*$" | grep -qv "root"; do while ! echo "$username" | grep "^[a-z_][a-z0-9_-]*$" | grep -qv "root"; do
$failed && warn "Invalid username, try again!" $failed && warn "Invalid username, try again!"
username=$(prompt "Input Username: ") username=$(prompt "Input Username: ")
failed=true failed=true
done done
if id -u "$username" >/dev/null 2>&1; then if id -u "$username" >/dev/null 2>&1; then
warn "User \"$username\" already exists, Skipping user creation!" warn "User \"$username\" already exists, Skipping user creation!"
usermod -G "$USER_GROUPS" "$username" usermod -G "$USER_GROUPS" "$username"
else else
info "Creating user \"$username\" with the following groups: \"$USER_GROUPS\"..." info "Creating user \"$username\" with the following groups: \"$USER_GROUPS\"..."
useradd -m -G "$USER_GROUPS" "$username" useradd -m -G "$USER_GROUPS" "$username"
failed=false failed=false
while [ -z "$pass1" ] || [ "$pass1" != "$pass2" ]; do while [ -z "$pass1" ] || [ "$pass1" != "$pass2" ]; do
$failed && warn "Passwords do not match or are empty, try again!" $failed && warn "Passwords do not match or are empty, try again!"
pass1=$(prompt "Input Password: ") pass1=$(prompt "Input Password: ")
pass2=$(prompt "Repeat Password: ") pass2=$(prompt "Repeat Password: ")
failed=true failed=true
done done
echo "$username:$pass1" | chpasswd echo "$username:$pass1" | chpasswd
fi fi
user_home=$(getent passwd "$username" | cut -d ':' -f 6) user_home=$(getent passwd "$username" | cut -d ':' -f 6)
[ -z "$username" ] && [ -z "$username" ] &&
error "\$username variable is empty, this script is bugged!" error "\$username variable is empty, this script is bugged!"
[ -z "$user_home" ] && [ -z "$user_home" ] &&
error "\$user_home variable is empty, this script is bugged!" error "\$user_home variable is empty, this script is bugged!"
sudo -u "$username" [ -w "$user_home" ] || error "$username can't write to '$user_home'!" sudo -u "$username" [ -w "$user_home" ] || error "$username can't write to '$user_home'!"
info "Done!" info "Done!"
} }
create_directories() { create_directories() {
#shellcheck disable=SC2016 #shellcheck disable=SC2016
_loop_wrapper "${SCRIPT_DIR}/directories.txt" \ _loop_wrapper "${SCRIPT_DIR}/directories.txt" \
'Creating directory $(echo $x | cut -d"," -f1)' \ 'Creating directory $(echo $x | cut -d"," -f1)' \
' '
dir=$(echo $x | cut -d"," -f1) dir=$(echo $x | cut -d"," -f1)
mod=$(echo $x | cut -d"," -f2) mod=$(echo $x | cut -d"," -f2)
sudo -u "$username" mkdir -p "${user_home}/${dir}" sudo -u "$username" mkdir -p "${user_home}/${dir}"
chmod "${mod}" "${user_home}/${dir}" chmod "${mod}" "${user_home}/${dir}"
' '
info "Done!" info "Done!"
} }
install_dotfiles() { install_dotfiles() {
info "Cloning dotfiles..." info "Cloning dotfiles..."
mkdir -p "${user_home}/${STOW_DIR}" mkdir -p "${user_home}/${STOW_DIR}"
if [ ! -d "${user_home}/${STOW_DIR}/${DOTS_PACKAGE}/.git" ]; then if [ ! -d "${user_home}/${STOW_DIR}/${DOTS_PACKAGE}/.git" ]; then
if ! git -C "${user_home}/${STOW_DIR}" clone -q --recurse-submodules -b "$DOTS_BRANCH" "$DOTS_REPO" "$DOTS_PACKAGE"; then if ! git -C "${user_home}/${STOW_DIR}" clone -q --recurse-submodules -b "$DOTS_BRANCH" "$DOTS_REPO" "$DOTS_PACKAGE"; then
warn "Failed to clone dotfiles" warn "Failed to clone dotfiles"
return 1 return 1
fi fi
fi fi
info "Symlinking dotfiles..." info "Symlinking dotfiles..."
if ! stow -d "$user_home/$STOW_DIR" -t "$user_home" "$DOTS_PACKAGE" 1>/dev/null 2>&1; then if ! stow -d "$user_home/$STOW_DIR" -t "$user_home" "$DOTS_PACKAGE" 1>/dev/null 2>&1; then
warn "Failed to symlink dotfiles" warn "Failed to symlink dotfiles"
return 2 return 2
fi fi
info "Done!" info "Done!"
} }
select_keymap() { select_keymap() {
[ -L "${user_home}/.local/share/xkb/compiled/keymap" ] && return [ -L "${user_home}/.local/share/xkb/compiled/keymap" ] && return
map="$(find "${user_home}/.local/share/xkb/compiled" -type f -printf "%f\n" | fzf --header="Select a keymap keymap:")" map="$(find "${user_home}/.local/share/xkb/compiled" -type f -printf "%f\n" | fzf --header="Select a keymap keymap:")"
ln -s "$map" "${user_home}/.local/share/xkb/compiled/keymap" ln -s "$map" "${user_home}/.local/share/xkb/compiled/keymap"
} }
enable_services() { enable_services() {
for sv in /var/service/*; do for sv in /var/service/*; do
grep -qx "$(basename "$sv")" "${SCRIPT_DIR}/services.txt" || rm "$sv" grep -qx "$(basename "$sv")" "${SCRIPT_DIR}/services.txt" || rm "$sv"
done done
# shellcheck disable=2016 # shellcheck disable=2016
_loop_wrapper "${SCRIPT_DIR}/services.txt" \ _loop_wrapper "${SCRIPT_DIR}/services.txt" \
'Enabling ${x} service' \ 'Enabling ${x} service' \
'[ ! -L /var/service/${x} ] && ln -s "/etc/sv/${x}" "/var/service/"' '[ ! -L /var/service/${x} ] && ln -s "/etc/sv/${x}" "/var/service/"'
info "Done!" info "Done!"
} }
finalize() { finalize() {
gid=$(getent passwd "$username" | cut -d ':' -f 4) gid=$(getent passwd "$username" | cut -d ':' -f 4)
groupname=$(getent group "$gid" | cut -d ':' -f 1) groupname=$(getent group "$gid" | cut -d ':' -f 1)
chown "$username:$groupname" "$user_home" chown "$username:$groupname" -R "$user_home"
info "Done!" info "Done!"
} }
### CONTROL FLOW BEGINS HERE ### ### CONTROL FLOW BEGINS HERE ###
@ -213,10 +213,10 @@ install_packages
username="$SUDO_USER" username="$SUDO_USER"
if [ -z "$username" ]; then if [ -z "$username" ]; then
emphasize "-- Creating User Account --" emphasize "-- Creating User Account --"
create_user create_user
else else
user_home=$(getent passwd "$username" | cut -d ':' -f 6) user_home=$(getent passwd "$username" | cut -d ':' -f 6)
fi fi
emphasize "-- Creating Standard Home Directories --" emphasize "-- Creating Standard Home Directories --"