#!/bin/sh # Enable strict error handling set -e # Function to log messages with timestamp log() { echo "[$(date +'%Y-%m-%d %H:%M:%S')] $*" >&2 } # Function to extract version from agent script (legacy) get_agent_version() { local file="$1" if [ -f "$file" ]; then grep -m 1 '^AGENT_VERSION=' "$file" | cut -d'"' -f2 2>/dev/null || echo "0.0.0" else echo "0.0.0" fi } # Function to get version from binary using --help flag get_binary_version() { local binary="$1" if [ -f "$binary" ]; then # Make sure binary is executable chmod +x "$binary" 2>/dev/null || true # Try to execute the binary and extract version from help output # The Go binary shows version in the --help output as "PatchMon Agent v1.3.0" local version=$("$binary" --help 2>&1 | grep -oE 'v[0-9]+\.[0-9]+\.[0-9]+' | head -n 1 | tr -d 'v') if [ -n "$version" ]; then echo "$version" else # Fallback: try --version flag version=$("$binary" --version 2>&1 | grep -oE '[0-9]+\.[0-9]+\.[0-9]+' | head -n 1) if [ -n "$version" ]; then echo "$version" else echo "0.0.0" fi fi else echo "0.0.0" fi } # Function to compare versions (returns 0 if $1 > $2) version_greater() { # Use sort -V for version comparison test "$(printf '%s\n' "$1" "$2" | sort -V | tail -n1)" = "$1" && test "$1" != "$2" } # Check and update agent files if necessary update_agents() { local backup_agent="/app/agents_backup/patchmon-agent.sh" local current_agent="/app/agents/patchmon-agent.sh" local backup_binary="/app/agents_backup/patchmon-agent-linux-amd64" local current_binary="/app/agents/patchmon-agent-linux-amd64" # Check if agents directory exists if [ ! -d "/app/agents" ]; then log "ERROR: /app/agents directory not found" return 1 fi # Check if backup exists if [ ! -d "/app/agents_backup" ]; then log "WARNING: agents_backup directory not found, skipping agent update" return 0 fi # Get versions from both script and binary local backup_script_version=$(get_agent_version "$backup_agent") local current_script_version=$(get_agent_version "$current_agent") local backup_binary_version=$(get_binary_version "$backup_binary") local current_binary_version=$(get_binary_version "$current_binary") log "Agent version check:" log " Image script version: ${backup_script_version}" log " Volume script version: ${current_script_version}" log " Image binary version: ${backup_binary_version}" log " Volume binary version: ${current_binary_version}" # Determine if update is needed local needs_update=0 # Case 1: No agents in volume at all (first time setup) if [ -z "$(find /app/agents -maxdepth 1 -type f 2>/dev/null | head -n 1)" ]; then log "Agents directory is empty - performing initial copy" needs_update=1 # Case 2: Binary exists but backup binary is newer elif [ "$current_binary_version" != "0.0.0" ] && version_greater "$backup_binary_version" "$current_binary_version"; then log "Newer agent binary available (${backup_binary_version} > ${current_binary_version})" needs_update=1 # Case 3: No binary in volume, but shell scripts exist (legacy setup) - copy binaries elif [ "$current_binary_version" = "0.0.0" ] && [ "$backup_binary_version" != "0.0.0" ]; then log "No binary found in volume but backup has binaries - performing update" needs_update=1 else log "Agents are up to date (binary: ${current_binary_version})" needs_update=0 fi # Perform update if needed if [ $needs_update -eq 1 ]; then log "Updating agents to version ${backup_binary_version}..." # Create backup of existing agents if they exist if [ -f "$current_agent" ] || [ -f "$current_binary" ]; then local backup_timestamp=$(date +%Y%m%d_%H%M%S) mkdir -p "/app/agents/backups" # Backup shell script if it exists if [ -f "$current_agent" ]; then cp "$current_agent" "/app/agents/backups/patchmon-agent.sh.${backup_timestamp}" 2>/dev/null || true log "Previous script backed up" fi # Backup binary if it exists if [ -f "$current_binary" ]; then cp "$current_binary" "/app/agents/backups/patchmon-agent-linux-amd64.${backup_timestamp}" 2>/dev/null || true log "Previous binary backed up" fi fi # Copy new agents (both scripts and binaries) cp -r /app/agents_backup/* /app/agents/ # Make agent binaries executable chmod +x /app/agents/patchmon-agent-linux-* 2>/dev/null || true # Verify update local new_binary_version=$(get_binary_version "$current_binary") if [ "$new_binary_version" = "$backup_binary_version" ]; then log "✅ Agents successfully updated to version ${new_binary_version}" else log "⚠️ Warning: Agent update may have failed (expected: ${backup_binary_version}, got: ${new_binary_version})" fi fi } # Main execution log "PatchMon Backend Container Starting..." log "Environment: ${NODE_ENV:-production}" # Update agents (version-aware) update_agents log "Running database migrations..." npx prisma migrate deploy log "Starting application..." if [ "${NODE_ENV}" = "development" ]; then exec npm run dev else exec npm start fi