feat: overhaul server automation, files editor, and CS2 setup workflows
This commit is contained in:
@@ -5,6 +5,11 @@ import { nodes, allocations, servers, games } from '@source/database';
|
||||
import { AppError } from '../../lib/errors.js';
|
||||
import { requirePermission } from '../../lib/permissions.js';
|
||||
import { createAuditLog } from '../../lib/audit.js';
|
||||
import {
|
||||
daemonGetNodeStats,
|
||||
daemonGetNodeStatus,
|
||||
type DaemonNodeConnection,
|
||||
} from '../../lib/daemon.js';
|
||||
import {
|
||||
NodeParamSchema,
|
||||
CreateNodeSchema,
|
||||
@@ -155,7 +160,7 @@ export default async function nodeRoutes(app: FastifyInstance) {
|
||||
});
|
||||
|
||||
// GET /api/organizations/:orgId/nodes/:nodeId/stats
|
||||
// Returns basic stats from DB; real-time stats come from daemon via gRPC
|
||||
// Returns real-time stats from daemon when available, with DB fallback.
|
||||
app.get('/:nodeId/stats', { schema: NodeParamSchema }, async (request) => {
|
||||
const { orgId, nodeId } = request.params as { orgId: string; nodeId: string };
|
||||
await requirePermission(request, orgId, 'node.read');
|
||||
@@ -171,17 +176,54 @@ export default async function nodeRoutes(app: FastifyInstance) {
|
||||
.where(eq(servers.nodeId, nodeId));
|
||||
|
||||
const totalServers = serverList.length;
|
||||
const activeServers = serverList.filter((s) => s.status === 'running').length;
|
||||
let activeServers = serverList.filter((s) => s.status === 'running').length;
|
||||
let cpuPercent = 0;
|
||||
let memoryUsed = 0;
|
||||
let memoryTotal = node.memoryTotal;
|
||||
let diskUsed = 0;
|
||||
let diskTotal = node.diskTotal;
|
||||
let uptime = 0;
|
||||
|
||||
const daemonNode: DaemonNodeConnection = {
|
||||
fqdn: node.fqdn,
|
||||
grpcPort: node.grpcPort,
|
||||
daemonToken: node.daemonToken,
|
||||
};
|
||||
|
||||
try {
|
||||
const [liveStats, liveStatus] = await Promise.all([
|
||||
daemonGetNodeStats(daemonNode),
|
||||
daemonGetNodeStatus(daemonNode),
|
||||
]);
|
||||
|
||||
cpuPercent = Number.isFinite(liveStats.cpuPercent)
|
||||
? Math.max(0, Math.min(100, liveStats.cpuPercent))
|
||||
: 0;
|
||||
memoryUsed = Math.max(0, liveStats.memoryUsed);
|
||||
memoryTotal = liveStats.memoryTotal > 0 ? liveStats.memoryTotal : node.memoryTotal;
|
||||
diskUsed = Math.max(0, liveStats.diskUsed);
|
||||
diskTotal = liveStats.diskTotal > 0 ? liveStats.diskTotal : node.diskTotal;
|
||||
uptime = Math.max(0, liveStatus.uptimeSeconds);
|
||||
|
||||
if (Number.isFinite(liveStatus.activeServers)) {
|
||||
activeServers = Math.max(0, Math.min(totalServers, liveStatus.activeServers));
|
||||
}
|
||||
} catch (error) {
|
||||
request.log.warn(
|
||||
{ error, nodeId, orgId },
|
||||
'Failed to fetch live node stats from daemon, returning fallback values',
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
cpuPercent: 0,
|
||||
memoryUsed: 0,
|
||||
memoryTotal: node.memoryTotal,
|
||||
diskUsed: 0,
|
||||
diskTotal: node.diskTotal,
|
||||
cpuPercent,
|
||||
memoryUsed,
|
||||
memoryTotal,
|
||||
diskUsed,
|
||||
diskTotal,
|
||||
activeServers,
|
||||
totalServers,
|
||||
uptime: 0,
|
||||
uptime,
|
||||
};
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user