siddr5 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of siddr5 might be problematic. Click here for more details.
- package/LICENSE +20 -0
- package/README.md +1091 -0
- package/lib/audio.js +222 -0
- package/lib/battery.js +308 -0
- package/lib/bluetooth.js +229 -0
- package/lib/cli.js +31 -0
- package/lib/cpu.js +1704 -0
- package/lib/docker.js +757 -0
- package/lib/dockerSocket.js +327 -0
- package/lib/filesystem.js +1495 -0
- package/lib/graphics.js +1103 -0
- package/lib/index.d.ts +1028 -0
- package/lib/index.js +504 -0
- package/lib/internet.js +236 -0
- package/lib/memory.js +555 -0
- package/lib/network.js +1779 -0
- package/lib/osinfo.js +1167 -0
- package/lib/printer.js +210 -0
- package/lib/processes.js +1289 -0
- package/lib/system.js +720 -0
- package/lib/usb.js +274 -0
- package/lib/users.js +363 -0
- package/lib/util.js +1303 -0
- package/lib/virtualbox.js +107 -0
- package/lib/wifi.js +744 -0
- package/package.json +94 -0
package/lib/docker.js
ADDED
@@ -0,0 +1,757 @@
|
|
1
|
+
'use strict';
|
2
|
+
// @ts-check
|
3
|
+
// ==================================================================================
|
4
|
+
// docker.js
|
5
|
+
// ----------------------------------------------------------------------------------
|
6
|
+
// Description: System Information - library
|
7
|
+
// for Node.js
|
8
|
+
// Copyright: (c) 2014 - 2023
|
9
|
+
// Author: Sebastian Hildebrandt
|
10
|
+
// ----------------------------------------------------------------------------------
|
11
|
+
// License: MIT
|
12
|
+
// ==================================================================================
|
13
|
+
// 13. Docker
|
14
|
+
// ----------------------------------------------------------------------------------
|
15
|
+
|
16
|
+
const util = require('./util');
|
17
|
+
const DockerSocket = require('./dockerSocket');
|
18
|
+
|
19
|
+
let _platform = process.platform;
|
20
|
+
const _windows = (_platform === 'win32');
|
21
|
+
|
22
|
+
let _docker_container_stats = {};
|
23
|
+
let _docker_socket;
|
24
|
+
let _docker_last_read = 0;
|
25
|
+
|
26
|
+
|
27
|
+
// --------------------------
|
28
|
+
// get containers (parameter all: get also inactive/exited containers)
|
29
|
+
|
30
|
+
function dockerInfo(callback) {
|
31
|
+
return new Promise((resolve) => {
|
32
|
+
process.nextTick(() => {
|
33
|
+
if (!_docker_socket) {
|
34
|
+
_docker_socket = new DockerSocket();
|
35
|
+
}
|
36
|
+
const result = {};
|
37
|
+
|
38
|
+
_docker_socket.getInfo((data) => {
|
39
|
+
result.id = data.ID;
|
40
|
+
result.containers = data.Containers;
|
41
|
+
result.containersRunning = data.ContainersRunning;
|
42
|
+
result.containersPaused = data.ContainersPaused;
|
43
|
+
result.containersStopped = data.ContainersStopped;
|
44
|
+
result.images = data.Images;
|
45
|
+
result.driver = data.Driver;
|
46
|
+
result.memoryLimit = data.MemoryLimit;
|
47
|
+
result.swapLimit = data.SwapLimit;
|
48
|
+
result.kernelMemory = data.KernelMemory;
|
49
|
+
result.cpuCfsPeriod = data.CpuCfsPeriod;
|
50
|
+
result.cpuCfsQuota = data.CpuCfsQuota;
|
51
|
+
result.cpuShares = data.CPUShares;
|
52
|
+
result.cpuSet = data.CPUSet;
|
53
|
+
result.ipv4Forwarding = data.IPv4Forwarding;
|
54
|
+
result.bridgeNfIptables = data.BridgeNfIptables;
|
55
|
+
result.bridgeNfIp6tables = data.BridgeNfIp6tables;
|
56
|
+
result.debug = data.Debug;
|
57
|
+
result.nfd = data.NFd;
|
58
|
+
result.oomKillDisable = data.OomKillDisable;
|
59
|
+
result.ngoroutines = data.NGoroutines;
|
60
|
+
result.systemTime = data.SystemTime;
|
61
|
+
result.loggingDriver = data.LoggingDriver;
|
62
|
+
result.cgroupDriver = data.CgroupDriver;
|
63
|
+
result.nEventsListener = data.NEventsListener;
|
64
|
+
result.kernelVersion = data.KernelVersion;
|
65
|
+
result.operatingSystem = data.OperatingSystem;
|
66
|
+
result.osType = data.OSType;
|
67
|
+
result.architecture = data.Architecture;
|
68
|
+
result.ncpu = data.NCPU;
|
69
|
+
result.memTotal = data.MemTotal;
|
70
|
+
result.dockerRootDir = data.DockerRootDir;
|
71
|
+
result.httpProxy = data.HttpProxy;
|
72
|
+
result.httpsProxy = data.HttpsProxy;
|
73
|
+
result.noProxy = data.NoProxy;
|
74
|
+
result.name = data.Name;
|
75
|
+
result.labels = data.Labels;
|
76
|
+
result.experimentalBuild = data.ExperimentalBuild;
|
77
|
+
result.serverVersion = data.ServerVersion;
|
78
|
+
result.clusterStore = data.ClusterStore;
|
79
|
+
result.clusterAdvertise = data.ClusterAdvertise;
|
80
|
+
result.defaultRuntime = data.DefaultRuntime;
|
81
|
+
result.liveRestoreEnabled = data.LiveRestoreEnabled;
|
82
|
+
result.isolation = data.Isolation;
|
83
|
+
result.initBinary = data.InitBinary;
|
84
|
+
result.productLicense = data.ProductLicense;
|
85
|
+
if (callback) { callback(result); }
|
86
|
+
resolve(result);
|
87
|
+
});
|
88
|
+
});
|
89
|
+
});
|
90
|
+
}
|
91
|
+
|
92
|
+
exports.dockerInfo = dockerInfo;
|
93
|
+
|
94
|
+
function dockerImages(all, callback) {
|
95
|
+
|
96
|
+
// fallback - if only callback is given
|
97
|
+
if (util.isFunction(all) && !callback) {
|
98
|
+
callback = all;
|
99
|
+
all = false;
|
100
|
+
}
|
101
|
+
if (typeof all === 'string' && all === 'true') {
|
102
|
+
all = true;
|
103
|
+
}
|
104
|
+
if (typeof all !== 'boolean' && all !== undefined) {
|
105
|
+
all = false;
|
106
|
+
}
|
107
|
+
|
108
|
+
all = all || false;
|
109
|
+
let result = [];
|
110
|
+
return new Promise((resolve) => {
|
111
|
+
process.nextTick(() => {
|
112
|
+
if (!_docker_socket) {
|
113
|
+
_docker_socket = new DockerSocket();
|
114
|
+
}
|
115
|
+
const workload = [];
|
116
|
+
|
117
|
+
_docker_socket.listImages(all, data => {
|
118
|
+
let dockerImages = {};
|
119
|
+
try {
|
120
|
+
dockerImages = data;
|
121
|
+
if (dockerImages && Object.prototype.toString.call(dockerImages) === '[object Array]' && dockerImages.length > 0) {
|
122
|
+
|
123
|
+
dockerImages.forEach(function (element) {
|
124
|
+
|
125
|
+
if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) {
|
126
|
+
element.Name = element.Names[0].replace(/^\/|\/$/g, '');
|
127
|
+
}
|
128
|
+
workload.push(dockerImagesInspect(element.Id.trim(), element));
|
129
|
+
});
|
130
|
+
if (workload.length) {
|
131
|
+
Promise.all(
|
132
|
+
workload
|
133
|
+
).then((data) => {
|
134
|
+
if (callback) { callback(data); }
|
135
|
+
resolve(data);
|
136
|
+
});
|
137
|
+
} else {
|
138
|
+
if (callback) { callback(result); }
|
139
|
+
resolve(result);
|
140
|
+
}
|
141
|
+
} else {
|
142
|
+
if (callback) { callback(result); }
|
143
|
+
resolve(result);
|
144
|
+
}
|
145
|
+
} catch (err) {
|
146
|
+
if (callback) { callback(result); }
|
147
|
+
resolve(result);
|
148
|
+
}
|
149
|
+
});
|
150
|
+
});
|
151
|
+
});
|
152
|
+
}
|
153
|
+
|
154
|
+
// --------------------------
|
155
|
+
// container inspect (for one container)
|
156
|
+
|
157
|
+
function dockerImagesInspect(imageID, payload) {
|
158
|
+
return new Promise((resolve) => {
|
159
|
+
process.nextTick(() => {
|
160
|
+
imageID = imageID || '';
|
161
|
+
if (typeof imageID !== 'string') {
|
162
|
+
return resolve();
|
163
|
+
}
|
164
|
+
const imageIDSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(imageID, true)).trim();
|
165
|
+
if (imageIDSanitized) {
|
166
|
+
|
167
|
+
if (!_docker_socket) {
|
168
|
+
_docker_socket = new DockerSocket();
|
169
|
+
}
|
170
|
+
|
171
|
+
_docker_socket.inspectImage(imageIDSanitized.trim(), data => {
|
172
|
+
try {
|
173
|
+
resolve({
|
174
|
+
id: payload.Id,
|
175
|
+
container: data.Container,
|
176
|
+
comment: data.Comment,
|
177
|
+
os: data.Os,
|
178
|
+
architecture: data.Architecture,
|
179
|
+
parent: data.Parent,
|
180
|
+
dockerVersion: data.DockerVersion,
|
181
|
+
size: data.Size,
|
182
|
+
sharedSize: payload.SharedSize,
|
183
|
+
virtualSize: data.VirtualSize,
|
184
|
+
author: data.Author,
|
185
|
+
created: data.Created ? Math.round(new Date(data.Created).getTime() / 1000) : 0,
|
186
|
+
containerConfig: data.ContainerConfig ? data.ContainerConfig : {},
|
187
|
+
graphDriver: data.GraphDriver ? data.GraphDriver : {},
|
188
|
+
repoDigests: data.RepoDigests ? data.RepoDigests : {},
|
189
|
+
repoTags: data.RepoTags ? data.RepoTags : {},
|
190
|
+
config: data.Config ? data.Config : {},
|
191
|
+
rootFS: data.RootFS ? data.RootFS : {},
|
192
|
+
});
|
193
|
+
} catch (err) {
|
194
|
+
resolve();
|
195
|
+
}
|
196
|
+
});
|
197
|
+
} else {
|
198
|
+
resolve();
|
199
|
+
}
|
200
|
+
});
|
201
|
+
});
|
202
|
+
}
|
203
|
+
|
204
|
+
exports.dockerImages = dockerImages;
|
205
|
+
|
206
|
+
function dockerContainers(all, callback) {
|
207
|
+
|
208
|
+
function inContainers(containers, id) {
|
209
|
+
let filtered = containers.filter(obj => {
|
210
|
+
/**
|
211
|
+
* @namespace
|
212
|
+
* @property {string} Id
|
213
|
+
*/
|
214
|
+
return (obj.Id && (obj.Id === id));
|
215
|
+
});
|
216
|
+
return (filtered.length > 0);
|
217
|
+
}
|
218
|
+
|
219
|
+
// fallback - if only callback is given
|
220
|
+
if (util.isFunction(all) && !callback) {
|
221
|
+
callback = all;
|
222
|
+
all = false;
|
223
|
+
}
|
224
|
+
if (typeof all === 'string' && all === 'true') {
|
225
|
+
all = true;
|
226
|
+
}
|
227
|
+
if (typeof all !== 'boolean' && all !== undefined) {
|
228
|
+
all = false;
|
229
|
+
}
|
230
|
+
|
231
|
+
all = all || false;
|
232
|
+
let result = [];
|
233
|
+
return new Promise((resolve) => {
|
234
|
+
process.nextTick(() => {
|
235
|
+
if (!_docker_socket) {
|
236
|
+
_docker_socket = new DockerSocket();
|
237
|
+
}
|
238
|
+
const workload = [];
|
239
|
+
|
240
|
+
_docker_socket.listContainers(all, data => {
|
241
|
+
let docker_containers = {};
|
242
|
+
try {
|
243
|
+
docker_containers = data;
|
244
|
+
if (docker_containers && Object.prototype.toString.call(docker_containers) === '[object Array]' && docker_containers.length > 0) {
|
245
|
+
// GC in _docker_container_stats
|
246
|
+
for (let key in _docker_container_stats) {
|
247
|
+
if ({}.hasOwnProperty.call(_docker_container_stats, key)) {
|
248
|
+
if (!inContainers(docker_containers, key)) { delete _docker_container_stats[key]; }
|
249
|
+
}
|
250
|
+
}
|
251
|
+
|
252
|
+
docker_containers.forEach(function (element) {
|
253
|
+
|
254
|
+
if (element.Names && Object.prototype.toString.call(element.Names) === '[object Array]' && element.Names.length > 0) {
|
255
|
+
element.Name = element.Names[0].replace(/^\/|\/$/g, '');
|
256
|
+
}
|
257
|
+
workload.push(dockerContainerInspect(element.Id.trim(), element));
|
258
|
+
});
|
259
|
+
if (workload.length) {
|
260
|
+
Promise.all(
|
261
|
+
workload
|
262
|
+
).then((data) => {
|
263
|
+
if (callback) { callback(data); }
|
264
|
+
resolve(data);
|
265
|
+
});
|
266
|
+
} else {
|
267
|
+
if (callback) { callback(result); }
|
268
|
+
resolve(result);
|
269
|
+
}
|
270
|
+
} else {
|
271
|
+
if (callback) { callback(result); }
|
272
|
+
resolve(result);
|
273
|
+
}
|
274
|
+
} catch (err) {
|
275
|
+
// GC in _docker_container_stats
|
276
|
+
for (let key in _docker_container_stats) {
|
277
|
+
if ({}.hasOwnProperty.call(_docker_container_stats, key)) {
|
278
|
+
if (!inContainers(docker_containers, key)) { delete _docker_container_stats[key]; }
|
279
|
+
}
|
280
|
+
}
|
281
|
+
if (callback) { callback(result); }
|
282
|
+
resolve(result);
|
283
|
+
}
|
284
|
+
});
|
285
|
+
});
|
286
|
+
});
|
287
|
+
}
|
288
|
+
|
289
|
+
// --------------------------
|
290
|
+
// container inspect (for one container)
|
291
|
+
|
292
|
+
function dockerContainerInspect(containerID, payload) {
|
293
|
+
return new Promise((resolve) => {
|
294
|
+
process.nextTick(() => {
|
295
|
+
containerID = containerID || '';
|
296
|
+
if (typeof containerID !== 'string') {
|
297
|
+
return resolve();
|
298
|
+
}
|
299
|
+
const containerIdSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerID, true)).trim();
|
300
|
+
if (containerIdSanitized) {
|
301
|
+
|
302
|
+
if (!_docker_socket) {
|
303
|
+
_docker_socket = new DockerSocket();
|
304
|
+
}
|
305
|
+
|
306
|
+
_docker_socket.getInspect(containerIdSanitized.trim(), data => {
|
307
|
+
try {
|
308
|
+
resolve({
|
309
|
+
id: payload.Id,
|
310
|
+
name: payload.Name,
|
311
|
+
image: payload.Image,
|
312
|
+
imageID: payload.ImageID,
|
313
|
+
command: payload.Command,
|
314
|
+
created: payload.Created,
|
315
|
+
started: data.State && data.State.StartedAt ? Math.round(new Date(data.State.StartedAt).getTime() / 1000) : 0,
|
316
|
+
finished: data.State && data.State.FinishedAt && !data.State.FinishedAt.startsWith('0001-01-01') ? Math.round(new Date(data.State.FinishedAt).getTime() / 1000) : 0,
|
317
|
+
createdAt: data.Created ? data.Created : '',
|
318
|
+
startedAt: data.State && data.State.StartedAt ? data.State.StartedAt : '',
|
319
|
+
finishedAt: data.State && data.State.FinishedAt && !data.State.FinishedAt.startsWith('0001-01-01') ? data.State.FinishedAt : '',
|
320
|
+
state: payload.State,
|
321
|
+
restartCount: data.RestartCount || 0,
|
322
|
+
platform: data.Platform || '',
|
323
|
+
driver: data.Driver || '',
|
324
|
+
ports: payload.Ports,
|
325
|
+
mounts: payload.Mounts,
|
326
|
+
// hostconfig: payload.HostConfig,
|
327
|
+
// network: payload.NetworkSettings
|
328
|
+
});
|
329
|
+
} catch (err) {
|
330
|
+
resolve();
|
331
|
+
}
|
332
|
+
});
|
333
|
+
} else {
|
334
|
+
resolve();
|
335
|
+
}
|
336
|
+
});
|
337
|
+
});
|
338
|
+
}
|
339
|
+
|
340
|
+
exports.dockerContainers = dockerContainers;
|
341
|
+
|
342
|
+
// --------------------------
|
343
|
+
// helper functions for calculation of docker stats
|
344
|
+
|
345
|
+
function docker_calcCPUPercent(cpu_stats, precpu_stats) {
|
346
|
+
/**
|
347
|
+
* @namespace
|
348
|
+
* @property {object} cpu_usage
|
349
|
+
* @property {number} cpu_usage.total_usage
|
350
|
+
* @property {number} system_cpu_usage
|
351
|
+
* @property {object} cpu_usage
|
352
|
+
* @property {Array} cpu_usage.percpu_usage
|
353
|
+
*/
|
354
|
+
|
355
|
+
if (!_windows) {
|
356
|
+
let cpuPercent = 0.0;
|
357
|
+
// calculate the change for the cpu usage of the container in between readings
|
358
|
+
let cpuDelta = cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage;
|
359
|
+
// calculate the change for the entire system between readings
|
360
|
+
let systemDelta = cpu_stats.system_cpu_usage - precpu_stats.system_cpu_usage;
|
361
|
+
|
362
|
+
if (systemDelta > 0.0 && cpuDelta > 0.0) {
|
363
|
+
// calculate the change for the cpu usage of the container in between readings
|
364
|
+
if (precpu_stats.online_cpus) {
|
365
|
+
cpuPercent = (cpuDelta / systemDelta) * precpu_stats.online_cpus * 100.0;
|
366
|
+
}
|
367
|
+
else {
|
368
|
+
cpuPercent = (cpuDelta / systemDelta) * cpu_stats.cpu_usage.percpu_usage.length * 100.0;
|
369
|
+
}
|
370
|
+
}
|
371
|
+
|
372
|
+
return cpuPercent;
|
373
|
+
} else {
|
374
|
+
let nanoSecNow = util.nanoSeconds();
|
375
|
+
let cpuPercent = 0.0;
|
376
|
+
if (_docker_last_read > 0) {
|
377
|
+
let possIntervals = (nanoSecNow - _docker_last_read); // / 100 * os.cpus().length;
|
378
|
+
let intervalsUsed = cpu_stats.cpu_usage.total_usage - precpu_stats.cpu_usage.total_usage;
|
379
|
+
if (possIntervals > 0) {
|
380
|
+
cpuPercent = 100.0 * intervalsUsed / possIntervals;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
_docker_last_read = nanoSecNow;
|
384
|
+
return cpuPercent;
|
385
|
+
}
|
386
|
+
}
|
387
|
+
|
388
|
+
function docker_calcNetworkIO(networks) {
|
389
|
+
let rx;
|
390
|
+
let wx;
|
391
|
+
for (let key in networks) {
|
392
|
+
// skip loop if the property is from prototype
|
393
|
+
if (!{}.hasOwnProperty.call(networks, key)) { continue; }
|
394
|
+
|
395
|
+
/**
|
396
|
+
* @namespace
|
397
|
+
* @property {number} rx_bytes
|
398
|
+
* @property {number} tx_bytes
|
399
|
+
*/
|
400
|
+
let obj = networks[key];
|
401
|
+
rx = +obj.rx_bytes;
|
402
|
+
wx = +obj.tx_bytes;
|
403
|
+
}
|
404
|
+
return {
|
405
|
+
rx,
|
406
|
+
wx
|
407
|
+
};
|
408
|
+
}
|
409
|
+
|
410
|
+
function docker_calcBlockIO(blkio_stats) {
|
411
|
+
let result = {
|
412
|
+
r: 0,
|
413
|
+
w: 0
|
414
|
+
};
|
415
|
+
|
416
|
+
/**
|
417
|
+
* @namespace
|
418
|
+
* @property {Array} io_service_bytes_recursive
|
419
|
+
*/
|
420
|
+
if (blkio_stats && blkio_stats.io_service_bytes_recursive && Object.prototype.toString.call(blkio_stats.io_service_bytes_recursive) === '[object Array]' && blkio_stats.io_service_bytes_recursive.length > 0) {
|
421
|
+
blkio_stats.io_service_bytes_recursive.forEach(function (element) {
|
422
|
+
/**
|
423
|
+
* @namespace
|
424
|
+
* @property {string} op
|
425
|
+
* @property {number} value
|
426
|
+
*/
|
427
|
+
|
428
|
+
if (element.op && element.op.toLowerCase() === 'read' && element.value) {
|
429
|
+
result.r += element.value;
|
430
|
+
}
|
431
|
+
if (element.op && element.op.toLowerCase() === 'write' && element.value) {
|
432
|
+
result.w += element.value;
|
433
|
+
}
|
434
|
+
});
|
435
|
+
}
|
436
|
+
return result;
|
437
|
+
}
|
438
|
+
|
439
|
+
function dockerContainerStats(containerIDs, callback) {
|
440
|
+
|
441
|
+
let containerArray = [];
|
442
|
+
return new Promise((resolve) => {
|
443
|
+
process.nextTick(() => {
|
444
|
+
|
445
|
+
// fallback - if only callback is given
|
446
|
+
if (util.isFunction(containerIDs) && !callback) {
|
447
|
+
callback = containerIDs;
|
448
|
+
containerArray = ['*'];
|
449
|
+
} else {
|
450
|
+
containerIDs = containerIDs || '*';
|
451
|
+
if (typeof containerIDs !== 'string') {
|
452
|
+
if (callback) { callback([]); }
|
453
|
+
return resolve([]);
|
454
|
+
}
|
455
|
+
let containerIDsSanitized = '';
|
456
|
+
containerIDsSanitized.__proto__.toLowerCase = util.stringToLower;
|
457
|
+
containerIDsSanitized.__proto__.replace = util.stringReplace;
|
458
|
+
containerIDsSanitized.__proto__.trim = util.stringTrim;
|
459
|
+
|
460
|
+
containerIDsSanitized = containerIDs;
|
461
|
+
containerIDsSanitized = containerIDsSanitized.trim();
|
462
|
+
if (containerIDsSanitized !== '*') {
|
463
|
+
containerIDsSanitized = '';
|
464
|
+
const s = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerIDs, true)).trim();
|
465
|
+
for (let i = 0; i <= util.mathMin(s.length, 2000); i++) {
|
466
|
+
if (s[i] !== undefined) {
|
467
|
+
s[i].__proto__.toLowerCase = util.stringToLower;
|
468
|
+
const sl = s[i].toLowerCase();
|
469
|
+
if (sl && sl[0] && !sl[1]) {
|
470
|
+
containerIDsSanitized = containerIDsSanitized + sl[0];
|
471
|
+
}
|
472
|
+
}
|
473
|
+
}
|
474
|
+
}
|
475
|
+
|
476
|
+
containerIDsSanitized = containerIDsSanitized.trim().toLowerCase().replace(/,+/g, '|');
|
477
|
+
containerArray = containerIDsSanitized.split('|');
|
478
|
+
}
|
479
|
+
|
480
|
+
const result = [];
|
481
|
+
|
482
|
+
const workload = [];
|
483
|
+
if (containerArray.length && containerArray[0].trim() === '*') {
|
484
|
+
containerArray = [];
|
485
|
+
dockerContainers().then(allContainers => {
|
486
|
+
for (let container of allContainers) {
|
487
|
+
containerArray.push(container.id.substring(0, 12));
|
488
|
+
}
|
489
|
+
if (containerArray.length) {
|
490
|
+
dockerContainerStats(containerArray.join(',')).then(result => {
|
491
|
+
if (callback) { callback(result); }
|
492
|
+
resolve(result);
|
493
|
+
});
|
494
|
+
} else {
|
495
|
+
if (callback) { callback(result); }
|
496
|
+
resolve(result);
|
497
|
+
}
|
498
|
+
});
|
499
|
+
} else {
|
500
|
+
for (let containerID of containerArray) {
|
501
|
+
workload.push(dockerContainerStatsSingle(containerID.trim()));
|
502
|
+
}
|
503
|
+
if (workload.length) {
|
504
|
+
Promise.all(
|
505
|
+
workload
|
506
|
+
).then((data) => {
|
507
|
+
if (callback) { callback(data); }
|
508
|
+
resolve(data);
|
509
|
+
});
|
510
|
+
} else {
|
511
|
+
if (callback) { callback(result); }
|
512
|
+
resolve(result);
|
513
|
+
}
|
514
|
+
}
|
515
|
+
});
|
516
|
+
});
|
517
|
+
}
|
518
|
+
|
519
|
+
// --------------------------
|
520
|
+
// container stats (for one container)
|
521
|
+
|
522
|
+
function dockerContainerStatsSingle(containerID) {
|
523
|
+
containerID = containerID || '';
|
524
|
+
let result = {
|
525
|
+
id: containerID,
|
526
|
+
memUsage: 0,
|
527
|
+
memLimit: 0,
|
528
|
+
memPercent: 0,
|
529
|
+
cpuPercent: 0,
|
530
|
+
pids: 0,
|
531
|
+
netIO: {
|
532
|
+
rx: 0,
|
533
|
+
wx: 0
|
534
|
+
},
|
535
|
+
blockIO: {
|
536
|
+
r: 0,
|
537
|
+
w: 0
|
538
|
+
},
|
539
|
+
restartCount: 0,
|
540
|
+
cpuStats: {},
|
541
|
+
precpuStats: {},
|
542
|
+
memoryStats: {},
|
543
|
+
networks: {},
|
544
|
+
};
|
545
|
+
return new Promise((resolve) => {
|
546
|
+
process.nextTick(() => {
|
547
|
+
if (containerID) {
|
548
|
+
|
549
|
+
if (!_docker_socket) {
|
550
|
+
_docker_socket = new DockerSocket();
|
551
|
+
}
|
552
|
+
|
553
|
+
_docker_socket.getInspect(containerID, dataInspect => {
|
554
|
+
try {
|
555
|
+
_docker_socket.getStats(containerID, data => {
|
556
|
+
try {
|
557
|
+
let stats = data;
|
558
|
+
if (!stats.message) {
|
559
|
+
if (data.id) { result.id = data.id; }
|
560
|
+
result.memUsage = (stats.memory_stats && stats.memory_stats.usage ? stats.memory_stats.usage : 0);
|
561
|
+
result.memLimit = (stats.memory_stats && stats.memory_stats.limit ? stats.memory_stats.limit : 0);
|
562
|
+
result.memPercent = (stats.memory_stats && stats.memory_stats.usage && stats.memory_stats.limit ? stats.memory_stats.usage / stats.memory_stats.limit * 100.0 : 0);
|
563
|
+
result.cpuPercent = (stats.cpu_stats && stats.precpu_stats ? docker_calcCPUPercent(stats.cpu_stats, stats.precpu_stats) : 0);
|
564
|
+
result.pids = (stats.pids_stats && stats.pids_stats.current ? stats.pids_stats.current : 0);
|
565
|
+
result.restartCount = (dataInspect.RestartCount ? dataInspect.RestartCount : 0);
|
566
|
+
if (stats.networks) { result.netIO = docker_calcNetworkIO(stats.networks); }
|
567
|
+
if (stats.blkio_stats) { result.blockIO = docker_calcBlockIO(stats.blkio_stats); }
|
568
|
+
result.cpuStats = (stats.cpu_stats ? stats.cpu_stats : {});
|
569
|
+
result.precpuStats = (stats.precpu_stats ? stats.precpu_stats : {});
|
570
|
+
result.memoryStats = (stats.memory_stats ? stats.memory_stats : {});
|
571
|
+
result.networks = (stats.networks ? stats.networks : {});
|
572
|
+
}
|
573
|
+
} catch (err) {
|
574
|
+
util.noop();
|
575
|
+
}
|
576
|
+
// }
|
577
|
+
resolve(result);
|
578
|
+
});
|
579
|
+
} catch (err) {
|
580
|
+
util.noop();
|
581
|
+
}
|
582
|
+
});
|
583
|
+
} else {
|
584
|
+
resolve(result);
|
585
|
+
}
|
586
|
+
});
|
587
|
+
});
|
588
|
+
}
|
589
|
+
|
590
|
+
exports.dockerContainerStats = dockerContainerStats;
|
591
|
+
|
592
|
+
// --------------------------
|
593
|
+
// container processes (for one container)
|
594
|
+
|
595
|
+
function dockerContainerProcesses(containerID, callback) {
|
596
|
+
let result = [];
|
597
|
+
return new Promise((resolve) => {
|
598
|
+
process.nextTick(() => {
|
599
|
+
containerID = containerID || '';
|
600
|
+
if (typeof containerID !== 'string') {
|
601
|
+
return resolve(result);
|
602
|
+
}
|
603
|
+
const containerIdSanitized = (util.isPrototypePolluted() ? '' : util.sanitizeShellString(containerID, true)).trim();
|
604
|
+
|
605
|
+
if (containerIdSanitized) {
|
606
|
+
|
607
|
+
if (!_docker_socket) {
|
608
|
+
_docker_socket = new DockerSocket();
|
609
|
+
}
|
610
|
+
|
611
|
+
_docker_socket.getProcesses(containerIdSanitized, data => {
|
612
|
+
/**
|
613
|
+
* @namespace
|
614
|
+
* @property {Array} Titles
|
615
|
+
* @property {Array} Processes
|
616
|
+
**/
|
617
|
+
try {
|
618
|
+
if (data && data.Titles && data.Processes) {
|
619
|
+
let titles = data.Titles.map(function (value) {
|
620
|
+
return value.toUpperCase();
|
621
|
+
});
|
622
|
+
let pos_pid = titles.indexOf('PID');
|
623
|
+
let pos_ppid = titles.indexOf('PPID');
|
624
|
+
let pos_pgid = titles.indexOf('PGID');
|
625
|
+
let pos_vsz = titles.indexOf('VSZ');
|
626
|
+
let pos_time = titles.indexOf('TIME');
|
627
|
+
let pos_elapsed = titles.indexOf('ELAPSED');
|
628
|
+
let pos_ni = titles.indexOf('NI');
|
629
|
+
let pos_ruser = titles.indexOf('RUSER');
|
630
|
+
let pos_user = titles.indexOf('USER');
|
631
|
+
let pos_rgroup = titles.indexOf('RGROUP');
|
632
|
+
let pos_group = titles.indexOf('GROUP');
|
633
|
+
let pos_stat = titles.indexOf('STAT');
|
634
|
+
let pos_rss = titles.indexOf('RSS');
|
635
|
+
let pos_command = titles.indexOf('COMMAND');
|
636
|
+
|
637
|
+
data.Processes.forEach(process => {
|
638
|
+
result.push({
|
639
|
+
pidHost: (pos_pid >= 0 ? process[pos_pid] : ''),
|
640
|
+
ppid: (pos_ppid >= 0 ? process[pos_ppid] : ''),
|
641
|
+
pgid: (pos_pgid >= 0 ? process[pos_pgid] : ''),
|
642
|
+
user: (pos_user >= 0 ? process[pos_user] : ''),
|
643
|
+
ruser: (pos_ruser >= 0 ? process[pos_ruser] : ''),
|
644
|
+
group: (pos_group >= 0 ? process[pos_group] : ''),
|
645
|
+
rgroup: (pos_rgroup >= 0 ? process[pos_rgroup] : ''),
|
646
|
+
stat: (pos_stat >= 0 ? process[pos_stat] : ''),
|
647
|
+
time: (pos_time >= 0 ? process[pos_time] : ''),
|
648
|
+
elapsed: (pos_elapsed >= 0 ? process[pos_elapsed] : ''),
|
649
|
+
nice: (pos_ni >= 0 ? process[pos_ni] : ''),
|
650
|
+
rss: (pos_rss >= 0 ? process[pos_rss] : ''),
|
651
|
+
vsz: (pos_vsz >= 0 ? process[pos_vsz] : ''),
|
652
|
+
command: (pos_command >= 0 ? process[pos_command] : '')
|
653
|
+
});
|
654
|
+
});
|
655
|
+
}
|
656
|
+
} catch (err) {
|
657
|
+
util.noop();
|
658
|
+
}
|
659
|
+
if (callback) { callback(result); }
|
660
|
+
resolve(result);
|
661
|
+
});
|
662
|
+
} else {
|
663
|
+
if (callback) { callback(result); }
|
664
|
+
resolve(result);
|
665
|
+
}
|
666
|
+
});
|
667
|
+
});
|
668
|
+
}
|
669
|
+
|
670
|
+
exports.dockerContainerProcesses = dockerContainerProcesses;
|
671
|
+
|
672
|
+
function dockerVolumes(callback) {
|
673
|
+
|
674
|
+
let result = [];
|
675
|
+
return new Promise((resolve) => {
|
676
|
+
process.nextTick(() => {
|
677
|
+
if (!_docker_socket) {
|
678
|
+
_docker_socket = new DockerSocket();
|
679
|
+
}
|
680
|
+
_docker_socket.listVolumes((data) => {
|
681
|
+
let dockerVolumes = {};
|
682
|
+
try {
|
683
|
+
dockerVolumes = data;
|
684
|
+
if (dockerVolumes && dockerVolumes.Volumes && Object.prototype.toString.call(dockerVolumes.Volumes) === '[object Array]' && dockerVolumes.Volumes.length > 0) {
|
685
|
+
|
686
|
+
dockerVolumes.Volumes.forEach(function (element) {
|
687
|
+
|
688
|
+
result.push({
|
689
|
+
name: element.Name,
|
690
|
+
driver: element.Driver,
|
691
|
+
labels: element.Labels,
|
692
|
+
mountpoint: element.Mountpoint,
|
693
|
+
options: element.Options,
|
694
|
+
scope: element.Scope,
|
695
|
+
created: element.CreatedAt ? Math.round(new Date(element.CreatedAt).getTime() / 1000) : 0,
|
696
|
+
});
|
697
|
+
});
|
698
|
+
if (callback) { callback(result); }
|
699
|
+
resolve(result);
|
700
|
+
} else {
|
701
|
+
if (callback) { callback(result); }
|
702
|
+
resolve(result);
|
703
|
+
}
|
704
|
+
} catch (err) {
|
705
|
+
if (callback) { callback(result); }
|
706
|
+
resolve(result);
|
707
|
+
}
|
708
|
+
});
|
709
|
+
});
|
710
|
+
});
|
711
|
+
}
|
712
|
+
|
713
|
+
exports.dockerVolumes = dockerVolumes;
|
714
|
+
|
715
|
+
function dockerAll(callback) {
|
716
|
+
return new Promise((resolve) => {
|
717
|
+
process.nextTick(() => {
|
718
|
+
dockerContainers(true).then(result => {
|
719
|
+
if (result && Object.prototype.toString.call(result) === '[object Array]' && result.length > 0) {
|
720
|
+
let l = result.length;
|
721
|
+
result.forEach(function (element) {
|
722
|
+
dockerContainerStats(element.id).then((res) => {
|
723
|
+
// include stats in array
|
724
|
+
element.memUsage = res[0].memUsage;
|
725
|
+
element.memLimit = res[0].memLimit;
|
726
|
+
element.memPercent = res[0].memPercent;
|
727
|
+
element.cpuPercent = res[0].cpuPercent;
|
728
|
+
element.pids = res[0].pids;
|
729
|
+
element.netIO = res[0].netIO;
|
730
|
+
element.blockIO = res[0].blockIO;
|
731
|
+
element.cpuStats = res[0].cpuStats;
|
732
|
+
element.precpuStats = res[0].precpuStats;
|
733
|
+
element.memoryStats = res[0].memoryStats;
|
734
|
+
element.networks = res[0].networks;
|
735
|
+
|
736
|
+
dockerContainerProcesses(element.id).then(processes => {
|
737
|
+
element.processes = processes;
|
738
|
+
|
739
|
+
l -= 1;
|
740
|
+
if (l === 0) {
|
741
|
+
if (callback) { callback(result); }
|
742
|
+
resolve(result);
|
743
|
+
}
|
744
|
+
});
|
745
|
+
// all done??
|
746
|
+
});
|
747
|
+
});
|
748
|
+
} else {
|
749
|
+
if (callback) { callback(result); }
|
750
|
+
resolve(result);
|
751
|
+
}
|
752
|
+
});
|
753
|
+
});
|
754
|
+
});
|
755
|
+
}
|
756
|
+
|
757
|
+
exports.dockerAll = dockerAll;
|