@tyevco/homelab-lxc-agent 1.6.0 → 1.9.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/dist/index.js +8 -4
- package/dist/server.js +45 -5
- package/package.json +29 -29
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ const port = parseInt(process.env.HOMELAB_AGENT_PORT ?? "5002", 10);
|
|
|
7
7
|
const hostname = process.env.HOMELAB_AGENT_HOSTNAME ?? "0.0.0.0";
|
|
8
8
|
const username = process.env.HOMELAB_AGENT_USERNAME ?? "admin";
|
|
9
9
|
const password = process.env.HOMELAB_AGENT_PASSWORD ?? "";
|
|
10
|
+
const scanInterval = parseInt(process.env.HOMELAB_AGENT_SCAN_INTERVAL ?? "60", 10);
|
|
10
11
|
if (!password) {
|
|
11
12
|
console.error("Error: HOMELAB_AGENT_PASSWORD is required.");
|
|
12
13
|
console.error("");
|
|
@@ -14,18 +15,21 @@ if (!password) {
|
|
|
14
15
|
console.error(" HOMELAB_AGENT_PASSWORD=secret homelab-lxc-agent");
|
|
15
16
|
console.error("");
|
|
16
17
|
console.error("Optional variables:");
|
|
17
|
-
console.error(" HOMELAB_AGENT_PORT
|
|
18
|
-
console.error(" HOMELAB_AGENT_HOSTNAME
|
|
19
|
-
console.error(" HOMELAB_AGENT_USERNAME
|
|
18
|
+
console.error(" HOMELAB_AGENT_PORT (default: 5002)");
|
|
19
|
+
console.error(" HOMELAB_AGENT_HOSTNAME (default: 0.0.0.0)");
|
|
20
|
+
console.error(" HOMELAB_AGENT_USERNAME (default: admin)");
|
|
21
|
+
console.error(" HOMELAB_AGENT_SCAN_INTERVAL (default: 60, seconds)");
|
|
20
22
|
process.exit(1);
|
|
21
23
|
}
|
|
22
24
|
const { httpServer } = (0, server_1.createAgentServer)({ username,
|
|
23
25
|
password,
|
|
24
|
-
version: pkg.version
|
|
26
|
+
version: pkg.version,
|
|
27
|
+
scanInterval });
|
|
25
28
|
httpServer.listen(port, hostname, () => {
|
|
26
29
|
console.log(`Homelab LXC Agent v${pkg.version}`);
|
|
27
30
|
console.log(`Listening on ${hostname}:${port}`);
|
|
28
31
|
console.log(`Username: ${username}`);
|
|
32
|
+
console.log(`Capability scan interval: ${scanInterval}s`);
|
|
29
33
|
console.log("");
|
|
30
34
|
console.log("Add this agent in the Homelab UI:");
|
|
31
35
|
console.log(` URL: http://<this-host>:${port}`);
|
package/dist/server.js
CHANGED
|
@@ -26,24 +26,63 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
26
26
|
exports.createAgentServer = void 0;
|
|
27
27
|
const http_1 = require("http");
|
|
28
28
|
const socket_io_1 = require("socket.io");
|
|
29
|
+
const promisify_child_process_1 = require("promisify-child-process");
|
|
29
30
|
const lxc = __importStar(require("./lxc"));
|
|
30
31
|
const terminal_1 = require("./terminal");
|
|
32
|
+
async function detectCapabilities() {
|
|
33
|
+
let lxcAvailable = false;
|
|
34
|
+
try {
|
|
35
|
+
await (0, promisify_child_process_1.spawn)("lxc-ls", ["--version"], { encoding: "utf8" });
|
|
36
|
+
lxcAvailable = true;
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// lxc-ls not found or failed
|
|
40
|
+
}
|
|
41
|
+
const found = [];
|
|
42
|
+
if (lxcAvailable) {
|
|
43
|
+
found.push("LXC");
|
|
44
|
+
}
|
|
45
|
+
if (found.length > 0) {
|
|
46
|
+
console.log(`[agent] Capabilities detected: ${found.join(", ")}`);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
console.log("[agent] No additional capabilities detected");
|
|
50
|
+
}
|
|
51
|
+
return { lxcAvailable };
|
|
52
|
+
}
|
|
31
53
|
function createAgentServer(config) {
|
|
32
54
|
const httpServer = (0, http_1.createServer)();
|
|
33
55
|
const io = new socket_io_1.Server(httpServer);
|
|
56
|
+
let capabilities = { lxcAvailable: false };
|
|
57
|
+
const authenticatedSockets = new Set();
|
|
58
|
+
const emitInfo = (socket) => {
|
|
59
|
+
socket.emit("info", {
|
|
60
|
+
version: config.version,
|
|
61
|
+
...capabilities,
|
|
62
|
+
});
|
|
63
|
+
};
|
|
64
|
+
const rescan = async () => {
|
|
65
|
+
console.log("[agent] Scanning capabilities...");
|
|
66
|
+
capabilities = await detectCapabilities();
|
|
67
|
+
for (const socket of authenticatedSockets) {
|
|
68
|
+
emitInfo(socket);
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
// Initial scan, then periodic rescan
|
|
72
|
+
rescan().then(() => {
|
|
73
|
+
setInterval(rescan, config.scanInterval * 1000);
|
|
74
|
+
});
|
|
34
75
|
io.on("connection", (socket) => {
|
|
35
76
|
// The main server sends its own endpoint string in the header so we can
|
|
36
77
|
// echo it back in push events (lxcContainerList, terminalWrite, etc.)
|
|
37
78
|
const endpoint = socket.handshake.headers["endpoint"] || "";
|
|
38
79
|
let loggedIn = false;
|
|
39
80
|
console.log(`[agent] Main server connected (endpoint: ${endpoint || "<none>"})`);
|
|
40
|
-
// Announce ourselves — main server checks version >= 1.4.0
|
|
41
|
-
socket
|
|
42
|
-
version: config.version,
|
|
43
|
-
lxcAvailable: true,
|
|
44
|
-
});
|
|
81
|
+
// Announce ourselves with current capabilities — main server checks version >= 1.4.0
|
|
82
|
+
emitInfo(socket);
|
|
45
83
|
socket.on("disconnect", () => {
|
|
46
84
|
console.log("[agent] Main server disconnected");
|
|
85
|
+
authenticatedSockets.delete(socket);
|
|
47
86
|
// Leave interactive terminals open (lxc-attach) across reconnects;
|
|
48
87
|
// only clean up non-interactive progress terminals which are already
|
|
49
88
|
// gone by the time the process exits.
|
|
@@ -58,6 +97,7 @@ function createAgentServer(config) {
|
|
|
58
97
|
const { username, password } = data;
|
|
59
98
|
if (username === config.username && password === config.password) {
|
|
60
99
|
loggedIn = true;
|
|
100
|
+
authenticatedSockets.add(socket);
|
|
61
101
|
console.log(`[agent] Authenticated as ${username}`);
|
|
62
102
|
cb?.({ ok: true });
|
|
63
103
|
}
|
package/package.json
CHANGED
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
2
|
+
"name": "@tyevco/homelab-lxc-agent",
|
|
3
|
+
"version": "1.9.0",
|
|
4
|
+
"description": "Lightweight LXC agent for Homelab",
|
|
5
|
+
"bin": {
|
|
6
|
+
"homelab-lxc-agent": "bin/homelab-lxc-agent.js"
|
|
7
|
+
},
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"prepare": "tsc",
|
|
11
|
+
"start": "node dist/index.js",
|
|
12
|
+
"dev": "ts-node src/index.ts"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist/",
|
|
16
|
+
"bin/"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@homebridge/node-pty-prebuilt-multiarch": "0.11.14",
|
|
20
|
+
"promisify-child-process": "^4.1.2",
|
|
21
|
+
"socket.io": "~4.8.1"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@types/node": "^20.0.0",
|
|
25
|
+
"ts-node": "^10.9.1",
|
|
26
|
+
"typescript": "~5.2.2"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=18"
|
|
30
|
+
}
|
|
31
31
|
}
|