From 502beec7e25d3d5c723f8a5e92933cf65fe7639f Mon Sep 17 00:00:00 2001 From: Peter Wood Date: Tue, 27 May 2025 22:11:14 -0400 Subject: [PATCH] feat: Add bash completion for backup scripts and enhance README documentation --- README.md | 47 +++++ completions/README.md | 221 +++++++++++++++++++++ completions/backup-scripts-completion.bash | 155 +++++++++++++++ dotfiles/.zshrc | 11 +- immich/README.md | 219 +++++++++++++++++++- immich/backup-immich.sh | 176 +++++++++++++++- setup/bootstrap.sh | 1 + setup/setup.sh | 18 ++ 8 files changed, 835 insertions(+), 13 deletions(-) create mode 100644 completions/README.md create mode 100644 completions/backup-scripts-completion.bash diff --git a/README.md b/README.md index 979703e..c0aa2e3 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,7 @@ This repository contains various shell scripts for managing media-related tasks - **[Backup Scripts](#backup-scripts)** - Enterprise-grade backup solutions - **[Management Scripts](#management-scripts)** - System and service management +- **[Tab Completion](#tab-completion)** - Intelligent command-line completion - **[Documentation](#documentation)** - Complete guides and references - **[Testing](#testing)** - Docker-based validation framework - **[Dotfiles](#dotfiles)** - System configuration files @@ -201,6 +202,51 @@ curl -fsSL https://raw.githubusercontent.com/acedanger/shell/main/bootstrap.sh | For more information about the dotfiles, see [Dotfiles README](./dotfiles/README.md). +## Tab Completion + +This repository includes intelligent bash completion for all backup scripts, providing tab completion for command-line flags and options. + +### Features + +- **Intelligent flag completion**: Tab completion for all backup script options +- **Webhook URL suggestions**: Auto-complete common webhook endpoints +- **Path-aware completion**: Works with relative, absolute, and PATH-based script execution +- **Cross-shell support**: Compatible with both bash and zsh + +### Supported Scripts + +- **backup-immich.sh**: `--help`, `--dry-run`, `--no-upload`, `--verbose` +- **backup-plex.sh**: `--help`, `--auto-repair`, `--check-integrity`, `--non-interactive`, `--no-parallel`, `--no-performance`, `--webhook`, `--email` +- **backup-media.sh**: `--help`, `--dry-run`, `--no-verify`, `--sequential`, `--interactive`, `--webhook` +- **Generic backup scripts**: Common flags for all backup utilities + +### Usage Examples + +```bash +# Tab completion for backup script flags +~/shell/immich/backup-immich.sh -- +# Shows: --help --dry-run --no-upload --verbose + +# Tab completion for webhook URLs +~/shell/plex/backup-plex.sh --webhook +# Shows: https://notify.peterwood.rocks/lab + +# Works with any script path +backup-immich.sh -- # From PATH +./backup-immich.sh -- # Relative path +/full/path/backup-immich.sh -- # Absolute path +``` + +### Installation + +Tab completion is automatically installed when you run the setup scripts: + +```bash +./setup/bootstrap.sh # Installs completion automatically +``` + +For manual installation or more details, see [Completions README](./completions/README.md). + ## Testing This repository includes Docker-based testing to validate the setup process across different environments. For complete testing documentation, see [Docker Bootstrap Testing Framework](./docs/docker-bootstrap-testing-framework.md). @@ -242,6 +288,7 @@ For complete crontab management documentation, see [Crontab Management Documenta ### Current Status The crontab system uses hostname-specific configuration files: + - **crontab-europa.txt** - Media server configuration - **crontab-io.txt** - Download/acquisition server configuration - **crontab-racknerd.txt** - Backup server configuration diff --git a/completions/README.md b/completions/README.md new file mode 100644 index 0000000..2418fd2 --- /dev/null +++ b/completions/README.md @@ -0,0 +1,221 @@ +# Bash Completion for Shell Scripts + +This directory contains bash completion scripts for various shell utilities in this repository. + +## Overview + +The completion system provides intelligent tab completion for command-line flags and options for all backup scripts in this repository. It's automatically installed and configured by the setup scripts. + +## Supported Scripts + +### backup-immich.sh + +- `--help`, `-h` - Show help message +- `--dry-run` - Preview backup without executing +- `--no-upload` - Skip B2 upload (local backup only) +- `--verbose` - Enable verbose logging + +### backup-plex.sh + +- `--help`, `-h` - Show help message +- `--auto-repair` - Automatically attempt to repair corrupted databases +- `--check-integrity` - Only check database integrity, don't backup +- `--non-interactive` - Run in non-interactive mode (for automation) +- `--no-parallel` - Disable parallel verification (slower but safer) +- `--no-performance` - Disable performance monitoring +- `--webhook=URL` - Send notifications to webhook URL +- `--email=ADDRESS` - Send notifications to email address + +### backup-media.sh + +- `--help`, `-h` - Show help message +- `--dry-run` - Show what would be backed up without actually doing it +- `--no-verify` - Skip backup verification +- `--sequential` - Run backups sequentially instead of in parallel +- `--interactive` - Ask for confirmation before each backup +- `--webhook URL` - Custom webhook URL for notifications + +### Generic backup scripts (backup-docker.sh, etc.) + +- `--help`, `-h` - Show help message +- `--dry-run` - Preview mode +- `--verbose` - Verbose output +- `--no-upload` - Skip upload operations +- `--webhook` - Webhook URL for notifications + +## Installation + +The completion system is **automatically installed** when you run the setup scripts: + +1. **bootstrap.sh** - Makes completion scripts executable +2. **setup.sh** - Copies completion scripts to the user's local completion directory (`~/.local/share/bash-completion/completions/`) +3. **.zshrc** - Sources the completion scripts in zsh with bash compatibility mode + +### Automatic Setup Process + +When you run `./setup/bootstrap.sh` or `./setup/setup.sh`, the system will: + +- Install bash completion support in zsh +- Copy completion scripts to the standard completion directory +- Ensure completion scripts are executable +- Source the completion in your shell configuration + +### Manual Installation + +If you need to install manually or re-install: + +```bash +# Enable bash completion compatibility in zsh +autoload -U +X bashcompinit && bashcompinit +autoload -U compinit && compinit -u + +# Load custom backup scripts completion +if [ -f "$HOME/shell/completions/backup-scripts-completion.bash" ]; then + source "$HOME/shell/completions/backup-scripts-completion.bash" +fi +``` + +## Usage Examples + +### Basic Tab Completion + +```bash +# Type the script name and start typing an option +$ backup-immich.sh -- +--help --dry-run --no-upload --verbose + +# Continue typing to filter +$ backup-immich.sh --d +$ backup-immich.sh --dry-run +``` + +### Webhook URL Completion + +```bash +# For scripts that support webhook URLs +$ backup-plex.sh --webhook +https://notify.peterwood.rocks/lab + +# Or for inline webhook options +$ backup-plex.sh --webhook= +https://notify.peterwood.rocks/lab +``` + +### Path-based Completion + +Completion works with various invocation methods: + +```bash +# Direct script name (if in PATH) +backup-immich.sh -- + +# Relative path +./backup-immich.sh -- + +# Absolute path +/home/acedanger/shell/immich/backup-immich.sh -- +``` + +## Features + +### Intelligent Argument Completion + +- **Flag completion**: All available flags for each script +- **Value completion**: Suggests common values for specific options +- **Context-aware**: Different completions based on script type + +### Cross-Script Support + +- **Specific completions**: Tailored for each backup script +- **Generic fallback**: Common options for any backup script +- **Pattern matching**: Automatic completion for `*backup*.sh` scripts + +### Advanced Features + +- **Webhook URL suggestions**: Common webhook endpoints +- **Email address completion**: For notification options +- **Multi-word option support**: Handles `--option value` and `--option=value` + +## Troubleshooting + +### Completion Not Working + +1. Verify the completion script is sourced: + + ```bash + complete -p | grep backup + ``` + +2. Reload your shell configuration: + + ```bash + source ~/.zshrc + ``` + +3. Check if bashcompinit is enabled: + + ```bash + # Should be in your .zshrc + autoload -U +X bashcompinit && bashcompinit + ``` + +### Adding New Scripts + +To add completion for a new backup script: + +1. Add the script patterns to the completion file +2. Define specific options for the script +3. Register the completion function + +Example: + +```bash +# Add to backup-scripts-completion.bash +complete -F _backup_generic_completion your-new-backup-script.sh +``` + +## Development + +### Testing Completions + +Use the test script to verify completions work: + +```bash +./test-completion.sh +``` + +### Adding New Options + +1. Update the relevant completion function in `backup-scripts-completion.bash` +2. Add the new option to the `opts` variable +3. Handle any special argument completion if needed +4. Test the completion with `compgen -W "options" -- "prefix"` + +### Custom Completion Functions + +Each script can have its own completion function following this pattern: + +```bash +_script_name_completion() { + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + opts="--option1 --option2 --option3" + + # Handle special cases + case "${prev}" in + --special-option) + COMPREPLY=( $(compgen -W "value1 value2" -- ${cur}) ) + return 0 + ;; + esac + + # Standard flag completion + if [[ ${cur} == -* ]]; then + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} +``` diff --git a/completions/backup-scripts-completion.bash b/completions/backup-scripts-completion.bash new file mode 100644 index 0000000..0ea30dd --- /dev/null +++ b/completions/backup-scripts-completion.bash @@ -0,0 +1,155 @@ +#!/bin/bash +# Bash completion for backup scripts in /home/acedanger/shell +# Source this file to enable tab completion for backup script flags + +# Completion function for backup-immich.sh +_backup_immich_completion() { + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # Available options for backup-immich.sh + opts="--help -h --dry-run --no-upload --verbose" + + # Handle specific option arguments + case "${prev}" in + --webhook) + # Could provide common webhook URLs here + COMPREPLY=( $(compgen -W "https://notify.peterwood.rocks/lab" -- ${cur}) ) + return 0 + ;; + *) + ;; + esac + + # Standard flag completion + if [[ ${cur} == -* ]]; then + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} + +# Completion function for backup-plex.sh +_backup_plex_completion() { + local cur prev opts + local common_emails="peter@peterwood.dev acedanger49@gmail.com alerts@peterwood.dev" + + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # Available options for backup-plex.sh + opts="--help -h --auto-repair --check-integrity --non-interactive --no-parallel --no-performance --webhook --email" + + # Handle specific option arguments + case "${prev}" in + --webhook) + COMPREPLY=( $(compgen -W "https://notify.peterwood.rocks/lab" -- ${cur}) ) + return 0 + ;; + --email) + # Provide common email addresses for completion + COMPREPLY=( $(compgen -W "${common_emails}" -- ${cur}) ) + return 0 + ;; + *) + ;; + esac + + # Standard flag completion + if [[ ${cur} == -* ]]; then + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} + +# Completion function for backup-media.sh +_backup_media_completion() { + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # Available options for backup-media.sh + opts="--help -h --dry-run --no-verify --sequential --interactive --webhook" + + # Handle specific option arguments + case "${prev}" in + --webhook) + COMPREPLY=( $(compgen -W "https://notify.peterwood.rocks/lab" -- ${cur}) ) + return 0 + ;; + *) + ;; + esac + + # Standard flag completion + if [[ ${cur} == -* ]]; then + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} + +# Completion function for generic backup scripts (fallback) +_backup_generic_completion() { + local cur prev opts + COMPREPLY=() + cur="${COMP_WORDS[COMP_CWORD]}" + prev="${COMP_WORDS[COMP_CWORD-1]}" + + # Common backup script options + opts="--help -h --dry-run --verbose --no-upload --webhook" + + # Handle specific option arguments + case "${prev}" in + --webhook) + COMPREPLY=( $(compgen -W "https://notify.peterwood.rocks/lab" -- ${cur}) ) + return 0 + ;; + *) + ;; + esac + + # Standard flag completion + if [[ ${cur} == -* ]]; then + COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) ) + return 0 + fi +} + +# Register completion functions for specific scripts +complete -F _backup_immich_completion backup-immich.sh +complete -F _backup_immich_completion ./backup-immich.sh +complete -F _backup_immich_completion /home/acedanger/shell/immich/backup-immich.sh + +complete -F _backup_plex_completion backup-plex.sh +complete -F _backup_plex_completion ./backup-plex.sh +complete -F _backup_plex_completion /home/acedanger/shell/plex/backup-plex.sh + +complete -F _backup_media_completion backup-media.sh +complete -F _backup_media_completion ./backup-media.sh +complete -F _backup_media_completion /home/acedanger/shell/backup-media.sh + +# Register completion for other backup scripts with generic completion +complete -F _backup_generic_completion backup-docker.sh +complete -F _backup_generic_completion ./backup-docker.sh +complete -F _backup_generic_completion /home/acedanger/shell/backup-docker.sh + +# You can add more specific completions here for other scripts +# Example: +# complete -F _backup_generic_completion your-other-backup-script.sh + +# Enable completion for script files when run with explicit paths +_backup_script_path_completion() { + local cur="${COMP_WORDS[COMP_CWORD]}" + + # If the current word looks like a backup script path, provide flag completion + if [[ "${COMP_WORDS[0]}" == *backup*.sh ]]; then + # Use generic completion for path-based calls + _backup_generic_completion + fi +} + +# Register for any script ending in backup*.sh +complete -o default -F _backup_script_path_completion -X '!*backup*.sh' diff --git a/dotfiles/.zshrc b/dotfiles/.zshrc index b683017..fa81249 100644 --- a/dotfiles/.zshrc +++ b/dotfiles/.zshrc @@ -117,4 +117,13 @@ load-nvmrc() { add-zsh-hook chpwd load-nvmrc load-nvmrc -[[ -s /home/acedanger/.autojump/etc/profile.d/autojump.sh ]] && source /home/acedanger/.autojump/etc/profile.d/autojump.sh autoload -U compinit && compinit -u +[[ -s /home/acedanger/.autojump/etc/profile.d/autojump.sh ]] && source /home/acedanger/.autojump/etc/profile.d/autojump.sh + +# Enable bash completion compatibility in zsh +autoload -U +X bashcompinit && bashcompinit +autoload -U compinit && compinit -u + +# Load custom backup scripts completion +if [ -f "$HOME/shell/completions/backup-scripts-completion.bash" ]; then + source "$HOME/shell/completions/backup-scripts-completion.bash" +fi diff --git a/immich/README.md b/immich/README.md index adbcd9a..419e554 100644 --- a/immich/README.md +++ b/immich/README.md @@ -22,7 +22,36 @@ Complete backup script for Immich installation that creates backups of: **Usage:** ```bash +./backup-immich.sh [OPTIONS] +``` + +**Command-Line Options:** + +- `--help, -h` - Show help message and exit +- `--dry-run` - Show what would be backed up without performing actual backup +- `--no-upload` - Skip B2 upload (local backup only) +- `--verbose` - Enable verbose logging + +**Examples:** + +```bash +# Standard backup (default behavior) ./backup-immich.sh + +# Show help and usage information +./backup-immich.sh --help + +# Preview what would be backed up without executing +./backup-immich.sh --dry-run + +# Backup locally only (skip B2 upload) +./backup-immich.sh --no-upload + +# Run with verbose logging +./backup-immich.sh --verbose + +# Combine options +./backup-immich.sh --no-upload --verbose ``` **Backup Location:** @@ -32,6 +61,9 @@ Complete backup script for Immich installation that creates backups of: **Features:** +- Command-line options for flexible operation (--help, --dry-run, --no-upload, --verbose) +- Dry-run mode to preview operations without executing +- Option to skip B2 upload for local-only backups - Automatic container pausing/resuming during backup - Comprehensive error handling and cleanup - Backup validation and health checks @@ -43,6 +75,191 @@ Complete backup script for Immich installation that creates backups of: - ☁️ **Backblaze B2 integration** for off-site backup storage - 📊 **File size reporting** in notifications +## Usage Examples + +### Basic Operations + +**Standard Backup (Default)** + +```bash +./backup-immich.sh +# Performs complete backup with all default settings: +# - Backs up database and upload directory +# - Uploads to B2 if configured +# - Sends webhook notifications +# - Logs to /home/acedanger/shell/logs/immich-backup.log +``` + +**Getting Help** + +```bash +./backup-immich.sh --help +# Shows complete usage information including: +# - All available command-line options +# - Configuration requirements +# - Examples and restore instructions +``` + +### Preview and Testing + +**Dry Run (Preview Mode)** + +```bash +./backup-immich.sh --dry-run +# Shows what would be backed up without executing: +# - Checks all prerequisites and container status +# - Displays backup file paths and estimated sizes +# - Validates B2 configuration if present +# - Reports any issues that would prevent backup +# - No files are created or modified +``` + +Example dry-run output: + +```text +=== DRY RUN MODE - NO ACTUAL BACKUP WILL BE PERFORMED === + +Configuration: + - Database: immich + - Username: postgres + - Upload Location: /opt/immich/upload + - Container: immich_postgres + - Backup Directory: /home/acedanger/shell/immich_backups + +Would create: + - Database backup: /home/acedanger/shell/immich_backups/immich_db_backup_20250527_140000.sql.gz + - Upload backup: /home/acedanger/shell/immich_backups/immich_uploads_20250527_140000.tar.gz + +Container Status Check: + ✓ immich_server: Running (would pause during backup) + ✓ immich_postgres: Running + ✓ Upload directory: /opt/immich/upload (42GB) + +B2 Upload Configuration: + ✓ B2 configured - would upload to bucket: my-immich-backups + ✓ B2 CLI found at: /home/acedanger/shell/immich/b2-linux + +=== DRY RUN COMPLETE - No files were created or modified === +``` + +### Local Backup Only + +**Skip B2 Upload** + +```bash +./backup-immich.sh --no-upload +# Performs backup but skips B2 upload: +# - Creates local backup files +# - Validates backup integrity +# - Sends notifications (without B2 status) +# - Useful for testing or when B2 is unavailable +``` + +### Verbose Logging + +**Detailed Output** + +```bash +./backup-immich.sh --verbose +# Enables detailed logging for troubleshooting: +# - Shows additional progress information +# - Includes Docker command output +# - Provides more detailed error messages +# - Helpful for debugging issues +``` + +### Combined Options + +**Local Backup with Verbose Output** + +```bash +./backup-immich.sh --no-upload --verbose +# Combines multiple options: +# - Creates local backup only (no B2 upload) +# - Shows detailed progress and logging +# - Useful for testing or troubleshooting +``` + +**Preview with Verbose Details** + +```bash +./backup-immich.sh --dry-run --verbose +# Shows detailed preview information: +# - Extended configuration validation +# - More detailed container status +# - Comprehensive B2 configuration check +# - Additional filesystem checks +``` + +### Automation Examples + +**Scheduled Backup (Crontab)** + +```bash +# Daily backup at 2:00 AM with logging +0 2 * * * /home/acedanger/shell/immich/backup-immich.sh >> /home/acedanger/shell/logs/immich-backup.log 2>&1 + +# Weekly local-only backup (no B2 upload) at 3:00 AM on Sundays +0 3 * * 0 /home/acedanger/shell/immich/backup-immich.sh --no-upload + +# Daily validation run (dry-run) at 1:55 AM to check system health +55 1 * * * /home/acedanger/shell/immich/backup-immich.sh --dry-run >> /home/acedanger/shell/logs/immich-validation.log 2>&1 +``` + +**Manual Backup Scripts** + +```bash +#!/bin/bash +# emergency-backup.sh - Quick local backup without B2 +echo "Starting emergency Immich backup..." +/home/acedanger/shell/immich/backup-immich.sh --no-upload --verbose + +#!/bin/bash +# weekly-validation.sh - Comprehensive system check +echo "Validating Immich backup system..." +/home/acedanger/shell/immich/backup-immich.sh --dry-run --verbose +``` + +### Troubleshooting Examples + +**Check System Status** + +```bash +# Quick system validation without backup +./backup-immich.sh --dry-run + +# If containers are not running: +docker ps | grep immich # Check container status +docker start immich_server immich_postgres # Start if needed + +# If upload directory missing: +ls -la /opt/immich/upload # Verify path exists +``` + +**Test B2 Configuration** + +```bash +# Backup without B2 to test local functionality +./backup-immich.sh --no-upload + +# Check B2 CLI manually +./b2-linux version # Verify B2 CLI works +./b2-linux authorize-account YOUR_KEY_ID YOUR_KEY # Test authorization +``` + +**Debug Backup Issues** + +```bash +# Run with maximum detail for troubleshooting +./backup-immich.sh --verbose --no-upload + +# Check logs for errors +tail -f /home/acedanger/shell/logs/immich-backup.log + +# Validate backup files +ls -la /home/acedanger/shell/immich_backups/ +``` + ## Configuration The scripts expect a `.env` file in the parent directory with the following variables: @@ -90,7 +307,7 @@ The backup script sends notifications to your webhook URL with: Example notification: -``` +```text 📦 Database: immich_db_backup_20250526_215913.sql.gz (150MB) 📁 Uploads: immich_uploads_20250526_215913.tar.gz (25GB) ☁️ Successfully uploaded to B2 bucket: my-immich-backups diff --git a/immich/backup-immich.sh b/immich/backup-immich.sh index 2c70392..c78ea6b 100755 --- a/immich/backup-immich.sh +++ b/immich/backup-immich.sh @@ -51,6 +51,80 @@ if [ -z "$DB_USERNAME" ] || [ -z "$DB_DATABASE_NAME" ] || [ -z "$UPLOAD_LOCATION exit 1 fi +# Help function +show_help() { + cat << EOF +Immich Complete Backup Script +This script creates a complete backup of the Immich installation including: +1. Postgres database (using pg_dumpall as recommended by Immich) +2. User upload directories (photos, videos, and metadata) + +USAGE: + $(basename "$0") [OPTIONS] + +OPTIONS: + --help, -h Show this help message and exit + --dry-run Show what would be backed up without performing actual backup + --no-upload Skip B2 upload (local backup only) + --verbose Enable verbose logging + +CONFIGURATION: + This script requires a .env file in the parent directory with: + - DB_USERNAME= + - DB_DATABASE_NAME= + - UPLOAD_LOCATION= + +OPTIONAL B2 CONFIGURATION: + - B2_APPLICATION_KEY_ID= + - B2_APPLICATION_KEY= + - B2_BUCKET_NAME= + +OPTIONAL WEBHOOK CONFIGURATION: + - WEBHOOK_URL= + +EXAMPLES: + $(basename "$0") # Run full backup + $(basename "$0") --help # Show this help + $(basename "$0") --dry-run # Preview backup without executing + $(basename "$0") --no-upload # Backup locally only (skip B2) + +RESTORE INSTRUCTIONS: + https://immich.app/docs/administration/backup-and-restore/ + +EOF +} + +# Parse command line arguments +DRY_RUN=false +NO_UPLOAD=false +VERBOSE=false + +while [[ $# -gt 0 ]]; do + case $1 in + --help|-h) + show_help + exit 0 + ;; + --dry-run) + DRY_RUN=true + shift + ;; + --no-upload) + NO_UPLOAD=true + shift + ;; + --verbose) + VERBOSE=true + shift + ;; + *) + echo "Error: Unknown option $1" + echo "Use --help for usage information" + exit 1 + ;; + esac +done + # B2 CLI tool path B2_CLI="$(dirname "$0")/b2-linux" @@ -143,6 +217,68 @@ DB_BACKUP_FILENAME="immich_db_backup_${TIMESTAMP}.sql" DB_BACKUP_PATH="${BACKUP_DIR}/${DB_BACKUP_FILENAME}" UPLOAD_BACKUP_PATH="${BACKUP_DIR}/immich_uploads_${TIMESTAMP}.tar.gz" +# Handle dry-run mode +if [ "$DRY_RUN" = true ]; then + echo "" + echo "=== DRY RUN MODE - NO ACTUAL BACKUP WILL BE PERFORMED ===" + echo "" + echo "Configuration:" + echo " - Database: ${DB_DATABASE_NAME}" + echo " - Username: ${DB_USERNAME}" + echo " - Upload Location: ${UPLOAD_LOCATION}" + echo " - Container: immich_postgres" + echo " - Backup Directory: ${BACKUP_DIR}" + echo "" + echo "Would create:" + echo " - Database backup: ${DB_BACKUP_PATH}.gz" + echo " - Upload backup: ${UPLOAD_BACKUP_PATH}" + echo "" + + # Check container status in dry-run + echo "Container Status Check:" + if docker ps -q --filter "name=immich_server" | grep -q .; then + echo " ✓ immich_server: Running (would pause during backup)" + else + echo " ! immich_server: Not running or not found" + fi + + if docker ps -q --filter "name=immich_postgres" | grep -q .; then + echo " ✓ immich_postgres: Running" + else + echo " ✗ immich_postgres: Not running - backup would fail!" + exit 1 + fi + + # Check upload directory + if [ -d "${UPLOAD_LOCATION}" ]; then + UPLOAD_SIZE=$(du -sh "${UPLOAD_LOCATION}" 2>/dev/null | cut -f1 || echo "unknown") + echo " ✓ Upload directory: ${UPLOAD_LOCATION} (${UPLOAD_SIZE})" + else + echo " ✗ Upload directory: ${UPLOAD_LOCATION} does not exist - backup would fail!" + exit 1 + fi + + # Check B2 configuration + echo "" + echo "B2 Upload Configuration:" + if [ "$NO_UPLOAD" = true ]; then + echo " ! B2 upload disabled by --no-upload flag" + elif [ -n "$B2_APPLICATION_KEY_ID" ] && [ -n "$B2_APPLICATION_KEY" ] && [ -n "$B2_BUCKET_NAME" ]; then + echo " ✓ B2 configured - would upload to bucket: ${B2_BUCKET_NAME}" + if [ -f "$B2_CLI" ]; then + echo " ✓ B2 CLI found at: ${B2_CLI}" + else + echo " ✗ B2 CLI not found at: ${B2_CLI} - upload would fail!" + fi + else + echo " ! B2 not configured - would skip upload" + fi + + echo "" + echo "=== DRY RUN COMPLETE - No files were created or modified ===" + exit 0 +fi + log_message "Starting complete backup of Immich installation..." log_message "Using settings from .env file:" log_message " - Database: ${DB_DATABASE_NAME}" @@ -151,6 +287,14 @@ log_message " - Upload Location: ${UPLOAD_LOCATION}" log_message " - Container: immich_postgres" log_message " - Backup Directory: ${BACKUP_DIR}" +if [ "$NO_UPLOAD" = true ]; then + log_message " - B2 Upload: DISABLED (--no-upload flag)" +fi + +if [ "$VERBOSE" = true ]; then + log_message " - Verbose logging: ENABLED" +fi + # Send start notification send_notification "🚀 Immich Backup Started" "Starting complete backup of Immich database and uploads directory" "info" @@ -271,19 +415,25 @@ echo "=== BACKUP SUMMARY ===" echo "Database backup size: ${DB_BACKUP_SIZE}" echo "Upload directory backup size: ${UPLOAD_BACKUP_SIZE}" -# Upload to B2 (if configured) +# Upload to B2 (if configured and not disabled) echo "" -echo "=== UPLOADING TO BACKBLAZE B2 ===" -B2_UPLOAD_SUCCESS=true +if [ "$NO_UPLOAD" = true ]; then + echo "=== SKIPPING B2 UPLOAD (--no-upload flag) ===" + log_message "B2 upload skipped due to --no-upload flag" + B2_UPLOAD_SUCCESS="skipped" +else + echo "=== UPLOADING TO BACKBLAZE B2 ===" + B2_UPLOAD_SUCCESS=true -# Upload database backup -if ! upload_to_b2 "${DB_BACKUP_PATH}.gz"; then - B2_UPLOAD_SUCCESS=false -fi + # Upload database backup + if ! upload_to_b2 "${DB_BACKUP_PATH}.gz"; then + B2_UPLOAD_SUCCESS=false + fi -# Upload uploads backup -if ! upload_to_b2 "${UPLOAD_BACKUP_PATH}"; then - B2_UPLOAD_SUCCESS=false + # Upload uploads backup + if ! upload_to_b2 "${UPLOAD_BACKUP_PATH}"; then + B2_UPLOAD_SUCCESS=false + fi fi # Prepare notification message @@ -292,7 +442,11 @@ UPLOAD_FILENAME=$(basename "${UPLOAD_BACKUP_PATH}") NOTIFICATION_MESSAGE="📦 Database: ${DB_FILENAME} (${DB_BACKUP_SIZE}) 📁 Uploads: ${UPLOAD_FILENAME} (${UPLOAD_BACKUP_SIZE})" -if [ "$B2_UPLOAD_SUCCESS" = true ] && [ -n "$B2_BUCKET_NAME" ]; then +if [ "$B2_UPLOAD_SUCCESS" = "skipped" ]; then + NOTIFICATION_MESSAGE="${NOTIFICATION_MESSAGE} +💾 Local backup only (B2 upload skipped)" + send_notification "✅ Immich Backup Completed (Local Only)" "$NOTIFICATION_MESSAGE" "success" +elif [ "$B2_UPLOAD_SUCCESS" = true ] && [ -n "$B2_BUCKET_NAME" ]; then NOTIFICATION_MESSAGE="${NOTIFICATION_MESSAGE} ☁️ Successfully uploaded to B2 bucket: ${B2_BUCKET_NAME}" send_notification "✅ Immich Backup Completed" "$NOTIFICATION_MESSAGE" "success" diff --git a/setup/bootstrap.sh b/setup/bootstrap.sh index a2fac2c..f583f50 100755 --- a/setup/bootstrap.sh +++ b/setup/bootstrap.sh @@ -71,6 +71,7 @@ fi # Make scripts executable chmod +x "$DOTFILES_DIR/setup/setup.sh" +chmod +x "$DOTFILES_DIR/completions/backup-scripts-completion.bash" 2>/dev/null || true # Run setup script "$DOTFILES_DIR/setup/setup.sh" diff --git a/setup/setup.sh b/setup/setup.sh index 10b3200..7eda314 100755 --- a/setup/setup.sh +++ b/setup/setup.sh @@ -279,6 +279,24 @@ clone_zsh_plugin "https://github.com/zsh-users/zsh-autosuggestions" "$PLUGINS_DI clone_zsh_plugin "https://github.com/zsh-users/zsh-syntax-highlighting" "$PLUGINS_DIR/zsh-syntax-highlighting" clone_zsh_plugin "https://github.com/MichaelAquilina/zsh-you-should-use" "$PLUGINS_DIR/zsh-you-should-use" +# Set up bash completion for backup scripts +echo -e "${YELLOW}Setting up bash completion for backup scripts...${NC}" +COMPLETION_SCRIPT="$DOTFILES_DIR/completions/backup-scripts-completion.bash" +if [ -f "$COMPLETION_SCRIPT" ]; then + # Create completions directory in home + mkdir -p "$HOME/.local/share/bash-completion/completions" + + # Copy completion script to user's completion directory + cp "$COMPLETION_SCRIPT" "$HOME/.local/share/bash-completion/completions/" + + # Make sure it's executable + chmod +x "$HOME/.local/share/bash-completion/completions/backup-scripts-completion.bash" + + echo -e "${GREEN}Bash completion script installed successfully!${NC}" +else + echo -e "${YELLOW}Warning: Bash completion script not found at $COMPLETION_SCRIPT${NC}" +fi + # Set up dotfiles echo -e "${YELLOW}Setting up dotfiles...${NC}" # Consolidate symbolic link creation for dotfiles