Fix: Agent-Rollout downloadete immer globale AGENT_VERSION statt Gruppen-Ziel (v2.5.0)

- downloadSetup() nutzte process.env.AGENT_VERSION statt der Patch-Gruppen-
  Zielversion → Staged Rollout (Test/Pilot/Produktion) hatte nie funktioniert,
  jeder Agent bekam beim Auto-Update immer dieselbe globale Version
- Fix: downloadSetup() löst jetzt per ?hostname=X die Gruppen-Zielversion auf,
  exakt wie checkin() es bereits tat
- ApiService.DownloadSetupAsync() schickt jetzt den Hostnamen mit
- Version: 2.4.0 → 2.5.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-19 09:35:01 +02:00
parent 7449b64398
commit e2521f405d
7 changed files with 28 additions and 9 deletions

View File

@@ -6,7 +6,7 @@ namespace ITNexusAgent;
public class AgentWorker public class AgentWorker
{ {
private const string Version = "2.4.0"; private const string Version = "2.5.0";
private const string DataDir = @"C:\ProgramData\IT Nexus Agent"; private const string DataDir = @"C:\ProgramData\IT Nexus Agent";
private const string ConfigPath = @"C:\ProgramData\IT Nexus Agent\config.json"; private const string ConfigPath = @"C:\ProgramData\IT Nexus Agent\config.json";
private const string StatusPath = @"C:\ProgramData\IT Nexus Agent\status.json"; private const string StatusPath = @"C:\ProgramData\IT Nexus Agent\status.json";

View File

@@ -7,8 +7,8 @@
<UseWindowsForms>true</UseWindowsForms> <UseWindowsForms>true</UseWindowsForms>
<AssemblyName>IT-Nexus-Agent</AssemblyName> <AssemblyName>IT-Nexus-Agent</AssemblyName>
<RootNamespace>ITNexusAgent</RootNamespace> <RootNamespace>ITNexusAgent</RootNamespace>
<Version>2.3.0</Version> <Version>2.5.0</Version>
<AssemblyVersion>2.3.0.0</AssemblyVersion> <AssemblyVersion>2.5.0.0</AssemblyVersion>
<Nullable>enable</Nullable> <Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings> <ImplicitUsings>enable</ImplicitUsings>
<AllowUnsafeBlocks>false</AllowUnsafeBlocks> <AllowUnsafeBlocks>false</AllowUnsafeBlocks>

View File

@@ -65,9 +65,9 @@ public class ApiService(string serverUrl, string agentKey)
return await resp.Content.ReadAsByteArrayAsync(); return await resp.Content.ReadAsByteArrayAsync();
} }
public async Task<byte[]> DownloadSetupAsync() public async Task<byte[]> DownloadSetupAsync(string hostname)
{ {
var req = BuildRequest(HttpMethod.Get, "/api/monitoring/agent-setup"); var req = BuildRequest(HttpMethod.Get, $"/api/monitoring/agent-setup?hostname={Uri.EscapeDataString(hostname)}");
var resp = await _http.SendAsync(req); var resp = await _http.SendAsync(req);
resp.EnsureSuccessStatusCode(); resp.EnsureSuccessStatusCode();
return await resp.Content.ReadAsByteArrayAsync(); return await resp.Content.ReadAsByteArrayAsync();

View File

@@ -125,7 +125,7 @@ public class CommandExecutor(ApiService api, string hostname, string dataDir, st
private async Task<string> UpdateAgent() private async Task<string> UpdateAgent()
{ {
var bytes = await _api.DownloadSetupAsync(); var bytes = await _api.DownloadSetupAsync(_hostname);
if (bytes.Length < 512 * 1024) return "Download fehlgeschlagen - Installer zu klein"; if (bytes.Length < 512 * 1024) return "Download fehlgeschlagen - Installer zu klein";
var setupPath = Path.Combine(_dataDir, "IT-Nexus-Agent-Setup-Update.exe"); var setupPath = Path.Combine(_dataDir, "IT-Nexus-Agent-Setup-Update.exe");

View File

@@ -1,5 +1,5 @@
#define MyAppName "IT Nexus Agent" #define MyAppName "IT Nexus Agent"
#define MyAppVersion "2.4.0" #define MyAppVersion "2.5.0"
#define MyAppPublisher "Cereda Systems GmbH" #define MyAppPublisher "Cereda Systems GmbH"
#define MyAppURL "https://it-nexus.cereda-systems.de" #define MyAppURL "https://it-nexus.cereda-systems.de"
#define MyAppExeName "IT-Nexus-Agent.exe" #define MyAppExeName "IT-Nexus-Agent.exe"

View File

@@ -212,7 +212,26 @@ const downloadSetup = asyncHandler(async (req, res) => {
const path = require('path'); const path = require('path');
const fs = require('fs'); const fs = require('fs');
const version = process.env.AGENT_VERSION || '2.0.0';
// Zielversion: Gruppen-spezifisch (staged rollout) oder globaler Default — gleiche Logik wie checkin()
let version = process.env.AGENT_VERSION || '2.0.0';
const hostname = req.query.hostname;
if (hostname) {
try {
const db = getDatabase();
const agent = db.prepare('SELECT id FROM monitoring_agents WHERE hostname = ?').get(hostname);
const groupRow = agent && db.prepare(`
SELECT pg.target_agent_version
FROM patch_agent_groups pag
JOIN patch_groups pg ON pg.id = pag.group_id
WHERE pag.agent_id = ?
ORDER BY pg.sort_order ASC
LIMIT 1
`).get(agent.id);
if (groupRow?.target_agent_version) version = groupRow.target_agent_version;
} catch { /* kein Gruppe zugewiesen → global */ }
}
const setupPath = path.join(__dirname, `../../agent/IT-Nexus-Agent-Setup-v${version}.exe`); const setupPath = path.join(__dirname, `../../agent/IT-Nexus-Agent-Setup-v${version}.exe`);
if (!fs.existsSync(setupPath)) { if (!fs.existsSync(setupPath)) {
return res.status(404).json({ status: 'error', message: 'Setup nicht gefunden' }); return res.status(404).json({ status: 'error', message: 'Setup nicht gefunden' });

View File

@@ -5,7 +5,7 @@ import { useAuth } from '../context/AuthContext';
const ANN_TYPES = { maintenance: { icon: '🔧', label: 'Wartung', color: '#f59e0b' }, warning: { icon: '⚠️', label: 'Warnung', color: '#ef4444' }, info: { icon: '', label: 'Info', color: '#6366f1' } }; const ANN_TYPES = { maintenance: { icon: '🔧', label: 'Wartung', color: '#f59e0b' }, warning: { icon: '⚠️', label: 'Warnung', color: '#ef4444' }, info: { icon: '', label: 'Info', color: '#6366f1' } };
const LATEST_AGENT_VERSION = '2.4.0'; const LATEST_AGENT_VERSION = '2.5.0';
const SEVERITY_LABELS = { critical: 'Kritisch', important: 'Wichtig', moderate: 'Moderat', low: 'Niedrig', all: 'Alle' }; const SEVERITY_LABELS = { critical: 'Kritisch', important: 'Wichtig', moderate: 'Moderat', low: 'Niedrig', all: 'Alle' };
const SEVERITY_COLORS = { critical: '#EF4444', important: '#F59E0B', moderate: '#3B82F6', low: '#6B7280', all: '#0D9488' }; const SEVERITY_COLORS = { critical: '#EF4444', important: '#F59E0B', moderate: '#3B82F6', low: '#6B7280', all: '#0D9488' };
const COMMAND_LABELS = { check_updates: '🔍 Update-Scan', install_updates: '⬇️ Installation', reboot: '🔄 Neustart', upgrade_win11: '🪟 Win 11 Upgrade', update_agent: '⬆️ Agent-Update' }; const COMMAND_LABELS = { check_updates: '🔍 Update-Scan', install_updates: '⬇️ Installation', reboot: '🔄 Neustart', upgrade_win11: '🪟 Win 11 Upgrade', update_agent: '⬆️ Agent-Update' };