Update PatchMon version to 1.2.7

- Updated agent script version to 1.2.7
- Updated all package.json files to version 1.2.7
- Updated backend version references
- Updated setup script version references
- Fixed agent file path issues in API endpoints
- Fixed linting issues (Node.js imports, unused variables, accessibility)
- Created comprehensive version update guide in patchmon-admin/READMEs/
This commit is contained in:
Muhammad Ibrahim
2025-09-29 20:42:14 +01:00
parent 49c02a54dc
commit b49ea6b197
20 changed files with 1197 additions and 1238 deletions

View File

@@ -1,12 +1,12 @@
#!/bin/bash
# PatchMon Agent Script v1.2.6
# PatchMon Agent Script v1.2.7
# This script sends package update information to the PatchMon server using API credentials
# Configuration
PATCHMON_SERVER="${PATCHMON_SERVER:-http://localhost:3001}"
API_VERSION="v1"
AGENT_VERSION="1.2.6"
AGENT_VERSION="1.2.7"
CONFIG_FILE="/etc/patchmon/agent.conf"
CREDENTIALS_FILE="/etc/patchmon/credentials"
LOG_FILE="/var/log/patchmon-agent.log"
@@ -144,7 +144,7 @@ EOF
test_credentials() {
load_credentials
local response=$(curl -ksv -X POST \
local response=$(curl -ks -X POST \
-H "Content-Type: application/json" \
-H "X-API-ID: $API_ID" \
-H "X-API-KEY: $API_KEY" \
@@ -809,7 +809,7 @@ EOF
local payload=$(echo "$base_payload $merged_json" | jq -s '.[0] * .[1]')
local response=$(curl -ksv -X POST \
local response=$(curl -ks -X POST \
-H "Content-Type: application/json" \
-H "X-API-ID: $API_ID" \
-H "X-API-KEY: $API_KEY" \
@@ -821,25 +821,18 @@ EOF
success "Update sent successfully"
echo "$response" | grep -o '"packagesProcessed":[0-9]*' | cut -d':' -f2 | xargs -I {} info "Processed {} packages"
# Check for PatchMon agent update instructions (this updates the agent script, not system packages)
if echo "$response" | grep -q '"autoUpdate":{'; then
local auto_update_section=$(echo "$response" | grep -o '"autoUpdate":{[^}]*}')
local should_update=$(echo "$auto_update_section" | grep -o '"shouldUpdate":true' | cut -d':' -f2)
if [[ "$should_update" == "true" ]]; then
local latest_version=$(echo "$auto_update_section" | grep -o '"latestVersion":"[^"]*' | cut -d'"' -f4)
local current_version=$(echo "$auto_update_section" | grep -o '"currentVersion":"[^"]*' | cut -d'"' -f4)
local update_message=$(echo "$auto_update_section" | grep -o '"message":"[^"]*' | cut -d'"' -f4)
info "PatchMon agent update detected: $update_message"
info "Current version: $current_version, Latest version: $latest_version"
# Automatically run update-agent command to update the PatchMon agent script
info "Automatically updating PatchMon agent to latest version..."
# Check if auto-update is enabled and check for agent updates locally
if check_auto_update_enabled; then
info "Auto-update is enabled, checking for agent updates..."
if check_agent_update_needed; then
info "Agent update available, automatically updating..."
if "$0" update-agent; then
success "PatchMon agent update completed successfully"
else
warning "PatchMon agent update failed, but data was sent successfully"
fi
else
info "Agent is up to date"
fi
fi
@@ -877,7 +870,7 @@ EOF
ping_server() {
load_credentials
local response=$(curl -ksv -X POST \
local response=$(curl -ks -X POST \
-H "Content-Type: application/json" \
-H "X-API-ID: $API_ID" \
-H "X-API-KEY: $API_KEY" \
@@ -920,7 +913,7 @@ check_version() {
info "Checking for agent updates..."
local response=$(curl -ksv -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/version")
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/version")
if [[ $? -eq 0 ]]; then
local current_version=$(echo "$response" | grep -o '"currentVersion":"[^"]*' | cut -d'"' -f4)
@@ -949,59 +942,147 @@ check_version() {
fi
}
# Check if auto-update is enabled (both globally and for this host)
check_auto_update_enabled() {
# Get settings from server using API credentials
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/settings" 2>/dev/null)
if [[ $? -ne 0 ]]; then
return 1
fi
# Check if both global and host auto-update are enabled
local global_auto_update=$(echo "$response" | grep -o '"auto_update":true' | cut -d':' -f2)
local host_auto_update=$(echo "$response" | grep -o '"host_auto_update":true' | cut -d':' -f2)
if [[ "$global_auto_update" == "true" && "$host_auto_update" == "true" ]]; then
return 0
else
return 1
fi
}
# Check if agent update is needed (internal function for auto-update)
check_agent_update_needed() {
# Get current agent timestamp
local current_timestamp=0
if [[ -f "$0" ]]; then
current_timestamp=$(stat -c %Y "$0" 2>/dev/null || stat -f %m "$0" 2>/dev/null || echo "0")
fi
# Get server agent info using API credentials
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/timestamp" 2>/dev/null)
if [[ $? -eq 0 ]]; then
local server_version=$(echo "$response" | grep -o '"version":"[^"]*' | cut -d'"' -f4)
local server_timestamp=$(echo "$response" | grep -o '"timestamp":[0-9]*' | cut -d':' -f2)
local server_exists=$(echo "$response" | grep -o '"exists":true' | cut -d':' -f2)
if [[ "$server_exists" != "true" ]]; then
return 1
fi
# Check if update is needed
if [[ "$server_version" != "$AGENT_VERSION" ]]; then
return 0 # Update needed due to version mismatch
elif [[ "$server_timestamp" -gt "$current_timestamp" ]]; then
return 0 # Update needed due to newer timestamp
else
return 1 # No update needed
fi
else
return 1 # Failed to check
fi
}
# Check for agent updates based on version and timestamp (interactive command)
check_agent_update() {
load_credentials
info "Checking for agent updates..."
# Get current agent timestamp
local current_timestamp=0
if [[ -f "$0" ]]; then
current_timestamp=$(stat -c %Y "$0" 2>/dev/null || stat -f %m "$0" 2>/dev/null || echo "0")
fi
# Get server agent info using API credentials
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/timestamp")
if [[ $? -eq 0 ]]; then
local server_version=$(echo "$response" | grep -o '"version":"[^"]*' | cut -d'"' -f4)
local server_timestamp=$(echo "$response" | grep -o '"timestamp":[0-9]*' | cut -d':' -f2)
local server_exists=$(echo "$response" | grep -o '"exists":true' | cut -d':' -f2)
if [[ "$server_exists" != "true" ]]; then
warning "No agent script found on server"
return 1
fi
info "Current agent version: $AGENT_VERSION (timestamp: $current_timestamp)"
info "Server agent version: $server_version (timestamp: $server_timestamp)"
# Check if update is needed
if [[ "$server_version" != "$AGENT_VERSION" ]]; then
info "Version mismatch detected - update needed"
return 0
elif [[ "$server_timestamp" -gt "$current_timestamp" ]]; then
info "Server script is newer - update needed"
return 0
else
info "Agent is up to date"
return 1
fi
else
error "Failed to check agent timestamp from server"
return 1
fi
}
# Update agent script
update_agent() {
load_credentials
info "Updating agent script..."
local response=$(curl -ksv -X GET "$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/version")
local download_url="$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/download"
if [[ $? -eq 0 ]]; then
local download_url=$(echo "$response" | grep -o '"downloadUrl":"[^"]*' | cut -d'"' -f4)
if [[ -z "$download_url" ]]; then
download_url="$PATCHMON_SERVER/api/$API_VERSION/hosts/agent/download"
elif [[ "$download_url" =~ ^/ ]]; then
# If download_url is relative, prepend the server URL
download_url="$PATCHMON_SERVER$download_url"
fi
info "Downloading latest agent from: $download_url"
# Create backup of current script
cp "$0" "$0.backup.$(date +%Y%m%d_%H%M%S)"
# Download new version
if curl -ksv -o "/tmp/patchmon-agent-new.sh" "$download_url"; then
# Verify the downloaded script is valid
if bash -n "/tmp/patchmon-agent-new.sh" 2>/dev/null; then
# Replace current script
mv "/tmp/patchmon-agent-new.sh" "$0"
chmod +x "$0"
success "Agent updated successfully"
info "Backup saved as: $0.backup.$(date +%Y%m%d_%H%M%S)"
# Get the new version number
local new_version=$(grep '^AGENT_VERSION=' "$0" | cut -d'"' -f2)
info "Updated to version: $new_version"
# Automatically run update to send new information to PatchMon
info "Sending updated information to PatchMon..."
if "$0" update; then
success "Successfully sent updated information to PatchMon"
else
warning "Failed to send updated information to PatchMon (this is not critical)"
fi
info "Downloading latest agent from: $download_url"
# Clean up old backups (keep only last 3)
ls -t "$0.backup."* 2>/dev/null | tail -n +4 | xargs -r rm -f
# Create backup of current script
local backup_file="$0.backup.$(date +%Y%m%d_%H%M%S)"
cp "$0" "$backup_file"
# Download new version using API credentials
if curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -o "/tmp/patchmon-agent-new.sh" "$download_url"; then
# Verify the downloaded script is valid
if bash -n "/tmp/patchmon-agent-new.sh" 2>/dev/null; then
# Replace current script
mv "/tmp/patchmon-agent-new.sh" "$0"
chmod +x "$0"
success "Agent updated successfully"
info "Backup saved as: $backup_file"
# Get the new version number
local new_version=$(grep '^AGENT_VERSION=' "$0" | cut -d'"' -f2)
info "Updated to version: $new_version"
# Automatically run update to send new information to PatchMon
info "Sending updated information to PatchMon..."
if "$0" update; then
success "Successfully sent updated information to PatchMon"
else
error "Downloaded script is invalid"
rm -f "/tmp/patchmon-agent-new.sh"
warning "Failed to send updated information to PatchMon (this is not critical)"
fi
else
error "Failed to download new agent script"
error "Downloaded script is invalid"
rm -f "/tmp/patchmon-agent-new.sh"
fi
else
error "Failed to get update information"
error "Failed to download new agent script"
fi
}
@@ -1009,7 +1090,7 @@ update_agent() {
update_crontab() {
load_credentials
info "Updating crontab with current policy..."
local response=$(curl -ksv -X GET "$PATCHMON_SERVER/api/$API_VERSION/settings/update-interval")
local response=$(curl -ks -H "X-API-ID: $API_ID" -H "X-API-KEY: $API_KEY" -X GET "$PATCHMON_SERVER/api/$API_VERSION/settings/update-interval")
if [[ $? -eq 0 ]]; then
local update_interval=$(echo "$response" | grep -o '"updateInterval":[0-9]*' | cut -d':' -f2)
if [[ -n "$update_interval" ]]; then
@@ -1024,18 +1105,27 @@ update_crontab() {
expected_crontab="*/$update_interval * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1"
fi
# Get current crontab
local current_crontab=$(crontab -l 2>/dev/null | grep "patchmon-agent.sh update" | head -1)
# Get current crontab (without patchmon entries)
local current_crontab_without_patchmon=$(crontab -l 2>/dev/null | grep -v "/usr/local/bin/patchmon-agent.sh update" || true)
local current_patchmon_entry=$(crontab -l 2>/dev/null | grep "/usr/local/bin/patchmon-agent.sh update" | head -1)
# Check if crontab needs updating
if [[ "$current_crontab" == "$expected_crontab" ]]; then
if [[ "$current_patchmon_entry" == "$expected_crontab" ]]; then
info "Crontab is already up to date (interval: $update_interval minutes)"
return 0
fi
info "Setting update interval to $update_interval minutes"
echo "$expected_crontab" | crontab -
success "Crontab updated successfully"
# Combine existing cron (without patchmon entries) + new patchmon entry
{
if [[ -n "$current_crontab_without_patchmon" ]]; then
echo "$current_crontab_without_patchmon"
fi
echo "$expected_crontab"
} | crontab -
success "Crontab updated successfully (duplicates removed)"
else
error "Could not determine update interval from server"
fi
@@ -1147,7 +1237,7 @@ main() {
check_root
setup_directories
load_config
configure_credentials "$2" "$3"
configure_credentials "$2" "$3" "$4"
;;
"test")
check_root
@@ -1178,6 +1268,11 @@ main() {
load_config
check_version
;;
"check-agent-update")
setup_directories
load_config
check_agent_update
;;
"update-agent")
check_root
setup_directories
@@ -1195,22 +1290,23 @@ main() {
;;
*)
echo "PatchMon Agent v$AGENT_VERSION - API Credential Based"
echo "Usage: $0 {configure|test|update|ping|config|check-version|update-agent|update-crontab|diagnostics}"
echo "Usage: $0 {configure|test|update|ping|config|check-version|check-agent-update|update-agent|update-crontab|diagnostics}"
echo ""
echo "Commands:"
echo " configure <API_ID> <API_KEY> - Configure API credentials for this host"
echo " configure <API_ID> <API_KEY> [SERVER_URL] - Configure API credentials for this host"
echo " test - Test API credentials connectivity"
echo " update - Send package update information to server"
echo " ping - Test connectivity to server"
echo " config - Show current configuration"
echo " check-version - Check for agent updates"
echo " check-agent-update - Check for agent updates using timestamp comparison"
echo " update-agent - Update agent to latest version"
echo " update-crontab - Update crontab with current policy"
echo " diagnostics - Show detailed system diagnostics"
echo ""
echo "Setup Process:"
echo " 1. Contact your PatchMon administrator to create a host entry"
echo " 2. Run: $0 configure <API_ID> <API_KEY> (provided by admin)"
echo " 2. Run: $0 configure <API_ID> <API_KEY> [SERVER_URL] (provided by admin)"
echo " 3. Run: $0 test (to verify connection)"
echo " 4. Run: $0 update (to send initial package data)"
echo ""

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# PatchMon Agent Installation Script
# Usage: curl -ksSL {PATCHMON_URL}/api/v1/hosts/install | bash -s -- {PATCHMON_URL} {API_ID} {API_KEY}
# Usage: curl -ks {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | bash
set -e
@@ -35,10 +35,34 @@ if [[ $EUID -ne 0 ]]; then
error "This script must be run as root (use sudo)"
fi
# Clean up old files (keep only last 3 of each type)
cleanup_old_files() {
# Clean up old credential backups
ls -t /etc/patchmon/credentials.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
# Clean up old agent backups
ls -t /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
# Clean up old log files
ls -t /var/log/patchmon-agent.log.old.* 2>/dev/null | tail -n +4 | xargs -r rm -f
}
# Run cleanup at start
cleanup_old_files
# Parse arguments from environment (passed via HTTP headers)
if [[ -z "$PATCHMON_URL" ]] || [[ -z "$API_ID" ]] || [[ -z "$API_KEY" ]]; then
error "Missing required parameters. This script should be called via the PatchMon web interface."
fi
info "🚀 Starting PatchMon Agent Installation..."
info "📋 Server: $PATCHMON_URL"
info "🔑 API ID: ${API_ID:0:16}..."
# Install required dependencies
info "📦 Installing required dependencies..."
# Detect package manager and install jq
# Detect package manager and install jq and curl
if command -v apt-get >/dev/null 2>&1; then
# Debian/Ubuntu
apt-get update >/dev/null 2>&1
@@ -62,76 +86,40 @@ else
warning "Could not detect package manager. Please ensure 'jq' and 'curl' are installed manually."
fi
# Verify jq installation
if ! command -v jq >/dev/null 2>&1; then
error "Failed to install 'jq'. Please install it manually: https://stedolan.github.io/jq/download/"
# Step 1: Handle existing configuration directory
info "📁 Setting up configuration directory..."
# Check if configuration directory already exists
if [[ -d "/etc/patchmon" ]]; then
warning "⚠️ Configuration directory already exists at /etc/patchmon"
warning "⚠️ Preserving existing configuration files"
# List existing files for user awareness
info "📋 Existing files in /etc/patchmon:"
ls -la /etc/patchmon/ 2>/dev/null | grep -v "^total" | while read -r line; do
echo " $line"
done
else
info "📁 Creating new configuration directory..."
mkdir -p /etc/patchmon
fi
success "Dependencies installed successfully!"
# Step 2: Create credentials file
info "🔐 Creating API credentials file..."
# Default server URL (will be replaced by backend with configured URL)
PATCHMON_URL="http://localhost:3001"
# Parse arguments
if [[ $# -ne 3 ]]; then
echo "Usage: curl -ksSL {PATCHMON_URL}/api/v1/hosts/install | bash -s -- {PATCHMON_URL} {API_ID} {API_KEY}"
echo ""
echo "Example:"
echo "curl -ksSL http://patchmon.example.com/api/v1/hosts/install | bash -s -- http://patchmon.example.com patchmon_1a2b3c4d abcd1234567890abcdef1234567890abcdef1234567890abcdef1234567890"
echo ""
echo "Contact your PatchMon administrator to get your API credentials."
exit 1
# Check if credentials file already exists
if [[ -f "/etc/patchmon/credentials" ]]; then
warning "⚠️ Credentials file already exists at /etc/patchmon/credentials"
warning "⚠️ Moving existing file out of the way for fresh installation"
# Clean up old credential backups (keep only last 3)
ls -t /etc/patchmon/credentials.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
# Move existing file out of the way
mv /etc/patchmon/credentials /etc/patchmon/credentials.backup.$(date +%Y%m%d_%H%M%S)
info "📋 Moved existing credentials to: /etc/patchmon/credentials.backup.$(date +%Y%m%d_%H%M%S)"
fi
PATCHMON_URL="$1"
API_ID="$2"
API_KEY="$3"
# Validate inputs
if [[ ! "$PATCHMON_URL" =~ ^https?:// ]]; then
error "Invalid URL format. Must start with http:// or https://"
fi
if [[ ! "$API_ID" =~ ^patchmon_[a-f0-9]{16}$ ]]; then
error "Invalid API ID format. API ID should be in format: patchmon_xxxxxxxxxxxxxxxx"
fi
if [[ ! "$API_KEY" =~ ^[a-f0-9]{64}$ ]]; then
error "Invalid API Key format. API Key should be 64 hexadecimal characters."
fi
info "🚀 Installing PatchMon Agent..."
info " Server: $PATCHMON_URL"
info " API ID: $API_ID"
# Create patchmon directory
info "📁 Creating configuration directory..."
mkdir -p /etc/patchmon
# Download the agent script
info "📥 Downloading PatchMon agent script..."
curl -ksSL "$PATCHMON_URL/api/v1/hosts/agent/download" -o /usr/local/bin/patchmon-agent.sh
chmod +x /usr/local/bin/patchmon-agent.sh
# Get the agent version from the downloaded script
AGENT_VERSION=$(grep '^AGENT_VERSION=' /usr/local/bin/patchmon-agent.sh | cut -d'"' -f2)
info "📋 Agent version: $AGENT_VERSION"
# Get expected agent version from server
EXPECTED_VERSION=$(curl -ksv "$PATCHMON_URL/api/v1/hosts/agent/version" | grep -o '"currentVersion":"[^"]*' | cut -d'"' -f4 2>/dev/null || echo "Unknown")
if [[ "$EXPECTED_VERSION" != "Unknown" ]]; then
info "📋 Expected version: $EXPECTED_VERSION"
if [[ "$AGENT_VERSION" != "$EXPECTED_VERSION" ]]; then
warning "⚠️ Agent version mismatch! Installed: $AGENT_VERSION, Expected: $EXPECTED_VERSION"
fi
fi
# Get update interval policy from server
UPDATE_INTERVAL=$(curl -ksv "$PATCHMON_URL/api/v1/settings/update-interval" | grep -o '"updateInterval":[0-9]*' | cut -d':' -f2 2>/dev/null || echo "60")
info "📋 Update interval: $UPDATE_INTERVAL minutes"
# Create credentials file
info "🔐 Setting up API credentials..."
cat > /etc/patchmon/credentials << EOF
# PatchMon API Credentials
# Generated on $(date)
@@ -139,63 +127,141 @@ PATCHMON_URL="$PATCHMON_URL"
API_ID="$API_ID"
API_KEY="$API_KEY"
EOF
chmod 600 /etc/patchmon/credentials
# Test the configuration
info "🧪 Testing configuration..."
# Step 3: Download the agent script using API credentials
info "📥 Downloading PatchMon agent script..."
# Check if agent script already exists
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
warning "⚠️ Agent script already exists at /usr/local/bin/patchmon-agent.sh"
warning "⚠️ Moving existing file out of the way for fresh installation"
# Clean up old agent backups (keep only last 3)
ls -t /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | tail -n +4 | xargs -r rm -f
# Move existing file out of the way
mv /usr/local/bin/patchmon-agent.sh /usr/local/bin/patchmon-agent.sh.backup.$(date +%Y%m%d_%H%M%S)
info "📋 Moved existing agent to: /usr/local/bin/patchmon-agent.sh.backup.$(date +%Y%m%d_%H%M%S)"
fi
curl -ks \
-H "X-API-ID: $API_ID" \
-H "X-API-KEY: $API_KEY" \
"$PATCHMON_URL/api/v1/hosts/agent/download" \
-o /usr/local/bin/patchmon-agent.sh
chmod +x /usr/local/bin/patchmon-agent.sh
# Get the agent version from the downloaded script
AGENT_VERSION=$(grep '^AGENT_VERSION=' /usr/local/bin/patchmon-agent.sh | cut -d'"' -f2 2>/dev/null || echo "Unknown")
info "📋 Agent version: $AGENT_VERSION"
# Handle existing log files
if [[ -f "/var/log/patchmon-agent.log" ]]; then
warning "⚠️ Existing log file found at /var/log/patchmon-agent.log"
warning "⚠️ Rotating log file for fresh start"
# Rotate the log file
mv /var/log/patchmon-agent.log /var/log/patchmon-agent.log.old.$(date +%Y%m%d_%H%M%S)
info "📋 Log file rotated to: /var/log/patchmon-agent.log.old.$(date +%Y%m%d_%H%M%S)"
fi
# Step 4: Test the configuration
info "🧪 Testing API credentials and connectivity..."
if /usr/local/bin/patchmon-agent.sh test; then
success "Configuration test passed!"
success "✅ API credentials are valid and server is reachable"
else
error "Configuration test failed. Please check your credentials."
error "❌ Failed to validate API credentials or reach server"
fi
# Send initial update
info "📊 Sending initial package data..."
# Step 5: Send initial data
info "📊 Sending initial package data to server..."
if /usr/local/bin/patchmon-agent.sh update; then
success "Initial package data sent successfully!"
success "Initial package data sent successfully"
else
warning "Initial package data failed, but agent is configured. You can run 'patchmon-agent.sh update' manually."
warning "⚠️ Failed to send initial data. You can retry later with: /usr/local/bin/patchmon-agent.sh update"
fi
# Setup crontab for automatic package status updates
info "Setting up automatic package status update every $UPDATE_INTERVAL minutes..."
# Step 6: Get update interval policy from server and setup crontab
info "⏰ Getting update interval policy from server..."
UPDATE_INTERVAL=$(curl -ks \
-H "X-API-ID: $API_ID" \
-H "X-API-KEY: $API_KEY" \
"$PATCHMON_URL/api/v1/settings/update-interval" | \
grep -o '"updateInterval":[0-9]*' | cut -d':' -f2 2>/dev/null || echo "60")
# Check if patchmon cron job already exists
PATCHMON_CRON_EXISTS=$(crontab -l 2>/dev/null | grep -c "patchmon-agent.sh update" || true)
info "📋 Update interval: $UPDATE_INTERVAL minutes"
if [[ $PATCHMON_CRON_EXISTS -gt 0 ]]; then
info " Existing PatchMon cron job found, removing old entry..."
# Remove existing patchmon cron entries and preserve other entries
(crontab -l 2>/dev/null | grep -v "patchmon-agent.sh update") | crontab -
# Setup crontab (smart duplicate detection)
info "📅 Setting up automated updates..."
# Check if PatchMon cron entries already exist
if crontab -l 2>/dev/null | grep -q "/usr/local/bin/patchmon-agent.sh update"; then
warning "⚠️ Existing PatchMon cron entries found"
warning "⚠️ These will be replaced with new schedule"
fi
if [[ $UPDATE_INTERVAL -eq 60 ]]; then
# Hourly updates - safely append to existing crontab
(crontab -l 2>/dev/null; echo "0 * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1") | crontab -
else
# Custom interval updates - safely append to existing crontab
(crontab -l 2>/dev/null; echo "*/$UPDATE_INTERVAL * * * * /usr/local/bin/patchmon-agent.sh update >/dev/null 2>&1") | crontab -
fi
# Function to setup crontab without duplicates
setup_crontab() {
local update_interval="$1"
local patchmon_pattern="/usr/local/bin/patchmon-agent.sh update"
# Get current crontab, remove any existing patchmon entries
local current_cron=$(crontab -l 2>/dev/null | grep -v "$patchmon_pattern" || true)
# Determine new cron entry
local new_entry
if [[ "$update_interval" -eq 60 ]]; then
# Hourly updates - use a random minute to spread load
local current_minute=$(date +%M)
new_entry="$current_minute * * * * $patchmon_pattern >/dev/null 2>&1"
info "📋 Configuring hourly updates at minute $current_minute"
else
# Custom interval updates
new_entry="*/$update_interval * * * * $patchmon_pattern >/dev/null 2>&1"
info "📋 Configuring updates every $update_interval minutes"
fi
# Combine existing cron (without patchmon entries) + new entry
{
if [[ -n "$current_cron" ]]; then
echo "$current_cron"
fi
echo "$new_entry"
} | crontab -
success "✅ Crontab configured successfully (duplicates removed)"
}
success "🎉 PatchMon Agent installation complete!"
setup_crontab "$UPDATE_INTERVAL"
# Installation complete
success "🎉 PatchMon Agent installation completed successfully!"
echo ""
echo "📋 Installation Summary:"
echo " • Dependencies installed: jq, curl"
echo -e "${GREEN}📋 Installation Summary:${NC}"
echo " • Configuration directory: /etc/patchmon"
echo " • Agent installed: /usr/local/bin/patchmon-agent.sh"
echo "Agent version: $AGENT_VERSION"
if [[ "$EXPECTED_VERSION" != "Unknown" ]]; then
echo "Expected version: $EXPECTED_VERSION"
fi
echo " • Config directory: /etc/patchmon/"
echo " • Credentials file: /etc/patchmon/credentials"
echo " • Status updates: Every $UPDATE_INTERVAL minutes via crontab"
echo " • View logs: tail -f /var/log/patchmon-agent.log"
echo ""
echo "🔧 Manual commands:"
echo " • Test connection: patchmon-agent.sh test"
echo " • Send update: patchmon-agent.sh update"
echo " • Check status: patchmon-agent.sh ping"
echo ""
success "Your host is now connected to PatchMon!"
echo " • Dependencies installed: jq, curl"
echo " • Crontab configured for automatic updates"
echo " • API credentials configured and tested"
# Check for moved files and show them
MOVED_FILES=$(ls /etc/patchmon/credentials.backup.* /usr/local/bin/patchmon-agent.sh.backup.* /var/log/patchmon-agent.log.old.* 2>/dev/null || true)
if [[ -n "$MOVED_FILES" ]]; then
echo ""
echo -e "${YELLOW}📋 Files Moved for Fresh Installation:${NC}"
echo "$MOVED_FILES" | while read -r moved_file; do
echo "$moved_file"
done
echo ""
echo -e "${BLUE}💡 Note: Old files are automatically cleaned up (keeping last 3)${NC}"
fi
echo ""
echo -e "${BLUE}🔧 Management Commands:${NC}"
echo " • Test connection: /usr/local/bin/patchmon-agent.sh test"
echo " • Manual update: /usr/local/bin/patchmon-agent.sh update"
echo " • Check status: /usr/local/bin/patchmon-agent.sh diagnostics"
echo ""
success "✅ Your system is now being monitored by PatchMon!"

217
agents/patchmon_remove.sh Executable file
View File

@@ -0,0 +1,217 @@
#!/bin/bash
# PatchMon Agent Removal Script
# Usage: curl -ks {PATCHMON_URL}/api/v1/hosts/remove | bash
# This script completely removes PatchMon from the system
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m' # No Color
# Functions
error() {
echo -e "${RED}❌ ERROR: $1${NC}" >&2
exit 1
}
info() {
echo -e "${BLUE} $1${NC}"
}
success() {
echo -e "${GREEN}$1${NC}"
}
warning() {
echo -e "${YELLOW}⚠️ $1${NC}"
}
# Check if running as root
if [[ $EUID -ne 0 ]]; then
error "This script must be run as root (use sudo)"
fi
info "🗑️ Starting PatchMon Agent Removal..."
echo ""
# Step 1: Stop any running PatchMon processes
info "🛑 Stopping PatchMon processes..."
if pgrep -f "patchmon-agent.sh" >/dev/null; then
warning "Found running PatchMon processes, stopping them..."
pkill -f "patchmon-agent.sh" || true
sleep 2
success "PatchMon processes stopped"
else
info "No running PatchMon processes found"
fi
# Step 2: Remove crontab entries
info "📅 Removing PatchMon crontab entries..."
if crontab -l 2>/dev/null | grep -q "patchmon-agent.sh"; then
warning "Found PatchMon crontab entries, removing them..."
crontab -l 2>/dev/null | grep -v "patchmon-agent.sh" | crontab -
success "Crontab entries removed"
else
info "No PatchMon crontab entries found"
fi
# Step 3: Remove agent script
info "📄 Removing agent script..."
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
warning "Removing agent script: /usr/local/bin/patchmon-agent.sh"
rm -f /usr/local/bin/patchmon-agent.sh
success "Agent script removed"
else
info "Agent script not found"
fi
# Step 4: Remove configuration directory and files
info "📁 Removing configuration files..."
if [[ -d "/etc/patchmon" ]]; then
warning "Removing configuration directory: /etc/patchmon"
# Show what's being removed
info "📋 Files in /etc/patchmon:"
ls -la /etc/patchmon/ 2>/dev/null | grep -v "^total" | while read -r line; do
echo " $line"
done
# Remove the directory
rm -rf /etc/patchmon
success "Configuration directory removed"
else
info "Configuration directory not found"
fi
# Step 5: Remove log files
info "📝 Removing log files..."
if [[ -f "/var/log/patchmon-agent.log" ]]; then
warning "Removing log file: /var/log/patchmon-agent.log"
rm -f /var/log/patchmon-agent.log
success "Log file removed"
else
info "Log file not found"
fi
# Step 6: Clean up backup files (optional)
info "🧹 Cleaning up backup files..."
BACKUP_COUNT=0
# Count credential backups
CRED_BACKUPS=$(ls /etc/patchmon/credentials.backup.* 2>/dev/null | wc -l || echo "0")
if [[ $CRED_BACKUPS -gt 0 ]]; then
BACKUP_COUNT=$((BACKUP_COUNT + CRED_BACKUPS))
fi
# Count agent backups
AGENT_BACKUPS=$(ls /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | wc -l || echo "0")
if [[ $AGENT_BACKUPS -gt 0 ]]; then
BACKUP_COUNT=$((BACKUP_COUNT + AGENT_BACKUPS))
fi
# Count log backups
LOG_BACKUPS=$(ls /var/log/patchmon-agent.log.old.* 2>/dev/null | wc -l || echo "0")
if [[ $LOG_BACKUPS -gt 0 ]]; then
BACKUP_COUNT=$((BACKUP_COUNT + LOG_BACKUPS))
fi
if [[ $BACKUP_COUNT -gt 0 ]]; then
warning "Found $BACKUP_COUNT backup files"
echo ""
echo -e "${YELLOW}📋 Backup files found:${NC}"
# Show credential backups
if [[ $CRED_BACKUPS -gt 0 ]]; then
echo " Credential backups:"
ls /etc/patchmon/credentials.backup.* 2>/dev/null | while read -r file; do
echo "$file"
done
fi
# Show agent backups
if [[ $AGENT_BACKUPS -gt 0 ]]; then
echo " Agent script backups:"
ls /usr/local/bin/patchmon-agent.sh.backup.* 2>/dev/null | while read -r file; do
echo "$file"
done
fi
# Show log backups
if [[ $LOG_BACKUPS -gt 0 ]]; then
echo " Log file backups:"
ls /var/log/patchmon-agent.log.old.* 2>/dev/null | while read -r file; do
echo "$file"
done
fi
echo ""
echo -e "${BLUE}💡 Note: Backup files are preserved for safety${NC}"
echo -e "${BLUE}💡 You can remove them manually if not needed${NC}"
else
info "No backup files found"
fi
# Step 7: Remove dependencies (optional)
info "📦 Checking for PatchMon-specific dependencies..."
if command -v jq >/dev/null 2>&1; then
warning "jq is installed (used by PatchMon)"
echo -e "${BLUE}💡 Note: jq may be used by other applications${NC}"
echo -e "${BLUE}💡 Consider keeping it unless you're sure it's not needed${NC}"
else
info "jq not found"
fi
if command -v curl >/dev/null 2>&1; then
warning "curl is installed (used by PatchMon)"
echo -e "${BLUE}💡 Note: curl is commonly used by many applications${NC}"
echo -e "${BLUE}💡 Consider keeping it unless you're sure it's not needed${NC}"
else
info "curl not found"
fi
# Step 8: Final verification
info "🔍 Verifying removal..."
REMAINING_FILES=0
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then
REMAINING_FILES=$((REMAINING_FILES + 1))
fi
if [[ -d "/etc/patchmon" ]]; then
REMAINING_FILES=$((REMAINING_FILES + 1))
fi
if [[ -f "/var/log/patchmon-agent.log" ]]; then
REMAINING_FILES=$((REMAINING_FILES + 1))
fi
if crontab -l 2>/dev/null | grep -q "patchmon-agent.sh"; then
REMAINING_FILES=$((REMAINING_FILES + 1))
fi
if [[ $REMAINING_FILES -eq 0 ]]; then
success "✅ PatchMon has been completely removed from the system!"
else
warning "⚠️ Some PatchMon files may still remain ($REMAINING_FILES items)"
echo -e "${BLUE}💡 You may need to remove them manually${NC}"
fi
echo ""
echo -e "${GREEN}📋 Removal Summary:${NC}"
echo " • Agent script: Removed"
echo " • Configuration files: Removed"
echo " • Log files: Removed"
echo " • Crontab entries: Removed"
echo " • Running processes: Stopped"
echo " • Backup files: Preserved (if any)"
echo ""
echo -e "${BLUE}🔧 Manual cleanup (if needed):${NC}"
echo " • Remove backup files: rm /etc/patchmon/credentials.backup.* /usr/local/bin/patchmon-agent.sh.backup.* /var/log/patchmon-agent.log.old.*"
echo " • Remove dependencies: apt remove jq curl (if not needed by other apps)"
echo ""
success "🎉 PatchMon removal completed!"