Initial commit: linux-provision repo
Distribution-agnostic provisioning script that sets up a new Linux machine (Detected via lib/distro.sh - supports Debian/Ubuntu/Pop and Fedora families). 13 stages covering: - System packages, external repos, toolchains (nvm, uv, Python) - Shell config (zsh, oh-my-zsh, p10k), git, SSH - Custom uv tools from ~40 git repos - Desktop config (keybindings, hotkeys, ghostty, fonts) - Docker, system tweaks, browser/app installs - Custom systemd user services (porridge, swayidle, mempi-sync, etc.) - API keys loaded from Bitwarden at shell startup
This commit is contained in:
131
provision.sh
Executable file
131
provision.sh
Executable file
@@ -0,0 +1,131 @@
|
||||
#!/usr/bin/env bash
|
||||
# ===========================================================================
|
||||
# Linux Machine Provisioning — Master Orchestrator
|
||||
# ===========================================================================
|
||||
# Usage:
|
||||
# bash provision.sh --all # Run all stages in order
|
||||
# bash provision.sh --stage <name> # Run a single stage
|
||||
# bash provision.sh --list # List all stages
|
||||
# source provision.sh --interactive # Source for manual calls
|
||||
#
|
||||
# Distribution-agnostic — detects Debian/Ubuntu/Pop/Fedora and adjusts
|
||||
# package manager, repo config, etc. automatically.
|
||||
# ===========================================================================
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
STAGES_DIR="${SCRIPT_DIR}/stages"
|
||||
LIBS_DIR="${SCRIPT_DIR}/lib"
|
||||
CONFIG_DIR="${SCRIPT_DIR}/config"
|
||||
|
||||
# ---- Source distro detection first ----
|
||||
source "${LIBS_DIR}/distro.sh"
|
||||
|
||||
# ---- Colour helpers ----
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m'
|
||||
|
||||
info() { echo -e "${BLUE}[INFO]${NC} $*"; }
|
||||
ok() { echo -e "${GREEN}[OK]${NC} $*"; }
|
||||
warn() { echo -e "${YELLOW}[WARN]${NC} $*"; }
|
||||
error() { echo -e "${RED}[ERROR]${NC} $*"; }
|
||||
|
||||
# ---- Available stages ----
|
||||
STAGES=(
|
||||
"00-envcheck" # Environment checks (uses lib/distro.sh vars)
|
||||
"01-repos" # Third-party repositories
|
||||
"02-packages" # System packages
|
||||
"03-toolchains" # nvm, Node, uv, Python
|
||||
"04-shell" # Zsh, oh-my-zsh, p10k
|
||||
"05-git" # Git config, SSH
|
||||
"06-uv-projects" # Clone + install Julian's Python tools
|
||||
"07-scripts" # ~/.local/bin custom scripts
|
||||
"08-systemd" # User systemd services
|
||||
"09-desktop" # Keybindings, hotkeys, desktop config
|
||||
"10-docker" # Docker CE
|
||||
"11-tweaks" # sysctl, kernel, TLP/powertop
|
||||
"12-other-apps" # Chrome, Signal, Zotero
|
||||
)
|
||||
|
||||
# ===========================================================================
|
||||
# Stage Runner
|
||||
# ===========================================================================
|
||||
|
||||
run_stage() {
|
||||
local stage_name="$1"
|
||||
local stage_file="${STAGES_DIR}/${stage_name}.sh"
|
||||
|
||||
if [ ! -f "$stage_file" ]; then
|
||||
error "Stage script not found: ${stage_file}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
info "=============================================="
|
||||
info " Running stage: ${stage_name}"
|
||||
info "=============================================="
|
||||
|
||||
source "$stage_file"
|
||||
|
||||
ok "Stage '${stage_name}' completed."
|
||||
echo ""
|
||||
}
|
||||
|
||||
# ===========================================================================
|
||||
# Main
|
||||
# ===========================================================================
|
||||
|
||||
main() {
|
||||
local mode="${1:-}"
|
||||
|
||||
case "$mode" in
|
||||
--all)
|
||||
info "Starting full provisioning on ${DISTRO_ID} ${DISTRO_VERSION} (${DISTRO_FAMILY})"
|
||||
info "You may be prompted for sudo password."
|
||||
for stage in "${STAGES[@]}"; do
|
||||
run_stage "$stage" || warn "Stage '${stage}' failed (continuing)."
|
||||
done
|
||||
ok "Provisioning complete!"
|
||||
warn "Review TODO.md for manual post-install steps."
|
||||
;;
|
||||
|
||||
--stage)
|
||||
local target="${2:-}"
|
||||
if [ -z "$target" ]; then
|
||||
error "Usage: provision.sh --stage <stage-name>"
|
||||
exit 1
|
||||
fi
|
||||
run_stage "$target"
|
||||
;;
|
||||
|
||||
--list)
|
||||
echo "Available stages (distro: ${DISTRO_ID} / ${DISTRO_FAMILY}):"
|
||||
for stage in "${STAGES[@]}"; do
|
||||
echo " ${stage}"
|
||||
done
|
||||
;;
|
||||
|
||||
--interactive)
|
||||
info "Sourcing stage functions for interactive use."
|
||||
for stage in "${STAGES[@]}"; do
|
||||
local f="${STAGES_DIR}/${stage}.sh"
|
||||
[ -f "$f" ] && source "$f"
|
||||
done
|
||||
info "Stages loaded. Call: run_stage <stage-name>"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Usage:"
|
||||
echo " bash provision.sh --all # Run everything"
|
||||
echo " bash provision.sh --stage <name> # Run one stage"
|
||||
echo " bash provision.sh --list # List stages"
|
||||
echo " source provision.sh --interactive # Load for manual use"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user