250 lines
8.7 KiB
Bash
Executable File
250 lines
8.7 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
|
|
source remove-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
|
|
|
|
# Remove replaced packages first, so their replacements don't conflict with them
|
|
echo "Removing unwanted packages..."
|
|
remove_packages "${REMOVE_PACMAN[@]}"
|
|
remove_flatpaks "${REMOVE_FLATPAKS[@]}"
|
|
|
|
# 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
|