#!/bin/bash # # Purpose : MiniServer installer # Wrapped in { ...; exit; } so bash reads the whole script up front; the git # pull below can replace this file while it runs. { # Print the logo print_logo() { cat << "EOF" ███╗ ███╗██╗███╗ ██╗██╗ ████╗ ████║██║████╗ ██║██║ ██╔████╔██║██║██╔██╗ ██║██║ ██║╚██╔╝██║██║██║╚██╗██║██║ ██║ ╚═╝ ██║██║██║ ╚████║██║ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝╚═╝ ███████╗███████╗██████╗ ██╗ ██╗███████╗██████╗ ██╔════╝██╔════╝██╔══██╗██║ ██║██╔════╝██╔══██╗ ███████╗█████╗ ██████╔╝██║ ██║█████╗ ██████╔╝ ╚════██║██╔══╝ ██╔══██╗╚██╗ ██╔╝██╔══╝ ██╔══██╗ ███████║███████╗██║ ██║ ╚████╔╝ ███████╗██║ ██║ ╚══════╝╚══════╝╚═╝ ╚═╝ ╚═══╝ ╚══════╝╚═╝ ╚═╝ EOF } # --- Main --- set -e export PATH="$HOME/.local/bin:$PATH" if ! grep -q 'LOCAL_BIN_PATH' "$HOME/.bashrc"; then echo '' >> "$HOME/.bashrc" echo '# Mini: add user local bin to PATH' >> "$HOME/.bashrc" echo 'export PATH="$HOME/.local/bin:$PATH" # LOCAL_BIN_PATH' >> "$HOME/.bashrc" fi clear print_logo cd ~ sudo -v # Grant passwordless sudo for the duration of the install, revoke on exit echo "$USER ALL=(ALL) NOPASSWD: ALL" | sudo tee /etc/sudoers.d/99-miniserver-install > /dev/null sudo chmod 440 /etc/sudoers.d/99-miniserver-install trap "sudo rm -f /etc/sudoers.d/99-miniserver-install" EXIT if ! command -v git &> /dev/null; then echo "Installing git..." sudo pacman -S --noconfirm git fi if ! pacman -Qi base-devel &> /dev/null; then echo "Installing base-devel..." sudo pacman -S --noconfirm base-devel else echo "base-devel is already installed, skipping." fi echo "Getting the latest version of MiniServer..." if [ -d "$HOME/.local/share/MiniServer/.git" ]; then git -C "$HOME/.local/share/MiniServer" pull else git clone https://gitea.young.computer/david/MiniServer.git "$HOME/.local/share/MiniServer" > /dev/null fi cd ~/.local/share/MiniServer # Source utility functions (provides install_packages, install_script and other helpers) source utils.sh # Install the refresh, update, sibling, version and configure scripts to the user's bin mkdir -p "$HOME/.local/bin" install_script "$HOME/.local/share/MiniServer/refresh" "$HOME/.local/bin/refresh" install_script "$HOME/.local/share/MiniServer/update" "$HOME/.local/bin/update" install_script "$HOME/.local/share/MiniServer/sibling" "$HOME/.local/bin/sibling" install_script "$HOME/.local/share/MiniServer/version" "$HOME/.local/bin/version" install_script "$HOME/.local/share/MiniServer/configure" "$HOME/.local/bin/configure" # Replaced by refresh and update rm -f "$HOME/.local/bin/miniserverrefresh" "$HOME/.local/bin/miniserverupdate" echo "Updating system..." sudo pacman -Syu --noconfirm install_yay() { rm -rf /tmp/yay git clone https://aur.archlinux.org/yay.git /tmp/yay cd /tmp/yay makepkg -si --noconfirm cd ~/.local/share/MiniServer rm -rf /tmp/yay } if ! command -v yay &> /dev/null; then echo "Installing yay AUR helper..." install_yay else echo "yay is already installed, skipping." fi if ! yay --version &> /dev/null; then echo "yay does not appear to be working, reinstalling..." install_yay fi # Source package list if [ ! -f "packages.conf" ]; then echo "Error: packages.conf not found!" exit 1 fi source packages.conf echo "Installing servers..." install_packages "${SERVERS[@]}" echo "Installing utilities..." install_packages "${UTILITIES[@]}" echo "Installing shell tools..." install_packages "${SHELL_TOOLS[@]}" echo "Installing AI agents and their sandbox..." install_packages "${AGENTS[@]}" if ! command -v pm2 &> /dev/null; then npm install pm2 -g --prefix "$HOME/.local" fi cd ~/.local/share/MiniServer # Fix Networking . fix-networking.sh # Set up Cockpit (installed with the utilities above) setup_cockpit echo "Cockpit is at https://$(uname -n).local:9090" # Set up firewalld (installed with the utilities above) setup_firewall || echo "Some firewall rules could not be applied, see above. Run 'update' to retry." # Install Sway config files if [ ! -d "$HOME/.config/sway" ]; then mkdir -p "$HOME/.config/sway" cp /etc/sway/config "$HOME/.config/sway/config" fi # Enable SDDM if ! systemctl is-enabled --quiet sddm; then sudo systemctl enable sddm fi # Install Claude Code echo "Installing Claude Code..." bash ~/.local/share/MiniServer/claude.sh # Run AI agents (opencode, hermes) in a sandbox, and turn on Claude Code's own echo "Setting up sandboxed AI agents..." bash ~/.local/share/MiniServer/sandbox/setup.sh # Prompt, zoxide, fzf key bindings, aliases and functions echo "Configuring the shell..." bash ~/.local/share/MiniServer/shell/setup.sh # Run one-time migrations not yet recorded on this machine. On a fresh install # they repeat setup done above, which is safe because each one is idempotent. echo "Running migrations..." run_migrations # Offer configure only if something is still to do, as refresh runs this too. # This script is usually piped into bash, so ask on the terminal, not stdin. if ~/.local/bin/configure --list | grep -q '^to do'; then echo echo "configure mounts your Nextcloud files and signs you in to the AI agents." if { : < /dev/tty; } 2> /dev/null && read -rp "Run configure now? [Y/n] " answer < /dev/tty \ && [[ "$answer" != [nN]* ]]; then ~/.local/bin/configure < /dev/tty || true else echo "To do it later, run: configure" fi fi echo "" read -rp "A reboot is required to complete setup. Reboot now? [y/N] " response /dev/null 2>&1; then echo "A newer kernel has been installed, a reboot is recommended." read -rp "Reboot now? [y/N] " response case "$response" in [yY][eE][sS]|[yY]) echo "Rebooting..." sudo reboot ;; *) echo "Reboot skipped. Please remember to reboot when convenient." exit 0 ;; esac else echo "Kernel is up to date, no reboot needed. You may want to consider a reboot if other significant software was updated or installed." fi exit }