2022-08-23 21:04:44 +02:00
#!/bin/sh
2024-01-01 21:29:15 +00:00
DOTS_REPO = "https://git.snaile.de/luca/dotfiles"
DOTS_BRANCH = "main"
STOW_DIR = ".local/share/stow"
DOTS_PACKAGE = "dots"
2022-08-23 21:04:44 +02:00
2024-02-05 15:35:11 +01:00
USER_GROUPS = "wheel,floppy,audio,video,cdrom,optical,kvm,xbuilder,users,docker" # Comma separated list
2024-01-01 21:29:15 +00:00
SCRIPT_DIR = " $( dirname " $( readlink -f " $0 " ) " ) "
BOLD = " $( tput bold) "
RED = " $( tput setaf 1) "
GREEN = " $( tput setaf 2) "
YELLOW = " $( tput setaf 3) "
BLUE = " $( tput setaf 4) "
RESET = " $( tput sgr0) "
2022-08-23 21:04:44 +02:00
error( ) {
2024-01-01 21:29:15 +00:00
printf "%b\n" " ${ RED } ${ BOLD } ${ 1 } ${ RESET } " >& 2
2022-08-23 21:04:44 +02:00
exit 1
}
2024-01-01 21:29:15 +00:00
prompt( ) {
message = $1
2024-01-13 14:59:15 +01:00
printf "%b" " ${ BLUE } ${ message } ${ RESET } " >" $( tty) "
2024-01-01 21:29:15 +00:00
# shellcheck disable=SC3037,SC2046
read -r x
echo " $x "
unset x
2022-08-23 21:04:44 +02:00
}
2024-01-01 21:29:15 +00:00
emphasize( ) {
printf "%b\n" " ${ GREEN } ${ BOLD } ${ 1 } ${ RESET } "
2022-08-23 21:04:44 +02:00
}
2024-01-01 21:29:15 +00:00
info( ) {
printf "%b\n" " ${ 1 } "
2023-05-22 23:21:57 +02:00
}
2024-01-01 21:29:15 +00:00
warn( ) {
printf "%b\n" " ${ YELLOW } ${ BOLD } ${ 1 } ${ RESET } "
2022-08-23 21:04:44 +02:00
}
2024-01-01 21:29:15 +00:00
_loop_wrapper( ) {
unset n
unset total
file = $1
message = $2
command = $3
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
skip_regex = " ^(#.*)? $"
total = $( grep -cvP " $skip_regex " " $file " )
2023-05-22 23:21:57 +02:00
2024-01-01 21:29:15 +00:00
while read -r x; do
echo " $x " | grep -qvP " $skip_regex " || continue
n = $(( n + 1 ))
eval " info \"( ${ n } / ${ total } ) $message \" "
eval " $command "
done <" $file "
}
check_root( ) {
[ " $( id -u) " != "0" ] &&
error "This script needs root!"
}
setup( ) {
info "Synchronizing XBPS index..."
2024-01-13 14:59:15 +01:00
xbps-install -S >/dev/null 2>& 1 || error "Failed to synchronize XBPS index! (Try manually running xbps-install -S)"
2024-01-01 21:29:15 +00:00
2024-01-13 14:59:15 +01:00
if ! xbps-query ntp >/dev/null 2>& 1; then
info "Installing ntp..."
xbps-install -y ntp >/dev/null 2>& 1
2024-01-01 21:29:15 +00:00
2024-01-13 14:59:15 +01:00
info "Synchronizing time..."
ntpdate "pool.ntp.org" >/dev/null 2>& 1 || warn "Failed to synchronize time!"
fi
2024-01-01 21:29:15 +00:00
info "Done!"
}
install_packages( ) {
2024-01-13 14:59:15 +01:00
#shellcheck disable=SC2016,SC2046
2024-03-29 07:27:52 +01:00
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"
2024-01-13 14:59:15 +01:00
info "Done!"
2024-01-01 21:29:15 +00:00
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!"
2022-08-23 21:04:44 +02:00
}
2024-01-01 21:29:15 +00:00
install_files( ) {
(
cd " ${ SCRIPT_DIR } /files " || exit 1
2024-03-28 16:22:40 +01:00
find . -type f,l -exec install -Dm 644 -o root -g root "{}" "/{}" \;
2024-01-01 21:29:15 +00:00
)
info "Done!"
2022-08-23 21:04:44 +02:00
}
2024-03-29 07:27:52 +01:00
create_symlinks( ) {
#shellcheck disable=SC2016
_loop_wrapper " ${ SCRIPT_DIR } /symlinks.txt " \
'Creating symlink $(echo $x | cut -d' ,' -f1) -> $(echo $x | cut -d' ,' -f2)' \
'
source = $( echo $x | cut -d"," -f2)
target = $( echo $x | cut -d"," -f1)
[ -L $target ] && rm $target
ln -s $source $target
'
}
2024-01-01 21:29:15 +00:00
create_user( ) {
failed = false
2024-01-13 14:59:15 +01:00
while ! echo " $username " | grep " ^[a-z_][a-z0-9_-]* $" | grep -qv "root" ; do
2024-01-01 21:29:15 +00:00
$failed && warn "Invalid username, try again!"
2024-01-13 14:59:15 +01:00
username = $( prompt "Input Username: " )
2024-01-01 21:29:15 +00:00
failed = true
done
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
if id -u " $username " >/dev/null 2>& 1; then
2024-01-13 14:59:15 +01:00
warn " User \" $username \" already exists, Skipping user creation! "
2024-01-29 14:41:34 +01:00
usermod -G " $USER_GROUPS " " $username "
2024-01-01 21:29:15 +00:00
else
info " Creating user \" $username \" with the following groups: \" $USER_GROUPS \"... "
useradd -m -G " $USER_GROUPS " " $username "
failed = false
while [ -z " $pass1 " ] || [ " $pass1 " != " $pass2 " ] ; do
$failed && warn "Passwords do not match or are empty, try again!"
2024-01-13 14:59:15 +01:00
pass1 = $( prompt "Input Password: " )
pass2 = $( prompt "Repeat Password: " )
2024-01-01 21:29:15 +00:00
failed = true
done
echo " $username : $pass1 " | chpasswd
fi
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
user_home = $( getent passwd " $username " | cut -d ':' -f 6)
[ -z " $username " ] &&
error "\$username variable is empty, this script is bugged!"
[ -z " $user_home " ] &&
error "\$user_home variable is empty, this script is bugged!"
sudo -u " $username " [ -w " $user_home " ] || error " $username can't write to ' $user_home '! "
info "Done!"
}
create_directories( ) {
#shellcheck disable=SC2016
2024-03-29 07:27:52 +01:00
_loop_wrapper " ${ SCRIPT_DIR } /directories.txt " \
2024-01-29 09:54:19 +01:00
'Creating directory $(echo $x | cut -d"," -f1)' \
'
dir = $( echo $x | cut -d"," -f1)
mod = $( echo $x | cut -d"," -f2)
sudo -u " $username " mkdir -p " ${ user_home } / ${ dir } "
chmod " ${ mod } " " ${ user_home } / ${ dir } "
'
2024-01-01 21:29:15 +00:00
info "Done!"
}
install_dotfiles( ) {
info "Cloning dotfiles..."
mkdir -p " ${ user_home } / ${ STOW_DIR } "
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
warn "Failed to clone dotfiles"
return 1
fi
fi
info "Symlinking dotfiles..."
if ! stow -d " $user_home / $STOW_DIR " -t " $user_home " " $DOTS_PACKAGE " 1>/dev/null 2>& 1; then
warn "Failed to symlink dotfiles"
return 2
fi
info "Done!"
}
2024-01-04 14:09:46 +01:00
select_keymap( ) {
2024-01-25 15:45:28 +01:00
[ -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:" ) "
ln -s " $map " " ${ user_home } /.local/share/xkb/compiled/keymap "
2024-01-04 14:09:46 +01:00
}
2024-01-01 21:29:15 +00:00
enable_services( ) {
2024-02-27 10:15:16 +01:00
for sv in /var/service/*; do
2024-03-29 07:27:52 +01:00
grep -qx " $( basename " $sv " ) " " ${ SCRIPT_DIR } /services.txt " || rm " $sv "
2024-02-27 10:15:16 +01:00
done
# shellcheck disable=2016
2024-03-29 07:27:52 +01:00
_loop_wrapper " ${ SCRIPT_DIR } /services.txt " \
2024-01-01 21:29:15 +00:00
'Enabling ${x} service' \
'[ ! -L /var/service/${x} ] && ln -s "/etc/sv/${x}" "/var/service/"'
info "Done!"
2022-08-23 21:04:44 +02:00
}
2023-05-22 23:21:57 +02:00
finalize( ) {
2024-01-03 20:51:44 +01:00
gid = $( getent passwd " $username " | cut -d ':' -f 4)
groupname = $( getent group " $gid " | cut -d ':' -f 1)
chown " $username : $groupname " " $user_home "
info "Done!"
2023-05-22 23:21:57 +02:00
}
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
### CONTROL FLOW BEGINS HERE ###
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
check_root
2022-08-23 21:04:44 +02:00
2024-01-13 13:29:39 +01:00
emphasize "-- Copying Files --"
install_files
2024-03-29 07:27:52 +01:00
emphasize "-- Creating Symlinks --"
create_symlinks
2024-01-01 21:29:15 +00:00
emphasize "-- Preparing Installation --"
setup
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
emphasize "-- Installing Packages --"
2024-03-29 07:27:52 +01:00
install_packages
2022-08-23 21:04:44 +02:00
2024-01-13 14:59:15 +01:00
username = " $SUDO_USER "
if [ -z " $username " ] ; then
emphasize "-- Creating User Account --"
create_user
else
user_home = $( getent passwd " $username " | cut -d ':' -f 6)
fi
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
emphasize "-- Creating Standard Home Directories --"
2024-03-29 07:27:52 +01:00
create_directories
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
emphasize "-- Installing Dotfiles --"
install_dotfiles
2024-01-04 14:09:46 +01:00
select_keymap
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
emphasize "-- Enabling Services --"
2024-03-29 07:27:52 +01:00
enable_services
2022-08-23 21:04:44 +02:00
2024-01-01 21:29:15 +00:00
emphasize "-- Finalizing Installation --"
2022-08-23 21:04:44 +02:00
finalize
2023-05-22 23:21:57 +02:00
2024-01-01 21:29:15 +00:00
emphasize "-- Installation Complete --"