Added server initiated Agent update

This commit is contained in:
Muhammad Ibrahim
2025-10-28 21:49:19 +00:00
parent 77a945a5b6
commit 79317b0052
10 changed files with 133 additions and 1 deletions

View File

@@ -1430,6 +1430,69 @@ router.patch(
},
);
// Force agent update for specific host
router.post(
"/:hostId/force-agent-update",
authenticateToken,
requireManageHosts,
async (req, res) => {
try {
const { hostId } = req.params;
// Get host to verify it exists
const host = await prisma.hosts.findUnique({
where: { id: hostId },
});
if (!host) {
return res.status(404).json({ error: "Host not found" });
}
// Get queue manager
const { QUEUE_NAMES } = require("../services/automation");
const queueManager = req.app.locals.queueManager;
if (!queueManager) {
return res.status(500).json({
error: "Queue manager not available",
});
}
// Get the agent-commands queue
const queue = queueManager.queues[QUEUE_NAMES.AGENT_COMMANDS];
// Add job to queue
await queue.add(
"update_agent",
{
api_id: host.api_id,
type: "update_agent",
},
{
attempts: 3,
backoff: {
type: "exponential",
delay: 2000,
},
},
);
res.json({
success: true,
message: "Agent update queued successfully",
host: {
id: host.id,
friendlyName: host.friendly_name,
apiId: host.api_id,
},
});
} catch (error) {
console.error("Force agent update error:", error);
res.status(500).json({ error: "Failed to force agent update" });
}
},
);
// Serve the installation script (requires API authentication)
router.get("/install", async (req, res) => {
try {

View File

@@ -176,6 +176,15 @@ function pushSettingsUpdate(apiId, newInterval) {
);
}
function pushUpdateAgent(apiId) {
const ws = apiIdToSocket.get(apiId);
safeSend(ws, JSON.stringify({ type: "update_agent" }));
}
function getConnectionByApiId(apiId) {
return apiIdToSocket.get(apiId);
}
function pushUpdateNotification(apiId, updateInfo) {
const ws = apiIdToSocket.get(apiId);
if (ws && ws.readyState === WebSocket.OPEN) {
@@ -330,10 +339,12 @@ module.exports = {
broadcastSettingsUpdate,
pushReportNow,
pushSettingsUpdate,
pushUpdateAgent,
pushUpdateNotification,
pushUpdateNotificationToAll,
// Expose read-only view of connected agents
getConnectedApiIds: () => Array.from(apiIdToSocket.keys()),
getConnectionByApiId,
isConnected: (apiId) => {
const ws = apiIdToSocket.get(apiId);
return !!ws && ws.readyState === WebSocket.OPEN;

View File

@@ -190,6 +190,19 @@ class QueueManager {
// For settings update, we need additional data
const { update_interval } = job.data;
agentWs.pushSettingsUpdate(api_id, update_interval);
} else if (type === "update_agent") {
// Force agent to update by sending WebSocket command
const ws = agentWs.getConnectionByApiId(api_id);
if (ws && ws.readyState === 1) {
// WebSocket.OPEN
agentWs.pushUpdateAgent(api_id);
console.log(`✅ Update command sent to agent ${api_id}`);
} else {
console.error(`❌ Agent ${api_id} is not connected`);
throw new Error(
`Agent ${api_id} is not connected. Cannot send update command.`,
);
}
} else {
console.error(`Unknown agent command type: ${type}`);
}