sysiddr5 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 sysiddr5 might be problematic. Click here for more details.

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;