From 4a57e9902ffba22c5518e089486f2eb9cb2d2744 Mon Sep 17 00:00:00 2001 From: thomas Date: Sun, 11 Oct 2026 18:10:27 +0100 Subject: [PATCH] Feature: Bootstrap script for new installs bootstrap.sh installs everything listed in system/packages.txt (pacman, AUR via yay, flatpak, official install scripts), auto-detects CPU microcode and GPU drivers, enables services, links dotfiles with stow and runs system/install.sh. Optional --svt-av1 installs svt-av1-essential-git and rebuilds ffmpeg against it via system/rebuild-ffmpeg.sh. Co-Authored-By: Claude Opus 5.5 --- README.md | 10 +- bootstrap.sh | 166 +++++++++++++++++++++++++++++++++ system/packages.txt | 197 +++++++++++++++++++++++++++++++++++++++ system/rebuild-ffmpeg.sh | 27 ++++++ 4 files changed, 399 insertions(+), 1 deletion(-) create mode 100755 bootstrap.sh create mode 100644 system/packages.txt create mode 100755 system/rebuild-ffmpeg.sh diff --git a/README.md b/README.md index b689728..b7254bf 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,15 @@ mkdir Projects git clone ssh://git@gitea.thomasleewilliams.co.uk:2222/thomas/dotfiles.git ``` -Once that is complete, run this command: +On a fresh install, run the bootstrap script. It installs drivers (auto-detected), +every package in `system/packages.txt`, yay, flatpaks, then links the dotfiles and +system config below: +```console +~/Projects/dotfiles/bootstrap.sh # asks about the optional SVT-AV1 + ffmpeg rebuild +~/Projects/dotfiles/bootstrap.sh --svt-av1 # or --no-svt-av1 to skip the question +``` + +To only link the dotfiles, run this command: ```console stow -d ~/Projects/dotfiles/ -t ~/ dotfiles ``` diff --git a/bootstrap.sh b/bootstrap.sh new file mode 100755 index 0000000..516ed28 --- /dev/null +++ b/bootstrap.sh @@ -0,0 +1,166 @@ +#!/usr/bin/env bash +# Sets up a fresh Arch install: drivers, packages, dotfiles and system config. +# Safe to re-run; anything already installed is skipped. +# +# Usage: ./bootstrap.sh [--svt-av1 | --no-svt-av1] +# --svt-av1 also install svt-av1-essential-git and rebuild ffmpeg against it +# --no-svt-av1 skip that without asking +# (neither) ask +set -euo pipefail + +repo="$(cd "$(dirname "$0")" && pwd)" +list="$repo/system/packages.txt" + +svt_av1=ask +for arg in "$@"; do + case "$arg" in + --svt-av1) svt_av1=yes ;; + --no-svt-av1) svt_av1=no ;; + *) echo "Unknown option: $arg" >&2; exit 1 ;; + esac +done + +if (( EUID == 0 )); then + echo "Run this as your normal user, not root (it uses sudo where needed)." >&2 + exit 1 +fi + +step() { printf '\n\033[1;34m==> %s\033[0m\n' "$*"; } + +# Prints the packages under a [section] of packages.txt, skipping comments +packages() { + awk -v want="[$1]" ' + /^\[/ { section = $1; next } + section == want { sub(/#.*/, ""); if (NF) print $1 } + ' "$list" +} + +# --- System config ----------------------------------------------------------- + +step "System config (pacman options)" +"$repo/system/install.sh" + +step "Enabling multilib (needed for Steam and 32-bit drivers)" +if ! grep -q '^\[multilib\]' /etc/pacman.conf; then + sudo sed -i '/^#\[multilib\]/,/^#Include/ s/^#//' /etc/pacman.conf +fi +sudo pacman -Syu --needed --noconfirm pciutils git base-devel + +# --- Hardware ---------------------------------------------------------------- + +step "Detecting CPU and GPU" +hw=() + +case "$(grep -m1 '^vendor_id' /proc/cpuinfo | awk '{print $3}')" in + AuthenticAMD) hw+=(amd-ucode); echo "CPU: AMD" ;; + GenuineIntel) hw+=(intel-ucode); echo "CPU: Intel" ;; + *) echo "CPU: unknown vendor, skipping microcode" ;; +esac + +# Vendor column of every display controller, e.g. "NVIDIA Corporation" +gpus="$(lspci -mm | awk -F'"' '$2 ~ /VGA|3D|Display/ { print $4 }')" +if grep -q NVIDIA <<<"$gpus"; then + echo "GPU: NVIDIA" + # nvidia-open only ships modules for the stock `linux` kernel; any other + # kernel needs the DKMS build. Supports Turing (GTX 16xx / RTX 20xx) and newer. + if pacman -Qq linux-lts linux-zen linux-hardened >/dev/null 2>&1; then + hw+=(nvidia-open-dkms linux-headers) + else + hw+=(nvidia-open) + fi + hw+=(nvidia-utils lib32-nvidia-utils libva-nvidia-driver) +fi +if grep -q 'Advanced Micro Devices' <<<"$gpus"; then + echo "GPU: AMD" + hw+=(mesa lib32-mesa vulkan-radeon lib32-vulkan-radeon) +fi +if grep -q 'Intel Corporation' <<<"$gpus"; then + echo "GPU: Intel" + hw+=(mesa lib32-mesa vulkan-intel lib32-vulkan-intel intel-media-driver) +fi + +# Installed before the main list so Steam's 32-bit Vulkan dependency is +# already satisfied by the right driver +if (( ${#hw[@]} )); then + sudo pacman -S --needed --noconfirm "${hw[@]}" +fi + +# --- Packages ---------------------------------------------------------------- + +step "Official repo packages" +mapfile -t pkgs < <(packages pacman) +sudo pacman -S --needed --noconfirm "${pkgs[@]}" + +step "yay (AUR helper)" +if ! command -v yay >/dev/null; then + build="$(mktemp -d)" + git clone https://aur.archlinux.org/yay-bin.git "$build/yay-bin" + (cd "$build/yay-bin" && makepkg -si --noconfirm) + rm -rf "$build" +else + echo "already installed" +fi + +step "AUR packages" +mapfile -t pkgs < <(packages aur) +yay -S --needed --noconfirm "${pkgs[@]}" + +step "Flatpak apps" +sudo flatpak remote-add --if-not-exists flathub https://dl.flathub.org/repo/flathub.flatpakrepo +mapfile -t pkgs < <(packages flatpak) +sudo flatpak install -y --noninteractive flathub "${pkgs[@]}" + +step "Apps from official install scripts" +mkdir -p "$HOME/.local/bin" +for app in $(packages installer); do + if command -v "$app" >/dev/null || [[ -x "$HOME/.local/bin/$app" ]]; then + echo "$app: already installed" + continue + fi + case "$app" in + claude) curl -fsSL https://claude.ai/install.sh | bash ;; + oh-my-posh) curl -fsSL https://ohmyposh.dev/install.sh | bash -s -- -d "$HOME/.local/bin" ;; + *) echo "$app: no install recipe in bootstrap.sh, skipping" >&2 ;; + esac +done + +# --- Optional: SVT-AV1 essential + ffmpeg rebuild ---------------------------- + +if [[ $svt_av1 == ask ]]; then + read -rp $'\nInstall svt-av1-essential-git and rebuild ffmpeg against it? (slow) [y/N] ' reply + [[ $reply == [yY]* ]] && svt_av1=yes || svt_av1=no +fi +if [[ $svt_av1 == yes ]]; then + step "svt-av1-essential-git" + # Interactive on purpose: pacman asks to replace the conflicting svt-av1, + # and --noconfirm would answer no + yay -S --needed svt-av1-essential-git + step "Rebuilding ffmpeg against svt-av1-essential-git" + "$repo/system/rebuild-ffmpeg.sh" +fi + +# --- Services ---------------------------------------------------------------- + +step "Enabling services" +# Not started now: sddm would take over the screen mid-script. They come up on reboot. +mapfile -t units < <(packages services) +sudo systemctl enable "${units[@]}" + +# --- Dotfiles ---------------------------------------------------------------- + +step "Linking dotfiles with stow" +# Create real parent dirs first, otherwise stow symlinks the whole directory +# (e.g. ~/.config) into the repo and every app's files end up in git +mkdir -p "$HOME/.config" "$HOME/.local/bin" "$HOME/.local/share" "$HOME/Pictures" +mkdir -p -m 700 "$HOME/.ssh" +if ! stow -d "$repo" -t "$HOME" --restow dotfiles; then + echo "stow hit conflicts (listed above). Move those files aside, then run:" >&2 + echo " stow -d \"$repo\" -t \"\$HOME\" dotfiles" >&2 +fi + +if [[ "$(getent passwd "$USER" | cut -d: -f7)" != */zsh ]]; then + step "Setting zsh as login shell" + chsh -s /usr/bin/zsh +fi + +step "Done — reboot to load drivers and start Hyprland" diff --git a/system/packages.txt b/system/packages.txt new file mode 100644 index 0000000..8d8812f --- /dev/null +++ b/system/packages.txt @@ -0,0 +1,197 @@ +# ============================================================================ +# Packages installed by bootstrap.sh on a new machine. +# +# - One package per line; anything after "#" is a description. +# - Lines starting with "#" are skipped (left here for reference). +# - [section] lines tell bootstrap.sh which installer to use; +# [services] lists systemd units to enable. +# +# Not listed here (bootstrap.sh handles them itself): +# - CPU microcode and GPU drivers: auto-detected from the hardware +# - yay: bootstrapped from the AUR before the [aur] section +# - svt-av1-essential-git: optional, also rebuilds ffmpeg against it +# ============================================================================ + +[pacman] +adw-gtk-theme # Unofficial GTK 3 port of the libadwaita theme +# amd-ucode # Microcode update image for AMD CPUs -- auto-detected by bootstrap.sh +awww # An Answer to your Wayland Wallpaper Woes +baobab # A graphical directory tree analyzer +base # Minimal package set to define a basic Arch Linux installation +base-devel # Basic tools to build Arch Linux packages +blueman # GTK+ Bluetooth Manager +bluez # Daemons for the bluetooth protocol stack +bluez-utils # Development and debugging utilities for the bluetooth protocol stack +btop # A monitor of system resources, bpytop ported to C++ +dolphin # KDE File Manager +# dunst # Customizable and lightweight notification-daemon !! you use swaync for notifications +efibootmgr # Linux user-space application to modify the EFI Boot Manager +fastfetch # A feature-rich and performance oriented neofetch like system information tool +ffmpeg # Complete solution to record, convert and stream audio and video +filezilla # Fast and reliable FTP, FTPS and SFTP client +firefox # Fast, Private & Safe Web Browser +flatpak # Linux application sandboxing and distribution framework (formerly xdg-app) +foot # Fast, lightweight, and minimalistic Wayland terminal emulator +fzf # Command-line fuzzy finder +galculator # GTK based scientific calculator +# garcon # Freedesktop.org compliant menu library !! XFCE desktop leftover? +gdu # Fast disk usage analyzer +git # the fast distributed version control system +gnome-calendar # Simple and beautiful calendar application designed to perfectly fit the GNOME desktop +gnome-disk-utility # Disk Management Utility for GNOME +gnome-font-viewer # A font viewer utility for GNOME +gnome-keyring # Stores passwords and encryption keys +gnome-text-editor # A simple text editor for the GNOME desktop +grim # Screenshot utility for Wayland +gst-plugin-pipewire # Multimedia graph framework - pipewire plugin +gvfs # Virtual filesystem implementation for GIO +gvfs-smb # Virtual filesystem implementation for GIO - SMB/CIFS backend (Windows file sharing) +htop # Interactive process viewer +hypridle # hyprland’s idle daemon +hyprland # a highly customizable dynamic tiling Wayland compositor +hyprlock # hyprland’s GPU-accelerated screen locking utility +hyprshot # Hyprland screenshot utility +imv # Image viewer for Wayland and X11 +jq # Command-line JSON processor +# kitty # A modern, hackable, featureful, OpenGL-based terminal emulator !! you use foot as terminal (kitty config not in dotfiles) +libgsf # Extensible I/O abstraction library for dealing with structured file formats +libmatroska # Matroska library +libpulse # A featureful, general-purpose sound server (client library) +# libva-nvidia-driver # VA-API implementation that uses NVDEC as a backend -- auto-detected by bootstrap.sh +linux # The Linux kernel and modules +linux-firmware # Firmware files for Linux - Default set +mkinitcpio # Modular initramfs image creation utility +mkvtoolnix-cli # Set of tools to create, edit and inspect Matroska files +mpv # a free, open source, and cross-platform media player +mullvad-vpn-daemon # Mullvad VPN client (daemon and CLI) +nano # Pico editor clone with enhancements +network-manager-applet # Applet for managing network connections +networkmanager # Network connection manager and user applications +noto-fonts # Google Noto TTF fonts +noto-fonts-cjk # Google Noto CJK fonts +noto-fonts-emoji # Google Noto Color Emoji font +noto-fonts-extra # Google Noto TTF fonts - additional variants +npm # JavaScript package manager +nss-mdns # glibc plugin providing host name resolution via mDNS +# nvidia-open # NVIDIA open kernel modules -- auto-detected by bootstrap.sh +pacman-contrib # Contributed scripts and tools for pacman systems +pam-u2f # Universal 2nd Factor (U2F) PAM authentication module from Yubico +papirus-icon-theme # Papirus icon theme +pipewire # Low-latency audio/video router and processor +pipewire-alsa # Low-latency audio/video router and processor - ALSA configuration +pipewire-jack # Low-latency audio/video router and processor - JACK replacement +pipewire-pulse # Low-latency audio/video router and processor - PulseAudio replacement +pnpm # Fast, disk space efficient package manager +polkit-kde-agent # Daemon providing a polkit authentication UI for KDE +postgresql # Sophisticated object-relational DBMS +postgresql-libs # Sophisticated object-relational DBMS - Client binaries and libraries +proton-vpn-cli # Official ProtonVPN CLI Linux app +qt5-wayland # Provides APIs for Wayland +qt6-quickeffectmaker # Qt Quick Effect Maker (QQEM) for creating and editing custom shader effects +qt6-wayland # Provides APIs for Wayland +rofi # A window switcher, application launcher and dmenu replacement +sddm # QML based X11 and Wayland display manager +slurp # Select a region in a Wayland compositor +smartmontools # Control and monitor S.M.A.R.T. enabled ATA and SCSI Hard Drives +steam # Valve's digital software delivery system +stow # Manage installation of multiple softwares in the same directory tree +sudo # Give certain users the ability to run some commands as root +swaync # A simple GTK based notification daemon for Sway +tailscale # A mesh VPN that makes it easy to connect your devices, wherever they are. +thunar # Modern, fast and easy-to-use file manager for Xfce +thunar-archive-plugin # Adds archive operations to the Thunar file context menus +thunar-media-tags-plugin # Adds special features for media files to the Thunar File Manager +thunar-shares-plugin # Thunar plugin to quickly share a folder using Samba without requiring root access +thunar-volman # Automatic management of removable drives and media for Thunar +ttf-dejavu # Font family based on the Bitstream Vera Fonts with a wider range of characters +ttf-iosevka-nerd # Patched font Iosevka from nerd fonts library +ttf-jetbrains-mono # Typeface for developers, by JetBrains +ttf-jetbrains-mono-nerd # Patched font JetBrains Mono from nerd fonts library +ttf-liberation # Font family which aims at metric compatibility with Arial, Times New Roman, and Courier New +ttf-material-icons # Material Design icons by Google (deprecated classic Material Icons static style) +ttf-material-symbols-variable # Material Design icons by Google (Material Symbols - 4 axis variable) +ttf-noto-nerd # Patched font Noto from nerd fonts library +tumbler # Thumbnail service implementing the thumbnail management D-Bus specification +uv # An extremely fast Python package installer and resolver written in Rust +uwsm # A standalone Wayland session manager +vim # Vi Improved, a highly configurable, improved version of the vi text editor +# waybar # Highly customizable Wayland bar for Sway and Wlroots based compositors !! you've switched to quickshell (waybar is commented out in startup.lua) +webp-pixbuf-loader # WebM GDK Pixbuf Loader library +wget # Network utility to retrieve files from the web +wireplumber # Session / policy manager implementation for PipeWire +# wofi # launcher for wlroots-based wayland compositors !! you also have rofi — need both? +wpa_supplicant # A utility providing key negotiation for WPA wireless networks +xarchiver # GTK frontend to various command line archivers +xdg-desktop-portal-hyprland # xdg-desktop-portal backend for hyprland +xdg-utils # Command line tools that assist applications with a variety of desktop integration tasks +# xfce4-appfinder # Application launcher and finder !! XFCE desktop leftover? +# xfce4-panel # Panel for the Xfce desktop environment !! XFCE desktop leftover? +# xfce4-power-manager # Power Manager for Xfce !! XFCE desktop leftover? +# xfce4-session # Xfce's session manager !! XFCE desktop leftover? +# xfce4-settings # Xfce's Configuration System !! XFCE desktop leftover? +# xfce4-terminal # A modern terminal emulator primarily for the Xfce desktop environment !! XFCE desktop leftover? +# xfdesktop # Xfce's desktop manager !! XFCE desktop leftover? +# xfwm4 # Xfce's window manager !! XFCE desktop leftover? +zram-generator # Systemd unit generator for zram devices +zsh # A very advanced and programmable command interpreter (shell) for UNIX + +# Used by the dotfiles, previously only pulled in by caelestia-shell / waybar +brightnessctl # Backlight control (quickshell, hypr keybinds) +cliphist # Clipboard history (wl-paste watcher in startup.lua) +playerctl # Media key control +power-profiles-daemon # Power profiles (quickshell battery widget) +wl-clipboard # wl-copy / wl-paste +openssh # SSH client/server (sshd service, git over ssh) +avahi # mDNS daemon (avahi-daemon service, used by nss-mdns) + +[aur] +bitwarden-bin # A secure and free password manager for all of your devices. +# caelestia-shell # The desktop shell for the Caelestia dotfiles !! alternative quickshell config, not used by your shell.qml +flutter-bin # Cross platform widget toolkit for Dart (monolithic) +google-chrome # The popular web browser by Google (Stable Channel) +hyprmod # Native GTK4/libadwaita settings app for Hyprland +# jellyfin-desktop-debug # Detached debugging symbols for jellyfin-desktop !! debug symbols, not needed +minecraft-launcher # Official Minecraft Launcher +# orbit-wifi # A WiFi/Bluetooth manager for Wayland with glassmorphism UI !! removed from your config in commit 88484f8 +plex-desktop # Plex desktop client for linux +plexamp-bin # Modern music client for Plex.(Prebuilt version.Use system-wide electron) +puddletag # An audio tag editor for GNU/Linux +quickshell-git # The shell your bar/OSD run on (previously a caelestia-shell dependency) +pwvucontrol # Pipewire volume control for GNOME +python-pywal # Generate and change colorschemes on the fly +raw-thumbnailer # A lightweight and fast raw image thumbnailer that can be used by file managers. +seafile-client # GUI client for synchronizing your local files with seafile server +sunshine # Self-hosted game stream host for Moonlight +# svt-av1-essential-git # A no-nonsense SVT-AV1 encoder fork with sensible defaults and Quality of Life improvements -- optional step in bootstrap.sh (rebuilds ffmpeg) +ttf-icomoon-feather # Icomoon feather font +tumbler-extra-thumbnailers # Customized thumbnailers for Tumbler +turritopsis # Desktop Jellyfin client with mpv playback +vesktop # A standalone Electron-based Discord app with Vencord & improved Linux support +visual-studio-code-bin # Visual Studio Code (vscode) +waypaper # GUI wallpaper setter for Wayland and Xorg window managers. It works as a frontend for popular wallpaper backends like swaybg, swww, wallutils, hyprpaper and feh. +# yay # Yet another yogurt. Pacman wrapper and AUR helper written in go. !! bootstrapped by the script itself anyway +# yay-debug # Detached debugging symbols for yay !! debug symbols, not needed +zen-browser-bin # Official package for Zen, a privacy-focused, feature packed Firefox-based web browser + +[flatpak] +com.makemkv.MakeMKV # MakeMKV +org.jellyfin.JellyfinDesktop # Jellyfin Desktop + +[installer] # official install scripts, see bootstrap.sh +claude # Claude Code CLI (official install script) +oh-my-posh # Prompt theme engine (official install script; your theme is already in dotfiles) +# ffmpeg # Static ffmpeg build — !! duplicate, ffmpeg is also installed via pacman above +# python3.13 # Standalone Python 3.13 — !! probably not needed, uv can provide Python + +[services] # enabled with systemctl, start on next boot +NetworkManager.service # Networking +bluetooth.service # Bluetooth +sddm.service # Login screen +sshd.service # SSH server +avahi-daemon.service # mDNS / .local hostnames +systemd-resolved.service # DNS resolver (used by the VPNs) +systemd-timesyncd.service # Clock sync +fstrim.timer # Weekly SSD trim +tailscaled.service # Tailscale +mullvad-daemon.service # Mullvad VPN +proton.VPN.service # Proton VPN diff --git a/system/rebuild-ffmpeg.sh b/system/rebuild-ffmpeg.sh new file mode 100755 index 0000000..aed08fd --- /dev/null +++ b/system/rebuild-ffmpeg.sh @@ -0,0 +1,27 @@ +#!/usr/bin/env bash +# Rebuilds Arch's ffmpeg package from source so it links against the installed +# svt-av1-essential-git instead of the repo svt-av1 it was built with. +# +# Re-run this after a `pacman -Syu` that updates ffmpeg, otherwise the repo +# build replaces this one. +set -euo pipefail + +if ! pacman -Qq svt-av1-essential-git >/dev/null 2>&1; then + echo "svt-av1-essential-git is not installed; nothing to rebuild against." >&2 + exit 1 +fi + +build="$(mktemp -d)" +trap 'rm -rf "$build"' EXIT + +git clone --depth 1 https://gitlab.archlinux.org/archlinux/packaging/packages/ffmpeg.git "$build/ffmpeg" +cd "$build/ffmpeg" + +# The PKGBUILD verifies a signed ffmpeg tag; makepkg won't fetch the keys itself +mapfile -t keys < <(source ./PKGBUILD && printf '%s\n' "${validpgpkeys[@]}") +if (( ${#keys[@]} )); then + gpg --keyserver hkps://keyserver.ubuntu.com --recv-keys "${keys[@]}" +fi + +# No --needed: the version matches what's installed, we want it replaced anyway +makepkg --syncdeps --install --cleanbuild --noconfirm