Simplify and clean up provisioning scripts

- lib/distro.sh: add DISTRO_CODENAME from VERSION_CODENAME; remove
  unused REPO_ADD_RPM variable; export DISTRO_CODENAME

- stages/01-repos.sh: replace repeated '. /etc/os-release' subshell
  calls with $DISTRO_CODENAME in Docker and Tailscale repo lines

- stages/00-envcheck.sh: combine four mkdir -p calls into one

- stages/02-packages.sh: remove identical if/else branches in fd
  symlink block; both branches were the same command

- stages/03-toolchains.sh: set NVM_DIR once before the if/else instead
  of twice; remove dead commented-out duplicate curl line

- stages/04-shell.sh: capture $(date +%Y%m%d) into _bak_date once per
  backup and reuse in cp and warn to avoid redundant forks

- stages/06-scripts.sh: split 'export VAR=$(cmd)' into assignment +
  export to correctly propagate errors under set -euo pipefail

- stages/07-uv-projects.sh: remove unused has_package_json field (always
  false, never read); fix stage completion message 06 -> 07

- stages/08-systemd.sh: remove mempi-sync.timer (deploy, enable, header
  comment); deploy mempi-sync.service only

- stages/09-desktop.sh: remove duplicate mkdir -p in COSMIC section;
  remove unused repo_url parameter from install_nerd_font()

- stages/12-other-apps.sh: replace manual distro branch for Nextcloud
  with pkg_install_mapped

- config/scripts/bw-load-ssh.sh: split 'export BW_SESSION=$(cat ...)'
  into assignment + export

- config/systemd/mempi-sync.timer: delete file
This commit is contained in:
2026-06-07 15:18:12 +10:00
parent 2ca9a2bdef
commit 5f8640c057
13 changed files with 39 additions and 64 deletions

View File

@@ -45,7 +45,8 @@ if [ $_ssh_exit -eq 2 ]; then
fi
# Read session key
export BW_SESSION=$(cat "$SESSION_FILE")
BW_SESSION=$(cat "$SESSION_FILE")
export BW_SESSION
# Verify session is still valid
if ! bw status 2>/dev/null | jq -e '.status == "unlocked"' >/dev/null 2>&1; then

View File

@@ -1,8 +0,0 @@
[Unit]
Description=Sync mempi database on boot
[Timer]
OnBootSec=5min
[Install]
WantedBy=timers.target

View File

@@ -24,6 +24,7 @@ if [ -f /etc/os-release ]; then
. /etc/os-release
DISTRO_ID="${ID:-}"
DISTRO_VERSION="${VERSION_ID:-}"
DISTRO_CODENAME="${VERSION_CODENAME:-}"
DISTRO_LIKE="${ID_LIKE:-}"
fi
@@ -97,7 +98,6 @@ elif [ "$DISTRO_FAMILY" = "fedora" ]; then
# Repo management
REPO_ADD_COPR="sudo dnf copr enable -y"
REPO_ADD_RPM="sudo dnf config-manager addrepo --from-repofile=" # Note: use as function call, see repo_add_rpm below
# Service / boot
SERVICE_ENABLE="sudo systemctl enable --now"
@@ -184,7 +184,7 @@ pkg_install_mapped() {
}
# Export all variables so sourced stages can use them
export DISTRO_FAMILY DISTRO_ID DISTRO_VERSION DISTRO_LIKE
export DISTRO_FAMILY DISTRO_ID DISTRO_VERSION DISTRO_CODENAME DISTRO_LIKE
export PKG_MGR PKG_UPDATE PKG_INSTALL PKG_INSTALL_NO_REC
export PKG_REMOVE PKG_PURGE PKG_AUTOREMOVE
export PKG_SEARCH PKG_LIST_INSTALLED

View File

