claude-home/vm-management/scripts/vm-post-install.sh
Cal Corum 10c9e0d854 CLAUDE: Migrate to technology-first documentation architecture
Complete restructure from patterns/examples/reference to technology-focused directories:

• Created technology-specific directories with comprehensive documentation:
  - /tdarr/ - Transcoding automation with gaming-aware scheduling
  - /docker/ - Container management with GPU acceleration patterns
  - /vm-management/ - Virtual machine automation and cloud-init
  - /networking/ - SSH infrastructure, reverse proxy, and security
  - /monitoring/ - System health checks and Discord notifications
  - /databases/ - Database patterns and troubleshooting
  - /development/ - Programming language patterns (bash, nodejs, python, vuejs)

• Enhanced CLAUDE.md with intelligent context loading:
  - Technology-first loading rules for automatic context provision
  - Troubleshooting keyword triggers for emergency scenarios
  - Documentation maintenance protocols with automated reminders
  - Context window management for optimal documentation updates

• Preserved valuable content from .claude/tmp/:
  - SSH security improvements and server inventory
  - Tdarr CIFS troubleshooting and Docker iptables solutions
  - Operational scripts with proper technology classification

• Benefits achieved:
  - Self-contained technology directories with complete context
  - Automatic loading of relevant documentation based on keywords
  - Emergency-ready troubleshooting with comprehensive guides
  - Scalable structure for future technology additions
  - Eliminated context bloat through targeted loading

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-12 23:20:15 -05:00

246 lines
7.2 KiB
Bash
Executable File

