From 5f37e28046bd593443e07b5d3f5e7f3add1ce996 Mon Sep 17 00:00:00 2001 From: cynfo3000 Date: Tue, 3 Mar 2026 23:13:32 +0100 Subject: [PATCH] install.sh: auto-download from backend, InstallGuide component for frontend dialogs --- frontend/src/components/InstallGuide.jsx | 220 +++++++++++++++++++++++ frontend/src/pages/Agents.jsx | 71 +------- frontend/src/pages/ProxmoxServers.jsx | 113 +----------- opnsense-plugin/install.sh | 40 +++-- 4 files changed, 258 insertions(+), 186 deletions(-) create mode 100644 frontend/src/components/InstallGuide.jsx diff --git a/frontend/src/components/InstallGuide.jsx b/frontend/src/components/InstallGuide.jsx new file mode 100644 index 0000000..43ae278 --- /dev/null +++ b/frontend/src/components/InstallGuide.jsx @@ -0,0 +1,220 @@ +import { useState } from 'react' +import { Copy, Check, Terminal, Monitor } from 'lucide-react' + +const BACKEND_URL = 'https://192.168.85.13:8443' +const API_KEY = '01532e5a7c9e70bf2757df77a2f5b9b9' +const INSTALL_SH_URL = 'https://git.cynfo.net/christian/rmm/raw/branch/main/opnsense-plugin/install.sh' + +export default function InstallGuide({ agentName, platform: initialPlatform }) { + const [platform, setPlatform] = useState(initialPlatform || 'freebsd') + const [copied, setCopied] = useState(null) + + const copyText = (text, id) => { + navigator.clipboard.writeText(text) + setCopied(id) + setTimeout(() => setCopied(null), 2000) + } + + const CopyBtn = ({ text, id, className = '' }) => ( + + ) + + const CodeBlock = ({ text, id }) => ( +
+
+        {text}
+      
+ +
+ ) + + const ConfigValue = ({ label, value, id, mono = false }) => ( +
+
+ {label} +
{value}
+
+ +
+ ) + + const opnInstallCmd = `fetch -o /tmp/install.sh "${INSTALL_SH_URL}" && sh /tmp/install.sh` + + const linuxInstallCmd = `#!/bin/sh +# RMM Agent + Updater Installation +set -e + +BACKEND="${BACKEND_URL}" +API_KEY="${API_KEY}" +NAME="${agentName || ''}" + +# Download +wget --no-check-certificate -O /tmp/rmm-bundle.zip \\ + "$BACKEND/api/v1/firmware/download?platform=linux&api_key=$API_KEY" +cd /tmp && unzip -o rmm-bundle.zip + +# Install binaries +install -m 755 /tmp/rmm-agent-linux /usr/local/bin/rmm-agent +install -m 755 /tmp/rmm-updater-linux /usr/local/bin/rmm-updater +mkdir -p /etc/rmm + +# Config +cat > /etc/rmm/config.yaml << EOF +backend_url: "$BACKEND" +api_key: "$API_KEY" +agent_name: "$NAME" +interval_seconds: 60 +insecure: true +EOF + +# Systemd services +cat > /etc/systemd/system/rmm-agent.service << EOF +[Unit] +Description=RMM Agent +After=network.target +[Service] +Type=simple +ExecStart=/usr/local/bin/rmm-agent +Restart=always +RestartSec=10 +[Install] +WantedBy=multi-user.target +EOF + +cat > /etc/systemd/system/rmm-updater.service << EOF +[Unit] +Description=RMM Updater +After=network.target +[Service] +Type=simple +ExecStart=/usr/local/bin/rmm-updater +Restart=always +RestartSec=30 +[Install] +WantedBy=multi-user.target +EOF + +systemctl daemon-reload +systemctl enable --now rmm-agent rmm-updater +echo "Fertig! Agent verbindet sich automatisch mit Backend." +` + + return ( +
+ {/* Platform Tabs */} + {!initialPlatform && ( +
+ + +
+ )} + + {platform === 'freebsd' ? ( +
+ {/* Step 1: Install Plugin */} +
+

+ 1 + Plugin installieren +

+

Per SSH oder WebGUI-Shell auf der Firewall ausfuehren:

+
+ +
+
+ + {/* Step 2: Configure via WebGUI */} +
+

+ 2 + Im WebGUI konfigurieren +

+

+ Services > RMM Agent > folgende Werte eintragen: +

+
+ + + '} id="opn-name" /> +
+
+ + {/* Step 3: Enable + Start */} +
+

+ 3 + Aktivieren und starten +

+

+ "Enabled" aktivieren, "Save & Apply", dann "Restart Service". + Der Agent verbindet sich automatisch. +

+
+
+ ) : ( +
+ {/* Linux: Single script */} +
+

+ 1 + Installscript ausfuehren +

+

Als root auf dem Server ausfuehren. Script kopieren, als Datei speichern und starten:

+
+ +
+
+ + {/* Config values for reference */} +
+

+ 2 + Konfigurationswerte (Referenz) +

+
+ + + '} id="linux-name" /> + +
+
+
+ )} + +

+ Der Agent meldet sich nach Installation automatisch beim Backend. Name und IP werden beim ersten Heartbeat uebernommen. +

+
+ ) +} diff --git a/frontend/src/pages/Agents.jsx b/frontend/src/pages/Agents.jsx index c6ee58e..a5a8430 100644 --- a/frontend/src/pages/Agents.jsx +++ b/frontend/src/pages/Agents.jsx @@ -2,7 +2,8 @@ import { useEffect, useState, useMemo } from 'react' import api from '../api/client' import StatusBadge from '../components/StatusBadge' import AgentPanel from '../components/AgentPanel' -import { Search, ChevronUp, ChevronDown, Plus, Copy, Check, X } from 'lucide-react' +import { Search, ChevronUp, ChevronDown, Plus, X } from 'lucide-react' +import InstallGuide from '../components/InstallGuide' export default function Agents() { const [agents, setAgents] = useState([]) @@ -276,10 +277,6 @@ function AddDeviceDialog({ customers, result, onAdd, onClose }) { const [custId, setCustId] = useState('') const [error, setError] = useState('') const [submitting, setSubmitting] = useState(false) - const [copied, setCopied] = useState(null) - - const BACKEND_URL = 'https://192.168.85.13:8443' - const API_KEY = '01532e5a7c9e70bf2757df77a2f5b9b9' const handleSubmit = async () => { if (!name.trim()) { setError('Name ist erforderlich'); return } @@ -293,39 +290,9 @@ function AddDeviceDialog({ customers, result, onAdd, onClose }) { setSubmitting(false) } - const copyText = (text, id) => { - navigator.clipboard.writeText(text) - setCopied(id) - setTimeout(() => setCopied(null), 2000) - } - - const CopyBtn = ({ text, id }) => ( - - ) - - const installCmd = `# Vom Mac Studio aus ausfuehren: - -# 1. Ins RMM-Verzeichnis wechseln: -cd /Users/cynfo/.openclaw/workspace/rmm - -# 2. Agent + Updater + Installer auf das Geraet kopieren: -scp build/rmm-agent build/rmm-updater root@:/tmp/ -scp opnsense-plugin/install.sh root@:/tmp/ - -# 3. Installation starten: -ssh root@ '/bin/sh /tmp/install.sh' - -# 4. Im OPNsense WebGUI unter Services > RMM Agent: -# Backend URL: ${BACKEND_URL} -# API Key: ${API_KEY} -# Agent Name: ${name || ''} -# -> Save & Apply` - return (
-
e.stopPropagation()}> +
e.stopPropagation()}>

Geraet hinzufuegen

@@ -373,37 +340,7 @@ ssh root@ '/bin/sh /tmp/install.sh'
Geraet "{result.name}" erfolgreich angelegt (ID: {result.id?.substring(0, 12)}...)
- -
-

Installationsanleitung

-
- {installCmd} - -
-
- -
-
- Backend URL: - {BACKEND_URL} - -
-
- API Key: - {API_KEY} - -
-
- -

- Der Agent verbindet sich nach der Installation automatisch mit dem Backend. - Hostname und IP werden beim ersten Heartbeat aktualisiert. -

+ )}
diff --git a/frontend/src/pages/ProxmoxServers.jsx b/frontend/src/pages/ProxmoxServers.jsx index f23f297..f5ae076 100644 --- a/frontend/src/pages/ProxmoxServers.jsx +++ b/frontend/src/pages/ProxmoxServers.jsx @@ -2,7 +2,8 @@ import { useEffect, useState, useMemo } from 'react' import api from '../api/client' import StatusBadge from '../components/StatusBadge' import ProxmoxPanel from '../components/ProxmoxPanel' -import { Search, ChevronUp, ChevronDown, Plus, Copy, Check, X } from 'lucide-react' +import { Search, ChevronUp, ChevronDown, Plus, X } from 'lucide-react' +import InstallGuide from '../components/InstallGuide' export default function ProxmoxServers() { const [agents, setAgents] = useState([]) @@ -273,10 +274,6 @@ function AddServerDialog({ customers, result, onAdd, onClose }) { const [custId, setCustId] = useState('') const [error, setError] = useState('') const [submitting, setSubmitting] = useState(false) - const [copied, setCopied] = useState(null) - - const BACKEND_URL = 'https://192.168.85.13:8443' - const API_KEY = '01532e5a7c9e70bf2757df77a2f5b9b9' const handleSubmit = async () => { if (!name.trim()) { setError('Name ist erforderlich'); return } @@ -290,81 +287,9 @@ function AddServerDialog({ customers, result, onAdd, onClose }) { setSubmitting(false) } - const copyText = (text, id) => { - navigator.clipboard.writeText(text) - setCopied(id) - setTimeout(() => setCopied(null), 2000) - } - - const CopyBtn = ({ text, id }) => ( - - ) - - const installCmd = `# Proxmox/Linux Server Installation: - -# 1. Agent + Updater auf den Server kopieren: -scp build/rmm-agent-linux build/rmm-updater-linux root@:/tmp/ - -# 2. Installation auf dem Server: -ssh root@ 'bash -s' << 'INSTALL' - mkdir -p /usr/local/bin /etc/rmm - - cp /tmp/rmm-agent-linux /usr/local/bin/rmm-agent - cp /tmp/rmm-updater-linux /usr/local/bin/rmm-updater - chmod +x /usr/local/bin/rmm-agent /usr/local/bin/rmm-updater - - # Config erstellen: - cat > /etc/rmm/config.yaml << EOF -backend_url: ${BACKEND_URL} -api_key: ${API_KEY} -agent_name: ${name || ''} -heartbeat_interval: 30 -insecure: true -EOF - - # Agent Service: - cat > /etc/systemd/system/rmm-agent.service << EOF -[Unit] -Description=RMM Agent -After=network.target - -[Service] -Type=simple -User=root -ExecStart=/usr/local/bin/rmm-agent -Restart=always -RestartSec=10 - -[Install] -WantedBy=multi-user.target -EOF - - # Updater Service: - cat > /etc/systemd/system/rmm-updater.service << EOF -[Unit] -Description=RMM Updater -After=network.target - -[Service] -Type=simple -User=root -ExecStart=/usr/local/bin/rmm-updater -Restart=always -RestartSec=30 - -[Install] -WantedBy=multi-user.target -EOF - - systemctl daemon-reload - systemctl enable --now rmm-agent rmm-updater -INSTALL` - return (
-
e.stopPropagation()}> +
e.stopPropagation()}>

Server hinzufuegen

@@ -412,37 +337,7 @@ INSTALL`
Server "{result.name}" erfolgreich angelegt (ID: {result.id?.substring(0, 12)}...)
- -
-

Installationsanleitung

-
- {installCmd} - -
-
- -
-
- Backend URL: - {BACKEND_URL} - -
-
- API Key: - {API_KEY} - -
-
- -

- Der Agent verbindet sich nach der Installation automatisch mit dem Backend. - Hostname und IP werden beim ersten Heartbeat aktualisiert. -

+ )}
diff --git a/opnsense-plugin/install.sh b/opnsense-plugin/install.sh index 34ee55b..b34f84f 100755 --- a/opnsense-plugin/install.sh +++ b/opnsense-plugin/install.sh @@ -2,12 +2,13 @@ # # RMM Agent Plugin Installer fuer OPNsense # -# Usage: -# scp install.sh rmm-agent root@opnsense:/tmp/ -# ssh root@opnsense '/bin/sh /tmp/install.sh' +# Usage (automatischer Download): +# fetch -o /tmp/install.sh "https://git.cynfo.net/christian/rmm/raw/branch/main/opnsense-plugin/install.sh" +# sh /tmp/install.sh # -# Oder remote: -# cat install.sh | ssh root@opnsense '/bin/sh' +# Oder mit lokalen Binaries: +# scp install.sh rmm-agent rmm-updater-freebsd root@opnsense:/tmp/ +# ssh root@opnsense '/bin/sh /tmp/install.sh' # set -e @@ -15,17 +16,36 @@ set -e BASEDIR="/tmp" BINARY="${BASEDIR}/rmm-agent" UPDATER_BINARY="${BASEDIR}/rmm-updater" +BACKEND_URL="https://192.168.85.13:8443" +API_KEY="01532e5a7c9e70bf2757df77a2f5b9b9" echo "========================================" echo " RMM Agent Plugin Installer" echo "========================================" -# Pruefen ob Binary vorhanden +# Binaries herunterladen wenn nicht lokal vorhanden if [ ! -f "${BINARY}" ]; then - echo "FEHLER: ${BINARY} nicht gefunden." - echo "Bitte vorher das Binary kopieren:" - echo " scp rmm-agent root@opnsense:/tmp/" - exit 1 + echo "[*] Binaries nicht lokal gefunden — lade vom Backend..." + /usr/local/bin/fetch --no-verify-peer -o "${BASEDIR}/rmm-bundle.zip" \ + "${BACKEND_URL}/api/v1/firmware/download?platform=freebsd&api_key=${API_KEY}" + if [ ! -f "${BASEDIR}/rmm-bundle.zip" ]; then + echo "FEHLER: Download fehlgeschlagen." + echo "Pruefe Backend-Erreichbarkeit: ${BACKEND_URL}" + exit 1 + fi + cd "${BASEDIR}" + unzip -o rmm-bundle.zip 2>/dev/null || true + # ZIP enthaelt rmm-agent und rmm-updater-freebsd + if [ -f "${BASEDIR}/rmm-updater-freebsd" ] && [ ! -f "${UPDATER_BINARY}" ]; then + mv "${BASEDIR}/rmm-updater-freebsd" "${UPDATER_BINARY}" + fi + rm -f rmm-bundle.zip + echo " Download OK" + if [ ! -f "${BINARY}" ]; then + echo "FEHLER: ${BINARY} nach Download nicht vorhanden." + echo "Firmware-ZIP muss 'rmm-agent' enthalten." + exit 1 + fi fi # Alten Agent stoppen falls vorhanden