@@ -21,10 +21,7 @@ while true; do sudo -n true; sleep 60; kill -0 "$$" || exit; done 2>/dev/null &
# ---- Directory structure ----
info "Setting up directory structure..."
mkdir -p "$HOME/Development"
mkdir -p "$HOME/.local/bin"
mkdir -p "$HOME/.config"
mkdir -p "$HOME/.local/share"
mkdir -p "$HOME/Development" "$HOME/.local/bin" "$HOME/.config" "$HOME/.local/share"
ok "Directory structure ready."
# ---- Internet check ----

View File

@@ -67,7 +67,7 @@ EOF
if [ ! -f /etc/apt/sources.list.d/docker.list ]; then
add_gpg_key "https://download.docker.com/linux/${DISTRO_ID}/gpg" \
"/etc/apt/keyrings/docker.asc"
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${DISTRO_ID} ${DISTRO_VERSION_CODENAME:-$(. /etc/os-release && echo "$VERSION_CODENAME")} stable" | \
echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/${DISTRO_ID} ${DISTRO_CODENAME} stable" | \
sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
ok " Docker CE repo added."
fi
@@ -75,11 +75,11 @@ EOF
# ---- Tailscale ----
info " Adding Tailscale repo..."
if [ ! -f /etc/apt/sources.list.d/tailscale.list ]; then
add_gpg_key "https://pkgs.tailscale.com/stable/${DISTRO_ID}/$(. /etc/os-release && echo "$VERSION_CODENAME").gz" \
add_gpg_key "https://pkgs.tailscale.com/stable/${DISTRO_ID}/${DISTRO_CODENAME}.gz" \
"/usr/share/keyrings/tailscale-archive-keyring.gpg" 2>/dev/null || \
add_gpg_key "https://pkgs.tailscale.com/stable/${DISTRO_ID}/repo.gpg" \
"/usr/share/keyrings/tailscale-archive-keyring.gpg"
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${DISTRO_ID} $(. /etc/os-release && echo "$VERSION_CODENAME") main" | \
echo "deb [signed-by=/usr/share/keyrings/tailscale-archive-keyring.gpg] https://pkgs.tailscale.com/stable/${DISTRO_ID} ${DISTRO_CODENAME} main" | \
sudo tee /etc/apt/sources.list.d/tailscale.list > /dev/null
ok " Tailscale repo added."
fi

View File

@@ -58,11 +58,7 @@ pkg_install \
# fd-find may need a symlink (binary is fdfind on both distros)
if command -v fdfind &>/dev/null && ! command -v fd &>/dev/null; then
if [ "$DISTRO_FAMILY" = "debian" ]; then
sudo ln -sf "$(which fdfind)" /usr/local/bin/fd 2>/dev/null || true
else
sudo ln -sf "$(which fdfind)" /usr/local/bin/fd 2>/dev/null || true
fi
fi
# Differently-named

View File

