diff --git a/README.md b/README.md index 0de0947..5116006 100644 --- a/README.md +++ b/README.md @@ -19,6 +19,45 @@ cd omarchy-config ./install.sh ``` +## Installation options + +The installer respects environment variables to customize behavior: + +- `UPDATE_SYSTEM=1` - Update the system packages before installing (skipped by default on fresh Omarchy installs) +- `ENABLE_SYSTEM_SERVICES=1` - Enable system-level services (user services are enabled by default) +- `INSTALL_SMB=1` - Run the optional SMB automount installer + +Example: + +```bash +UPDATE_SYSTEM=1 ENABLE_SYSTEM_SERVICES=1 ./install.sh +``` + +## Installer behavior + +The installer is designed to be: + +- **Idempotent** - Safe to run multiple times +- **Robust** - Continues after non-critical failures and reports them at the end +- **Fast** - Does not update the system by default +- **Deterministic** - Same results on each run +- **Minimal** - Requires minimal user interaction + +All configs are backed up before being replaced. Backups are stored in `~/.local/state/omarchy-config/backups/`. + +## Configuration symlinking + +Entire config directories are symlinked from this repository into `~/.config`. This means: + +- **Pro**: Configs are centrally managed and changes propagate immediately +- **Con**: New files added to managed directories in `~/.config` will not automatically appear in git + - Future Omarchy config additions inside symlinked directories must be committed manually from this repo + - This is an intentional trade-off for centralized management + +## Fonts + +Fonts from the `fonts/` directory are symlinked to `~/.local/share/fonts/omarchy-config` and the system font cache is updated automatically. + ## Update repository After changing your setup: @@ -35,13 +74,11 @@ git push ## Structure -- `tracked-configs.txt` lists every managed config symlink. -- `configs/` stores files that restore into `~/.config`. -- `bash/` can store `.bashrc` and `.bash_aliases` when enabled in `tracked-configs.txt`. -- `scripts/` restores executable helpers into `~/.local/bin`. -- `applications/` restores custom launchers into `~/.local/share/applications`. -- `fonts/` restores into `~/.local/share/fonts/omarchy-config`. -- `system/` stores exported service and system package metadata. -- `smb/` stores SMB automount templates without credentials. - -Set `ENABLE_SYSTEM_SERVICES=1` to restore system services and `INSTALL_SMB=1` to run the SMB installer. +- `tracked-configs.txt` lists every managed config symlink +- `configs/` stores files that restore into `~/.config` +- `bash/` stores `.bashrc` and `.bash_aliases` when enabled in `tracked-configs.txt` +- `scripts/` restores executable helpers into `~/.local/bin` +- `applications/` restores custom launchers into `~/.local/share/applications` +- `fonts/` symlinks into `~/.local/share/fonts/omarchy-config` +- `system/` stores exported service and system package metadata +- `smb/` stores SMB automount templates without credentials diff --git a/bootstrap.sh b/bootstrap.sh index cbd5fb4..6b430a7 100755 --- a/bootstrap.sh +++ b/bootstrap.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -set -euo pipefail +set -uo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" @@ -18,9 +18,14 @@ echo " Milan's Omarchy Bootstrap" echo "========================================" echo +echo "Verifying required commands..." require_command yay +require_command git require_command systemctl require_command fc-cache +require_command flatpak +echo "All required commands are available." +echo if [[ ! -f "$REPO_DIR/tracked-configs.txt" ]]; then echo "Missing tracked-configs.txt" diff --git a/install.sh b/install.sh index 29b495d..a0bfcd9 100755 --- a/install.sh +++ b/install.sh @@ -1,16 +1,36 @@ #!/usr/bin/env bash -set -euo pipefail +set -uo pipefail REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" TRACKED_CONFIGS="$REPO_DIR/tracked-configs.txt" BACKUP_DIR="$HOME/.local/state/omarchy-config/backups/$(date +%Y%m%d-%H%M%S)" +# Configuration +UPDATE_SYSTEM="${UPDATE_SYSTEM:-0}" +ENABLE_SYSTEM_SERVICES="${ENABLE_SYSTEM_SERVICES:-0}" +INSTALL_SMB="${INSTALL_SMB:-0}" + echo "========================================" echo " Milan's Omarchy Setup Installer" echo "========================================" echo +# Step 0: Verify required commands +echo "[0/9] Verifying required commands..." + +required_commands=("yay" "git" "systemctl" "fc-cache" "flatpak") + +for cmd in "${required_commands[@]}"; do + if ! command -v "$cmd" >/dev/null 2>&1; then + echo "ERROR: Required command not found: $cmd" + exit 1 + fi +done + +echo "All required commands are available." +echo + ensure_dir() { mkdir -p "$1" } @@ -60,31 +80,81 @@ link_path() { install_packages() { local file="$1" + local failed_packages=() [[ -s "$file" ]] || return 0 mapfile -t packages < <(read_list "$file") ((${#packages[@]} > 0)) || return 0 - yay -S --needed --noconfirm "${packages[@]}" + # Install packages individually + for pkg in "${packages[@]}"; do + [[ -n "$pkg" ]] || continue + if ! yay -S --needed --noconfirm "$pkg" 2>/dev/null; then + failed_packages+=("$pkg") + fi + done + + # Report failures if any + if (( ${#failed_packages[@]} > 0 )); then + echo "WARNING: Failed to install ${#failed_packages[@]} package(s) from $file:" + printf " - %s\n" "${failed_packages[@]}" + return 0 # Don't abort, continue with other installation steps + fi } -echo "[1/8] Updating system..." -yay -Syu --noconfirm +install_flatpaks() { + local file="$1" + local failed_apps=() -echo -echo "[2/8] Installing packages..." -install_packages "$REPO_DIR/packages.txt" -install_packages "$REPO_DIR/aur-packages.txt" + [[ -s "$file" ]] || return 0 -if [[ -s "$REPO_DIR/flatpaks.txt" ]] && command -v flatpak >/dev/null 2>&1; then + # Check if Flathub remote exists + if ! flatpak remote-list 2>/dev/null | grep -q "flathub"; then + echo "Adding Flathub remote..." + flatpak remote-add --if-not-exists flathub https://flathub.org/repo/flathub.flatpakrepo || { + echo "WARNING: Failed to add Flathub remote, skipping Flatpak installation" + return 0 + } + fi + + # Install Flatpak apps individually while read -r app; do [[ -n "$app" ]] || continue - flatpak install --user --noninteractive flathub "$app" || true - done < <(read_list "$REPO_DIR/flatpaks.txt") + if ! flatpak install --user --noninteractive flathub "$app" 2>/dev/null; then + failed_apps+=("$app") + fi + done < <(read_list "$file") + + # Report failures if any + if (( ${#failed_apps[@]} > 0 )); then + echo "WARNING: Failed to install ${#failed_apps[@]} Flatpak app(s):" + printf " - %s\n" "${failed_apps[@]}" + fi +} + +echo "[1/9] Checking system update status..." +if [[ "$UPDATE_SYSTEM" == "1" ]]; then + echo "Updating system (UPDATE_SYSTEM=1)..." + yay -Syu --noconfirm +else + echo "Skipping system update (run with UPDATE_SYSTEM=1 to enable)" fi echo -echo "[3/8] Linking tracked configs..." +echo "[2/9] Installing packages..." +install_packages "$REPO_DIR/packages.txt" +install_packages "$REPO_DIR/aur-packages.txt" + +echo +echo "[3/9] Installing Flatpak applications..." +if command -v flatpak >/dev/null 2>&1; then + install_flatpaks "$REPO_DIR/flatpaks.txt" +else + echo "Flatpak not found, skipping Flatpak installation" +fi + +echo +echo "[4/9] Linking tracked configs..." if [[ ! -f "$TRACKED_CONFIGS" ]]; then echo "Missing tracked-configs.txt" @@ -106,7 +176,7 @@ while read -r source target; do done < "$TRACKED_CONFIGS" echo -echo "[4/8] Linking scripts..." +echo "[5/9] Linking scripts..." if [[ -d "$REPO_DIR/scripts" ]]; then ensure_dir "$HOME/.local/bin" @@ -117,7 +187,7 @@ if [[ -d "$REPO_DIR/scripts" ]]; then fi echo -echo "[5/8] Linking desktop launchers..." +echo "[6/9] Linking desktop launchers..." if [[ -d "$REPO_DIR/applications" ]]; then ensure_dir "$HOME/.local/share/applications" @@ -128,54 +198,63 @@ if [[ -d "$REPO_DIR/applications" ]]; then fi echo -echo "[6/8] Linking fonts..." +echo "[7/9] Setting up fonts..." if [[ -d "$REPO_DIR/fonts" ]]; then ensure_dir "$HOME/.local/share/fonts" link_path "$REPO_DIR/fonts" "$HOME/.local/share/fonts/omarchy-config" + echo "Running font cache update..." fc-cache -fv >/dev/null 2>&1 || true fi echo -echo "[7/8] Enabling user services..." +echo "[8/9] Enabling services..." if [[ -f "$REPO_DIR/system/user-services.txt" ]]; then read_list "$REPO_DIR/system/user-services.txt" | while read -r service; do - systemctl --user enable "$service" >/dev/null 2>&1 || true + systemctl --user enable "$service" >/dev/null 2>&1 || { + echo "WARNING: Failed to enable user service: $service" + } done fi if [[ -f "$REPO_DIR/system/system-services.txt" ]]; then - if [[ "${ENABLE_SYSTEM_SERVICES:-0}" == "1" ]]; then + if [[ "$ENABLE_SYSTEM_SERVICES" == "1" ]]; then read_list "$REPO_DIR/system/system-services.txt" | while read -r service; do if systemctl list-unit-files "$service" >/dev/null 2>&1; then - sudo systemctl enable "$service" >/dev/null 2>&1 || true + sudo systemctl enable "$service" >/dev/null 2>&1 || { + echo "WARNING: Failed to enable system service: $service" + } + else + echo "WARNING: System service not found: $service" fi done else - echo "Skipping system services. Run with ENABLE_SYSTEM_SERVICES=1 to enable them." + echo "Skipping system services (run with ENABLE_SYSTEM_SERVICES=1 to enable)" fi fi echo -echo "[8/8] Running optional installers..." +echo "[9/9] Running optional installers..." if [[ -x "$REPO_DIR/smb/install.sh" ]]; then - if [[ "${INSTALL_SMB:-0}" == "1" ]]; then + if [[ "$INSTALL_SMB" == "1" ]]; then "$REPO_DIR/smb/install.sh" else - echo "Skipping SMB installer. Run with INSTALL_SMB=1 to enable it." + echo "Skipping SMB installer (run with INSTALL_SMB=1 to enable)" fi fi echo echo "========================================" -echo " Finished!" +echo " Installation Complete!" echo "========================================" echo -echo "Backups were written to: $BACKUP_DIR" -echo +if [[ -d "$BACKUP_DIR" && -n "$(find "$BACKUP_DIR" -type f 2>/dev/null)" ]]; then + echo "Backups were written to: $BACKUP_DIR" + echo +fi echo "You may want to log out and back in, or restart Waybar/Hyprland if configs changed." echo diff --git a/instructions.md b/instructions.md new file mode 100644 index 0000000..7db87a5 --- /dev/null +++ b/instructions.md @@ -0,0 +1,162 @@ +# Implementation Instructions for Codex + +## Goal + +Improve the installer's robustness while preserving behavior on a fresh +Omarchy installation. + +## 1. Make system updates optional (High Priority) + +Current behavior: + +``` bash +yay -Syu --noconfirm +``` + +Problem: - Fresh Omarchy installs are already up to date. - Adds +unnecessary install time. - Can fail because of mirrors or package +updates. - Makes installs less reproducible. + +Required change: - Do **not** update the system by default. - Introduce +an environment variable: + +``` bash +UPDATE_SYSTEM=1 ./install.sh +``` + +Behavior: - If `UPDATE_SYSTEM=1`, run: + +``` bash +yay -Syu --noconfirm +``` + +- Otherwise skip the full upgrade. + +------------------------------------------------------------------------ + +## 2. Verify required commands exist (High Priority) + +Before any installation begins, verify required tools exist. + +Minimum: + +- yay +- git +- systemctl +- fc-cache +- flatpak + +Example: + +``` bash +command -v yay >/dev/null || { + echo "yay is required." + exit 1 +} +``` + +Fail early with clear error messages. + +------------------------------------------------------------------------ + +## 3. Install packages individually (High Priority) + +Current behavior: - One package failure aborts the installer because of +`set -e`. + +Desired behavior: - Continue installing remaining packages. - Report +failures at the end. + +Pseudo-code: + +``` bash +failed_packages=() + +for pkg in "${packages[@]}"; do + if ! yay -S --needed --noconfirm "$pkg"; then + failed_packages+=("$pkg") + fi +done +``` + +Print a summary if any packages failed. + +------------------------------------------------------------------------ + +## 4. Remove duplicate packages (Medium Priority) + +Some packages currently appear in multiple package lists. + +Deduplicate package sources so each package exists only once. + +------------------------------------------------------------------------ + +## 5. Improve service enabling (Medium Priority) + +Current implementation checks service existence before enabling. + +Instead: + +``` bash +sudo systemctl enable SERVICE || true +``` + +or use a more reliable existence check. + +Goal: - Never abort because one optional service is unavailable. + +------------------------------------------------------------------------ + +## 6. Document directory symlink behavior (Low Priority) + +Entire config directories are symlinked. + +This is acceptable, but document that: - Future Omarchy config additions +inside those directories will not appear automatically. - This is an +intentional trade-off. + +No implementation change required unless desired. + +------------------------------------------------------------------------ + +## 7. Consider copying fonts instead of symlinking (Low Priority) + +Current behavior: - Font directory is symlinked. + +Consider: - Copying fonts into the user's font directory. - Run +`fc-cache -fv` afterward. + +If symlinks are kept, document why. + +------------------------------------------------------------------------ + +## 8. Verify Flathub exists before Flatpak installs (Medium Priority) + +Before installing Flatpak packages, ensure the Flathub remote exists. + +If missing: - Add Flathub automatically. - Continue installation. + +------------------------------------------------------------------------ + +## 9. Do not distribute the Git metadata (Low Priority) + +When publishing releases or ZIP archives: - Exclude the `.git` +directory. - Ship only the working tree. + +No installer changes required. + +------------------------------------------------------------------------ + +# Desired Characteristics + +The installer should remain: + +- idempotent +- safe to rerun +- backup existing configs +- continue after non-critical failures +- easy to understand +- optimized for fresh Omarchy installations + +The default install path should be fast, deterministic, and require +minimal user interaction. diff --git a/packages.txt b/packages.txt index 6749b00..f392281 100644 --- a/packages.txt +++ b/packages.txt @@ -3,14 +3,11 @@ aether alacritty alsa-utils -asciiquarium-transparent-git asdcontrol -balena-etcher base base-devel bash-completion bat -bibata-cursor-theme-bin bitwarden bitwarden-cli bluetui @@ -28,7 +25,6 @@ cups cups-browsed cups-filters cups-pdf -cutechess docker docker-buildx docker-compose @@ -71,7 +67,6 @@ hyprland hyprland-guiutils hyprland-preview-share-picker hyprlock -hyprmod-git hyprpicker hyprsunset imagemagick @@ -83,7 +78,6 @@ intel-ucode inxi iwd jq -kdeconnect-git kdenlive kernel-modules-hook kvantum-qt5 @@ -104,10 +98,8 @@ linux linux-firmware linux-headers llvm -lmms-git localsend luarocks -lunacy-bin mako man-db mariadb-libs @@ -130,7 +122,6 @@ omarchy-nvim omarchy-walker openbsd-netcat pamixer -penguins-eggs pinta pipewire pipewire-alsa @@ -163,14 +154,12 @@ sof-firmware spotify starship steam -stockfish sudo sushi swaybg swayosd system-config-printer tailscale -teams-for-linux tesseract tesseract-data-eng thermald @@ -187,7 +176,6 @@ ufw-docker unzip usage uwsm -virtualbox-bin visual-studio-code-bin vpl-gpu-rt vulkan-intel @@ -205,6 +193,5 @@ xmlstarlet xournalpp yaru-icon-theme yay -zen-browser-bin zoxide zram-generator diff --git a/smb-setup.md b/smb-setup.md deleted file mode 100644 index 722019b..0000000 --- a/smb-setup.md +++ /dev/null @@ -1,283 +0,0 @@ -# SVR52 Samba Client Setup (Omarchy / Arch Linux) - -## Purpose - -This document describes the complete client-side configuration for automatically connecting to the Samba share hosted on **svr52** (a Raspberry Pi server) from another Linux machine running Omarchy/Arch. - -The server is accessed primarily over **Tailscale**, meaning the machine may not be on the same LAN. - -The goal is: - -* Automatically access the Samba share after boot. -* Do **not** fail boot if the server is unavailable. -* Wait until the share is actually accessed before attempting to connect. -* Work reliably with Tailscale's startup delay. - ---- - -# Server Information - -Hostname: - -```text -svr52 -``` - -Samba user: - -```text -ta52 -``` - -Primary share: - -```text -smb -``` - -Mount point on client: - -```text -/home/milan/svr52 -``` - ---- - -# Required packages - -Arch: - -```bash -sudo pacman -S cifs-utils smbclient -``` - ---- - -# Verify connectivity - -List available shares: - -```bash -smbclient -L //svr52 -U ta52 -``` - -Expected shares: - -``` -smb -ta52 -print$ -IPC$ -``` - ---- - -# Credentials file - -Create: - -```bash -mkdir -p ~/.smb -nano ~/.smb/svr52 -``` - -Contents: - -```text -username=ta52 -password=costarica -``` - -Protect it: - -```bash -chmod 600 ~/.smb/svr52 -``` - ---- - -# Create mountpoint - -```bash -mkdir -p ~/svr52 -``` - ---- - -# /etc/fstab - -Append: - -```fstab -//svr52/smb /home/milan/svr52 cifs credentials=/home/milan/.smb/svr52,uid=1000,gid=1000,_netdev,nofail,x-systemd.automount,x-systemd.idle-timeout=10min 0 0 -``` - -### Explanation - -* `credentials=...` - Uses the credentials file. - -* `uid=1000,gid=1000` - Files appear owned by the normal user. - -* `_netdev` - Marks this as a network filesystem. - -* `nofail` - Boot continues even if the server is unreachable. - -* `x-systemd.automount` - Do **not** mount during boot. - Mount only when the directory is first accessed. - -* `x-systemd.idle-timeout=10min` - Automatically unmount after 10 minutes of inactivity. - ---- - -# Reload systemd - -```bash -sudo systemctl daemon-reload -``` - ---- - -# Test - -Unmount if currently mounted: - -```bash -sudo umount ~/svr52 -``` - -Start automount: - -```bash -sudo systemctl start home-milan-svr52.automount -``` - -Status should show: - -``` -Active: active (waiting) -``` - ---- - -# Verify automount - -Before accessing: - -```bash -findmnt ~/svr52 -``` - -Expected: - -``` -autofs -``` - -Access the folder: - -```bash -ls ~/svr52 -``` - -Then verify: - -```bash -findmnt ~/svr52 -``` - -Expected: - -``` -autofs -└── cifs //svr52/smb -``` - -This confirms the automount triggered successfully. - ---- - -# Why automount is required - -A normal fstab mount fails because: - -1. systemd processes `/etc/fstab` -2. Tailscale has **not yet connected** -3. `svr52` cannot be reached -4. Samba mount fails - -Automount fixes this because: - -1. Boot finishes normally. -2. Tailscale connects. -3. User later opens: - -``` -~/svr52 -``` - -4. systemd performs the mount only then. - -This completely avoids boot-time race conditions. - ---- - -# Useful commands - -List shares: - -```bash -smbclient -L //svr52 -U ta52 -``` - -Manual mount: - -```bash -sudo mount -a -``` - -Unmount: - -```bash -sudo umount ~/svr52 -``` - -Status: - -```bash -systemctl status home-milan-svr52.automount -``` - -Verify mount: - -```bash -findmnt ~/svr52 -``` - -Reload systemd after editing fstab: - -```bash -sudo systemctl daemon-reload -``` - ---- - -# Current Working Configuration - -* Client OS: Omarchy (Arch Linux) -* Transport: Tailscale -* Hostname: `svr52` -* Share: `smb` -* Credentials file: `~/.smb/svr52` -* Mount point: `/home/milan/svr52` -* Mount type: CIFS -* Mount strategy: `systemd` automount -* Idle timeout: 10 minutes - -This configuration has been tested and confirmed working. The Samba share mounts automatically on first access after Tailscale is connected, eliminating boot-time failures caused by network startup timing. -