mirror of
https://github.com/9technologygroup/patchmon.net.git
synced 2025-10-23 07:42:05 +00:00
feat: Implement machine_id based host identification
- Add machine_id field to hosts schema (unique, indexed) - Remove unique constraint from friendly_name (allow duplicate hostnames) - Agent installer now generates/reads persistent machine_id - Proxmox script retrieves machine_id from LXC containers - Backend will check machine_id instead of hostname for duplicates This allows multiple hosts with same hostname to coexist in PatchMon
This commit is contained in:
@@ -109,14 +109,32 @@ cleanup_old_files() {
|
||||
# Run cleanup at start
|
||||
cleanup_old_files
|
||||
|
||||
# Generate or retrieve machine ID
|
||||
get_machine_id() {
|
||||
# Try multiple sources for machine ID
|
||||
if [[ -f /etc/machine-id ]]; then
|
||||
cat /etc/machine-id
|
||||
elif [[ -f /var/lib/dbus/machine-id ]]; then
|
||||
cat /var/lib/dbus/machine-id
|
||||
else
|
||||
# Fallback: generate from hardware info (less ideal but works)
|
||||
echo "patchmon-$(cat /sys/class/dmi/id/product_uuid 2>/dev/null || cat /proc/sys/kernel/random/uuid)"
|
||||
fi
|
||||
}
|
||||
|
||||
# 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
|
||||
|
||||
# Get unique machine ID for this host
|
||||
MACHINE_ID=$(get_machine_id)
|
||||
export MACHINE_ID
|
||||
|
||||
info "🚀 Starting PatchMon Agent Installation..."
|
||||
info "📋 Server: $PATCHMON_URL"
|
||||
info "🔑 API ID: ${API_ID:0:16}..."
|
||||
info "🆔 Machine ID: ${MACHINE_ID:0:16}..."
|
||||
|
||||
# Display diagnostic information
|
||||
echo ""
|
||||
@@ -261,6 +279,33 @@ if [[ -f "/var/log/patchmon-agent.log" ]]; then
|
||||
fi
|
||||
|
||||
# Step 4: Test the configuration
|
||||
# Check if this machine is already enrolled
|
||||
info "🔍 Checking if machine is already enrolled..."
|
||||
existing_check=$(curl $CURL_FLAGS -s -X POST \
|
||||
-H "X-API-ID: $API_ID" \
|
||||
-H "X-API-KEY: $API_KEY" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{\"machine_id\": \"$MACHINE_ID\"}" \
|
||||
"$PATCHMON_URL/api/v1/hosts/check-machine-id" \
|
||||
-w "\n%{http_code}" 2>&1)
|
||||
|
||||
http_code=$(echo "$existing_check" | tail -n 1)
|
||||
response_body=$(echo "$existing_check" | sed '$d')
|
||||
|
||||
if [[ "$http_code" == "200" ]]; then
|
||||
already_enrolled=$(echo "$response_body" | jq -r '.exists' 2>/dev/null || echo "false")
|
||||
if [[ "$already_enrolled" == "true" ]]; then
|
||||
warning "⚠️ This machine is already enrolled in PatchMon"
|
||||
info "Machine ID: $MACHINE_ID"
|
||||
info "Existing host: $(echo "$response_body" | jq -r '.host.friendly_name' 2>/dev/null)"
|
||||
info ""
|
||||
info "The agent will be reinstalled/updated with existing credentials."
|
||||
echo ""
|
||||
else
|
||||
success "✅ Machine not yet enrolled - proceeding with installation"
|
||||
fi
|
||||
fi
|
||||
|
||||
info "🧪 Testing API credentials and connectivity..."
|
||||
if /usr/local/bin/patchmon-agent.sh test; then
|
||||
success "✅ TEST: API credentials are valid and server is reachable"
|
||||
|
@@ -4,7 +4,7 @@ set -eo pipefail # Exit on error, pipe failures (removed -u as we handle unset
|
||||
# Trap to catch errors only (not normal exits)
|
||||
trap 'echo "[ERROR] Script failed at line $LINENO with exit code $?"' ERR
|
||||
|
||||
SCRIPT_VERSION="1.3.0"
|
||||
SCRIPT_VERSION="2.0.0"
|
||||
echo "[DEBUG] Script Version: $SCRIPT_VERSION ($(date +%Y-%m-%d\ %H:%M:%S))"
|
||||
|
||||
# =============================================================================
|
||||
@@ -151,12 +151,16 @@ while IFS= read -r line; do
|
||||
hostname=$(timeout 5 pct exec "$vmid" -- hostname 2>/dev/null </dev/null || echo "$name")
|
||||
ip_address=$(timeout 5 pct exec "$vmid" -- hostname -I 2>/dev/null </dev/null | awk '{print $1}' || echo "unknown")
|
||||
os_info=$(timeout 5 pct exec "$vmid" -- cat /etc/os-release 2>/dev/null </dev/null | grep "^PRETTY_NAME=" | cut -d'"' -f2 || echo "unknown")
|
||||
|
||||
# Get machine ID from container
|
||||
machine_id=$(timeout 5 pct exec "$vmid" -- bash -c "cat /etc/machine-id 2>/dev/null || cat /var/lib/dbus/machine-id 2>/dev/null || echo 'proxmox-lxc-$vmid-'$(cat /proc/sys/kernel/random/uuid)" </dev/null 2>/dev/null || echo "proxmox-lxc-$vmid-unknown")
|
||||
|
||||
friendly_name="${HOST_PREFIX}${hostname}"
|
||||
|
||||
info " Hostname: $hostname"
|
||||
info " IP Address: $ip_address"
|
||||
info " OS: $os_info"
|
||||
info " Machine ID: ${machine_id:0:16}..."
|
||||
|
||||
if [[ "$DRY_RUN" == "true" ]]; then
|
||||
info " [DRY RUN] Would enroll: $friendly_name"
|
||||
@@ -174,6 +178,7 @@ while IFS= read -r line; do
|
||||
-H "Content-Type: application/json" \
|
||||
-d "{
|
||||
\"friendly_name\": \"$friendly_name\",
|
||||
\"machine_id\": \"$machine_id\",
|
||||
\"metadata\": {
|
||||
\"vmid\": \"$vmid\",
|
||||
\"proxmox_node\": \"$(hostname)\",
|
||||
|
@@ -60,7 +60,8 @@ model host_repositories {
|
||||
|
||||
model hosts {
|
||||
id String @id
|
||||
friendly_name String @unique
|
||||
machine_id String @unique
|
||||
friendly_name String
|
||||
ip String?
|
||||
os_type String
|
||||
os_version String
|
||||
@@ -92,6 +93,10 @@ model hosts {
|
||||
host_repositories host_repositories[]
|
||||
host_groups host_groups? @relation(fields: [host_group_id], references: [id])
|
||||
update_history update_history[]
|
||||
|
||||
@@index([machine_id])
|
||||
@@index([friendly_name])
|
||||
@@index([hostname])
|
||||
}
|
||||
|
||||
model packages {
|
||||
|
Reference in New Issue
Block a user