LXC Agent Remote Updater

Report Page

info:

Ready to update agents. Select a container below.

SSH Configuration Required

Please update the $ssh_user and $ssh_key_path variables in the **config.php** file.

Ensure the web server user has a passwordless SSH key authorized on the LXC containers.

Available LXC Containers (Agent v1.1.6)

frigate

VMID: 100
IP: 192.168.68.45
Node: server3
Agent: 1.1.6

mariadb

VMID: 101
IP: 192.168.68.41
Node: server2
Agent: 1.1.6

grafana

VMID: 102
IP: 192.168.68.39
Node: server1
Agent: 1.1.6

influxdb

VMID: 102
IP: 192.168.68.40
Node: server2
Agent: 1.1.6

prometheus

VMID: 103
IP: 192.168.68.68
Node: server1
Agent: 1.1.6

esphome

VMID: 103
IP: 192.168.68.37
Node: server2
Agent: 1.1.6

uptimekuma

VMID: 104
IP: 192.168.68.69
Node: server1
Agent: 1.1.6

vaultwarden

VMID: 104
IP: 192.168.68.50
Node: server2
Agent: 1.1.6

docker

VMID: 105
IP: 192.168.68.42
Node: server1
Agent: 1.1.6

mqtt

VMID: 105
IP: 192.168.68.34
Node: server2
Agent: 1.1.6

mrtg

VMID: 106
IP: 192.168.68.44
Node: server2
Agent: 1.1.6

heimdall

VMID: 107
IP: 192.168.68.52
Node: server1
Agent: 1.1.6

immich

VMID: 107
IP: 192.168.68.66
Node: server2
Agent: 1.1.6

public-web

VMID: 108
IP: 192.168.68.51
Node: server2
Agent: 1.1.6

gitea

VMID: 109
IP: 192.168.68.75
Node: server1
Agent: 1.1.6

webserver

VMID: 109
IP: 192.168.68.57
Node: server2
Agent: 1.1.6

graylog

VMID: 110
IP: 192.168.68.58
Node: server2
Agent: 1.1.6

postgresql

VMID: 111
IP: 192.168.68.73
Node: server1
Agent: 1.1.6

technitiumdns

VMID: 111
IP: 192.168.68.48
Node: server2
Agent: 1.1.6

caddy

VMID: 112
IP: 192.168.68.46
Node: server2
Agent: 1.1.6

zabbix

VMID: 113
IP: 192.168.68.62
Node: server1
Agent: 1.1.6

nginx

VMID: 113
IP: 192.168.68.49
Node: server2
Agent: 1.1.6

nextcloud

VMID: 114
IP: 192.168.68.53
Node: server2
Agent: 1.1.6

nagios

VMID: 115
IP: 192.168.68.65
Node: server1
Agent: 1.1.6

public-web-13

VMID: 115
IP: 192.168.68.47
Node: server2
Agent: 1.1.6

frigate

VMID: 116
IP: 192.168.68.59
Node: server1
Agent: 1.1.6

inventree

VMID: 116
IP: 192.168.68.71
Node: server2
Agent: 1.1.6

docker-nr

VMID: 117
IP: 192.168.68.33
Node: server2
Agent: 1.1.6

parts-db

VMID: 118
IP: 192.168.68.63
Node: server2
Agent: 1.1.6

omada

VMID: 119
IP: 192.168.68.43
Node: server1
Agent: 1.1.6

obico

VMID: 119
IP: 192.168.72.65
Node: server2
Agent: 1.1.6

Latest Agent Script Preview (v1.1.6)

This is the exact script content being pushed to your containers' /opt/tiny_agent/tiny_agent.sh path.

#!/bin/bash
# Tiny Asset Reporting Agent for LXC Containers
# Designed for periodic execution via Cron.

# --- Configuration ---
AGENT_VERSION="1.1.6"
REPORT_URL="http://asset-manager.jnetinc.com/collect_assets.php"
PROXMOX_NODE="DUMMY_NODE" # INJECTED FROM DB
VMID="000"         # INJECTED FROM DB

REPORT_FILE="/tmp/asset_report.json"
AGENT_DIR="/opt/tiny_agent"
AGENT_SCRIPT="$AGENT_DIR/tiny_agent.sh"
NODE_NAME=$(hostname -s | tr '[:upper:]' '[:lower:]')

# --- Helper Functions ---

get_asset_type() {
    echo "lxc_container"
}

get_status() {
    # If the script runs, the status must be 'running'
    echo "running"
}

get_cpu_cores() {
    nproc
}

