- config/git/gitconfig: replace real name, email, SSH signing key, and self-hosted git credential URL with placeholder values - stages/06-scripts.sh: remove hardcoded personal email from bw login; CLI prompts interactively - config/shell/zshrc.local.example: replace personal server URLs (Nextcloud, LiteLLM proxy), university email address, institution- specific Canvas LMS URL, and identifying Canvas key prefix with generic example.com placeholders - TODO.md: replace personal email and Nextcloud URL in code examples with generic placeholders - stages/07-uv-projects.sh: remove private org name from comment
204 lines
8.0 KiB
Bash
Executable File
204 lines
8.0 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# ===========================================================================
|
|
# Stage 06: Custom Scripts (~/.local/bin/)
|
|
# Deploys Julian's custom scripts: Bitwarden SSH loader, Zoom wrapper,
|
|
# idle battery suspend, env PATH helper, and more.
|
|
# ===========================================================================
|
|
# These are the "glue" scripts that make the desktop work the way Julian
|
|
# expects. They were found in ~/.local/bin/ on the Pop machine.
|
|
#
|
|
# Config templates are in config/scripts/
|
|
# ===========================================================================
|
|
|
|
CONFIG_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/config"
|
|
SCRIPTS_DIR="${CONFIG_DIR}/scripts"
|
|
TARGET_DIR="$HOME/.local/bin"
|
|
|
|
mkdir -p "$TARGET_DIR"
|
|
|
|
info "Deploying custom scripts to $TARGET_DIR..."
|
|
|
|
# ---- 1. env.sh — PATH helper (sourced by .profile / .bashrc) ----
|
|
# Ensures ~/.local/bin is in PATH without duplicate entries.
|
|
if [ -f "$SCRIPTS_DIR/env.sh" ]; then
|
|
cp "$SCRIPTS_DIR/env.sh" "$TARGET_DIR/env"
|
|
chmod +x "$TARGET_DIR/env"
|
|
ok "env deployed."
|
|
fi
|
|
|
|
# ---- 2. bw-load-ssh.sh — Load SSH keys from Bitwarden ----
|
|
# Script that fetches SSH keys from Bitwarden vault and loads into ssh-agent.
|
|
# Depends on: bw (Bitwarden CLI), jq, ssh-agent running.
|
|
if [ -f "$SCRIPTS_DIR/bw-load-ssh.sh" ]; then
|
|
cp "$SCRIPTS_DIR/bw-load-ssh.sh" "$TARGET_DIR/bw-load-ssh.sh"
|
|
chmod +x "$TARGET_DIR/bw-load-ssh.sh"
|
|
ok "bw-load-ssh.sh deployed."
|
|
fi
|
|
|
|
# ---- 3. zoom.sh — Zoom wrapper for Wayland + AMD GPU ----
|
|
# Forces Wayland native mode and VAAPI hardware video decoding on AMD Radeon.
|
|
# Without this, Zoom would use XWayland and software decoding (bad perf).
|
|
if [ -f "$SCRIPTS_DIR/zoom.sh" ]; then
|
|
cp "$SCRIPTS_DIR/zoom.sh" "$TARGET_DIR/zoom"
|
|
chmod +x "$TARGET_DIR/zoom"
|
|
ok "zoom wrapper deployed."
|
|
else
|
|
# Create default Zoom wrapper
|
|
cat > "$TARGET_DIR/zoom" << 'SCRIPT'
|
|
#!/bin/bash
|
|
# Zoom wrapper — forces Wayland + HW acceleration on AMD GPU
|
|
export QT_QPA_PLATFORM=wayland
|
|
export LIBVA_DRIVER_NAME=radeonsi
|
|
export LIBVA_DRI3_DISABLE=0
|
|
exec /usr/bin/zoom "$@"
|
|
SCRIPT
|
|
chmod +x "$TARGET_DIR/zoom"
|
|
ok "zoom wrapper created (default)."
|
|
fi
|
|
|
|
# ---- 4. idle-battery-suspend.sh — Suspend on battery after idle ----
|
|
# Checks if AC is disconnected before suspending. Prevents suspend on desktop.
|
|
# Used by swayidle.service (stage 08).
|
|
if [ -f "$SCRIPTS_DIR/idle-battery-suspend.sh" ]; then
|
|
cp "$SCRIPTS_DIR/idle-battery-suspend.sh" "$TARGET_DIR/idle-battery-suspend.sh"
|
|
chmod +x "$TARGET_DIR/idle-battery-suspend.sh"
|
|
ok "idle-battery-suspend.sh deployed."
|
|
fi
|
|
|
|
# ---- 5. Bitwarden CLI (bw) ----
|
|
# On Pop: ~/.local/bin/bw (138 MB standalone binary)
|
|
if ! command -v bw &>/dev/null; then
|
|
info "Installing Bitwarden CLI..."
|
|
# bw is a standalone binary — download it
|
|
BW_LATEST=$(curl -fsSL "https://api.github.com/repos/bitwarden/clients/releases?per_page=1" | grep -oP '"tag_name":\s*"cli-v\K[^"]+' | head -1) || BW_LATEST="2025.1.0"
|
|
curl -fsSL "https://github.com/bitwarden/clients/releases/download/cli-v${BW_LATEST}/bw-linux-${BW_LATEST}.zip" -o /tmp/bw.zip 2>/dev/null && {
|
|
unzip -o /tmp/bw.zip -d /tmp/bw-extract 2>/dev/null
|
|
cp /tmp/bw-extract/bw "$TARGET_DIR/bw"
|
|
chmod +x "$TARGET_DIR/bw"
|
|
rm -rf /tmp/bw.zip /tmp/bw-extract
|
|
ok "Bitwarden CLI installed."
|
|
} || warn "Bitwarden CLI download failed. Install manually: https://bitwarden.com/help/cli/"
|
|
fi
|
|
|
|
# Ensure permissions
|
|
chmod -R 755 "$TARGET_DIR" 2>/dev/null || true
|
|
|
|
# ===========================================================================
|
|
# 6. Bitwarden Login & Session Setup
|
|
# Interactive step: logs into Bitwarden and saves session key for later use.
|
|
# Run bw-load-ssh.sh afterwards to load SSH keys from the vault.
|
|
# ===========================================================================
|
|
echo ""
|
|
info "============================================"
|
|
info " Bitwarden CLI Setup"
|
|
info "============================================"
|
|
info ""
|
|
info "Julian stores SSH keys and API tokens in Bitwarden."
|
|
info "This step will log you into Bitwarden and save your session."
|
|
info ""
|
|
|
|
BW_SESSION_DIR="$HOME/.config/Bitwarden CLI"
|
|
BW_SESSION_FILE="${BW_SESSION_DIR}/.session"
|
|
mkdir -p "$BW_SESSION_DIR"
|
|
|
|
# ---- Skip if session already exists and is valid ----
|
|
if [ -f "$BW_SESSION_FILE" ]; then
|
|
BW_SESSION=$(cat "$BW_SESSION_FILE")
|
|
export BW_SESSION
|
|
BW_STATUS=$(bw status 2>/dev/null | jq -r '.status // "unauthenticated"' 2>/dev/null || echo "unauthenticated")
|
|
if [ "$BW_STATUS" = "unlocked" ]; then
|
|
ok "Bitwarden session already valid (skipping login)."
|
|
# Skip to SSH key loading
|
|
else
|
|
# Session file exists but expired — need to re-authenticate
|
|
warn "Session file exists but vault is $BW_STATUS. Re-authenticating..."
|
|
_do_bw_setup=true
|
|
fi
|
|
else
|
|
_do_bw_setup=true
|
|
fi
|
|
|
|
if [ "${_do_bw_setup:-false}" = true ]; then
|
|
# ---- Self-hosted server configuration ----
|
|
CURRENT_SERVER=$(bw config server 2>/dev/null || echo "https://bitwarden.com")
|
|
if [ "$CURRENT_SERVER" = "https://bitwarden.com" ] || [ "$CURRENT_SERVER" = "null" ]; then
|
|
echo "----------------------------------------"
|
|
info "Server: Bitwarden cloud (default)"
|
|
echo "----------------------------------------"
|
|
echo ""
|
|
if [ -t 0 ]; then
|
|
read -r -p "Use a self-hosted Bitwarden server instead? [y/N] " use_selfhosted
|
|
if [[ "$use_selfhosted" =~ ^[Yy]$ ]]; then
|
|
echo ""
|
|
read -r -p "Enter your self-hosted server URL (e.g. https://vault.example.com): " server_url
|
|
if [ -n "$server_url" ]; then
|
|
bw config server "$server_url" 2>/dev/null && ok "Server set to $server_url" || warn "Failed to set server URL."
|
|
echo ""
|
|
fi
|
|
fi
|
|
else
|
|
info "Non-interactive mode: using default Bitwarden cloud."
|
|
info "To use a self-hosted server, run: bw config server <your-url>"
|
|
fi
|
|
else
|
|
info "Server: $CURRENT_SERVER (self-hosted)"
|
|
fi
|
|
|
|
# Check current bw status
|
|
BW_STATUS=$(bw status 2>/dev/null | jq -r '.status // "unauthenticated"' 2>/dev/null || echo "unauthenticated")
|
|
|
|
if [ "$BW_STATUS" = "unauthenticated" ]; then
|
|
echo "----------------------------------------"
|
|
info "Step 1: Log in to Bitwarden"
|
|
info "You will be prompted for your email and master password."
|
|
info "If you have 2FA enabled, you'll be prompted for that too."
|
|
echo "----------------------------------------"
|
|
echo ""
|
|
bw login || {
|
|
warn "Bitwarden login failed or was cancelled."
|
|
warn "You can run 'bw login' manually later."
|
|
}
|
|
echo ""
|
|
elif [ "$BW_STATUS" = "locked" ]; then
|
|
info "Bitwarden vault is locked (already logged in)."
|
|
elif [ "$BW_STATUS" = "unlocked" ]; then
|
|
info "Bitwarden vault is already unlocked."
|
|
fi
|
|
|
|
echo "----------------------------------------"
|
|
info "Step 2: Unlock vault and save session key"
|
|
info "You will be prompted for your master password again."
|
|
info "The session key will be saved to ${BW_SESSION_FILE}"
|
|
echo "----------------------------------------"
|
|
echo ""
|
|
bw unlock --raw > "$BW_SESSION_FILE" 2>/dev/null && {
|
|
chmod 600 "$BW_SESSION_FILE"
|
|
ok "Session key saved to ${BW_SESSION_FILE}"
|
|
} || warn "Failed to save session key. Run 'bw unlock --raw > ${BW_SESSION_FILE}' manually."
|
|
echo ""
|
|
fi
|
|
|
|
# ---- Load SSH keys from Bitwarden ----
|
|
if [ -x "$TARGET_DIR/bw-load-ssh.sh" ]; then
|
|
echo "----------------------------------------"
|
|
info "Step 3: Load SSH keys from Bitwarden"
|
|
echo "----------------------------------------"
|
|
echo ""
|
|
# Export session so bw-load-ssh can use it
|
|
if [ -f "$BW_SESSION_FILE" ]; then
|
|
BW_SESSION=$(cat "$BW_SESSION_FILE")
|
|
export BW_SESSION
|
|
fi
|
|
|
|
if bw status 2>/dev/null | jq -e '.status == "unlocked"' >/dev/null 2>&1; then
|
|
info "Running bw-load-ssh.sh..."
|
|
bash "$TARGET_DIR/bw-load-ssh.sh" && ok "SSH keys loaded." || warn "SSH key loading had issues."
|
|
else
|
|
warn "Vault is not unlocked. Skipping SSH key loading."
|
|
warn "Run 'bw-load-ssh.sh' manually after unlocking."
|
|
fi
|
|
echo ""
|
|
fi
|
|
|
|
ok "Stage 06 complete: custom scripts and Bitwarden configured."
|