@@ -12,19 +12,15 @@
# nvm is installed to ~/.nvm. Node LTS is installed and set as default.
# This matches the Pop machine which had v24.11.1 via nvm.
info "Installing nvm (Node Version Manager)..."
if [ -d "$HOME/.nvm" ] && [ -f "$HOME/.nvm/nvm.sh" ]; then
export NVM_DIR="$HOME/.nvm"
if [ -d "$NVM_DIR" ] && [ -f "$NVM_DIR/nvm.sh" ]; then
ok "nvm already installed."
else
# Install latest nvm
# curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
# Use the install script from nvm's GitHub
export NVM_DIR="$HOME/.nvm"
curl -fsSL https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.2/install.sh | bash
ok "nvm installed."
fi
# Source nvm for this script
export NVM_DIR="$HOME/.nvm"
[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"
# Install latest LTS Node

View File

@@ -61,9 +61,9 @@ fi
info "Deploying .zshrc..."
CONFIG_DIR="${SCRIPT_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)}/config"
if [ -f "$HOME/.zshrc" ]; then
# Backup existing
cp "$HOME/.zshrc" "$HOME/.zshrc.bak.$(date +%Y%m%d)" 2>/dev/null
warn "Backed up existing .zshrc to .zshrc.bak.$(date +%Y%m%d)"
_bak_date=$(date +%Y%m%d)
cp "$HOME/.zshrc" "$HOME/.zshrc.bak.${_bak_date}" 2>/dev/null
warn "Backed up existing .zshrc to .zshrc.bak.${_bak_date}"
fi
cp "${CONFIG_DIR}/shell/zshrc" "$HOME/.zshrc"
ok ".zshrc deployed."
@@ -71,7 +71,8 @@ ok ".zshrc deployed."
# ---- Deploy .p10k.zsh ----
info "Deploying .p10k.zsh..."
if [ -f "$HOME/.p10k.zsh" ]; then
cp "$HOME/.p10k.zsh" "$HOME/.p10k.zsh.bak.$(date +%Y%m%d)" 2>/dev/null
_bak_date=$(date +%Y%m%d)
cp "$HOME/.p10k.zsh" "$HOME/.p10k.zsh.bak.${_bak_date}" 2>/dev/null
warn "Backed up existing .p10k.zsh"
fi
cp "${CONFIG_DIR}/shell/p10k.zsh" "$HOME/.p10k.zsh"

View File

@@ -103,7 +103,8 @@ mkdir -p "$BW_SESSION_DIR"
# ---- Skip if session already exists and is valid ----
if [ -f "$BW_SESSION_FILE" ]; then
export BW_SESSION=$(cat "$BW_SESSION_FILE")
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)."
@@ -185,7 +186,8 @@ if [ -x "$TARGET_DIR/bw-load-ssh.sh" ]; then
echo ""
# Export session so bw-load-ssh can use it
if [ -f "$BW_SESSION_FILE" ]; then
export BW_SESSION=$(cat "$BW_SESSION_FILE")
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

View File

@@ -19,22 +19,21 @@
export PATH="$HOME/.local/bin:$PATH"
# ---- Define tool repos ----
# Format: "repo_name:github_org:has_pyproject:has_package_json"
# Format: "repo_name:github_org:has_pyproject"
# repo_name = directory name under ~/Development/
# github_org = GitHub org (julianprester or re3-work)
# has_pyproject = true if it has pyproject.toml and should be uv-installed
# has_package_json = true if it has package.json and should be npm-linked
TOOLS=(
"porridge:julianprester:true:false" # Zoom meeting transcriber daemon
"deepis:julianprester:true:false" # Literature discovery CLI
"pi-persist:julianprester:true:false" # Memory persistence (mempi, pi-overview)
"panac:julianprester:true:false" # Pandoc wrapper CLI
"gromd:julianprester:true:false" # Gromd tool
"kannwas:julianprester:true:false" # Kannwas tool
"tb-api:julianprester:false:false" # Thunderbird REST API (not a Python/npm pkg — Firefox addon)
"hotkeys:julianprester:false:false" # Shell scripts for Wayland hotkeys (no install needed)
"ocpa-repo:julianprester:true:false" # OpenCode pi agent Python package
"porridge:julianprester:true" # Zoom meeting transcriber daemon
"deepis:julianprester:true" # Literature discovery CLI
"pi-persist:julianprester:true" # Memory persistence (mempi, pi-overview)
"panac:julianprester:true" # Pandoc wrapper CLI
"gromd:julianprester:true" # Gromd tool
"kannwas:julianprester:true" # Kannwas tool
"tb-api:julianprester:false" # Thunderbird REST API (not a Python pkg — Firefox addon)
"hotkeys:julianprester:false" # Shell scripts for Wayland hotkeys (no install needed)
"ocpa-repo:julianprester:true" # OpenCode pi agent Python package
)
# ===========================================================================
@@ -44,7 +43,7 @@ mkdir -p "$HOME/Development"
# ---- Clone and install each tool ----
for tool_entry in "${TOOLS[@]}"; do
IFS=':' read -r name org has_pyproject has_package_json <<< "$tool_entry"
IFS=':' read -r name org has_pyproject <<< "$tool_entry"
target_dir="$HOME/Development/$name"
if [ -d "$target_dir" ]; then
@@ -82,4 +81,4 @@ echo ""
info "Verifying uv tool installations..."
uv tool list 2>/dev/null || warn "No uv tools installed."
ok "Stage 06 complete: uv tools installed."
ok "Stage 07 complete: uv tools installed."

