@calltelemetry/ct-lab-mcp 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +309 -0
- package/dist/bin/ct-lab-mcp.d.ts +60 -0
- package/dist/bin/ct-lab-mcp.d.ts.map +1 -0
- package/dist/bin/ct-lab-mcp.js +261 -0
- package/dist/bin/ct-lab-mcp.js.map +1 -0
- package/dist/bin/proxmox-mcp.d.ts +58 -0
- package/dist/bin/proxmox-mcp.d.ts.map +1 -0
- package/dist/bin/proxmox-mcp.js +248 -0
- package/dist/bin/proxmox-mcp.js.map +1 -0
- package/dist/src/appliance/commands.d.ts +33 -0
- package/dist/src/appliance/commands.d.ts.map +1 -0
- package/dist/src/appliance/commands.js +241 -0
- package/dist/src/appliance/commands.js.map +1 -0
- package/dist/src/appliance/executor.d.ts +34 -0
- package/dist/src/appliance/executor.d.ts.map +1 -0
- package/dist/src/appliance/executor.js +214 -0
- package/dist/src/appliance/executor.js.map +1 -0
- package/dist/src/appliance/index.d.ts +8 -0
- package/dist/src/appliance/index.d.ts.map +1 -0
- package/dist/src/appliance/index.js +8 -0
- package/dist/src/appliance/index.js.map +1 -0
- package/dist/src/appliance/mock.d.ts +66 -0
- package/dist/src/appliance/mock.d.ts.map +1 -0
- package/dist/src/appliance/mock.js +339 -0
- package/dist/src/appliance/mock.js.map +1 -0
- package/dist/src/appliance/types.d.ts +83 -0
- package/dist/src/appliance/types.d.ts.map +1 -0
- package/dist/src/appliance/types.js +58 -0
- package/dist/src/appliance/types.js.map +1 -0
- package/dist/src/credentials/doppler.d.ts +25 -0
- package/dist/src/credentials/doppler.d.ts.map +1 -0
- package/dist/src/credentials/doppler.js +68 -0
- package/dist/src/credentials/doppler.js.map +1 -0
- package/dist/src/credentials/index.d.ts +4 -0
- package/dist/src/credentials/index.d.ts.map +1 -0
- package/dist/src/credentials/index.js +4 -0
- package/dist/src/credentials/index.js.map +1 -0
- package/dist/src/credentials/resolver.d.ts +36 -0
- package/dist/src/credentials/resolver.d.ts.map +1 -0
- package/dist/src/credentials/resolver.js +427 -0
- package/dist/src/credentials/resolver.js.map +1 -0
- package/dist/src/credentials/types.d.ts +73 -0
- package/dist/src/credentials/types.d.ts.map +1 -0
- package/dist/src/credentials/types.js +5 -0
- package/dist/src/credentials/types.js.map +1 -0
- package/dist/src/guardrails/index.d.ts +3 -0
- package/dist/src/guardrails/index.d.ts.map +1 -0
- package/dist/src/guardrails/index.js +3 -0
- package/dist/src/guardrails/index.js.map +1 -0
- package/dist/src/guardrails/safety.d.ts +45 -0
- package/dist/src/guardrails/safety.d.ts.map +1 -0
- package/dist/src/guardrails/safety.js +217 -0
- package/dist/src/guardrails/safety.js.map +1 -0
- package/dist/src/guardrails/types.d.ts +36 -0
- package/dist/src/guardrails/types.d.ts.map +1 -0
- package/dist/src/guardrails/types.js +20 -0
- package/dist/src/guardrails/types.js.map +1 -0
- package/dist/src/hypervisors/esxi/client.d.ts +103 -0
- package/dist/src/hypervisors/esxi/client.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/client.js +395 -0
- package/dist/src/hypervisors/esxi/client.js.map +1 -0
- package/dist/src/hypervisors/esxi/mock.d.ts +45 -0
- package/dist/src/hypervisors/esxi/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/esxi/mock.js +202 -0
- package/dist/src/hypervisors/esxi/mock.js.map +1 -0
- package/dist/src/hypervisors/index.d.ts +10 -0
- package/dist/src/hypervisors/index.d.ts.map +1 -0
- package/dist/src/hypervisors/index.js +10 -0
- package/dist/src/hypervisors/index.js.map +1 -0
- package/dist/src/hypervisors/manager.d.ts +78 -0
- package/dist/src/hypervisors/manager.d.ts.map +1 -0
- package/dist/src/hypervisors/manager.js +415 -0
- package/dist/src/hypervisors/manager.js.map +1 -0
- package/dist/src/hypervisors/proxmox/client.d.ts +29 -0
- package/dist/src/hypervisors/proxmox/client.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/client.js +278 -0
- package/dist/src/hypervisors/proxmox/client.js.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts +17 -0
- package/dist/src/hypervisors/proxmox/mock.d.ts.map +1 -0
- package/dist/src/hypervisors/proxmox/mock.js +26 -0
- package/dist/src/hypervisors/proxmox/mock.js.map +1 -0
- package/dist/src/hypervisors/types.d.ts +159 -0
- package/dist/src/hypervisors/types.d.ts.map +1 -0
- package/dist/src/hypervisors/types.js +6 -0
- package/dist/src/hypervisors/types.js.map +1 -0
- package/dist/src/index.d.ts +19 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +19 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/proxmox/client.d.ts +37 -0
- package/dist/src/proxmox/client.d.ts.map +1 -0
- package/dist/src/proxmox/client.js +282 -0
- package/dist/src/proxmox/client.js.map +1 -0
- package/dist/src/proxmox/index.d.ts +53 -0
- package/dist/src/proxmox/index.d.ts.map +1 -0
- package/dist/src/proxmox/index.js +109 -0
- package/dist/src/proxmox/index.js.map +1 -0
- package/dist/src/proxmox/mock.d.ts +40 -0
- package/dist/src/proxmox/mock.d.ts.map +1 -0
- package/dist/src/proxmox/mock.js +362 -0
- package/dist/src/proxmox/mock.js.map +1 -0
- package/dist/src/proxmox/poller.d.ts +29 -0
- package/dist/src/proxmox/poller.d.ts.map +1 -0
- package/dist/src/proxmox/poller.js +107 -0
- package/dist/src/proxmox/poller.js.map +1 -0
- package/dist/src/server/index.d.ts +2 -0
- package/dist/src/server/index.d.ts.map +1 -0
- package/dist/src/server/index.js +2 -0
- package/dist/src/server/index.js.map +1 -0
- package/dist/src/server/mcp-server.d.ts +5 -0
- package/dist/src/server/mcp-server.d.ts.map +1 -0
- package/dist/src/server/mcp-server.js +5 -0
- package/dist/src/server/mcp-server.js.map +1 -0
- package/dist/src/server.d.ts +35 -0
- package/dist/src/server.d.ts.map +1 -0
- package/dist/src/server.js +95 -0
- package/dist/src/server.js.map +1 -0
- package/dist/src/slot/gc.d.ts +42 -0
- package/dist/src/slot/gc.d.ts.map +1 -0
- package/dist/src/slot/gc.js +79 -0
- package/dist/src/slot/gc.js.map +1 -0
- package/dist/src/slot/index.d.ts +4 -0
- package/dist/src/slot/index.d.ts.map +1 -0
- package/dist/src/slot/index.js +4 -0
- package/dist/src/slot/index.js.map +1 -0
- package/dist/src/slot/manager.d.ts +92 -0
- package/dist/src/slot/manager.d.ts.map +1 -0
- package/dist/src/slot/manager.js +650 -0
- package/dist/src/slot/manager.js.map +1 -0
- package/dist/src/slot/types.d.ts +184 -0
- package/dist/src/slot/types.d.ts.map +1 -0
- package/dist/src/slot/types.js +67 -0
- package/dist/src/slot/types.js.map +1 -0
- package/dist/src/tools/appliance-exec.d.ts +81 -0
- package/dist/src/tools/appliance-exec.d.ts.map +1 -0
- package/dist/src/tools/appliance-exec.js +134 -0
- package/dist/src/tools/appliance-exec.js.map +1 -0
- package/dist/src/tools/claim-slot.d.ts +5 -0
- package/dist/src/tools/claim-slot.d.ts.map +1 -0
- package/dist/src/tools/claim-slot.js +5 -0
- package/dist/src/tools/claim-slot.js.map +1 -0
- package/dist/src/tools/index.d.ts +26 -0
- package/dist/src/tools/index.d.ts.map +1 -0
- package/dist/src/tools/index.js +63 -0
- package/dist/src/tools/index.js.map +1 -0
- package/dist/src/tools/list-hosts.d.ts +41 -0
- package/dist/src/tools/list-hosts.d.ts.map +1 -0
- package/dist/src/tools/list-hosts.js +91 -0
- package/dist/src/tools/list-hosts.js.map +1 -0
- package/dist/src/tools/list-inventory.d.ts +50 -0
- package/dist/src/tools/list-inventory.d.ts.map +1 -0
- package/dist/src/tools/list-inventory.js +112 -0
- package/dist/src/tools/list-inventory.js.map +1 -0
- package/dist/src/tools/list-slots.d.ts +5 -0
- package/dist/src/tools/list-slots.d.ts.map +1 -0
- package/dist/src/tools/list-slots.js +5 -0
- package/dist/src/tools/list-slots.js.map +1 -0
- package/dist/src/tools/provision-tools.d.ts +231 -0
- package/dist/src/tools/provision-tools.d.ts.map +1 -0
- package/dist/src/tools/provision-tools.js +289 -0
- package/dist/src/tools/provision-tools.js.map +1 -0
- package/dist/src/tools/release-slot.d.ts +5 -0
- package/dist/src/tools/release-slot.d.ts.map +1 -0
- package/dist/src/tools/release-slot.js +5 -0
- package/dist/src/tools/release-slot.js.map +1 -0
- package/dist/src/tools/slot-tools.d.ts +173 -0
- package/dist/src/tools/slot-tools.d.ts.map +1 -0
- package/dist/src/tools/slot-tools.js +296 -0
- package/dist/src/tools/slot-tools.js.map +1 -0
- package/dist/src/tools/vm-action.d.ts +189 -0
- package/dist/src/tools/vm-action.d.ts.map +1 -0
- package/dist/src/tools/vm-action.js +300 -0
- package/dist/src/tools/vm-action.js.map +1 -0
- package/dist/src/transports/index.d.ts +3 -0
- package/dist/src/transports/index.d.ts.map +1 -0
- package/dist/src/transports/index.js +3 -0
- package/dist/src/transports/index.js.map +1 -0
- package/dist/src/transports/sse.d.ts +38 -0
- package/dist/src/transports/sse.d.ts.map +1 -0
- package/dist/src/transports/sse.js +167 -0
- package/dist/src/transports/sse.js.map +1 -0
- package/dist/src/transports/stdio.d.ts +15 -0
- package/dist/src/transports/stdio.d.ts.map +1 -0
- package/dist/src/transports/stdio.js +34 -0
- package/dist/src/transports/stdio.js.map +1 -0
- package/dist/src/types/config.d.ts +17 -0
- package/dist/src/types/config.d.ts.map +1 -0
- package/dist/src/types/config.js +5 -0
- package/dist/src/types/config.js.map +1 -0
- package/dist/src/types/index.d.ts +4 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +4 -0
- package/dist/src/types/index.js.map +1 -0
- package/dist/src/types/mcp.d.ts +38 -0
- package/dist/src/types/mcp.d.ts.map +1 -0
- package/dist/src/types/mcp.js +46 -0
- package/dist/src/types/mcp.js.map +1 -0
- package/dist/src/types/proxmox.d.ts +181 -0
- package/dist/src/types/proxmox.d.ts.map +1 -0
- package/dist/src/types/proxmox.js +5 -0
- package/dist/src/types/proxmox.js.map +1 -0
- package/dist/src/types/slot.d.ts +5 -0
- package/dist/src/types/slot.d.ts.map +1 -0
- package/dist/src/types/slot.js +5 -0
- package/dist/src/types/slot.js.map +1 -0
- package/dist/src/utils/formatters.d.ts +71 -0
- package/dist/src/utils/formatters.d.ts.map +1 -0
- package/dist/src/utils/formatters.js +480 -0
- package/dist/src/utils/formatters.js.map +1 -0
- package/dist/src/utils/index.d.ts +6 -0
- package/dist/src/utils/index.d.ts.map +1 -0
- package/dist/src/utils/index.js +6 -0
- package/dist/src/utils/index.js.map +1 -0
- package/dist/src/utils/logger.d.ts +28 -0
- package/dist/src/utils/logger.d.ts.map +1 -0
- package/dist/src/utils/logger.js +74 -0
- package/dist/src/utils/logger.js.map +1 -0
- package/dist/src/utils/mutex.d.ts +32 -0
- package/dist/src/utils/mutex.d.ts.map +1 -0
- package/dist/src/utils/mutex.js +86 -0
- package/dist/src/utils/mutex.js.map +1 -0
- package/dist/src/utils/redact.d.ts +6 -0
- package/dist/src/utils/redact.d.ts.map +1 -0
- package/dist/src/utils/redact.js +6 -0
- package/dist/src/utils/redact.js.map +1 -0
- package/dist/src/utils/redactor.d.ts +50 -0
- package/dist/src/utils/redactor.d.ts.map +1 -0
- package/dist/src/utils/redactor.js +170 -0
- package/dist/src/utils/redactor.js.map +1 -0
- package/package.json +75 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Call Telemetry Lab MCP Server Factory
|
|
3
|
+
*
|
|
4
|
+
* Instantiates and wires the McpServer with MultiHypervisorManager, SlotManager,
|
|
5
|
+
* SafetyGuardrailEngine, ApplianceSshExecutor / MockApplianceExecutor, and registers all 7 MCP tools.
|
|
6
|
+
*/
|
|
7
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
|
+
import { SlotManager } from "./slot/manager.js";
|
|
9
|
+
import { MultiHypervisorManager } from "./hypervisors/manager.js";
|
|
10
|
+
import { defaultSafetyGuardrailEngine } from "./guardrails/safety.js";
|
|
11
|
+
import { registerAllTools } from "./tools/index.js";
|
|
12
|
+
import { applianceSshExecutor } from "./appliance/executor.js";
|
|
13
|
+
import { mockApplianceExecutor } from "./appliance/mock.js";
|
|
14
|
+
export const DEFAULT_SERVER_INSTRUCTIONS = "You are connected to @calltelemetry/ct-lab-mcp, the unified Call Telemetry lab, fleet, and appliance management MCP server.\n\n" +
|
|
15
|
+
"Capabilities:\n" +
|
|
16
|
+
"- Multi-Hypervisor Capacity & Health: Query Proxmox VE (proxmox-lab, proxmox-mini) and VMware ESXi (esxi-intel-192-168-123-176) with 'list_hosts'.\n" +
|
|
17
|
+
"- Unified Fleet Inventory: Discover VMs across Proxmox and ESXi with status, IP, VLAN, protected state, release version, and Linear leases via 'list_inventory'.\n" +
|
|
18
|
+
"- Global 8GB Slot Engine: Enforce hard partition quotas (2 slots on proxmox-lab, 4 on proxmox-mini, 8 on ESXi) via 'claim_slot' and 'release_slot'.\n" +
|
|
19
|
+
"- Disposable VM Provisioning: Clone test appliance VMs from templates with network configuration via 'provision_vm'.\n" +
|
|
20
|
+
"- Power Lifecycle & Guardrails: Manage power states (start/stop/reboot/destroy) with non-bypassable guardrails protecting core infrastructure (CUCM, CUBE, templates) via 'vm_action'.\n" +
|
|
21
|
+
"- Remote Appliance CLI Control: Execute mediated commands (status, health, db_vacuum, migrate, docker, logs) over secure SSH on Port 2222 via 'appliance_exec'.";
|
|
22
|
+
/**
|
|
23
|
+
* Creates and configures an McpServer instance with all Call Telemetry management tools registered.
|
|
24
|
+
*/
|
|
25
|
+
export function createMcpServer(options = {}) {
|
|
26
|
+
const name = options.name || "ct-lab-mcp";
|
|
27
|
+
const version = options.version || "0.1.0";
|
|
28
|
+
const description = options.description ||
|
|
29
|
+
"Call Telemetry unified lab, fleet, and appliance management MCP server across Proxmox VE and VMware ESXi.";
|
|
30
|
+
const instructions = options.instructions || DEFAULT_SERVER_INSTRUCTIONS;
|
|
31
|
+
// 1. Safety Guardrail Engine
|
|
32
|
+
const guardrailEngine = options.guardrailEngine || defaultSafetyGuardrailEngine;
|
|
33
|
+
// 2. Multi-Hypervisor Manager
|
|
34
|
+
let hypervisorManager = options.hypervisorManager;
|
|
35
|
+
if (!hypervisorManager) {
|
|
36
|
+
hypervisorManager = new MultiHypervisorManager({
|
|
37
|
+
credentials: options.credentials,
|
|
38
|
+
proxmoxConfigs: options.proxmoxConfigs || options.hostConfigs,
|
|
39
|
+
esxiConfigs: options.esxiConfigs,
|
|
40
|
+
safetyEngine: guardrailEngine,
|
|
41
|
+
forceMock: options.forceMock,
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
// 3. Slot Manager
|
|
45
|
+
let slotManager = options.slotManager;
|
|
46
|
+
if (!slotManager) {
|
|
47
|
+
slotManager = new SlotManager({
|
|
48
|
+
proxmoxManager: options.proxmoxManager,
|
|
49
|
+
includeEsxi: true,
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
// 4. Remote Appliance Executor
|
|
53
|
+
let applianceExecutor = options.applianceExecutor;
|
|
54
|
+
if (!applianceExecutor) {
|
|
55
|
+
const isMock = options.forceMock ||
|
|
56
|
+
options.credentials?.tier === "mock_fallback";
|
|
57
|
+
if (isMock) {
|
|
58
|
+
applianceExecutor = mockApplianceExecutor;
|
|
59
|
+
}
|
|
60
|
+
else {
|
|
61
|
+
applianceExecutor = applianceSshExecutor;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// 5. McpServer instantiation
|
|
65
|
+
const server = new McpServer({
|
|
66
|
+
name,
|
|
67
|
+
version,
|
|
68
|
+
description,
|
|
69
|
+
}, {
|
|
70
|
+
capabilities: {
|
|
71
|
+
tools: {
|
|
72
|
+
listChanged: true,
|
|
73
|
+
},
|
|
74
|
+
logging: {},
|
|
75
|
+
},
|
|
76
|
+
instructions,
|
|
77
|
+
});
|
|
78
|
+
const context = {
|
|
79
|
+
slotManager,
|
|
80
|
+
hypervisorManager,
|
|
81
|
+
guardrailEngine,
|
|
82
|
+
applianceExecutor,
|
|
83
|
+
proxmoxManager: options.proxmoxManager,
|
|
84
|
+
};
|
|
85
|
+
// 6. Register all 7 MCP tools
|
|
86
|
+
registerAllTools(server, context);
|
|
87
|
+
// Attach context for testing and reflection
|
|
88
|
+
Object.defineProperty(server, "_context", {
|
|
89
|
+
value: context,
|
|
90
|
+
writable: false,
|
|
91
|
+
enumerable: false,
|
|
92
|
+
});
|
|
93
|
+
return server;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/server.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Lease Garbage Collector
|
|
3
|
+
* Periodically scans active slot leases and transitions expired leases back to AVAILABLE status.
|
|
4
|
+
*/
|
|
5
|
+
import { SlotManager } from "./manager.js";
|
|
6
|
+
export interface LeaseGCWorkerOptions {
|
|
7
|
+
intervalMs?: number;
|
|
8
|
+
onExpired?: (expiredCount: number) => void;
|
|
9
|
+
onError?: (error: Error) => void;
|
|
10
|
+
runImmediatelyOnStart?: boolean;
|
|
11
|
+
}
|
|
12
|
+
export declare class LeaseGCWorker {
|
|
13
|
+
private slotManager;
|
|
14
|
+
private intervalMs;
|
|
15
|
+
private timer;
|
|
16
|
+
private running;
|
|
17
|
+
private onExpired?;
|
|
18
|
+
private onError?;
|
|
19
|
+
private runImmediatelyOnStart;
|
|
20
|
+
constructor(slotManager: SlotManager, options?: LeaseGCWorkerOptions);
|
|
21
|
+
/**
|
|
22
|
+
* Starts the periodic garbage collection timer.
|
|
23
|
+
*/
|
|
24
|
+
start(): void;
|
|
25
|
+
/**
|
|
26
|
+
* Stops the periodic garbage collection timer.
|
|
27
|
+
*/
|
|
28
|
+
stop(): void;
|
|
29
|
+
/**
|
|
30
|
+
* Performs an immediate sweep of expired slot leases.
|
|
31
|
+
*/
|
|
32
|
+
sweep(): Promise<number>;
|
|
33
|
+
/**
|
|
34
|
+
* Whether the GC worker is currently running.
|
|
35
|
+
*/
|
|
36
|
+
get isRunning(): boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Configured sweep interval in milliseconds.
|
|
39
|
+
*/
|
|
40
|
+
get interval(): number;
|
|
41
|
+
}
|
|
42
|
+
//# sourceMappingURL=gc.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc.d.ts","sourceRoot":"","sources":["../../../src/slot/gc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAE3C,MAAM,WAAW,oBAAoB;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;IACjC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,KAAK,CAA+B;IAC5C,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,SAAS,CAAC,CAAiC;IACnD,OAAO,CAAC,OAAO,CAAC,CAAyB;IACzC,OAAO,CAAC,qBAAqB,CAAU;gBAE3B,WAAW,EAAE,WAAW,EAAE,OAAO,GAAE,oBAAyB;IAQxE;;OAEG;IACH,KAAK,IAAI,IAAI;IAmBb;;OAEG;IACH,IAAI,IAAI,IAAI;IAQZ;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC;IAe9B;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,CAErB;CACF"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Background Lease Garbage Collector
|
|
3
|
+
* Periodically scans active slot leases and transitions expired leases back to AVAILABLE status.
|
|
4
|
+
*/
|
|
5
|
+
export class LeaseGCWorker {
|
|
6
|
+
slotManager;
|
|
7
|
+
intervalMs;
|
|
8
|
+
timer = null;
|
|
9
|
+
running = false;
|
|
10
|
+
onExpired;
|
|
11
|
+
onError;
|
|
12
|
+
runImmediatelyOnStart;
|
|
13
|
+
constructor(slotManager, options = {}) {
|
|
14
|
+
this.slotManager = slotManager;
|
|
15
|
+
this.intervalMs = options.intervalMs ?? 30000;
|
|
16
|
+
this.onExpired = options.onExpired;
|
|
17
|
+
this.onError = options.onError;
|
|
18
|
+
this.runImmediatelyOnStart = options.runImmediatelyOnStart ?? false;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Starts the periodic garbage collection timer.
|
|
22
|
+
*/
|
|
23
|
+
start() {
|
|
24
|
+
if (this.running)
|
|
25
|
+
return;
|
|
26
|
+
this.running = true;
|
|
27
|
+
if (this.runImmediatelyOnStart) {
|
|
28
|
+
void this.sweep();
|
|
29
|
+
}
|
|
30
|
+
this.timer = setInterval(() => {
|
|
31
|
+
void this.sweep();
|
|
32
|
+
}, this.intervalMs);
|
|
33
|
+
// Unref timer so it does not prevent Node process exit
|
|
34
|
+
if (this.timer && typeof this.timer.unref === "function") {
|
|
35
|
+
this.timer.unref();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Stops the periodic garbage collection timer.
|
|
40
|
+
*/
|
|
41
|
+
stop() {
|
|
42
|
+
if (this.timer) {
|
|
43
|
+
clearInterval(this.timer);
|
|
44
|
+
this.timer = null;
|
|
45
|
+
}
|
|
46
|
+
this.running = false;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Performs an immediate sweep of expired slot leases.
|
|
50
|
+
*/
|
|
51
|
+
async sweep() {
|
|
52
|
+
try {
|
|
53
|
+
const reclaimed = await this.slotManager.reclaimExpired();
|
|
54
|
+
if (reclaimed > 0 && this.onExpired) {
|
|
55
|
+
this.onExpired(reclaimed);
|
|
56
|
+
}
|
|
57
|
+
return reclaimed;
|
|
58
|
+
}
|
|
59
|
+
catch (err) {
|
|
60
|
+
if (this.onError) {
|
|
61
|
+
this.onError(err instanceof Error ? err : new Error(String(err)));
|
|
62
|
+
}
|
|
63
|
+
return 0;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* Whether the GC worker is currently running.
|
|
68
|
+
*/
|
|
69
|
+
get isRunning() {
|
|
70
|
+
return this.running;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Configured sweep interval in milliseconds.
|
|
74
|
+
*/
|
|
75
|
+
get interval() {
|
|
76
|
+
return this.intervalMs;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=gc.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gc.js","sourceRoot":"","sources":["../../../src/slot/gc.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,MAAM,OAAO,aAAa;IAChB,WAAW,CAAc;IACzB,UAAU,CAAS;IACnB,KAAK,GAA0B,IAAI,CAAC;IACpC,OAAO,GAAG,KAAK,CAAC;IAChB,SAAS,CAAkC;IAC3C,OAAO,CAA0B;IACjC,qBAAqB,CAAU;IAEvC,YAAY,WAAwB,EAAE,UAAgC,EAAE;QACtE,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;QAC/B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,KAAK,CAAC;QAC9C,IAAI,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;QACnC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;QAC/B,IAAI,CAAC,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,IAAI,KAAK,CAAC;IACtE,CAAC;IAED;;OAEG;IACH,KAAK;QACH,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QAEzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,IAAI,IAAI,CAAC,qBAAqB,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;QAED,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;YAC5B,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAEpB,uDAAuD;QACvD,IAAI,IAAI,CAAC,KAAK,IAAI,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,KAAK,UAAU,EAAE,CAAC;YACzD,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QACrB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI;QACF,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,aAAa,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;QACpB,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;IACvB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,KAAK;QACT,IAAI,CAAC;YACH,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,cAAc,EAAE,CAAC;YAC1D,IAAI,SAAS,GAAG,CAAC,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACpC,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;YAC5B,CAAC;YACD,OAAO,SAAS,CAAC;QACnB,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAClB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACjB,IAAI,CAAC,OAAO,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YACpE,CAAC;YACD,OAAO,CAAC,CAAC;QACX,CAAC;IACH,CAAC;IAED;;OAEG;IACH,IAAI,SAAS;QACX,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IAED;;OAEG;IACH,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,UAAU,CAAC;IACzB,CAAC;CACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/slot/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/slot/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,cAAc,CAAC;AAC7B,cAAc,SAAS,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Global Slot Allocation & Capacity Partitioning Engine
|
|
3
|
+
* Manages 8GB appliance slots across Proxmox VE and VMware ESXi hosts with hard partition limits,
|
|
4
|
+
* atomic concurrency locking (AsyncMutex), TTL lease management, and candidate slot ranking.
|
|
5
|
+
*/
|
|
6
|
+
import { HostId, SlotDefinition, HostCapacityStatus, GlobalCapacitySummary, SlotCapacityReport, SlotClaimRequest, SlotClaimResult, ReleaseSlotOptions, ReleaseSlotParams, ReleaseSlotResult, LeaseExtensionResult, ListSlotsOptions, ISlotManager } from "./types.js";
|
|
7
|
+
import { MultiHostProxmoxManager } from "../proxmox/index.js";
|
|
8
|
+
export * from "./types.js";
|
|
9
|
+
export interface SlotManagerHostConfig {
|
|
10
|
+
hostId: HostId;
|
|
11
|
+
name: string;
|
|
12
|
+
hypervisorType?: "proxmox" | "esxi";
|
|
13
|
+
totalMemoryMb: number;
|
|
14
|
+
reservedHeadroomMb: number;
|
|
15
|
+
maxSlots: number;
|
|
16
|
+
slotSizeMb: number;
|
|
17
|
+
freeDiskGb?: number;
|
|
18
|
+
totalDiskGb?: number;
|
|
19
|
+
datastoreFreeBytes?: number;
|
|
20
|
+
}
|
|
21
|
+
export interface SlotManagerOptions {
|
|
22
|
+
hosts?: SlotManagerHostConfig[];
|
|
23
|
+
defaultDurationMinutes?: number;
|
|
24
|
+
proxmoxManager?: MultiHostProxmoxManager;
|
|
25
|
+
includeEsxi?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare const DEFAULT_ESXI_HOST_CONFIG: SlotManagerHostConfig;
|
|
28
|
+
export declare class SlotManager implements ISlotManager {
|
|
29
|
+
private hosts;
|
|
30
|
+
private slots;
|
|
31
|
+
private mutex;
|
|
32
|
+
private defaultDurationMinutes;
|
|
33
|
+
private proxmoxManager?;
|
|
34
|
+
constructor(options?: SlotManagerOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Register a host and initialize its slot definitions.
|
|
37
|
+
*/
|
|
38
|
+
registerHost(host: SlotManagerHostConfig): void;
|
|
39
|
+
/**
|
|
40
|
+
* Normalizes host ID strings (e.g. mapping aliases like proxmox-minis-lab -> proxmox-mini).
|
|
41
|
+
*/
|
|
42
|
+
private normalizeHostId;
|
|
43
|
+
/**
|
|
44
|
+
* Internal lazy expiration sweep (must be called inside mutex or synchronous method).
|
|
45
|
+
*/
|
|
46
|
+
private sweepExpiredSlotsInternal;
|
|
47
|
+
/**
|
|
48
|
+
* Atomically claims an 8GB appliance slot.
|
|
49
|
+
*/
|
|
50
|
+
claimSlot(request: SlotClaimRequest): Promise<SlotClaimResult>;
|
|
51
|
+
/**
|
|
52
|
+
* Releases one or more slots matching claimId, tag, slotId, requester, or linearIssue.
|
|
53
|
+
*/
|
|
54
|
+
releaseSlot(optionsOrClaimId: string | ReleaseSlotOptions | ReleaseSlotParams, destroyVmFlag?: boolean): Promise<ReleaseSlotResult>;
|
|
55
|
+
/**
|
|
56
|
+
* Extends the lease of an active slot up to the 24h cumulative ceiling.
|
|
57
|
+
*/
|
|
58
|
+
extendLease(claimId: string, additionalMinutes: number, sessionId?: string): Promise<LeaseExtensionResult>;
|
|
59
|
+
/**
|
|
60
|
+
* List slots with optional filtering and computed remaining TTL.
|
|
61
|
+
*/
|
|
62
|
+
listSlots(options?: ListSlotsOptions): Promise<SlotDefinition[]>;
|
|
63
|
+
/**
|
|
64
|
+
* List host capacities or global cluster summary.
|
|
65
|
+
*/
|
|
66
|
+
listHosts(hostId?: HostId | "all"): Promise<GlobalCapacitySummary | HostCapacityStatus>;
|
|
67
|
+
/**
|
|
68
|
+
* Returns available slot capacity report conforming to ISlotManager.getAvailableSlots.
|
|
69
|
+
*/
|
|
70
|
+
getAvailableSlots(hostName?: string): Promise<SlotCapacityReport | GlobalCapacitySummary | HostCapacityStatus>;
|
|
71
|
+
/**
|
|
72
|
+
* Reclaim all expired slots and return count.
|
|
73
|
+
*/
|
|
74
|
+
reclaimExpired(): Promise<number>;
|
|
75
|
+
/**
|
|
76
|
+
* Attach a created VMID or VM name to a claimed slot.
|
|
77
|
+
*/
|
|
78
|
+
attachVm(claimId: string, vmId: number | string, vmName?: string): Promise<SlotDefinition>;
|
|
79
|
+
/**
|
|
80
|
+
* Lookup single slot by slotId.
|
|
81
|
+
*/
|
|
82
|
+
getSlot(slotId: string): Promise<SlotDefinition | null>;
|
|
83
|
+
/**
|
|
84
|
+
* Lookup slot by active claimId.
|
|
85
|
+
*/
|
|
86
|
+
getSlotByClaimId(claimId: string): Promise<SlotDefinition | null>;
|
|
87
|
+
/**
|
|
88
|
+
* Clears all claims (primarily for test resets).
|
|
89
|
+
*/
|
|
90
|
+
clearAll(): Promise<void>;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../../src/slot/manager.ts"],"names":[],"mappings":"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"}
|