Files
coredesktop/install.sh
T
davidandClaude Opus 5.5 1507ae925e
shellcheck / shellcheck (push) Failing after 17s
Say "CoreDesktop is installed." at the end of every install
When configure had nothing left to do, install.sh ended on the kernel check
and the firewall's warnings just above it, so a successful run could be taken
for a failure. Move the end of install.sh to system/finish-install.sh, which
now says the install worked before the reboot advice and configure offer, and
test it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-10 06:51:10 -07:00

297 lines
10 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
# Log the install to ~/.local/state/coredesktop/logs (update deletes old ones).
# It's usually piped into bash, so it can't run itself again under script(1)
# the way update does; send its output through tee instead.
if mkdir -p -m 700 "$HOME/.local/state/coredesktop/logs"; then
INSTALL_LOG="$HOME/.local/state/coredesktop/logs/install-$(date +%Y-%m-%d-%H%M%S).log"
exec > >(tee -a "$INSTALL_LOG") 2>&1
TEE_PID=$!
fi
# Exit on any error
set -e
# What can't be fixed from here, checked before anything changes. The rest of
# the checks need the repo (system/preflight.sh, below).
if [ "$(id -u)" -eq 0 ]; then
echo "Run this as your own user, not as root. It asks for your password when it needs sudo."
exit 1
fi
if [ ! -f /etc/arch-release ] || ! command -v pacman &> /dev/null; then
echo "CoreDesktop needs Arch Linux. See \"Installing Arch\" in the README."
exit 1
fi
if [ "$(uname -m)" != x86_64 ]; then
echo "CoreDesktop needs a 64-bit PC (x86_64); this is $(uname -m)."
exit 1
fi
if ! curl -fsS --max-time 15 -o /dev/null https://archlinux.org; then
echo "Couldn't reach archlinux.org. Connect to the internet and run this again."
exit 1
fi
# 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.
if ! sudo -v; then
echo "Couldn't use sudo. If your password was right, your user needs sudo rights (in"
echo "archinstall, make the user a superuser): https://wiki.archlinux.org/title/Sudo"
exit 1
fi
while kill -0 $$ 2> /dev/null; do sudo -n -v; sleep 60; done > /dev/null 2>&1 &
SUDO_KEEPALIVE_PID=$!
on_exit() {
local status=$?
kill "$SUDO_KEEPALIVE_PID" 2> /dev/null
if (( status != 0 )) && [ -n "$INSTALL_LOG" ]; then
echo "The install stopped with an error. The full output is in $INSTALL_LOG"
# Offer to send the log to us, once tee has written all of it (a second at
# most). report asks on the terminal, so this needs one.
local report="$HOME/.local/share/coredesktop/report" i
if [ -f "$report" ] && { : < /dev/tty; } 2> /dev/null; then
exec > /dev/tty 2>&1
for (( i = 0; i < 10; i++ )); do
kill -0 "$TEE_PID" 2> /dev/null || break
sleep 0.1
done
bash "$report" --offer "$INSTALL_LOG" install.sh
fi
fi
}
trap on_exit 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 --ff-only
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, audit and report 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
install_script ~/.local/share/coredesktop/report ~/.local/bin/report
# 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
# Disk space, btrfs, display manager and sound server: stops, asks, or offers
# to fix what it finds
bash ~/.local/share/coredesktop/system/preflight.sh
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 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
# Leave Wi-Fi to NetworkManager alone if archinstall turned on iwd as well
echo "Checking Wi-Fi..."
bash ~/.local/share/coredesktop/system/wifi.sh
# SSH logins with keys only, not passwords
echo "Configuring the SSH server..."
bash ~/.local/share/coredesktop/system/sshd.sh
# Block incoming connections except SSH, mDNS, LocalSend and Tailscale
echo "Configuring the firewall..."
bash ~/.local/share/coredesktop/system/firewall.sh
# Keep pacman on mirrors that are up to date with Arch
echo "Configuring package mirrors..."
bash ~/.local/share/coredesktop/system/mirrors.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
# Keep WinBoat's Windows container from starting at boot (if it's set up)
bash ~/.local/share/coredesktop/system/winboat.sh
# Notify in GNOME when a new version of CoreDesktop is available
echo "Configuring update notifications..."
bash ~/.local/share/coredesktop/system/update-notify.sh
# Pause a Core's email when the mail server stops taking its password
echo "Configuring email password checks..."
bash ~/.local/share/coredesktop/system/email-watch.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
# Say the install worked, whether to reboot, and offer configure
bash ~/.local/share/coredesktop/system/finish-install.sh