Compare commits

...

10 Commits

Author SHA1 Message Date
Muhammad Ibrahim
f0b028cb77 alpine support on the agent installation script 2025-11-08 22:00:34 +00:00
Muhammad Ibrahim
8c2d4aa42b alpine support (apk) support agents 2025-11-08 21:15:08 +00:00
Muhammad Ibrahim
082ceed27c arm support 2025-11-08 12:23:50 +00:00
9 Technology Group LTD
5a3938d7fc Merge pull request #291 from PatchMon/1-3-3
fixed env flag issue when auto-enrolling into proxmox
2025-11-08 09:35:52 +00:00
Muhammad Ibrahim
eb433719dd fixed env flag issue when auto-enrolling into proxmox 2025-11-08 09:34:39 +00:00
9 Technology Group LTD
106ab6f5f8 Merge pull request #290 from PatchMon/1-3-3
new agent files for 1.3.3
2025-11-07 23:07:49 +00:00
Muhammad Ibrahim
148ff2e77f new agent files for 1.3.3 2025-11-07 23:02:53 +00:00
9 Technology Group LTD
a9e4349f5f Merge pull request #289 from PatchMon/1-3-3
1 3 3
2025-11-07 22:33:28 +00:00
Muhammad Ibrahim
a655a24f2f 1.3.3 agents 2025-11-07 22:32:11 +00:00
Muhammad Ibrahim
417f6deccf 1.3.3 version changes 2025-11-07 22:29:13 +00:00
11 changed files with 265 additions and 82 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -1,7 +1,32 @@
#!/bin/bash #!/bin/sh
# PatchMon Agent Installation Script
# This script requires bash for full functionality
# Usage: curl -s {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | sh
# Check if bash is available, if not try to install it (for Alpine Linux)
if ! command -v bash >/dev/null 2>&1; then
if command -v apk >/dev/null 2>&1; then
echo "Installing bash for script compatibility..."
apk add --no-cache bash >/dev/null 2>&1 || true
fi
fi
# If bash is available and we're not already running in bash, switch to bash
# When piped, we can't re-execute easily, so we'll continue with sh
# but ensure bash is available for bash-specific features
if command -v bash >/dev/null 2>&1 && [ -z "${BASH_VERSION:-}" ]; then
# Check if we're being piped (stdin is not a terminal)
if [ -t 0 ]; then
# Direct execution, re-execute with bash
exec bash "$0" "$@"
exit $?
fi
# When piped, we continue with sh but bash is now available
# The script will use bash-specific features which should work if bash is installed
fi
# PatchMon Agent Installation Script # PatchMon Agent Installation Script
# Usage: curl -s {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | bash # Usage: curl -s {PATCHMON_URL}/api/v1/hosts/install -H "X-API-ID: {API_ID}" -H "X-API-KEY: {API_KEY}" | sh
set -e set -e
@@ -36,7 +61,7 @@ warning() {
} }
# Check if running as root # Check if running as root
if [[ $EUID -ne 0 ]]; then if [ "$(id -u)" -ne 0 ]; then
error "This script must be run as root (use sudo)" error "This script must be run as root (use sudo)"
fi fi
@@ -45,8 +70,8 @@ verify_datetime() {
info "🕐 Verifying system datetime and timezone..." info "🕐 Verifying system datetime and timezone..."
# Get current system time # Get current system time
local system_time=$(date) system_time=$(date)
local timezone=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Unknown") timezone=$(timedatectl show --property=Timezone --value 2>/dev/null || echo "Unknown")
# Display current datetime info # Display current datetime info
echo "" echo ""
@@ -56,14 +81,17 @@ verify_datetime() {
echo "" echo ""
# Check if we can read from stdin (interactive terminal) # Check if we can read from stdin (interactive terminal)
if [[ -t 0 ]]; then if [ -t 0 ]; then
# Interactive terminal - ask user # Interactive terminal - ask user
read -p "Does this date/time look correct to you? (y/N): " -r response printf "Does this date/time look correct to you? (y/N): "
if [[ "$response" =~ ^[Yy]$ ]]; then read -r response
case "$response" in
[Yy]*)
success "✅ Date/time verification passed" success "✅ Date/time verification passed"
echo "" echo ""
return 0 return 0
else ;;
*)
echo "" echo ""
echo -e "${RED}❌ Date/time verification failed${NC}" echo -e "${RED}❌ Date/time verification failed${NC}"
echo "" echo ""
@@ -74,7 +102,8 @@ verify_datetime() {
echo "" echo ""
echo -e "${BLUE} After fixing the date/time, re-run this installation script.${NC}" echo -e "${BLUE} After fixing the date/time, re-run this installation script.${NC}"
error "Installation cancelled - please fix date/time and re-run" error "Installation cancelled - please fix date/time and re-run"
fi ;;
esac
else else
# Non-interactive (piped from curl) - show warning and continue # Non-interactive (piped from curl) - show warning and continue
echo -e "${YELLOW}⚠️ Non-interactive installation detected${NC}" echo -e "${YELLOW}⚠️ Non-interactive installation detected${NC}"
@@ -121,9 +150,9 @@ cleanup_old_files
# Generate or retrieve machine ID # Generate or retrieve machine ID
get_machine_id() { get_machine_id() {
# Try multiple sources for machine ID # Try multiple sources for machine ID
if [[ -f /etc/machine-id ]]; then if [ -f /etc/machine-id ]; then
cat /etc/machine-id cat /etc/machine-id
elif [[ -f /var/lib/dbus/machine-id ]]; then elif [ -f /var/lib/dbus/machine-id ]; then
cat /var/lib/dbus/machine-id cat /var/lib/dbus/machine-id
else else
# Fallback: generate from hardware info (less ideal but works) # Fallback: generate from hardware info (less ideal but works)
@@ -132,12 +161,12 @@ get_machine_id() {
} }
# Parse arguments from environment (passed via HTTP headers) # Parse arguments from environment (passed via HTTP headers)
if [[ -z "$PATCHMON_URL" ]] || [[ -z "$API_ID" ]] || [[ -z "$API_KEY" ]]; then 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." error "Missing required parameters. This script should be called via the PatchMon web interface."
fi fi
# Auto-detect architecture if not explicitly set # Auto-detect architecture if not explicitly set
if [[ -z "$ARCHITECTURE" ]]; then if [ -z "$ARCHITECTURE" ]; then
arch_raw=$(uname -m 2>/dev/null || echo "unknown") arch_raw=$(uname -m 2>/dev/null || echo "unknown")
# Map architecture to supported values # Map architecture to supported values
@@ -162,13 +191,16 @@ if [[ -z "$ARCHITECTURE" ]]; then
fi fi
# Validate architecture # Validate architecture
if [[ "$ARCHITECTURE" != "amd64" && "$ARCHITECTURE" != "386" && "$ARCHITECTURE" != "arm64" && "$ARCHITECTURE" != "arm" ]]; then if [ "$ARCHITECTURE" != "amd64" ] && [ "$ARCHITECTURE" != "386" ] && [ "$ARCHITECTURE" != "arm64" ] && [ "$ARCHITECTURE" != "arm" ]; then
error "Invalid architecture '$ARCHITECTURE'. Must be one of: amd64, 386, arm64, arm" error "Invalid architecture '$ARCHITECTURE'. Must be one of: amd64, 386, arm64, arm"
fi fi
# Check if --force flag is set (for bypassing broken packages) # Check if --force flag is set (for bypassing broken packages)
FORCE_INSTALL="${FORCE_INSTALL:-false}" FORCE_INSTALL="${FORCE_INSTALL:-false}"
if [[ "$*" == *"--force"* ]] || [[ "$FORCE_INSTALL" == "true" ]]; then case "$*" in
*"--force"*) FORCE_INSTALL="true" ;;
esac
if [ "$FORCE_INSTALL" = "true" ]; then
FORCE_INSTALL="true" FORCE_INSTALL="true"
warning "⚠️ Force mode enabled - will bypass broken packages" warning "⚠️ Force mode enabled - will bypass broken packages"
fi fi
@@ -224,7 +256,7 @@ install_apt_packages() {
# Build apt-get command based on force mode # Build apt-get command based on force mode
local apt_cmd="apt-get install ${missing_packages[*]} -y" local apt_cmd="apt-get install ${missing_packages[*]} -y"
if [[ "$FORCE_INSTALL" == "true" ]]; then if [ "$FORCE_INSTALL" = "true" ]; then
info "Using force mode - bypassing broken packages..." info "Using force mode - bypassing broken packages..."
apt_cmd="$apt_cmd -o APT::Get::Fix-Broken=false -o DPkg::Options::=\"--force-confold\" -o DPkg::Options::=\"--force-confdef\"" apt_cmd="$apt_cmd -o APT::Get::Fix-Broken=false -o DPkg::Options::=\"--force-confold\" -o DPkg::Options::=\"--force-confdef\""
fi fi
@@ -240,7 +272,7 @@ install_apt_packages() {
local all_ok=true local all_ok=true
for pkg in "${packages[@]}"; do for pkg in "${packages[@]}"; do
if ! command_exists "$pkg"; then if ! command_exists "$pkg"; then
if [[ "$FORCE_INSTALL" == "true" ]]; then if [ "$FORCE_INSTALL" = "true" ]; then
error "Critical dependency '$pkg' is not available even with --force. Please install manually." error "Critical dependency '$pkg' is not available even with --force. Please install manually."
else else
error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apt-get install $pkg" error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apt-get install $pkg"
@@ -279,7 +311,7 @@ install_yum_dnf_packages() {
info "Need to install: ${missing_packages[*]}" info "Need to install: ${missing_packages[*]}"
if [[ "$pkg_manager" == "yum" ]]; then if [ "$pkg_manager" = "yum" ]; then
yum install -y "${missing_packages[@]}" yum install -y "${missing_packages[@]}"
else else
dnf install -y "${missing_packages[@]}" dnf install -y "${missing_packages[@]}"
@@ -346,7 +378,41 @@ install_apk_packages() {
fi fi
info "Need to install: ${missing_packages[*]}" info "Need to install: ${missing_packages[*]}"
apk add --no-cache "${missing_packages[@]}"
# Update package index before installation
info "Updating package index..."
apk update -q || true
# Build apk command
local apk_cmd="apk add --no-cache ${missing_packages[*]}"
# Try to install packages
if eval "$apk_cmd" 2>&1 | tee /tmp/patchmon_apk_install.log; then
success "Packages installed successfully"
return 0
else
warning "Package installation encountered issues, checking if required tools are available..."
# Verify critical dependencies are actually available
local all_ok=true
for pkg in "${packages[@]}"; do
if ! command_exists "$pkg"; then
if [ "$FORCE_INSTALL" = "true" ]; then
error "Critical dependency '$pkg' is not available even with --force. Please install manually."
else
error "Critical dependency '$pkg' is not available. Try again with --force flag or install manually: apk add $pkg"
fi
all_ok=false
fi
done
if $all_ok; then
success "All required tools are available despite installation warnings"
return 0
else
return 1
fi
fi
} }
# Detect package manager and install jq, curl, and bc # Detect package manager and install jq, curl, and bc
@@ -357,7 +423,7 @@ if command -v apt-get >/dev/null 2>&1; then
# Check for broken packages # Check for broken packages
if dpkg -l | grep -q "^iH\|^iF" 2>/dev/null; then if dpkg -l | grep -q "^iH\|^iF" 2>/dev/null; then
if [[ "$FORCE_INSTALL" == "true" ]]; then if [ "$FORCE_INSTALL" = "true" ]; then
warning "Detected broken packages on system - force mode will work around them" warning "Detected broken packages on system - force mode will work around them"
else else
warning "⚠️ Broken packages detected on system" warning "⚠️ Broken packages detected on system"
@@ -412,7 +478,7 @@ echo ""
info "📁 Setting up configuration directory..." info "📁 Setting up configuration directory..."
# Check if configuration directory already exists # Check if configuration directory already exists
if [[ -d "/etc/patchmon" ]]; then if [ -d "/etc/patchmon" ]; then
warning "⚠️ Configuration directory already exists at /etc/patchmon" warning "⚠️ Configuration directory already exists at /etc/patchmon"
warning "⚠️ Preserving existing configuration files" warning "⚠️ Preserving existing configuration files"
@@ -429,8 +495,8 @@ fi
# Check if agent is already configured and working (before we overwrite anything) # Check if agent is already configured and working (before we overwrite anything)
info "🔍 Checking if agent is already configured..." info "🔍 Checking if agent is already configured..."
if [[ -f /etc/patchmon/config.yml ]] && [[ -f /etc/patchmon/credentials.yml ]]; then if [ -f /etc/patchmon/config.yml ] && [ -f /etc/patchmon/credentials.yml ]; then
if [[ -f /usr/local/bin/patchmon-agent ]]; then if [ -f /usr/local/bin/patchmon-agent ]; then
info "📋 Found existing agent configuration" info "📋 Found existing agent configuration"
info "🧪 Testing existing configuration with ping..." info "🧪 Testing existing configuration with ping..."
@@ -461,7 +527,7 @@ fi
info "🔐 Creating configuration files..." info "🔐 Creating configuration files..."
# Check if config file already exists # Check if config file already exists
if [[ -f "/etc/patchmon/config.yml" ]]; then if [ -f "/etc/patchmon/config.yml" ]; then
warning "⚠️ Config file already exists at /etc/patchmon/config.yml" warning "⚠️ Config file already exists at /etc/patchmon/config.yml"
warning "⚠️ Moving existing file out of the way for fresh installation" warning "⚠️ Moving existing file out of the way for fresh installation"
@@ -474,7 +540,7 @@ if [[ -f "/etc/patchmon/config.yml" ]]; then
fi fi
# Check if credentials file already exists # Check if credentials file already exists
if [[ -f "/etc/patchmon/credentials.yml" ]]; then if [ -f "/etc/patchmon/credentials.yml" ]; then
warning "⚠️ Credentials file already exists at /etc/patchmon/credentials.yml" warning "⚠️ Credentials file already exists at /etc/patchmon/credentials.yml"
warning "⚠️ Moving existing file out of the way for fresh installation" warning "⚠️ Moving existing file out of the way for fresh installation"
@@ -487,7 +553,7 @@ if [[ -f "/etc/patchmon/credentials.yml" ]]; then
fi fi
# Clean up old credentials file if it exists (from previous installations) # Clean up old credentials file if it exists (from previous installations)
if [[ -f "/etc/patchmon/credentials" ]]; then if [ -f "/etc/patchmon/credentials" ]; then
warning "⚠️ Found old credentials file, removing it..." warning "⚠️ Found old credentials file, removing it..."
rm -f /etc/patchmon/credentials rm -f /etc/patchmon/credentials
info "📋 Removed old credentials file" info "📋 Removed old credentials file"
@@ -523,7 +589,7 @@ info "📥 Downloading PatchMon agent binary..."
BINARY_NAME="patchmon-agent-linux-${ARCHITECTURE}" BINARY_NAME="patchmon-agent-linux-${ARCHITECTURE}"
# Check if agent binary already exists # Check if agent binary already exists
if [[ -f "/usr/local/bin/patchmon-agent" ]]; then if [ -f "/usr/local/bin/patchmon-agent" ]; then
warning "⚠️ Agent binary already exists at /usr/local/bin/patchmon-agent" warning "⚠️ Agent binary already exists at /usr/local/bin/patchmon-agent"
warning "⚠️ Moving existing file out of the way for fresh installation" warning "⚠️ Moving existing file out of the way for fresh installation"
@@ -536,7 +602,7 @@ if [[ -f "/usr/local/bin/patchmon-agent" ]]; then
fi fi
# Clean up old shell script if it exists (from previous installations) # Clean up old shell script if it exists (from previous installations)
if [[ -f "/usr/local/bin/patchmon-agent.sh" ]]; then if [ -f "/usr/local/bin/patchmon-agent.sh" ]; then
warning "⚠️ Found old shell script agent, removing it..." warning "⚠️ Found old shell script agent, removing it..."
rm -f /usr/local/bin/patchmon-agent.sh rm -f /usr/local/bin/patchmon-agent.sh
info "📋 Removed old shell script agent" info "📋 Removed old shell script agent"
@@ -562,7 +628,7 @@ info "📁 Setting up log directory..."
mkdir -p /etc/patchmon/logs mkdir -p /etc/patchmon/logs
# Handle existing log files # Handle existing log files
if [[ -f "/etc/patchmon/logs/patchmon-agent.log" ]]; then if [ -f "/etc/patchmon/logs/patchmon-agent.log" ]; then
warning "⚠️ Existing log file found at /etc/patchmon/logs/patchmon-agent.log" warning "⚠️ Existing log file found at /etc/patchmon/logs/patchmon-agent.log"
warning "⚠️ Rotating log file for fresh start" warning "⚠️ Rotating log file for fresh start"
@@ -579,8 +645,11 @@ else
error "❌ Failed to validate API credentials or reach server" error "❌ Failed to validate API credentials or reach server"
fi fi
# Step 5: Setup systemd service for WebSocket connection # Step 5: Setup service for WebSocket connection
# Note: The service will automatically send an initial report on startup (see serve.go) # Note: The service will automatically send an initial report on startup (see serve.go)
# Detect init system and create appropriate service
if command -v systemctl >/dev/null 2>&1; then
# Systemd is available
info "🔧 Setting up systemd service..." info "🔧 Setting up systemd service..."
# Stop and disable existing service if it exists # Stop and disable existing service if it exists
@@ -638,6 +707,86 @@ else
warning "⚠️ Service may have failed to start. Check status with: systemctl status patchmon-agent" warning "⚠️ Service may have failed to start. Check status with: systemctl status patchmon-agent"
fi fi
SERVICE_TYPE="systemd"
elif [ -d /etc/init.d ] && command -v rc-service >/dev/null 2>&1; then
# OpenRC is available (Alpine Linux)
info "🔧 Setting up OpenRC service..."
# Stop and disable existing service if it exists
if rc-service patchmon-agent status >/dev/null 2>&1; then
warning "⚠️ Stopping existing PatchMon agent service..."
rc-service patchmon-agent stop
fi
if rc-update show default 2>/dev/null | grep -q "patchmon-agent"; then
warning "⚠️ Disabling existing PatchMon agent service..."
rc-update del patchmon-agent default
fi
# Create OpenRC service file
cat > /etc/init.d/patchmon-agent << 'EOF'
#!/sbin/openrc-run
name="patchmon-agent"
description="PatchMon Agent Service"
command="/usr/local/bin/patchmon-agent"
command_args="serve"
command_user="root"
pidfile="/var/run/patchmon-agent.pid"
command_background="yes"
working_dir="/etc/patchmon"
depend() {
need net
after net
}
EOF
chmod +x /etc/init.d/patchmon-agent
# Clean up old crontab entries if they exist (from previous installations)
if crontab -l 2>/dev/null | grep -q "patchmon-agent"; then
warning "⚠️ Found old crontab entries, removing them..."
crontab -l 2>/dev/null | grep -v "patchmon-agent" | crontab -
info "📋 Removed old crontab entries"
fi
# Enable and start the service
rc-update add patchmon-agent default
rc-service patchmon-agent start
# Check if service started successfully
if rc-service patchmon-agent status >/dev/null 2>&1; then
success "✅ PatchMon Agent service started successfully"
info "🔗 WebSocket connection established"
else
warning "⚠️ Service may have failed to start. Check status with: rc-service patchmon-agent status"
fi
SERVICE_TYPE="openrc"
else
# No init system detected, use crontab as fallback
warning "⚠️ No init system detected (systemd or OpenRC). Using crontab for service management."
# Clean up old crontab entries if they exist
if crontab -l 2>/dev/null | grep -q "patchmon-agent"; then
warning "⚠️ Found old crontab entries, removing them..."
crontab -l 2>/dev/null | grep -v "patchmon-agent" | crontab -
info "📋 Removed old crontab entries"
fi
# Add crontab entry to run the agent
(crontab -l 2>/dev/null; echo "@reboot /usr/local/bin/patchmon-agent serve >/dev/null 2>&1") | crontab -
info "📋 Added crontab entry for PatchMon agent"
# Start the agent manually
/usr/local/bin/patchmon-agent serve >/dev/null 2>&1 &
success "✅ PatchMon Agent started in background"
info "🔗 WebSocket connection established"
SERVICE_TYPE="crontab"
fi
# Installation complete # Installation complete
success "🎉 PatchMon Agent installation completed successfully!" success "🎉 PatchMon Agent installation completed successfully!"
echo "" echo ""
@@ -646,14 +795,20 @@ echo " • Configuration directory: /etc/patchmon"
echo " • Agent binary installed: /usr/local/bin/patchmon-agent" echo " • Agent binary installed: /usr/local/bin/patchmon-agent"
echo " • Architecture: $ARCHITECTURE" echo " • Architecture: $ARCHITECTURE"
echo " • Dependencies installed: jq, curl, bc" echo " • Dependencies installed: jq, curl, bc"
if [ "$SERVICE_TYPE" = "systemd" ]; then
echo " • Systemd service configured and running" echo " • Systemd service configured and running"
elif [ "$SERVICE_TYPE" = "openrc" ]; then
echo " • OpenRC service configured and running"
else
echo " • Service configured via crontab"
fi
echo " • API credentials configured and tested" echo " • API credentials configured and tested"
echo " • WebSocket connection established" echo " • WebSocket connection established"
echo " • Logs directory: /etc/patchmon/logs" echo " • Logs directory: /etc/patchmon/logs"
# Check for moved files and show them # Check for moved files and show them
MOVED_FILES=$(ls /etc/patchmon/credentials.yml.backup.* /etc/patchmon/config.yml.backup.* /usr/local/bin/patchmon-agent.backup.* /etc/patchmon/logs/patchmon-agent.log.old.* /usr/local/bin/patchmon-agent.sh.backup.* /etc/patchmon/credentials.backup.* 2>/dev/null || true) MOVED_FILES=$(ls /etc/patchmon/credentials.yml.backup.* /etc/patchmon/config.yml.backup.* /usr/local/bin/patchmon-agent.backup.* /etc/patchmon/logs/patchmon-agent.log.old.* /usr/local/bin/patchmon-agent.sh.backup.* /etc/patchmon/credentials.backup.* 2>/dev/null || true)
if [[ -n "$MOVED_FILES" ]]; then if [ -n "$MOVED_FILES" ]; then
echo "" echo ""
echo -e "${YELLOW}📋 Files Moved for Fresh Installation:${NC}" echo -e "${YELLOW}📋 Files Moved for Fresh Installation:${NC}"
echo "$MOVED_FILES" | while read -r moved_file; do echo "$MOVED_FILES" | while read -r moved_file; do
@@ -668,8 +823,17 @@ echo -e "${BLUE}🔧 Management Commands:${NC}"
echo " • Test connection: /usr/local/bin/patchmon-agent ping" echo " • Test connection: /usr/local/bin/patchmon-agent ping"
echo " • Manual report: /usr/local/bin/patchmon-agent report" echo " • Manual report: /usr/local/bin/patchmon-agent report"
echo " • Check status: /usr/local/bin/patchmon-agent diagnostics" echo " • Check status: /usr/local/bin/patchmon-agent diagnostics"
if [ "$SERVICE_TYPE" = "systemd" ]; then
echo " • Service status: systemctl status patchmon-agent" echo " • Service status: systemctl status patchmon-agent"
echo " • Service logs: journalctl -u patchmon-agent -f" echo " • Service logs: journalctl -u patchmon-agent -f"
echo " • Restart service: systemctl restart patchmon-agent" echo " • Restart service: systemctl restart patchmon-agent"
elif [ "$SERVICE_TYPE" = "openrc" ]; then
echo " • Service status: rc-service patchmon-agent status"
echo " • Service logs: tail -f /etc/patchmon/logs/patchmon-agent.log"
echo " • Restart service: rc-service patchmon-agent restart"
else
echo " • Service logs: tail -f /etc/patchmon/logs/patchmon-agent.log"
echo " • Restart service: pkill -f 'patchmon-agent serve' && /usr/local/bin/patchmon-agent serve &"
fi
echo "" echo ""
success "✅ Your system is now being monitored by PatchMon!" success "✅ Your system is now being monitored by PatchMon!"

View File

@@ -318,7 +318,8 @@ while IFS= read -r line; do
# Download and execute in separate steps to avoid stdin issues with piping # Download and execute in separate steps to avoid stdin issues with piping
# Pass CURL_FLAGS as environment variable to container # Pass CURL_FLAGS as environment variable to container
install_output=$(timeout 180 pct exec "$vmid" --env CURL_FLAGS="$CURL_FLAGS" -- bash -c " install_output=$(timeout 180 pct exec "$vmid" -- bash -c "
export CURL_FLAGS='$CURL_FLAGS'
cd /tmp cd /tmp
curl \$CURL_FLAGS \ curl \$CURL_FLAGS \
-H \"X-API-ID: $api_id\" \ -H \"X-API-ID: $api_id\" \
@@ -458,7 +459,8 @@ if [[ ${#dpkg_error_containers[@]} -gt 0 ]]; then
install_exit_code=0 install_exit_code=0
# Pass CURL_FLAGS as environment variable to container # Pass CURL_FLAGS as environment variable to container
install_output=$(timeout 180 pct exec "$vmid" --env CURL_FLAGS="$CURL_FLAGS" -- bash -c " install_output=$(timeout 180 pct exec "$vmid" -- bash -c "
export CURL_FLAGS='$CURL_FLAGS'
cd /tmp cd /tmp
curl \$CURL_FLAGS \ curl \$CURL_FLAGS \
-H \"X-API-ID: $api_id\" \ -H \"X-API-ID: $api_id\" \

View File

@@ -1,6 +1,6 @@
{ {
"name": "patchmon-backend", "name": "patchmon-backend",
"version": "1.3.2", "version": "1.3.3",
"description": "Backend API for Linux Patch Monitoring System", "description": "Backend API for Linux Patch Monitoring System",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "src/server.js", "main": "src/server.js",

View File

@@ -1,6 +1,7 @@
const axios = require("axios"); const axios = require("axios");
const fs = require("node:fs").promises; const fs = require("node:fs").promises;
const path = require("node:path"); const path = require("node:path");
const os = require("node:os");
const { exec, spawn } = require("node:child_process"); const { exec, spawn } = require("node:child_process");
const { promisify } = require("node:util"); const { promisify } = require("node:util");
const _execAsync = promisify(exec); const _execAsync = promisify(exec);
@@ -106,10 +107,26 @@ class AgentVersionService {
try { try {
console.log("🔍 Getting current agent version..."); console.log("🔍 Getting current agent version...");
// Try to find the agent binary in agents/ folder only (what gets distributed) // Detect server architecture and map to Go architecture names
const serverArch = os.arch();
// Map Node.js architecture to Go architecture names
const archMap = {
x64: "amd64",
ia32: "386",
arm64: "arm64",
arm: "arm",
};
const serverGoArch = archMap[serverArch] || serverArch;
console.log(
`🔍 Detected server architecture: ${serverArch} -> ${serverGoArch}`,
);
// Try to find the agent binary in agents/ folder based on server architecture
const possiblePaths = [ const possiblePaths = [
path.join(this.agentsDir, "patchmon-agent-linux-amd64"), path.join(this.agentsDir, `patchmon-agent-linux-${serverGoArch}`),
path.join(this.agentsDir, "patchmon-agent"), path.join(this.agentsDir, "patchmon-agent-linux-amd64"), // Fallback
path.join(this.agentsDir, "patchmon-agent"), // Legacy fallback
]; ];
let agentPath = null; let agentPath = null;
@@ -126,7 +143,7 @@ class AgentVersionService {
if (!agentPath) { if (!agentPath) {
console.log( console.log(
"⚠️ No agent binary found in agents/ folder, current version will be unknown", `⚠️ No agent binary found in agents/ folder for architecture ${serverGoArch}, current version will be unknown`,
); );
console.log("💡 Use the Download Updates button to get agent binaries"); console.log("💡 Use the Download Updates button to get agent binaries");
this.currentVersion = null; this.currentVersion = null;

View File

@@ -1,7 +1,7 @@
{ {
"name": "patchmon-frontend", "name": "patchmon-frontend",
"private": true, "private": true,
"version": "1.3.2", "version": "1.3.3",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@@ -1,6 +1,6 @@
{ {
"name": "patchmon", "name": "patchmon",
"version": "1.3.2", "version": "1.3.3",
"description": "Linux Patch Monitoring System", "description": "Linux Patch Monitoring System",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"private": true, "private": true,

View File

@@ -34,7 +34,7 @@ BLUE='\033[0;34m'
NC='\033[0m' # No Color NC='\033[0m' # No Color
# Global variables # Global variables
SCRIPT_VERSION="self-hosting-install.sh v1.3.2-selfhost-2025-10-31-1" SCRIPT_VERSION="self-hosting-install.sh v1.3.3-selfhost-2025-11-07"
DEFAULT_GITHUB_REPO="https://github.com/PatchMon/PatchMon.git" DEFAULT_GITHUB_REPO="https://github.com/PatchMon/PatchMon.git"
FQDN="" FQDN=""
CUSTOM_FQDN="" CUSTOM_FQDN=""