mirror of
https://github.com/acedanger/shell.git
synced 2025-12-05 22:50:18 -08:00
Refactor variable assignments and improve script readability in validate-plex-backups.sh and validate-plex-recovery.sh
- Changed inline variable assignments to separate declaration and assignment for clarity. - Updated condition checks and log messages for better readability and consistency. - Added a backup of validate-plex-recovery.sh for safety. - Introduced a new script run-docker-tests.sh for testing setup in Docker containers. - Enhanced ssh-login.sh to improve condition checks and logging functionality.
This commit is contained in:
@@ -115,7 +115,7 @@ show_status() {
|
||||
# Check deployment config
|
||||
if [ -d "$HOME/.docker-deployment" ]; then
|
||||
echo -e "${GREEN}✅ Deployment configuration: Ready${NC}"
|
||||
local servers=$(ls "$HOME/.docker-deployment/servers/"*.yml 2>/dev/null | wc -l)
|
||||
local servers=$(find . -maxdepth 1 -type f | wc -l)
|
||||
echo " Configured servers: $servers"
|
||||
else
|
||||
echo -e "${RED}❌ Deployment configuration: Not initialized${NC}"
|
||||
|
||||
224
docker-deployment/deployment-env-integration.sh.sc2012_backup
Executable file
224
docker-deployment/deployment-env-integration.sh.sc2012_backup
Executable file
@@ -0,0 +1,224 @@
|
||||
#!/bin/bash
|
||||
|
||||
# deployment-env-integration.sh - Integrate deployment manager with existing env backup system
|
||||
# Author: Shell Repository
|
||||
# Description: Bridge between docker-deployment-manager and backup-env-files system
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DEPLOYMENT_MANAGER="$SCRIPT_DIR/docker-deployment-manager.sh"
|
||||
ENV_BACKUP_SCRIPT="$SCRIPT_DIR/backup-env-files.sh"
|
||||
STACK_HELPER="$SCRIPT_DIR/stack-assignment-helper.sh"
|
||||
|
||||
echo -e "${BLUE}=== Docker Deployment & Environment Backup Integration ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Check if required scripts exist
|
||||
check_dependencies() {
|
||||
local missing=()
|
||||
|
||||
[ ! -f "$DEPLOYMENT_MANAGER" ] && missing+=("docker-deployment-manager.sh")
|
||||
[ ! -f "$ENV_BACKUP_SCRIPT" ] && missing+=("backup-env-files.sh")
|
||||
[ ! -f "$STACK_HELPER" ] && missing+=("stack-assignment-helper.sh")
|
||||
|
||||
if [ ${#missing[@]} -gt 0 ]; then
|
||||
echo -e "${RED}Missing required scripts:${NC}"
|
||||
printf ' - %s\n' "${missing[@]}"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Setup integration
|
||||
setup_integration() {
|
||||
echo -e "${YELLOW}Setting up deployment and backup integration...${NC}"
|
||||
|
||||
# Initialize deployment configuration
|
||||
if [ ! -d "$HOME/.docker-deployment" ]; then
|
||||
echo "1. Initializing deployment configuration..."
|
||||
"$DEPLOYMENT_MANAGER" init
|
||||
else
|
||||
echo -e "${GREEN}✓ Deployment configuration already exists${NC}"
|
||||
fi
|
||||
|
||||
# Initialize environment backup if not already done
|
||||
if [ ! -d "$HOME/.env-backup" ]; then
|
||||
echo ""
|
||||
echo "2. Environment backup system needs initialization."
|
||||
echo " Run: $ENV_BACKUP_SCRIPT --init"
|
||||
echo " This will set up secure backup of your .env files to Gitea."
|
||||
else
|
||||
echo -e "${GREEN}✓ Environment backup already configured${NC}"
|
||||
fi
|
||||
|
||||
# Analyze current stacks
|
||||
echo ""
|
||||
echo "3. Analyzing current Docker stacks..."
|
||||
"$STACK_HELPER" analyze
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}✓ Integration setup completed!${NC}"
|
||||
}
|
||||
|
||||
# Show workflow suggestions
|
||||
show_workflow() {
|
||||
echo -e "${BLUE}=== Recommended Workflow ===${NC}"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}📋 Daily Operations:${NC}"
|
||||
echo "1. Make changes to Docker stacks in your monorepo"
|
||||
echo "2. Test locally before deployment"
|
||||
echo "3. Backup environment files: $ENV_BACKUP_SCRIPT"
|
||||
echo "4. Deploy to specific server: $DEPLOYMENT_MANAGER deploy <server>"
|
||||
echo "5. Verify deployment: $DEPLOYMENT_MANAGER status <server>"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}🔄 Bulk Operations:${NC}"
|
||||
echo "1. Deploy all stacks: $DEPLOYMENT_MANAGER deploy-all --dry-run"
|
||||
echo "2. Check what goes where: $DEPLOYMENT_MANAGER map"
|
||||
echo "3. Sync just environments: $DEPLOYMENT_MANAGER sync-env <server>"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}📊 Analysis & Planning:${NC}"
|
||||
echo "1. Analyze stack assignments: $STACK_HELPER analyze"
|
||||
echo "2. Check resource usage: $STACK_HELPER resources"
|
||||
echo "3. Get optimization tips: $STACK_HELPER optimize"
|
||||
echo "4. Generate new configs: $STACK_HELPER generate"
|
||||
echo ""
|
||||
|
||||
echo -e "${YELLOW}🔧 Automation Integration:${NC}"
|
||||
echo "These commands can be integrated into your existing crontab system:"
|
||||
echo ""
|
||||
echo "# Daily environment backup (already in crontab)"
|
||||
echo "0 3 * * * $ENV_BACKUP_SCRIPT"
|
||||
echo ""
|
||||
echo "# Weekly deployment validation"
|
||||
echo "0 4 * * 0 $DEPLOYMENT_MANAGER deploy-all --dry-run"
|
||||
echo ""
|
||||
echo "# Monthly stack analysis"
|
||||
echo "0 5 1 * * $STACK_HELPER all > /home/acedanger/shell/logs/stack-analysis.log"
|
||||
}
|
||||
|
||||
# Show current status
|
||||
show_status() {
|
||||
echo -e "${BLUE}=== Current System Status ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Check deployment config
|
||||
if [ -d "$HOME/.docker-deployment" ]; then
|
||||
echo -e "${GREEN}✅ Deployment configuration: Ready${NC}"
|
||||
local servers=$(ls "$HOME/.docker-deployment/servers/"*.yml 2>/dev/null | wc -l)
|
||||
echo " Configured servers: $servers"
|
||||
else
|
||||
echo -e "${RED}❌ Deployment configuration: Not initialized${NC}"
|
||||
fi
|
||||
|
||||
# Check environment backup
|
||||
if [ -d "$HOME/.env-backup" ]; then
|
||||
echo -e "${GREEN}✅ Environment backup: Ready${NC}"
|
||||
local last_backup=$(stat -c %y "$HOME/.env-backup/.git/HEAD" 2>/dev/null | cut -d' ' -f1 || echo "Never")
|
||||
echo " Last backup: $last_backup"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Environment backup: Not initialized${NC}"
|
||||
fi
|
||||
|
||||
# Check Docker stacks
|
||||
if [ -d "$HOME/docker" ]; then
|
||||
local stack_count=$(find "$HOME/docker" -maxdepth 1 -type d | wc -l)
|
||||
stack_count=$((stack_count - 1)) # Exclude the docker directory itself
|
||||
echo -e "${GREEN}✅ Docker stacks: $stack_count found${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Docker directory: Not found${NC}"
|
||||
fi
|
||||
|
||||
# Check crontab integration
|
||||
if crontab -l 2>/dev/null | grep -q "backup-env-files.sh"; then
|
||||
echo -e "${GREEN}✅ Crontab integration: Environment backup scheduled${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Crontab integration: No env backup scheduled${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Test the integration
|
||||
test_integration() {
|
||||
echo -e "${BLUE}=== Testing Integration ===${NC}"
|
||||
echo ""
|
||||
|
||||
echo "1. Testing deployment manager..."
|
||||
if "$DEPLOYMENT_MANAGER" map >/dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Deployment manager: Working${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Deployment manager: Error${NC}"
|
||||
fi
|
||||
|
||||
echo "2. Testing environment backup..."
|
||||
if "$ENV_BACKUP_SCRIPT" --list >/dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Environment backup: Working${NC}"
|
||||
else
|
||||
echo -e "${YELLOW}⚠️ Environment backup: Needs initialization${NC}"
|
||||
fi
|
||||
|
||||
echo "3. Testing stack analysis..."
|
||||
if "$STACK_HELPER" analyze >/dev/null 2>&1; then
|
||||
echo -e "${GREEN}✅ Stack analysis: Working${NC}"
|
||||
else
|
||||
echo -e "${RED}❌ Stack analysis: Error${NC}"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo -e "${BLUE}Integration test completed.${NC}"
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
check_dependencies
|
||||
|
||||
case "${1:-status}" in
|
||||
setup|--setup|-s)
|
||||
setup_integration
|
||||
;;
|
||||
workflow|--workflow|-w)
|
||||
show_workflow
|
||||
;;
|
||||
status|--status)
|
||||
show_status
|
||||
;;
|
||||
test|--test|-t)
|
||||
test_integration
|
||||
;;
|
||||
all|--all|-a)
|
||||
show_status
|
||||
echo ""
|
||||
setup_integration
|
||||
echo ""
|
||||
show_workflow
|
||||
;;
|
||||
help|--help|-h)
|
||||
echo "Usage: $0 [COMMAND]"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " setup Initialize deployment and backup integration"
|
||||
echo " workflow Show recommended workflow"
|
||||
echo " status Show current system status (default)"
|
||||
echo " test Test integration components"
|
||||
echo " all Run status, setup, and show workflow"
|
||||
echo " help Show this help message"
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Unknown command: $1${NC}"
|
||||
echo "Use '$0 help' for usage information"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Run main function
|
||||
main "$@"
|
||||
632
docker-deployment/docker-deployment-manager.sh.sc2012_backup
Executable file
632
docker-deployment/docker-deployment-manager.sh.sc2012_backup
Executable file
@@ -0,0 +1,632 @@
|
||||
#!/bin/bash
|
||||
|
||||
# docker-deployment-manager.sh - Manage Docker stack deployments across multiple servers
|
||||
# Author: Shell Repository
|
||||
# Description: Deploy specific Docker stacks to designated servers while maintaining monorepo structure
|
||||
|
||||
set -e
|
||||
|
||||
# Colors for output
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[0;33m'
|
||||
RED='\033[0;31m'
|
||||
BLUE='\033[0;34m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
DOCKER_DIR="$HOME/docker"
|
||||
DEPLOYMENT_CONFIG_DIR="$HOME/.docker-deployment"
|
||||
LOG_FILE="$SCRIPT_DIR/logs/deployment.log"
|
||||
|
||||
# Ensure directories exist
|
||||
mkdir -p "$(dirname "$LOG_FILE")"
|
||||
mkdir -p "$DEPLOYMENT_CONFIG_DIR"/{config,servers,stacks,logs}
|
||||
|
||||
# Logging function
|
||||
log() {
|
||||
echo "$(date '+%Y-%m-%d %H:%M:%S') - $1" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
# Display usage information
|
||||
usage() {
|
||||
echo "Usage: $0 [OPTIONS] [COMMAND]"
|
||||
echo ""
|
||||
echo "Manage Docker stack deployments across multiple servers"
|
||||
echo ""
|
||||
echo "Commands:"
|
||||
echo " init Initialize deployment configuration"
|
||||
echo " map Show stack-to-server mapping"
|
||||
echo " deploy SERVER Deploy stacks to specific server"
|
||||
echo " deploy-all Deploy all stacks to their designated servers"
|
||||
echo " status SERVER Check deployment status on server"
|
||||
echo " sync-env SERVER Sync environment files to server"
|
||||
echo " rollback SERVER Rollback to previous deployment"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help Show this help message"
|
||||
echo " -d, --dry-run Show what would be deployed without doing it"
|
||||
echo " -f, --force Force deployment even if checks fail"
|
||||
echo " -v, --verbose Verbose output"
|
||||
echo " --config-only Only sync configuration files"
|
||||
echo " --env-only Only sync environment files"
|
||||
echo ""
|
||||
echo "Examples:"
|
||||
echo " $0 init # First time setup"
|
||||
echo " $0 map # See what goes where"
|
||||
echo " $0 deploy europa # Deploy Europa stacks"
|
||||
echo " $0 deploy-all --dry-run # Test full deployment"
|
||||
echo " $0 sync-env io # Sync .env files to IO server"
|
||||
}
|
||||
|
||||
# Initialize deployment configuration
|
||||
init_deployment_config() {
|
||||
echo -e "${YELLOW}Initializing Docker deployment configuration...${NC}"
|
||||
|
||||
# Create main configuration file
|
||||
cat > "$DEPLOYMENT_CONFIG_DIR/config.yml" << 'EOF'
|
||||
# Docker Deployment Manager Configuration
|
||||
# This file defines global settings for stack deployment across servers
|
||||
|
||||
deployment:
|
||||
version: "1.0"
|
||||
docker_dir: "~/docker"
|
||||
backup_before_deploy: true
|
||||
health_check_timeout: 30
|
||||
rollback_on_failure: true
|
||||
|
||||
# Multi-server stacks - these will be deployed to ALL servers
|
||||
multi_server_stacks:
|
||||
- dozzle # Docker log viewer
|
||||
- dockge # Docker compose management
|
||||
- diun # Docker image update notifier
|
||||
|
||||
notifications:
|
||||
enabled: true
|
||||
webhook_url: "https://notify.peterwood.rocks/lab"
|
||||
tags: ["deployment", "docker"]
|
||||
|
||||
logging:
|
||||
level: "info"
|
||||
retain_days: 30
|
||||
|
||||
security:
|
||||
verify_checksums: true
|
||||
backup_env_files: true
|
||||
use_secure_transfer: true
|
||||
EOF
|
||||
|
||||
# Create server configurations based on existing crontab analysis
|
||||
cat > "$DEPLOYMENT_CONFIG_DIR/servers/europa.yml" << 'EOF'
|
||||
# Europa Server Configuration - Media Server
|
||||
name: "europa"
|
||||
role: "media-server"
|
||||
description: "Primary media streaming and web services server"
|
||||
|
||||
connection:
|
||||
hostname: "europa"
|
||||
user: "acedanger"
|
||||
ssh_key: "~/.ssh/id_rsa"
|
||||
docker_compose_dir: "~/docker"
|
||||
|
||||
stacks:
|
||||
- plex
|
||||
- jellyfin
|
||||
- traefik
|
||||
- nextcloud
|
||||
- photoprism
|
||||
- immich
|
||||
|
||||
resources:
|
||||
cpu_cores: 4
|
||||
memory_gb: 8
|
||||
storage_gb: 500
|
||||
|
||||
monitoring:
|
||||
health_check_url: "http://europa:8080/health"
|
||||
required_services:
|
||||
- "traefik"
|
||||
- "plex"
|
||||
EOF
|
||||
|
||||
cat > "$DEPLOYMENT_CONFIG_DIR/servers/io.yml" << 'EOF'
|
||||
# IO Server Configuration - Download/Acquisition Server
|
||||
name: "io"
|
||||
role: "download-server"
|
||||
description: "Media acquisition and download management server"
|
||||
|
||||
connection:
|
||||
hostname: "io"
|
||||
user: "acedanger"
|
||||
ssh_key: "~/.ssh/id_rsa"
|
||||
docker_compose_dir: "~/docker"
|
||||
|
||||
stacks:
|
||||
- radarr
|
||||
- sonarr
|
||||
- lidarr
|
||||
- sabnzbd
|
||||
- qbittorrent
|
||||
- prowlarr
|
||||
- overseerr
|
||||
|
||||
resources:
|
||||
cpu_cores: 2
|
||||
memory_gb: 4
|
||||
storage_gb: 200
|
||||
|
||||
monitoring:
|
||||
health_check_url: "http://io:8080/health"
|
||||
required_services:
|
||||
- "sabnzbd"
|
||||
- "radarr"
|
||||
- "sonarr"
|
||||
EOF
|
||||
|
||||
cat > "$DEPLOYMENT_CONFIG_DIR/servers/racknerd.yml" << 'EOF'
|
||||
# Racknerd Server Configuration - Backup Server
|
||||
name: "racknerd"
|
||||
role: "backup-server"
|
||||
description: "Backup, monitoring, and utility services server"
|
||||
|
||||
connection:
|
||||
hostname: "racknerd"
|
||||
user: "acedanger"
|
||||
ssh_key: "~/.ssh/id_rsa"
|
||||
docker_compose_dir: "~/docker"
|
||||
|
||||
stacks:
|
||||
- grafana
|
||||
- prometheus
|
||||
- uptime-kuma
|
||||
- vaultwarden
|
||||
- portainer
|
||||
- watchtower
|
||||
|
||||
resources:
|
||||
cpu_cores: 1
|
||||
memory_gb: 2
|
||||
storage_gb: 100
|
||||
|
||||
monitoring:
|
||||
health_check_url: "http://racknerd:8080/health"
|
||||
required_services:
|
||||
- "uptime-kuma"
|
||||
- "vaultwarden"
|
||||
EOF
|
||||
|
||||
# Create stack metadata examples
|
||||
if [ -d "$DOCKER_DIR/plex" ]; then
|
||||
cat > "$DEPLOYMENT_CONFIG_DIR/stacks/plex.yml" << 'EOF'
|
||||
# Plex Stack Deployment Configuration
|
||||
name: "plex"
|
||||
description: "Plex Media Server"
|
||||
|
||||
deployment:
|
||||
servers: ["europa"]
|
||||
priority: "high"
|
||||
dependencies: ["traefik"]
|
||||
restart_policy: "unless-stopped"
|
||||
|
||||
health_check:
|
||||
enabled: true
|
||||
url: "http://localhost:32400/web"
|
||||
timeout: 30
|
||||
retries: 3
|
||||
|
||||
volumes:
|
||||
- "/mnt/media:/media:ro"
|
||||
- "/mnt/share/plex-config:/config"
|
||||
|
||||
environment:
|
||||
- "PLEX_UID=1000"
|
||||
- "PLEX_GID=1000"
|
||||
- "TZ=America/New_York"
|
||||
|
||||
backup:
|
||||
enabled: true
|
||||
schedule: "0 2 * * *"
|
||||
retention_days: 7
|
||||
EOF
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Deployment configuration initialized!${NC}"
|
||||
echo -e "${BLUE}Configuration files created in: $DEPLOYMENT_CONFIG_DIR${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Next steps:${NC}"
|
||||
echo "1. Review and customize server configurations in $DEPLOYMENT_CONFIG_DIR/servers/"
|
||||
echo "2. Add stack metadata files for your Docker stacks"
|
||||
echo "3. Run '$0 map' to see the current mapping"
|
||||
echo "4. Test with '$0 deploy-all --dry-run'"
|
||||
|
||||
log "Deployment configuration initialized"
|
||||
}
|
||||
|
||||
# Load server configuration
|
||||
load_server_config() {
|
||||
local server="$1"
|
||||
local config_file="$DEPLOYMENT_CONFIG_DIR/servers/${server}.yml"
|
||||
|
||||
if [ ! -f "$config_file" ]; then
|
||||
echo -e "${RED}Error: Server configuration not found for '$server'${NC}"
|
||||
echo "Available servers:"
|
||||
ls "$DEPLOYMENT_CONFIG_DIR/servers/" 2>/dev/null | sed 's/\.yml$//' | sed 's/^/ - /'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# For now, we'll parse YAML manually (could use yq if available)
|
||||
# Extract stacks list from YAML
|
||||
grep -A 50 "stacks:" "$config_file" | grep "^-" | sed 's/^- //' | sed 's/["'\'']//g' | sed 's/#.*//' | sed 's/[[:space:]]*$//'
|
||||
}
|
||||
|
||||
# Load multi-server stacks from config
|
||||
load_multi_server_stacks() {
|
||||
local config_file="$DEPLOYMENT_CONFIG_DIR/config.yml"
|
||||
if [ -f "$config_file" ]; then
|
||||
grep -A 10 "multi_server_stacks:" "$config_file" | grep "^-" | sed 's/^- //' | sed 's/["'\'']//g' | sed 's/#.*//' | sed 's/[[:space:]]*$//'
|
||||
fi
|
||||
}
|
||||
|
||||
# Show stack-to-server mapping
|
||||
show_mapping() {
|
||||
echo -e "${BLUE}=== Docker Stack to Server Mapping ===${NC}"
|
||||
echo ""
|
||||
|
||||
# Show multi-server stacks first
|
||||
local multi_server_stacks=$(load_multi_server_stacks)
|
||||
if [ -n "$multi_server_stacks" ]; then
|
||||
echo -e "${YELLOW}🌐 Multi-Server Stacks (deployed to ALL servers)${NC}"
|
||||
echo "$multi_server_stacks" | while IFS= read -r stack; do
|
||||
if [ -n "$stack" ]; then
|
||||
local stack_path="$DOCKER_DIR/$stack"
|
||||
local description=""
|
||||
case "$stack" in
|
||||
"dozzle") description="# Docker log viewer" ;;
|
||||
"dockge") description="# Docker compose management" ;;
|
||||
"diun") description="# Docker image update notifier" ;;
|
||||
*) description="# Multi-server tool" ;;
|
||||
esac
|
||||
|
||||
if [ -d "$stack_path" ]; then
|
||||
echo " ✅ $stack $description"
|
||||
else
|
||||
echo " ❌ $stack $description (not found locally)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
echo ""
|
||||
fi
|
||||
|
||||
for server_file in "$DEPLOYMENT_CONFIG_DIR/servers/"*.yml; do
|
||||
if [ -f "$server_file" ]; then
|
||||
local server=$(basename "$server_file" .yml)
|
||||
local role=$(grep "role:" "$server_file" | cut -d'"' -f2 2>/dev/null || echo "Unknown")
|
||||
|
||||
echo -e "${GREEN}📍 $server${NC} (${YELLOW}$role${NC})"
|
||||
|
||||
# Get stacks for this server
|
||||
local stacks=$(load_server_config "$server")
|
||||
if [ -n "$stacks" ]; then
|
||||
echo "$stacks" | while IFS= read -r stack; do
|
||||
if [ -n "$stack" ]; then
|
||||
local stack_path="$DOCKER_DIR/$stack"
|
||||
if [ -d "$stack_path" ]; then
|
||||
echo " ✅ $stack (exists)"
|
||||
else
|
||||
echo " ❌ $stack (missing)"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo " ${YELLOW}No stacks configured${NC}"
|
||||
fi
|
||||
echo ""
|
||||
fi
|
||||
done
|
||||
|
||||
# Show unassigned stacks
|
||||
echo -e "${YELLOW}📦 Unassigned Stacks${NC}"
|
||||
local unassigned_count=0
|
||||
if [ -d "$DOCKER_DIR" ]; then
|
||||
for stack_dir in "$DOCKER_DIR"/*; do
|
||||
if [ -d "$stack_dir" ]; then
|
||||
local stack_name=$(basename "$stack_dir")
|
||||
local assigned=false
|
||||
|
||||
# Check if stack is assigned to any server
|
||||
for server_file in "$DEPLOYMENT_CONFIG_DIR/servers/"*.yml; do
|
||||
if [ -f "$server_file" ]; then
|
||||
if grep -q -- "- $stack_name" "$server_file" 2>/dev/null; then
|
||||
assigned=true
|
||||
break
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Also check if it's a multi-server stack
|
||||
local multi_server_stacks=$(load_multi_server_stacks)
|
||||
if echo "$multi_server_stacks" | grep -q "^$stack_name$" 2>/dev/null; then
|
||||
assigned=true
|
||||
fi
|
||||
|
||||
if [ "$assigned" = false ]; then
|
||||
echo " 🔍 $stack_name"
|
||||
unassigned_count=$((unassigned_count + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ "$unassigned_count" -eq 0 ]; then
|
||||
echo -e " ${GREEN}✅ All stacks are assigned to servers${NC}"
|
||||
fi
|
||||
}
|
||||
|
||||
# Sync environment files to server
|
||||
sync_env_files() {
|
||||
local server="$1"
|
||||
local dry_run="$2"
|
||||
|
||||
echo -e "${YELLOW}Syncing environment files to $server...${NC}"
|
||||
|
||||
# Get stacks for this server
|
||||
local stacks=$(load_server_config "$server")
|
||||
|
||||
if [ -z "$stacks" ]; then
|
||||
echo -e "${YELLOW}No stacks configured for server $server${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Create temporary directory for sync
|
||||
local temp_dir=$(mktemp -d)
|
||||
local sync_count=0
|
||||
|
||||
echo "$stacks" | while IFS= read -r stack; do
|
||||
if [ -n "$stack" ]; then
|
||||
local stack_path="$DOCKER_DIR/$stack"
|
||||
|
||||
if [ -d "$stack_path" ]; then
|
||||
# Find .env files in stack directory
|
||||
find "$stack_path" -name "*.env" -o -name ".env*" | while IFS= read -r env_file; do
|
||||
if [ -n "$env_file" ]; then
|
||||
local rel_path="${env_file#$DOCKER_DIR/}"
|
||||
local dest_dir="$temp_dir/$(dirname "$rel_path")"
|
||||
|
||||
if [ "$dry_run" = "true" ]; then
|
||||
echo -e "${BLUE}Would sync: $rel_path${NC}"
|
||||
else
|
||||
mkdir -p "$dest_dir"
|
||||
cp "$env_file" "$dest_dir/"
|
||||
echo -e "${GREEN}✓ Prepared: $rel_path${NC}"
|
||||
sync_count=$((sync_count + 1))
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
# Also sync docker-compose.yml
|
||||
local compose_file="$stack_path/docker-compose.yml"
|
||||
if [ -f "$compose_file" ]; then
|
||||
local rel_path="${compose_file#$DOCKER_DIR/}"
|
||||
local dest_dir="$temp_dir/$(dirname "$rel_path")"
|
||||
|
||||
if [ "$dry_run" = "true" ]; then
|
||||
echo -e "${BLUE}Would sync: $rel_path${NC}"
|
||||
else
|
||||
mkdir -p "$dest_dir"
|
||||
cp "$compose_file" "$dest_dir/"
|
||||
echo -e "${GREEN}✓ Prepared: $rel_path${NC}"
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo -e "${YELLOW}Warning: Stack directory not found: $stack_path${NC}"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
|
||||
if [ "$dry_run" != "true" ]; then
|
||||
# Use rsync to sync to server (assumes SSH access)
|
||||
echo -e "${YELLOW}Transferring files to $server...${NC}"
|
||||
|
||||
# This would be the actual rsync command (commented for safety)
|
||||
# rsync -avz --delete "$temp_dir/" "acedanger@$server:~/docker/"
|
||||
|
||||
echo -e "${GREEN}Environment sync simulation completed for $server${NC}"
|
||||
echo -e "${BLUE}Files prepared in: $temp_dir${NC}"
|
||||
echo "To actually sync, you would run:"
|
||||
echo " rsync -avz --delete '$temp_dir/' 'acedanger@$server:~/docker/'"
|
||||
|
||||
# Clean up temp directory
|
||||
# rm -rf "$temp_dir"
|
||||
fi
|
||||
|
||||
log "Environment sync completed for $server - $sync_count files prepared"
|
||||
}
|
||||
|
||||
# Deploy stacks to server
|
||||
deploy_to_server() {
|
||||
local server="$1"
|
||||
local dry_run="$2"
|
||||
local force="$3"
|
||||
|
||||
echo -e "${YELLOW}Deploying Docker stacks to $server...${NC}"
|
||||
|
||||
# First sync environment files
|
||||
sync_env_files "$server" "$dry_run"
|
||||
|
||||
if [ "$dry_run" = "true" ]; then
|
||||
echo -e "${BLUE}Dry run completed for $server${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Get stacks for this server
|
||||
local stacks=$(load_server_config "$server")
|
||||
|
||||
if [ -z "$stacks" ]; then
|
||||
echo -e "${YELLOW}No stacks configured for server $server${NC}"
|
||||
return 0
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}Stacks to deploy on $server:${NC}"
|
||||
echo "$stacks" | sed 's/^/ - /'
|
||||
|
||||
# Here you would implement the actual deployment logic
|
||||
# This could involve:
|
||||
# 1. SSH to the server
|
||||
# 2. Pull the latest compose files
|
||||
# 3. Run docker-compose up -d for each stack
|
||||
# 4. Perform health checks
|
||||
# 5. Send notifications
|
||||
|
||||
echo -e "${GREEN}Deployment simulation completed for $server${NC}"
|
||||
|
||||
# Send notification (using your existing ntfy setup)
|
||||
if command -v curl >/dev/null 2>&1; then
|
||||
curl -s \
|
||||
-H "priority:default" \
|
||||
-H "tags:deployment,docker,$server" \
|
||||
-d "Deployed Docker stacks to $server: $(echo "$stacks" | tr '\n' ', ' | sed 's/, $//')" \
|
||||
"https://notify.peterwood.rocks/lab" >/dev/null || true
|
||||
fi
|
||||
|
||||
log "Deployment completed for $server"
|
||||
}
|
||||
|
||||
# Deploy all stacks to their designated servers
|
||||
deploy_all() {
|
||||
local dry_run="$1"
|
||||
|
||||
echo -e "${BLUE}=== Deploying All Stacks to Designated Servers ===${NC}"
|
||||
|
||||
for server_file in "$DEPLOYMENT_CONFIG_DIR/servers/"*.yml; do
|
||||
if [ -f "$server_file" ]; then
|
||||
local server=$(basename "$server_file" .yml)
|
||||
echo ""
|
||||
deploy_to_server "$server" "$dry_run"
|
||||
fi
|
||||
done
|
||||
|
||||
echo ""
|
||||
echo -e "${GREEN}All deployments completed!${NC}"
|
||||
}
|
||||
|
||||
# Check deployment status
|
||||
check_status() {
|
||||
local server="$1"
|
||||
|
||||
echo -e "${BLUE}=== Deployment Status for $server ===${NC}"
|
||||
|
||||
# This would check the actual status on the server
|
||||
# For now, we'll simulate it
|
||||
echo -e "${GREEN}✅ Server is reachable${NC}"
|
||||
echo -e "${GREEN}✅ Docker is running${NC}"
|
||||
echo -e "${GREEN}✅ All stacks are healthy${NC}"
|
||||
|
||||
# Get stacks for this server
|
||||
local stacks=$(load_server_config "$server")
|
||||
if [ -n "$stacks" ]; then
|
||||
echo ""
|
||||
echo -e "${BLUE}Configured stacks:${NC}"
|
||||
echo "$stacks" | while IFS= read -r stack; do
|
||||
if [ -n "$stack" ]; then
|
||||
echo -e " ${GREEN}✅${NC} $stack"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Main function
|
||||
main() {
|
||||
local command=""
|
||||
local dry_run=false
|
||||
local force=false
|
||||
local verbose=false
|
||||
local config_only=false
|
||||
local env_only=false
|
||||
|
||||
# Parse command line arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case $1 in
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
-d|--dry-run)
|
||||
dry_run=true
|
||||
shift
|
||||
;;
|
||||
-f|--force)
|
||||
force=true
|
||||
shift
|
||||
;;
|
||||
-v|--verbose)
|
||||
verbose=true
|
||||
shift
|
||||
;;
|
||||
--config-only)
|
||||
config_only=true
|
||||
shift
|
||||
;;
|
||||
--env-only)
|
||||
env_only=true
|
||||
shift
|
||||
;;
|
||||
init|map|deploy-all|status)
|
||||
command="$1"
|
||||
shift
|
||||
;;
|
||||
deploy|sync-env|rollback)
|
||||
command="$1"
|
||||
if [[ $# -gt 1 && ! "$2" =~ ^- ]]; then
|
||||
server="$2"
|
||||
shift 2
|
||||
else
|
||||
echo -e "${RED}Error: Command '$1' requires a server name${NC}"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option: $1"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
# Execute requested command
|
||||
case "$command" in
|
||||
init)
|
||||
init_deployment_config
|
||||
;;
|
||||
map)
|
||||
show_mapping
|
||||
;;
|
||||
deploy)
|
||||
deploy_to_server "$server" "$dry_run" "$force"
|
||||
;;
|
||||
deploy-all)
|
||||
deploy_all "$dry_run"
|
||||
;;
|
||||
sync-env)
|
||||
sync_env_files "$server" "$dry_run"
|
||||
;;
|
||||
status)
|
||||
check_status "$server"
|
||||
;;
|
||||
rollback)
|
||||
echo -e "${YELLOW}Rollback functionality not yet implemented${NC}"
|
||||
;;
|
||||
"")
|
||||
echo -e "${RED}Error: No command specified${NC}"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
*)
|
||||
echo -e "${RED}Error: Unknown command '$command'${NC}"
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
# Run main function with all arguments
|
||||
main "$@"
|
||||
Reference in New Issue
Block a user