#!/usr/bin/env bash ## An idempotent system configuration script. ## ## Usage: configure ## ## Dependencies: Fedora 40 ## ## I run this script after performing a minimal installation of Fedora Linux, ## and I run it daily thereafter. set -euo pipefail shopt -s inherit_errexit die() { echo -e "$(basename "$0"): $1" >&2; exit 1; } [[ " $* " =~ ' --help ' ]] && sed -n 's/^## *//p' "$0" && exit (( UID != 0 )) || die 'do not run as root' # Add user to groups. sudo gpasswd -a "$USER" lp # Create directories. mkdir -p ~/{.cache,.local/{bin,lib,share,state},pending} sudo mkdir -p /media/{cdrom,samsung-128gb,wd-25a2-2tb,wd-25e2-2tb-{1,2}} # Add file systems to fstab and mount them. fstab_text=$(< /etc/fstab) fstab_update=$(<<-EOF /dev/sr0 /media/cdrom auto nofail,ro,user 0 0 UUID=7746-0C3C /media/samsung-128gb exfat nofail 0 0 UUID=48f7a023-824c-4e34-bc79-fb95ffd767c4 /media/wd-25a2-2tb ext4 nofail,noatime 0 2 UUID=0f7ada7d-8766-4712-8cea-d010a98f5437 /media/wd-25e2-2tb-1 ext4 nofail,noatime 0 2 UUID=f1f754ca-6f6b-42ae-a037-c25a1fd6a253 /media/wd-25e2-2tb-2 btrfs nofail,noatime 0 2 EOF ) if [[ ! $fstab_text =~ $fstab_update ]]; then echo -e '\nAdding file systems to fstab and mounting them...' sudo tee -a /etc/fstab <<< "$fstab_update" > /dev/null sudo systemctl daemon-reload # Must be run after modifying fstab. sudo mount -a fi # Restore files from backup. if [[ ! -d ~/main ]]; then if [[ -d /media/wd-25e2-2tb-2/backups/latest ]]; then backup=/media/wd-25e2-2tb-2/backups/latest elif [[ -d /media/cdrom/main ]]; then backup=/media/cdrom # The backup I restore when testing this script on a VM. else die '\nbackup not found' fi echo -e '\nRestoring files from backup...' cp -aT "$backup" ~ [[ $backup == /media/cdrom ]] && chmod -R +rw ~ fi # Configure DNF. dnfconf_text=$(< /etc/dnf/dnf.conf) dnfconf_update="install_weak_deps=False" if [[ ! $dnfconf_text =~ $dnfconf_update ]]; then sudo tee -a /etc/dnf/dnf.conf <<< "$dnfconf_update" > /dev/null fi echo -e '\nUpgrading RPMs...' sudo dnf upgrade echo -e "\nEnabling RPM Fusion's package repos..." fedora_version=$(rpm -E %fedora) dnf list --installed rpmfusion-free-release > /dev/null || sudo dnf install \ https://mirrors.rpmfusion.org/free/fedora/rpmfusion-free-release-"$fedora_version".noarch.rpm dnf list --installed rpmfusion-nonfree-release > /dev/null || sudo dnf install \ https://mirrors.rpmfusion.org/nonfree/fedora/rpmfusion-nonfree-release-"$fedora_version".noarch.rpm sudo dnf install rpmfusion-free-release-tainted rpmfusion-nonfree-release-tainted echo -e '\nInstalling RPMs from RPM Fusion...' sudo dnf install ffmpeg echo -e '\nInstalling RPMs from the fedora-cisco-openh264 repo...' sudo dnf install mozilla-openh264 echo -e "\nInstalling RPMs from Fedora's main package repo..." main_rpms=( altermime bash-completion chromium cups darkhttpd dunst emacs-gtk+x11 epiphany evince fd-find fontconfig fzf gimp git golang-github-tdewolff-minify gthumb ImageMagick inotify-tools maildir-utils mpg123 mpv nodejs nodejs-npm openbox pass pavucontrol pdfgrep printer-driver-brlaser qemu-img qemu-system-x86 ripgrep rsms-inter-fonts rsync sane-backends ShellCheck sysstat tar tree unzip xinput xorg-x11-server-Xorg xorg-x11-xauth xorg-x11-xinit xorriso xterm zathura zathura-pdf-poppler ) sudo dnf install "${main_rpms[@]}" echo -e "\nInstalling Node.js packages..." npm install -g prettier@latest | grep -v '^$' # Install Firefox using Mozilla's binary. echo read -rp "Install Firefox using Mozilla's binary? " input if [[ $input =~ ^[Yy] ]]; then sudo dnf install dbus-glib # Install runtime dependency. curl -fLsSo /tmp/firefox.tar.bz2 \ "https://download.mozilla.org/?product=firefox-latest-ssl&os=linux64" sudo rm -rf /opt/firefox sudo tar -xf /tmp/firefox.tar.bz2 -C /opt sudo ln -sf /opt/firefox/firefox /usr/local/bin/firefox fi echo -e '\nRemoving RPMs that were dependencies but are no longer required...' sudo dnf autoremove echo -e '\nRemoving cached RPMs...' sudo dnf clean packages # Initialize mu's message database and index messages in my maildir. if ! mu info &> /dev/null; then echo -e "\nInitializing mu's message database and indexing messages..." mu_init_opts=(--maildir="$HOME"/main/m/maildir) mapfile -t my_addresses < ~/main/m/maildir/my-addresses for line in "${my_addresses[@]}"; do [[ $line =~ @ ]] && mu_init_opts+=(--my-address="$line") done mu init "${mu_init_opts[@]}" mu index fi # Remove unwanted files. rm -f ~/.bash_history # HISTFILE variable is set to a different path. rm -f ~/.local/share/Trash/{files,info}/*