@oussema_mili/test-pkg-123 1.1.32
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 +29 -0
- package/README.md +220 -0
- package/auth-callback.html +97 -0
- package/auth.js +276 -0
- package/cli-commands.js +1921 -0
- package/containerManager.js +304 -0
- package/daemon/agentRunner.js +491 -0
- package/daemon/daemonEntry.js +64 -0
- package/daemon/daemonManager.js +266 -0
- package/daemon/logManager.js +227 -0
- package/dist/styles.css +504 -0
- package/docker-actions/apps.js +3913 -0
- package/docker-actions/config-transformer.js +380 -0
- package/docker-actions/containers.js +355 -0
- package/docker-actions/general.js +171 -0
- package/docker-actions/images.js +1128 -0
- package/docker-actions/logs.js +224 -0
- package/docker-actions/metrics.js +270 -0
- package/docker-actions/registry.js +1100 -0
- package/docker-actions/setup-tasks.js +859 -0
- package/docker-actions/terminal.js +247 -0
- package/docker-actions/volumes.js +713 -0
- package/helper-functions.js +193 -0
- package/index.html +83 -0
- package/index.js +341 -0
- package/package.json +82 -0
- package/postcss.config.mjs +5 -0
- package/scripts/release.sh +212 -0
- package/setup/setupWizard.js +403 -0
- package/store/agentSessionStore.js +51 -0
- package/store/agentStore.js +113 -0
- package/store/configStore.js +171 -0
- package/store/daemonStore.js +217 -0
- package/store/deviceCredentialStore.js +107 -0
- package/store/npmTokenStore.js +65 -0
- package/store/registryStore.js +329 -0
- package/store/setupState.js +147 -0
- package/styles.css +1 -0
- package/utils/appLogger.js +223 -0
- package/utils/deviceInfo.js +98 -0
- package/utils/ecrAuth.js +225 -0
- package/utils/encryption.js +112 -0
- package/utils/envSetup.js +41 -0
- package/utils/errorHandler.js +327 -0
- package/utils/portUtils.js +59 -0
- package/utils/prerequisites.js +323 -0
- package/utils/prompts.js +318 -0
- package/utils/ssl-certificates.js +256 -0
- package/websocket-server.js +415 -0
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import Docker from "dockerode";
|
|
2
|
+
import { formatUptime } from "../helper-functions.js";
|
|
3
|
+
import os from "os";
|
|
4
|
+
|
|
5
|
+
// Create Docker client
|
|
6
|
+
let docker;
|
|
7
|
+
try {
|
|
8
|
+
docker = new Docker();
|
|
9
|
+
} catch (error) {
|
|
10
|
+
console.error(`Failed to connect to Docker daemon: ${error.message}`);
|
|
11
|
+
process.exit(1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Format container for response
|
|
15
|
+
const formatContainer = async (container) => {
|
|
16
|
+
try {
|
|
17
|
+
const containerInfo = await container.inspect();
|
|
18
|
+
const stats = await container.stats({ stream: false });
|
|
19
|
+
|
|
20
|
+
// Calculate CPU usage percentage using a simpler approach
|
|
21
|
+
let cpuPercent = 0;
|
|
22
|
+
try {
|
|
23
|
+
const cpuDelta =
|
|
24
|
+
stats.cpu_stats.cpu_usage.total_usage -
|
|
25
|
+
stats.precpu_stats.cpu_usage.total_usage;
|
|
26
|
+
const systemCpuDelta =
|
|
27
|
+
stats.cpu_stats.system_cpu_usage - stats.precpu_stats.system_cpu_usage;
|
|
28
|
+
const cpuCores = stats.cpu_stats.online_cpus || os.cpus().length;
|
|
29
|
+
|
|
30
|
+
if (systemCpuDelta > 0 && cpuDelta > 0) {
|
|
31
|
+
cpuPercent = (cpuDelta / systemCpuDelta) * cpuCores * 100;
|
|
32
|
+
}
|
|
33
|
+
} catch (err) {
|
|
34
|
+
console.error("Error calculating CPU percentage:", err.message);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Calculate memory usage percentage
|
|
38
|
+
let memoryPercent = 0;
|
|
39
|
+
try {
|
|
40
|
+
const memoryUsage = stats.memory_stats.usage || 0;
|
|
41
|
+
const memoryLimit = stats.memory_stats.limit || 1;
|
|
42
|
+
memoryPercent = (memoryUsage / memoryLimit) * 100;
|
|
43
|
+
} catch (err) {
|
|
44
|
+
console.error("Error calculating memory percentage:", err.message);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Format ports
|
|
48
|
+
const ports = [];
|
|
49
|
+
if (containerInfo.NetworkSettings && containerInfo.NetworkSettings.Ports) {
|
|
50
|
+
Object.entries(containerInfo.NetworkSettings.Ports).forEach(
|
|
51
|
+
([containerPort, hostBindings]) => {
|
|
52
|
+
if (hostBindings) {
|
|
53
|
+
hostBindings.forEach((binding) => {
|
|
54
|
+
ports.push(`${binding.HostPort}:${containerPort}`);
|
|
55
|
+
});
|
|
56
|
+
} else {
|
|
57
|
+
ports.push(containerPort);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Calculate uptime
|
|
64
|
+
const startTime = new Date(containerInfo.State.StartedAt).getTime();
|
|
65
|
+
const uptime = containerInfo.State.Running
|
|
66
|
+
? formatUptime(Date.now() - startTime)
|
|
67
|
+
: "-";
|
|
68
|
+
|
|
69
|
+
// Extract app-related labels
|
|
70
|
+
const labels = containerInfo.Config.Labels || {};
|
|
71
|
+
const appName = labels["app.name"] || null;
|
|
72
|
+
const fwId = labels["app.fwId"] || labels["app.backstageId"] || null;
|
|
73
|
+
|
|
74
|
+
return {
|
|
75
|
+
id: container.id,
|
|
76
|
+
name: containerInfo.Name.replace(/^\//, ""), // Remove leading slash
|
|
77
|
+
image: containerInfo.Config.Image,
|
|
78
|
+
status: containerInfo.State.Running ? "running" : "stopped",
|
|
79
|
+
uptime,
|
|
80
|
+
ports,
|
|
81
|
+
cpu: isNaN(cpuPercent) ? 0 : Math.round(cpuPercent * 100) / 100,
|
|
82
|
+
memory: isNaN(memoryPercent) ? 0 : Math.round(memoryPercent * 100) / 100,
|
|
83
|
+
created: new Date(containerInfo.Created).toLocaleDateString(),
|
|
84
|
+
appName,
|
|
85
|
+
fwId,
|
|
86
|
+
};
|
|
87
|
+
} catch (error) {
|
|
88
|
+
console.error("Error formatting container:", error.message);
|
|
89
|
+
return {
|
|
90
|
+
id: container.id,
|
|
91
|
+
name: "Unknown",
|
|
92
|
+
image: "Unknown",
|
|
93
|
+
status: "error",
|
|
94
|
+
uptime: "-",
|
|
95
|
+
ports: [],
|
|
96
|
+
cpu: 0,
|
|
97
|
+
memory: 0,
|
|
98
|
+
created: "Unknown",
|
|
99
|
+
appName: null,
|
|
100
|
+
fwId: null,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
async function handleContainerAction(ws, action, payload) {
|
|
106
|
+
switch (action) {
|
|
107
|
+
case "fetchContainers":
|
|
108
|
+
return await handleFetchContainers(ws, payload);
|
|
109
|
+
case "startContainer":
|
|
110
|
+
return await handleStartContainer(ws, payload);
|
|
111
|
+
case "stopContainer":
|
|
112
|
+
return await handleStopContainer(ws, payload);
|
|
113
|
+
case "restartContainer":
|
|
114
|
+
return await handleRestartContainer(ws, payload);
|
|
115
|
+
case "deleteContainer":
|
|
116
|
+
return await handleDeleteContainer(ws, payload);
|
|
117
|
+
case "createContainer":
|
|
118
|
+
return await handleCreateContainer(ws, payload);
|
|
119
|
+
case "inspectContainer":
|
|
120
|
+
return await handleInspectContainer(ws, payload);
|
|
121
|
+
default:
|
|
122
|
+
throw new Error(`Unknown container action: ${action}`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
async function handleFetchContainers(ws, payload = {}) {
|
|
127
|
+
try {
|
|
128
|
+
const containers = await docker.listContainers({ all: true });
|
|
129
|
+
const containerPromises = containers.map((container) =>
|
|
130
|
+
formatContainer(docker.getContainer(container.Id))
|
|
131
|
+
);
|
|
132
|
+
const formattedContainers = await Promise.all(containerPromises);
|
|
133
|
+
|
|
134
|
+
ws.send(
|
|
135
|
+
JSON.stringify({
|
|
136
|
+
type: "containers",
|
|
137
|
+
containers: formattedContainers,
|
|
138
|
+
requestId: payload.requestId,
|
|
139
|
+
})
|
|
140
|
+
);
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error("Error fetching containers:", error);
|
|
143
|
+
ws.send(
|
|
144
|
+
JSON.stringify({
|
|
145
|
+
type: "error",
|
|
146
|
+
error: "Failed to fetch containers: " + error.message,
|
|
147
|
+
requestId: payload.requestId,
|
|
148
|
+
})
|
|
149
|
+
);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
async function handleStartContainer(ws, payload) {
|
|
154
|
+
try {
|
|
155
|
+
const container = docker.getContainer(payload.id);
|
|
156
|
+
await container.start();
|
|
157
|
+
const formattedContainer = await formatContainer(container);
|
|
158
|
+
|
|
159
|
+
ws.send(
|
|
160
|
+
JSON.stringify({
|
|
161
|
+
type: "containerStarted",
|
|
162
|
+
container: formattedContainer,
|
|
163
|
+
requestId: payload.requestId,
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
} catch (error) {
|
|
167
|
+
console.error("Error starting container:", error);
|
|
168
|
+
ws.send(
|
|
169
|
+
JSON.stringify({
|
|
170
|
+
type: "error",
|
|
171
|
+
error: "Failed to start container: " + error.message,
|
|
172
|
+
requestId: payload.requestId,
|
|
173
|
+
})
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
async function handleStopContainer(ws, payload) {
|
|
179
|
+
try {
|
|
180
|
+
const container = docker.getContainer(payload.id);
|
|
181
|
+
await container.stop();
|
|
182
|
+
const formattedContainer = await formatContainer(container);
|
|
183
|
+
|
|
184
|
+
ws.send(
|
|
185
|
+
JSON.stringify({
|
|
186
|
+
type: "containerStopped",
|
|
187
|
+
container: formattedContainer,
|
|
188
|
+
requestId: payload.requestId,
|
|
189
|
+
})
|
|
190
|
+
);
|
|
191
|
+
} catch (error) {
|
|
192
|
+
console.error("Error stopping container:", error);
|
|
193
|
+
ws.send(
|
|
194
|
+
JSON.stringify({
|
|
195
|
+
type: "error",
|
|
196
|
+
error: "Failed to stop container: " + error.message,
|
|
197
|
+
requestId: payload.requestId,
|
|
198
|
+
})
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
async function handleRestartContainer(ws, payload) {
|
|
204
|
+
try {
|
|
205
|
+
const container = docker.getContainer(payload.id);
|
|
206
|
+
await container.restart();
|
|
207
|
+
const formattedContainer = await formatContainer(container);
|
|
208
|
+
|
|
209
|
+
ws.send(
|
|
210
|
+
JSON.stringify({
|
|
211
|
+
type: "containerRestarted",
|
|
212
|
+
container: formattedContainer,
|
|
213
|
+
requestId: payload.requestId,
|
|
214
|
+
})
|
|
215
|
+
);
|
|
216
|
+
} catch (error) {
|
|
217
|
+
console.error("Error restarting container:", error);
|
|
218
|
+
ws.send(
|
|
219
|
+
JSON.stringify({
|
|
220
|
+
type: "error",
|
|
221
|
+
error: "Failed to restart container: " + error.message,
|
|
222
|
+
requestId: payload.requestId,
|
|
223
|
+
})
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
async function handleDeleteContainer(ws, payload) {
|
|
229
|
+
try {
|
|
230
|
+
const container = docker.getContainer(payload.id);
|
|
231
|
+
await container.remove({ force: true });
|
|
232
|
+
|
|
233
|
+
ws.send(
|
|
234
|
+
JSON.stringify({
|
|
235
|
+
type: "containerDeleted",
|
|
236
|
+
id: payload.id,
|
|
237
|
+
success: true,
|
|
238
|
+
requestId: payload.requestId,
|
|
239
|
+
})
|
|
240
|
+
);
|
|
241
|
+
} catch (error) {
|
|
242
|
+
console.error("Error deleting container:", error);
|
|
243
|
+
ws.send(
|
|
244
|
+
JSON.stringify({
|
|
245
|
+
type: "error",
|
|
246
|
+
error: "Failed to delete container: " + error.message,
|
|
247
|
+
requestId: payload.requestId,
|
|
248
|
+
})
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
async function handleCreateContainer(ws, payload) {
|
|
254
|
+
try {
|
|
255
|
+
const options = payload.options;
|
|
256
|
+
|
|
257
|
+
// Format port bindings
|
|
258
|
+
const portBindings = {};
|
|
259
|
+
if (options.ports) {
|
|
260
|
+
const portMappings = options.ports.split(",").map((p) => p.trim());
|
|
261
|
+
portMappings.forEach((mapping) => {
|
|
262
|
+
const [hostPort, containerPort] = mapping.split(":");
|
|
263
|
+
portBindings[`${containerPort}/tcp`] = [{ HostPort: hostPort }];
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Format volumes
|
|
268
|
+
const volumes = {};
|
|
269
|
+
const binds = [];
|
|
270
|
+
if (options.volumes) {
|
|
271
|
+
const volumeMappings = options.volumes.split(",").map((v) => v.trim());
|
|
272
|
+
volumeMappings.forEach((mapping) => {
|
|
273
|
+
const [hostPath, containerPath] = mapping.split(":");
|
|
274
|
+
volumes[containerPath] = {};
|
|
275
|
+
binds.push(`${hostPath}:${containerPath}`);
|
|
276
|
+
});
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
// Format environment variables
|
|
280
|
+
const env = [];
|
|
281
|
+
if (options.environment) {
|
|
282
|
+
const envMappings = options.environment.split(",").map((e) => e.trim());
|
|
283
|
+
envMappings.forEach((mapping) => {
|
|
284
|
+
env.push(mapping);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Create container
|
|
289
|
+
const container = await docker.createContainer({
|
|
290
|
+
name: options.name,
|
|
291
|
+
Image: options.image,
|
|
292
|
+
ExposedPorts: Object.keys(portBindings).reduce((acc, port) => {
|
|
293
|
+
acc[port] = {};
|
|
294
|
+
return acc;
|
|
295
|
+
}, {}),
|
|
296
|
+
HostConfig: {
|
|
297
|
+
PortBindings: portBindings,
|
|
298
|
+
Binds: binds,
|
|
299
|
+
RestartPolicy: {
|
|
300
|
+
Name: options.restart || "no",
|
|
301
|
+
},
|
|
302
|
+
},
|
|
303
|
+
Env: env,
|
|
304
|
+
Volumes: volumes,
|
|
305
|
+
});
|
|
306
|
+
|
|
307
|
+
const formattedContainer = await formatContainer(container);
|
|
308
|
+
|
|
309
|
+
ws.send(
|
|
310
|
+
JSON.stringify({
|
|
311
|
+
type: "containerCreated",
|
|
312
|
+
container: formattedContainer,
|
|
313
|
+
requestId: payload.requestId,
|
|
314
|
+
})
|
|
315
|
+
);
|
|
316
|
+
} catch (error) {
|
|
317
|
+
console.error("Error creating container:", error);
|
|
318
|
+
ws.send(
|
|
319
|
+
JSON.stringify({
|
|
320
|
+
type: "error",
|
|
321
|
+
error: "Failed to create container: " + error.message,
|
|
322
|
+
requestId: payload.requestId,
|
|
323
|
+
})
|
|
324
|
+
);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
async function handleInspectContainer(ws, payload) {
|
|
329
|
+
try {
|
|
330
|
+
const { id, requestId } = payload;
|
|
331
|
+
const container = docker.getContainer(id);
|
|
332
|
+
const inspectionData = await container.inspect();
|
|
333
|
+
|
|
334
|
+
ws.send(
|
|
335
|
+
JSON.stringify({
|
|
336
|
+
type: "containerInspected",
|
|
337
|
+
data: inspectionData,
|
|
338
|
+
requestId,
|
|
339
|
+
})
|
|
340
|
+
);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
console.error("Error inspecting container:", error);
|
|
343
|
+
ws.send(
|
|
344
|
+
JSON.stringify({
|
|
345
|
+
type: "error",
|
|
346
|
+
error: "Failed to inspect container: " + error.message,
|
|
347
|
+
requestId: payload.requestId,
|
|
348
|
+
})
|
|
349
|
+
);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
export default { handleContainerAction, formatContainer, docker };
|
|
354
|
+
|
|
355
|
+
export { handleContainerAction, formatContainer, docker };
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import os from 'os';
|
|
2
|
+
import { formatUptime } from '../helper-functions.js';
|
|
3
|
+
import { docker } from './containers.js';
|
|
4
|
+
import agentStore from '../store/agentStore.js';
|
|
5
|
+
import { loadSession } from '../auth.js';
|
|
6
|
+
import agentSessionStore from '../store/agentSessionStore.js';
|
|
7
|
+
|
|
8
|
+
// Version from package.json
|
|
9
|
+
import packageJson from '../package.json' with { type: 'json' };
|
|
10
|
+
const { version } = packageJson;
|
|
11
|
+
|
|
12
|
+
// Agent informations - startTime will be loaded from store or set when server starts
|
|
13
|
+
let agentStartTime = new Date();
|
|
14
|
+
const agentInfo = {
|
|
15
|
+
version,
|
|
16
|
+
hostname: os.hostname(),
|
|
17
|
+
startTime: agentStartTime,
|
|
18
|
+
cpus: os.cpus().length,
|
|
19
|
+
memory: {
|
|
20
|
+
total: Math.round(os.totalmem() / (1024 * 1024)), // MB
|
|
21
|
+
free: Math.round(os.freemem() / (1024 * 1024)), // MB
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Initialize agent start time - called when server actually starts
|
|
27
|
+
* Always creates a fresh start time when the server starts
|
|
28
|
+
*/
|
|
29
|
+
async function initializeAgentStartTime() {
|
|
30
|
+
try {
|
|
31
|
+
// Always create a fresh start time when the server starts
|
|
32
|
+
agentStartTime = new Date();
|
|
33
|
+
agentInfo.startTime = agentStartTime;
|
|
34
|
+
await agentStore.saveAgentStartTime(agentStartTime);
|
|
35
|
+
} catch (err) {
|
|
36
|
+
console.error('Failed to initialize agent start time:', err);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async function handleGeneralAction(ws, clientId, action, payload) {
|
|
41
|
+
switch (action) {
|
|
42
|
+
case 'getAgentInfo':
|
|
43
|
+
return await handleGetAgentInfo(ws, payload);
|
|
44
|
+
case 'getDockerInfo':
|
|
45
|
+
return await handleGetDockerInfo(ws, payload);
|
|
46
|
+
case 'execInContainer':
|
|
47
|
+
return await handleExecInContainer(ws, clientId, payload);
|
|
48
|
+
default:
|
|
49
|
+
throw new Error(`Unknown general action: ${action}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
async function handleGetAgentInfo(ws, payload = {}) {
|
|
54
|
+
try {
|
|
55
|
+
const currentTime = Date.now();
|
|
56
|
+
const uptimeMs = currentTime - new Date(agentInfo.startTime).getTime();
|
|
57
|
+
const formattedUptime = formatUptime(uptimeMs);
|
|
58
|
+
|
|
59
|
+
// Get session info
|
|
60
|
+
const sessionInfo = agentSessionStore.getAgentSessionInfo();
|
|
61
|
+
const session = loadSession();
|
|
62
|
+
|
|
63
|
+
const info = {
|
|
64
|
+
...agentInfo,
|
|
65
|
+
timestamp: Date.now(),
|
|
66
|
+
uptime: formattedUptime,
|
|
67
|
+
agentId: sessionInfo.agentId,
|
|
68
|
+
userEntityRef:
|
|
69
|
+
sessionInfo.userEntityRef || (session && session.userEntityRef),
|
|
70
|
+
sessionExpiresAt:
|
|
71
|
+
sessionInfo.sessionExpiresAt || (session && session.expiresAt),
|
|
72
|
+
status: 'connected', // Agent is connected if responding
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
ws.send(
|
|
76
|
+
JSON.stringify({
|
|
77
|
+
type: 'agentInfo',
|
|
78
|
+
info,
|
|
79
|
+
requestId: payload.requestId,
|
|
80
|
+
})
|
|
81
|
+
);
|
|
82
|
+
} catch (error) {
|
|
83
|
+
console.error('Error getting agent info:', error);
|
|
84
|
+
ws.send(
|
|
85
|
+
JSON.stringify({
|
|
86
|
+
type: 'error',
|
|
87
|
+
error: 'Failed to get agent info: ' + error.message,
|
|
88
|
+
requestId: payload.requestId,
|
|
89
|
+
})
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
async function handleExecInContainer(ws, clientId, payload) {
|
|
95
|
+
try {
|
|
96
|
+
const { containerId, command, requestId } = payload;
|
|
97
|
+
|
|
98
|
+
const container = docker.getContainer(containerId);
|
|
99
|
+
const exec = await container.exec({
|
|
100
|
+
AttachStdin: false,
|
|
101
|
+
AttachStdout: true,
|
|
102
|
+
AttachStderr: true,
|
|
103
|
+
Tty: false,
|
|
104
|
+
Cmd: ['/bin/sh', '-c', command],
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
const stream = await exec.start({ hijack: true, stdin: false });
|
|
108
|
+
let output = '';
|
|
109
|
+
|
|
110
|
+
stream.on('data', (chunk) => {
|
|
111
|
+
output += chunk.toString();
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
stream.on('end', () => {
|
|
115
|
+
ws.send(
|
|
116
|
+
JSON.stringify({
|
|
117
|
+
type: 'execResult',
|
|
118
|
+
containerId,
|
|
119
|
+
output,
|
|
120
|
+
requestId,
|
|
121
|
+
})
|
|
122
|
+
);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
stream.on('error', (err) => {
|
|
126
|
+
ws.send(
|
|
127
|
+
JSON.stringify({
|
|
128
|
+
type: 'error',
|
|
129
|
+
error: `Error executing command: ${err.message}`,
|
|
130
|
+
requestId,
|
|
131
|
+
})
|
|
132
|
+
);
|
|
133
|
+
});
|
|
134
|
+
} catch (error) {
|
|
135
|
+
console.error('Error executing command in container:', error);
|
|
136
|
+
ws.send(
|
|
137
|
+
JSON.stringify({
|
|
138
|
+
type: 'error',
|
|
139
|
+
error: 'Failed to execute command in container: ' + error.message,
|
|
140
|
+
requestId: payload.requestId,
|
|
141
|
+
})
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
async function handleGetDockerInfo(ws, payload = {}) {
|
|
147
|
+
try {
|
|
148
|
+
const info = await docker.info();
|
|
149
|
+
|
|
150
|
+
ws.send(
|
|
151
|
+
JSON.stringify({
|
|
152
|
+
type: 'dockerInfo',
|
|
153
|
+
info,
|
|
154
|
+
requestId: payload.requestId,
|
|
155
|
+
})
|
|
156
|
+
);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
console.error('Error getting Docker info:', error);
|
|
159
|
+
ws.send(
|
|
160
|
+
JSON.stringify({
|
|
161
|
+
type: 'error',
|
|
162
|
+
error: 'Failed to get Docker info: ' + error.message,
|
|
163
|
+
requestId: payload.requestId,
|
|
164
|
+
})
|
|
165
|
+
);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export default { handleGeneralAction, agentInfo, initializeAgentStartTime };
|
|
170
|
+
|
|
171
|
+
export { handleGeneralAction, agentInfo, initializeAgentStartTime };
|