|
|
@ -1,61 +1,80 @@ |
|
|
|
module.exports = function() { |
|
|
|
module.exports = function(io) { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var pty = require('pty.js'); |
|
|
|
|
|
|
|
var proc = require('child_process'); |
|
|
|
|
|
|
|
|
|
|
|
var module={}; |
|
|
|
var module={}; |
|
|
|
|
|
|
|
var idtoname = {}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function broadcast(signal, data) { |
|
|
|
|
|
|
|
console.log("<= signal: "+signal); |
|
|
|
|
|
|
|
io.sockets.emit(signal, data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function exec(cmd, callback) { |
|
|
|
|
|
|
|
console.log("== "+cmd); |
|
|
|
|
|
|
|
proc.exec(cmd, callback); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
module.connection = function(socket) { |
|
|
|
var oldcontainer = null; |
|
|
|
|
|
|
|
function containerinspect(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("inspect docker containers failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
JSON.parse(stdout).forEach(function(n) { |
|
|
|
|
|
|
|
idtoname[n.Id] = n.Name.replace(/^\//, '');; |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
if (oldcontainer && oldcontainer==stdout) return; // do not resend same containers
|
|
|
|
|
|
|
|
oldcontainer = stdout; |
|
|
|
|
|
|
|
broadcast("containers", stdout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function containerlist(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("list docker containers failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker inspect "+stdout.trim().replace(/\n/g, " "), containerinspect); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
//var sys = require('sys');
|
|
|
|
function updatecontainers(error, stdout, stderr) { |
|
|
|
var pty = require('pty.js'); |
|
|
|
if (error || stderr) |
|
|
|
var proc = require('child_process'); |
|
|
|
return fail("update docker container failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker ps -aq --no-trunc ", containerlist); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function stats(ids) { |
|
|
|
var oldimage = null; |
|
|
|
var res = {}; |
|
|
|
function imageinspect(error, stdout, stderr) { |
|
|
|
var fs = require('fs'); |
|
|
|
if (error || stderr) |
|
|
|
var async = require('async'); |
|
|
|
return fail("inspect docker images failed", { |
|
|
|
var base = "/sys/fs/cgroup/"; |
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
var dataPoints = { |
|
|
|
|
|
|
|
"cpuacct": [ |
|
|
|
|
|
|
|
"stat" |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
"memory": [ |
|
|
|
|
|
|
|
"usage_in_bytes", |
|
|
|
|
|
|
|
"max_usage_in_bytes" |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
async.each(ids, function(id, cb1) { |
|
|
|
|
|
|
|
res[id] = {}; |
|
|
|
|
|
|
|
async.forEachOf(dataPoints, function(val1, category, cb2) { |
|
|
|
|
|
|
|
res[id][category] = {}; |
|
|
|
|
|
|
|
async.each(val1, function(element, cb3) { |
|
|
|
|
|
|
|
var file = base + category + '/docker/' + id + '/' + category + '.' + element; |
|
|
|
|
|
|
|
res[id][category][element] = {}; |
|
|
|
|
|
|
|
fs.readFile(file, 'utf8', function(err, data) { |
|
|
|
|
|
|
|
if (err) {cb3(err); return} |
|
|
|
|
|
|
|
data.trim().split('\n').forEach(function(v, i) { |
|
|
|
|
|
|
|
var vals = v.split(' '); |
|
|
|
|
|
|
|
switch (vals.length) { |
|
|
|
|
|
|
|
case 1: |
|
|
|
|
|
|
|
res[id][category][element] = vals[0]; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 2: |
|
|
|
|
|
|
|
res[id][category][element][vals[0]] = vals[1]; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
cb3(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, function(err) { |
|
|
|
|
|
|
|
cb2(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, function(err) { |
|
|
|
|
|
|
|
cb1(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, function(err) { |
|
|
|
|
|
|
|
if (err) return; |
|
|
|
|
|
|
|
broadcast("stats", res); |
|
|
|
|
|
|
|
}); |
|
|
|
}); |
|
|
|
} |
|
|
|
if (oldimage && oldimage==stdout) return; // do not resend same images
|
|
|
|
|
|
|
|
oldimage = stdout; |
|
|
|
|
|
|
|
broadcast("images", stdout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function imagelist(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("list docker images failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker inspect "+stdout.trim().replace(/\n/g, " "), imageinspect); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateimages(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("update docker images failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker images -q --no-trunc", imagelist); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function connection(socket) { |
|
|
|
|
|
|
|
|
|
|
|
console.log("new client"); |
|
|
|
console.log("new client"); |
|
|
|
|
|
|
|
|
|
|
|
function emit(signal, data, info) { |
|
|
|
function emit(signal, data, info) { |
|
|
@ -68,80 +87,17 @@ module.exports = function() { |
|
|
|
socket.emit(signal, data); |
|
|
|
socket.emit(signal, data); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function broadcast(signal, data) { |
|
|
|
|
|
|
|
console.log("<= signal: "+signal); |
|
|
|
|
|
|
|
socket.broadcast.emit(signal, data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function exec(cmd, callback) { |
|
|
|
|
|
|
|
console.log("== "+cmd); |
|
|
|
|
|
|
|
proc.exec(cmd, callback); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function fail(txt, data) { |
|
|
|
function fail(txt, data) { |
|
|
|
console.log("** "+txt, data); |
|
|
|
console.log("** "+txt, data); |
|
|
|
emit("fail", txt); |
|
|
|
emit("fail", txt); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function containerinspect(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("inspect docker containers failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
emit("containers", stdout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function containerlist(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("list docker containers failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker inspect "+stdout.trim().replace(/\n/g, " "), containerinspect); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updatecontainers(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("update docker container failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker ps -aq --no-trunc ", containerlist); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function modify(cmd, name) { |
|
|
|
function modify(cmd, name) { |
|
|
|
if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) |
|
|
|
if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) |
|
|
|
return fail("illegal instance name"); |
|
|
|
return fail("illegal instance name"); |
|
|
|
exec("docker "+cmd+" "+name, updatecontainers); |
|
|
|
exec("docker "+cmd+" "+name, updatecontainers); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function containers() { |
|
|
|
|
|
|
|
console.log("-> containers"); |
|
|
|
|
|
|
|
updatecontainers(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function imageinspect(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("inspect docker images failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
emit("images", stdout); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function imagelist(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("list docker images failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker inspect "+stdout.trim().replace(/\n/g, " "), imageinspect); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function updateimages(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("update docker images failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
exec("docker images -q --no-trunc", imagelist); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function modify(cmd, name) { |
|
|
|
function modify(cmd, name) { |
|
|
|
if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) |
|
|
|
if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) |
|
|
|
return fail("illegal instance name"); |
|
|
|
return fail("illegal instance name"); |
|
|
@ -150,14 +106,16 @@ module.exports = function() { |
|
|
|
|
|
|
|
|
|
|
|
function containers() { |
|
|
|
function containers() { |
|
|
|
console.log("-> containers"); |
|
|
|
console.log("-> containers"); |
|
|
|
updatecontainers(); |
|
|
|
if (oldcontainer) emit("containers", oldcontainer); |
|
|
|
|
|
|
|
else updatecontainers(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function images() { |
|
|
|
function images() { |
|
|
|
console.log("-> images"); |
|
|
|
console.log("-> images"); |
|
|
|
updateimages(); |
|
|
|
if (oldimage) emit("images", oldimage); |
|
|
|
|
|
|
|
else updateimages(); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
function start(name) { |
|
|
|
function start(name) { |
|
|
|
console.log("-> start("+name+")"); |
|
|
|
console.log("-> start("+name+")"); |
|
|
|
modify("start", name); |
|
|
|
modify("start", name); |
|
|
@ -242,15 +200,73 @@ module.exports = function() { |
|
|
|
.on('bash-input', bash_input) |
|
|
|
.on('bash-input', bash_input) |
|
|
|
.on('bash-end', bash_end); |
|
|
|
.on('bash-end', bash_end); |
|
|
|
|
|
|
|
|
|
|
|
setInterval(function() { |
|
|
|
|
|
|
|
exec("docker ps -q --no-trunc ", function(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) return; // ignore
|
|
|
|
|
|
|
|
stats(stdout.trim().split('\n')); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
}, |
|
|
|
|
|
|
|
1000); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function stats() { |
|
|
|
|
|
|
|
var res = {}; |
|
|
|
|
|
|
|
var fs = require('fs'); |
|
|
|
|
|
|
|
var async = require('async'); |
|
|
|
|
|
|
|
var base = "/sys/fs/cgroup/"; |
|
|
|
|
|
|
|
var dataPoints = { |
|
|
|
|
|
|
|
"cpuacct": [ |
|
|
|
|
|
|
|
"usage" |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
"memory": [ |
|
|
|
|
|
|
|
"usage_in_bytes", |
|
|
|
|
|
|
|
"limit_in_bytes", |
|
|
|
|
|
|
|
"max_usage_in_bytes" |
|
|
|
|
|
|
|
] |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
async.forEachOf(idtoname, function(name, id, cb1) { |
|
|
|
|
|
|
|
res[name] = {}; |
|
|
|
|
|
|
|
async.forEachOf(dataPoints, function(val1, category, cb2) { |
|
|
|
|
|
|
|
res[name][category] = {}; |
|
|
|
|
|
|
|
async.each(val1, function(element, cb3) { |
|
|
|
|
|
|
|
var file = base + category + '/docker/' + id + '/' + category + '.' + element; |
|
|
|
|
|
|
|
fs.readFile(file, 'utf8', function(err, data) { |
|
|
|
|
|
|
|
res[name][category][element] = { |
|
|
|
|
|
|
|
date: (new Date()).getTime(), |
|
|
|
|
|
|
|
data: {} |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
if (err) {cb3(err); return} |
|
|
|
|
|
|
|
data.trim().split('\n').forEach(function(v, i) { |
|
|
|
|
|
|
|
var vals = v.split(' '); |
|
|
|
|
|
|
|
switch (vals.length) { |
|
|
|
|
|
|
|
case 1: |
|
|
|
|
|
|
|
res[name][category][element].data = parseInt(vals[0]); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
case 2: |
|
|
|
|
|
|
|
res[name][category][element].data[vals[0]] = parseInt(vals[1]); |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
cb3(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, function(err) { |
|
|
|
|
|
|
|
cb2(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, function(err) { |
|
|
|
|
|
|
|
cb1(); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
}, function(err) { |
|
|
|
|
|
|
|
if (err) return; |
|
|
|
|
|
|
|
broadcast("stats", res); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Handle Connection
|
|
|
|
|
|
|
|
io.sockets.on('connection', connection); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Regular Update of Stats
|
|
|
|
|
|
|
|
setInterval(function() { |
|
|
|
|
|
|
|
stats(); |
|
|
|
|
|
|
|
}, 1000); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Regular Update of Images and Containers
|
|
|
|
|
|
|
|
setInterval(function() { |
|
|
|
|
|
|
|
updateimages(); |
|
|
|
|
|
|
|
updatecontainers(); |
|
|
|
|
|
|
|
}, 10000); |
|
|
|
|
|
|
|
|
|
|
|
return module; |
|
|
|
return module; |
|
|
|
} |
|
|
|
} |
|
|
|