Files
coredesktop/install.sh
T
2026-10-29 09:41:43 -06:00

244 lines
8.4 KiB
Bash
Executable File

#!/bin/bash -i
#
# Purpose : CoreDesktop installer
# Print the logo
print_logo() {
cat << "EOF"
██
█ ██
██ ██████ █████ ██ █████ █████ ████ ██ █████ ██
██ ██ ██ ███ ███████ ██ ██ ██ ██ ██ ████████ ██ ██ ███████
█████ ██████ ██ ██ ██████ ██ ████████ ██ █ ███████ ██ ██
██ ██████ ███████ ██████ ██ ██████ ██████ ██████ ███████
EOF
}
# Clear screen and show logo
clear
print_logo
cd
# Exit on any error
set -e
# Ask for the password once, then keep sudo's cached credentials fresh until
# the install exits, so long builds don't stop for a password again. Unlike a
# passwordless sudoers entry, nothing is left behind if the install is killed.
sudo -v
while kill -0 $$ 2> /dev/null; do sudo -n -v; sleep 60; done 2> /dev/null &
SUDO_KEEPALIVE_PID=$!
trap 'kill "$SUDO_KEEPALIVE_PID" 2> /dev/null' EXIT
# Ensure git is available before attempting to clone anything
if ! command -v git &> /dev/null; then
echo "Installing git..."
sudo pacman -S git --noconfirm
else
echo "git is installed."
fi
# Update or clone the CoreDesktop repo
echo "Getting the latest version of CoreDesktop..."
if [ -d "$HOME/.local/share/coredesktop/.git" ]; then
git -C ~/.local/share/coredesktop pull
else
git clone https://gitea.federated.computer/Federated_Computer/coredesktop.git ~/.local/share/coredesktop
fi
cd ~/.local/share/coredesktop
# Source utility functions (provides install_packages and other helpers)
source utils.sh
# Install the refresh, update, sibling, version, configure and audit scripts to the user's bin
mkdir -p ~/.local/bin
install_script ~/.local/share/coredesktop/refresh ~/.local/bin/refresh
install_script ~/.local/share/coredesktop/update ~/.local/bin/update
install_script ~/.local/share/coredesktop/sibling ~/.local/bin/sibling
install_script ~/.local/share/coredesktop/version ~/.local/bin/version
install_script ~/.local/share/coredesktop/configure ~/.local/bin/configure
install_script ~/.local/share/coredesktop/audit ~/.local/bin/audit
# Source the package list (defines SYSTEM_UTILS, DEV_TOOLS, DESKTOP, etc. arrays)
if [ ! -f "packages.conf" ]; then
echo "Error: packages.conf not found!"
exit 1
fi
source packages.conf
echo "Starting full system setup..."
# Federated Computer's own packages (Federated Calendar, ...)
echo "Adding the Federated Computer package repo..."
ensure_federated_repo
# Bring the system fully up to date before installing anything new
echo "Updating system..."
sudo pacman -Sy --needed --noconfirm archlinux-keyring
sudo pacman -Su --noconfirm
cd ~/
# Install yay AUR helper if not present — required for AUR packages installed later
if ! command -v yay &> /dev/null; then
echo "Installing yay AUR helper..."
sudo pacman -S --needed git base-devel --noconfirm
if [[ -d "yay" ]]; then
echo "yay directory already exists, removing it..."
rm -rf yay
fi
echo "Cloning yay repository..."
git clone https://aur.archlinux.org/yay.git
cd yay
echo "Building yay..."
makepkg -si --noconfirm
cd ..
rm -rf yay
else
echo "yay is already installed."
fi
# Install packages grouped by category as defined in packages.conf
echo "Installing system utilities..."
install_packages "${SYSTEM_UTILS[@]}"
echo "Installing development tools..."
install_packages "${DEV_TOOLS[@]}"
echo "Installing system maintenance tools..."
install_packages "${MAINTENANCE[@]}"
echo "Installing desktop environment..."
install_packages "${DESKTOP[@]}"
echo "Installing media packages..."
install_packages "${MEDIA[@]}"
echo "Installing fonts..."
install_packages "${FONTS[@]}"
echo "Installing pipx applications..."
install_pipx_apps "${PIPX[@]}"
# Enable the services in SERVICES, and enable and start those in START_SERVICES,
# then register the SSH Avahi service so the machine is discoverable over mDNS
echo "Configuring services..."
enable_services "${SERVICES[@]}"
enable_services --now "${START_SERVICES[@]}"
sudo cp /usr/share/doc/avahi/ssh.service /etc/avahi/services/
cd ~/.local/share/coredesktop
# Install GNOME shell extensions via the dedicated script
echo "Installing GNOME extensions..."
. gnome/gnome-extensions.sh
# Install Flatpak apps — some programs run better sandboxed as Flatpaks
echo "Installing flatpaks..."
. install-flatpaks.sh
# Install TPM (Tmux Plugin Manager) and configured plugins
echo "Installing tmux plug-in manager..."
. install-tpm.sh
# Install Mise version manager, then use it to set up Ruby and Rails
echo "Installing Mise, Ruby, Rails..."
cd ~/.local/share/coredesktop
. install-mise-ruby-rails.sh
# Install Kickstart Neovim config as the default Neovim configuration
echo "Installing Kickstart Neovim..."
. install-kickstart-nvim.sh
# Install Claude Code and configure desktop notification hooks
echo "Installing Claude Code..."
bash 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/coredesktop/sandbox/setup.sh
# Configure Bitwarden SSH agent
echo "Configuring Bitwarden SSH agent..."
. bitwarden.sh
# Add the current user to the docker group and start the Docker daemon
# Group membership takes effect at next login (newgrp would start an interactive shell)
sudo usermod -aG docker $USER
sudo systemctl enable docker.service
sudo systemctl start docker.service
# Enable and start Tailscale daemon
if ! systemctl is-enabled tailscaled &> /dev/null; then
sudo systemctl enable tailscaled
fi
if ! systemctl is-active tailscaled &> /dev/null; then
sudo systemctl start tailscaled
fi
# SSH keepalives, login lockout, shutdown timeout, OOM protection, boot, SSH PATH
echo "Applying system defaults..."
bash ~/.local/share/coredesktop/system/defaults.sh
# Block incoming connections except SSH, mDNS, LocalSend and Tailscale
echo "Configuring the firewall..."
bash ~/.local/share/coredesktop/system/firewall.sh
# Snapshot / before each update (btrfs only)
echo "Configuring Snapper..."
bash ~/.local/share/coredesktop/system/snapper.sh
echo "Installing GPU drivers..."
bash ~/.local/share/coredesktop/system/vulkan.sh
bash ~/.local/share/coredesktop/system/nvidia.sh
# Prompt, zoxide, fzf key bindings, aliases and functions
echo "Configuring the shell..."
bash ~/.local/share/coredesktop/shell/setup.sh
# Notify in GNOME when a new version of CoreDesktop is available
echo "Configuring update notifications..."
bash ~/.local/share/coredesktop/system/update-notify.sh
# Apply GNOME dconf settings only if the settings file has changed since last run
bash ~/.local/share/coredesktop/gnome/apply-gnome-settings.sh
# Fix mDNS configuration if systemd-resolved is managing DNS on this system
if systemctl is-enabled systemd-resolved.service &> /dev/null; then
echo "systemd-resolved is enabled, applying mDNS fix..."
bash ~/.local/share/coredesktop/fixmdns.sh
fi
# 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
CONFIGURE_HINT="configure connects to your Federated Computer Core, sets up backups and signs you in to the AI agents."
# If the running kernel's modules are gone, a newer kernel was installed during
# this run. configure waits for the reboot: until then, modules it needs, such
# as Tailscale's tun and davfs2's fuse, can't be loaded.
if [ ! -d "/usr/lib/modules/$(uname -r)" ]; then
echo "A newer kernel has been installed. Reboot, then run: configure"
echo "$CONFIGURE_HINT"
exit 0
fi
echo "Kernel is up to date, no reboot needed. You may want to consider a reboot if other significant software was updated or installed."
# 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_HINT"
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