View File

@@ -9,7 +9,6 @@
# - pi-overview.service : Session dashboard on port 3000
# - bw-ssh-keys.service : Load Bitwarden SSH keys at boot
# - mempi-sync.service : Sync memory DB to Nextcloud
# - mempi-sync.timer : Run mempi-sync on boot +5min
# - empty_downloads.service : Clear Downloads folder at login
# ===========================================================================
@@ -45,7 +44,7 @@ install_service_file "$SERVICES_DIR/pi-overview.service" "pi-overview.service"
# ---- 4. bw-ssh-keys.service — Load Bitwarden SSH keys at boot ----
install_service_file "$SERVICES_DIR/bw-ssh-keys.service" "bw-ssh-keys.service"
# ---- 5. mempi-sync.service — Sync memory DB to Nextcloud ----
# ---- 5. mempi-sync.service + timer — Sync memory DB to Nextcloud ----
install_service_file "$SERVICES_DIR/mempi-sync.service" "mempi-sync.service"
# ---- 6. empty_downloads.service — Clear Downloads at login ----
@@ -86,7 +85,6 @@ fi
systemctl --user enable --now empty_downloads.service 2>/dev/null && ok "empty_downloads.service enabled" || warn "empty_downloads.service not started."
# (No timers currently)
info "===== Service Status ====="
systemctl --user list-units --type=service --state=running 2>/dev/null | grep -E "(porridge|swayidle|pi-overview|mempi|bw-ssh|empty)" || true

View File

@@ -98,7 +98,6 @@ case "$DE" in
cp "$CONFIG_DIR/cosmic/custom-shortcuts.ron" \
"$HOME/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1/custom"
# Set terminal command (COSMIC desktop)
mkdir -p "$HOME/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1"
echo '{
Terminal: "/usr/bin/ghostty --gtk-single-instance=true",
}' > "$HOME/.config/cosmic/com.system76.CosmicSettings.Shortcuts/v1/system_actions"
@@ -187,7 +186,6 @@ mkdir -p "$FONT_DIR"
# This is the font used on the Pop machine (MesloLGS NF Regular).
install_nerd_font() {
local font_name="$1"
local repo_url="$2"
local font_dir="$FONT_DIR"
# Check if already installed
@@ -213,8 +211,8 @@ install_nerd_font() {
# MesloLGS NF (Regular, Bold, Italic, Bold Italic)
# FiraCode Nerd Font Propo
# ApercuMonoPro-Regular.otf (proprietary — not distributed)
install_nerd_font "Meslo" ""
install_nerd_font "FiraCode" ""
install_nerd_font "Meslo"
install_nerd_font "FiraCode"
# Rebuild font cache
fc-cache -f "$FONT_DIR" 2>/dev/null || true

View File

@@ -46,13 +46,8 @@ fi
# ---- Nextcloud Desktop Client ----
info "Installing Nextcloud Desktop Client..."
if [ "$DISTRO_FAMILY" = "debian" ]; then
pkg_install nextcloud-desktop 2>/dev/null && ok "Nextcloud client installed." || \
pkg_install_mapped "nextcloud-desktop" "nextcloud-client" 2>/dev/null && ok "Nextcloud client installed." || \
warn "Nextcloud client not available."
else
pkg_install nextcloud-client 2>/dev/null && ok "Nextcloud client installed." || \
warn "Nextcloud client not available."
fi
# ---- Thunderbird (email client) ----
info "Installing Thunderbird..."