get_max_memory_mib() {
    # Total RAM in MiB. Use AWK to calculate and round to the nearest MiB integer.
    awk '/MemTotal/ {print int($2/1024 + 0.5)}' /proc/meminfo
}

get_max_disk_gb() {
    # Root partition size in GiB
    df -BG --output=size / | tail -1 | tr -d 'G'
}

get_root_used() {
    df -BG --output=pcent / | tail -1 | tr -d '%' | awk '{print $1/100}'
}

get_os_name() {
    # Get OS Name and Version (e.g., Ubuntu 22.04)
    if [ -f /etc/os-release ]; then
        . /etc/os-release
        echo "$PRETTY_NAME"
    else
        echo "Linux"
    fi
}

get_ip_address() {
    # Get the primary IP address, excluding loopback and common internal ranges
    ip addr show | grep 'inet ' | grep -v '127.0.0.1' | grep -v 'inet 172.17' | awk '{print $2}' | cut -d/ -f1 | head -n 1
}

get_kernel_version() {
    uname -r
}

get_last_pkg_update() {
    local LOG_FILES="/var/log/apt/history.log /var/log/apt/history.log.*"
    
    # Look specifically for 'upgrade' commands (includes full-upgrade)
    local LAST_UPDATE_LINE=$(zgrep -h -a -B 1 '^Commandline: .*upgrade' $LOG_FILES 2>/dev/null | \
                            grep '^Start-Date: ' | \
                            sort -k 2 | \
                            tail -1)

    if [ -n "$LAST_UPDATE_LINE" ]; then
        # Example line: Start-Date: 2023-10-27  12:30:00
        echo "$LAST_UPDATE_LINE" | awk '{print $2}'
    else
        echo "2025-01-01 00:00:00" # No full system upgrade found
    fi
}

run_get_agent_version() {
    "$AGENT_SCRIPT" "get_version"
}

# --- Main Logic ---
generate_report() {
    local DATA_JSON=$(cat << EOF
{
    "source_proxmox_node": "$PROXMOX_NODE",
    "vmid": $VMID,
    "hostname": "$(hostname -s)",
    "asset_type": "$(get_asset_type)",
    "status": "$(get_status)",
    "cpu_cores": $(get_cpu_cores),
    "maxmem_mib": $(get_max_memory_mib),
    "maxdisk_gb": $(get_max_disk_gb),
    "os_name": "$(get_os_name)",
    "ip_address": "$(get_ip_address)",
    "kernel_version": "$(get_kernel_version)",
    "last_pkg_update": "$(get_last_pkg_update)",
    "root_used": "$(get_root_used)",
    "agent_version": "$(run_get_agent_version)"
}
EOF
)
    echo "$DATA_JSON" > "$REPORT_FILE"
}

send_report() {
    if [ ! -f "$REPORT_FILE" ]; then
        echo "Error: Report file not found."
        exit 1
    fi

    local RESPONSE=$(curl -s -X POST -H "Content-Type: application/json" --data @"$REPORT_FILE" "$REPORT_URL")
    if [ $? -eq 0 ]; then
        echo "Report sent successfully."
    else
        echo "Error: Failed to send report."
    fi
}


run_agent() {
    generate_report
    send_report
}

# --- Installation / Execution Entry Point ---
install_agent() {
    # 1. Setup variables
    local CRON_JOB="0 * * * * $AGENT_SCRIPT run_agent >/dev/null 2>&1"
    
    echo "Starting agent installation (v$AGENT_VERSION)..."

    # 2. Set permissions (The file is already written by the updater's tee command)
    echo "Setting execution permissions."
    # Use sudo to ensure permissions are set correctly on the root-owned file
    sudo chmod +x "$AGENT_SCRIPT" 

    # 3. Add/Update Cron job
    echo "Checking/replacing crontab entry."
    
    # Remove existing job if it exists (using grep to find any line referencing the script)
    (sudo crontab -l 2>/dev/null | grep -v "$AGENT_SCRIPT") | sudo crontab -

    # Add the new job
    (sudo crontab -l 2>/dev/null; echo "$CRON_JOB") | sudo crontab -
    
    echo "Installation complete. Cron job set to run hourly."
    echo "Run agent now with: $AGENT_SCRIPT run_agent"

    sudo "$AGENT_SCRIPT" "run_agent"
}

get_agent_version() {
    echo "$AGENT_VERSION"
}

case "$1" in
    install)
        install_agent
        ;;
    run_agent)
        run_agent
        ;;
    get_version)
        get_agent_version
        ;;
    *)
        echo "Usage: $0 {install|run_agent}"
        exit 1
        ;;
esac