#!/bin/bash
#
# VM Post-Installation Provisioning Script
# Handles: System updates, SSH key deployment, Docker installation
#
# Usage: ./vm-post-install.sh <vm-ip> [ssh-user]
# Example: ./vm-post-install.sh 10.10.0.100 cal
#
set -e
# Configuration
VM_IP="$1"
SSH_USER="${2:-cal}"
HOMELAB_KEY="$HOME/.ssh/homelab_rsa"
EMERGENCY_KEY="$HOME/.ssh/emergency_homelab_rsa"
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Logging function
log() {
echo -e "${GREEN}[$(date '+%H:%M:%S')]${NC} $1"
}
warn() {
echo -e "${YELLOW}[$(date '+%H:%M:%S')] WARNING:${NC} $1"
}
error() {
echo -e "${RED}[$(date '+%H:%M:%S')] ERROR:${NC} $1"
exit 1
}
# Validation
if [ -z "$VM_IP" ]; then
error "Usage: $0 <vm-ip> [ssh-user]"
fi
if [ ! -f "$HOMELAB_KEY" ]; then
error "Homelab SSH key not found at $HOMELAB_KEY"
fi
if [ ! -f "$EMERGENCY_KEY" ]; then
error "Emergency SSH key not found at $EMERGENCY_KEY"
fi
log "Starting VM provisioning for $VM_IP as user $SSH_USER"
# Test initial connectivity (assume password auth is still enabled)
log "Testing initial connectivity to $VM_IP..."
if ! timeout 10 bash -c "nc -z $VM_IP 22" >/dev/null 2>&1; then
error "Cannot reach $VM_IP on port 22"
fi
# Function to run commands on remote VM
run_remote() {
local cmd="$1"
local use_key="${2:-false}"
if [ "$use_key" = "true" ]; then
ssh -i "$HOMELAB_KEY" -o StrictHostKeyChecking=accept-new "$SSH_USER@$VM_IP" "$cmd"
else
# Initial connection might need password
ssh -o StrictHostKeyChecking=accept-new "$SSH_USER@$VM_IP" "$cmd"
fi
}
# Function to copy files to remote VM
copy_to_remote() {
local src="$1"
local dest="$2"
local use_key="${3:-false}"
if [ "$use_key" = "true" ]; then
scp -i "$HOMELAB_KEY" -o StrictHostKeyChecking=accept-new "$src" "$SSH_USER@$VM_IP:$dest"
else
scp -o StrictHostKeyChecking=accept-new "$src" "$SSH_USER@$VM_IP:$dest"
fi
}
# Step 1: System Updates
log "Step 1: Running system updates..."
run_remote "
echo 'Updating package lists...'
sudo apt update
echo 'Upgrading packages...'
sudo apt upgrade -y
echo 'Installing essential packages...'
sudo apt install -y curl wget git vim htop unzip software-properties-common apt-transport-https ca-certificates gnupg lsb-release
echo 'Cleaning up...'
sudo apt autoremove -y
sudo apt autoclean
"
log "✅ System updates completed"
# Step 2: SSH Key Installation
log "Step 2: Installing SSH keys..."
# Create .ssh directory if it doesn't exist
run_remote "mkdir -p ~/.ssh && chmod 700 ~/.ssh"
# Deploy primary homelab key
log "Installing primary homelab SSH key..."
cat "$HOMELAB_KEY.pub" | run_remote "cat >> ~/.ssh/authorized_keys"
# Deploy emergency key
log "Installing emergency SSH key..."
cat "$EMERGENCY_KEY.pub" | run_remote "cat >> ~/.ssh/authorized_keys"
# Set proper permissions
run_remote "chmod 600 ~/.ssh/authorized_keys"
# Test key-based authentication
log "Testing key-based authentication..."
if run_remote "echo 'SSH key authentication working'" true; then
log "✅ SSH key authentication successful"
else
error "SSH key authentication failed"
fi
# Step 3: Secure SSH Configuration
log "Step 3: Securing SSH configuration..."
run_remote "
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.backup
sudo sed -i 's/#PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/' /etc/ssh/sshd_config
sudo sed -i 's/#PubkeyAuthentication yes/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sudo sed -i 's/PubkeyAuthentication no/PubkeyAuthentication yes/' /etc/ssh/sshd_config
sudo systemctl restart sshd
" true
log "✅ SSH hardened (password authentication disabled)"
# Step 4: Docker Installation
log "Step 4: Installing Docker and Docker Compose..."
run_remote "
# Remove any old Docker installations
sudo apt remove -y docker docker-engine docker.io containerd runc 2>/dev/null || true
# Add Docker GPG key
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
# Add Docker repository
echo \"deb [arch=\$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu \$(lsb_release -cs) stable\" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
# Update package list
sudo apt update
# Install Docker
sudo apt install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin
# Add user to docker group
sudo usermod -aG docker $USER
# Enable Docker service
sudo systemctl enable docker
sudo systemctl start docker
" true
# Verify Docker installation
log "Verifying Docker installation..."
run_remote "
docker --version
docker compose version
sudo docker run --rm hello-world
" true
log "✅ Docker and Docker Compose installed successfully"
# Step 5: System Configuration
log "Step 5: Additional system configuration..."
run_remote "
# Configure automatic security updates
sudo apt install -y unattended-upgrades
sudo dpkg-reconfigure -plow unattended-upgrades
# Set timezone (adjust as needed)
sudo timedatectl set-timezone America/New_York
# Configure system hostname if needed
echo 'System configuration completed'
" true
# Step 6: Create useful aliases and environment
log "Step 6: Setting up user environment..."
run_remote "
# Create useful aliases
cat >> ~/.bashrc << 'EOF'
# Docker aliases
alias dps='docker ps'
alias dlog='docker logs'
alias dexec='docker exec -it'
alias dstop='docker stop \$(docker ps -q)'
alias dprune='docker system prune -f'
# System aliases
alias ll='ls -alF'
alias la='ls -A'
alias l='ls -CF'
alias ..='cd ..'
alias ...='cd ../..'
# Docker Compose aliases
alias dc='docker compose'
alias dcup='docker compose up -d'
alias dcdown='docker compose down'
alias dclogs='docker compose logs -f'
EOF
# Source the updated bashrc
source ~/.bashrc 2>/dev/null || true
" true
log "✅ User environment configured"
# Step 7: Final verification
log "Step 7: Final system verification..."
HOSTNAME=$(run_remote "hostname" true)
KERNEL=$(run_remote "uname -r" true)
DOCKER_VERSION=$(run_remote "docker --version" true)
UPTIME=$(run_remote "uptime" true)
log "🎉 VM provisioning completed successfully!"
echo ""
echo -e "${BLUE}=== PROVISIONING SUMMARY ===${NC}"
echo -e "${GREEN}VM IP:${NC} $VM_IP"
echo -e "${GREEN}User:${NC} $SSH_USER"
echo -e "${GREEN}Hostname:${NC} $HOSTNAME"
echo -e "${GREEN}Kernel:${NC} $KERNEL"
echo -e "${GREEN}Docker:${NC} $DOCKER_VERSION"
echo -e "${GREEN}Uptime:${NC} $UPTIME"
echo ""
echo -e "${YELLOW}Next Steps:${NC}"
echo "1. SSH access: ssh $SSH_USER@$VM_IP"
echo "2. Test Docker: ssh $SSH_USER@$VM_IP 'docker run --rm hello-world'"
echo "3. Deploy applications using Docker Compose"
echo ""
echo -e "${YELLOW}Security Notes:${NC}"
echo "- Password authentication is DISABLED"
echo "- Only key-based SSH access is allowed"
echo "- Both primary and emergency SSH keys are installed"
echo "- Automatic security updates are enabled"