|
|
@ -1,247 +1,17 @@ |
|
|
|
module.exports = function(app, io, docker, authentication) { |
|
|
|
module.exports = function(app, io, authentication) { |
|
|
|
|
|
|
|
|
|
|
|
var pty = require('pty.js'); |
|
|
|
var docker = require('docker.js')(app, io); |
|
|
|
var proc = require('child_process'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var module={}; |
|
|
|
|
|
|
|
var running=""; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function broadcast(signal, data) { |
|
|
|
|
|
|
|
console.log("<= signal: "+signal); |
|
|
|
|
|
|
|
io.sockets.emit(signal, data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function exec(cmd, callback) { |
|
|
|
|
|
|
|
if (cmd.length>40) { |
|
|
|
|
|
|
|
console.log("== "+cmd.slice(0, 30+cmd.slice(30).indexOf(' '))+" ..."); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
console.log("== "+cmd); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
proc.exec(cmd, {maxBuffer: 10*1024*1024}, callback); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function fail(txt, data) { |
|
|
|
|
|
|
|
console.log("** "+txt, data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var oldcontainer = null; |
|
|
|
|
|
|
|
function containerinspect(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("inspect docker containers failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
running = ""; |
|
|
|
|
|
|
|
JSON.parse(stdout).forEach(function(n) { |
|
|
|
|
|
|
|
if (n.State.Running) running+=" "+n.Name.replace(/^\//, ''); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
if (oldcontainer!=stdout) broadcast("containers", stdout); |
|
|
|
|
|
|
|
oldcontainer = stdout; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function containerlist(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("list docker containers failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
var containers = stdout.trim().replace(/\n/g, " "); |
|
|
|
|
|
|
|
exec("docker inspect "+containers, 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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var oldimage = null; |
|
|
|
|
|
|
|
function imageinspect(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("inspect docker images failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
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); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// New Authenticated Client
|
|
|
|
function connection(socket, userdata) { |
|
|
|
function connection(socket, userdata) { |
|
|
|
|
|
|
|
|
|
|
|
console.log("=> new connection from "+userdata.username); |
|
|
|
console.log("=> new connection from "+userdata.username); |
|
|
|
|
|
|
|
docker.connect(socket); |
|
|
|
function emit(signal, data, info) { |
|
|
|
|
|
|
|
if (typeof data == 'string' && !data.match("\n")) { |
|
|
|
|
|
|
|
console.log("<- signal: "+signal+"("+data+")"); |
|
|
|
|
|
|
|
} else { |
|
|
|
|
|
|
|
console.log("<- signal: "+signal); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (info) console.log(info); |
|
|
|
|
|
|
|
socket.emit(signal, data); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function fail(txt, data) { |
|
|
|
|
|
|
|
console.log("** "+txt, data); |
|
|
|
|
|
|
|
emit("fail", txt); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function modify(cmd, name) { |
|
|
|
|
|
|
|
if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) |
|
|
|
|
|
|
|
return this.fail("illegal instance name"); |
|
|
|
|
|
|
|
exec("docker "+cmd+" "+name, updatecontainers); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function createContainer(cmds) { |
|
|
|
|
|
|
|
if (cmds.length>0) |
|
|
|
|
|
|
|
exec(cmds.shift(), function(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return this.fail("create container failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
createContainer(cmds); |
|
|
|
|
|
|
|
}) |
|
|
|
|
|
|
|
else |
|
|
|
|
|
|
|
updatecontainers(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function containers() { |
|
|
|
|
|
|
|
console.log("-> containers"); |
|
|
|
|
|
|
|
if (oldcontainer) emit("containers", oldcontainer); |
|
|
|
|
|
|
|
else updatecontainers(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function images() { |
|
|
|
|
|
|
|
console.log("-> images"); |
|
|
|
|
|
|
|
if (oldimage) emit("images", oldimage); |
|
|
|
|
|
|
|
else updateimages(); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function start(name) { |
|
|
|
|
|
|
|
console.log("-> start("+name+")"); |
|
|
|
|
|
|
|
modify("start", name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function stop(name) { |
|
|
|
|
|
|
|
console.log("-> stop("+name+")"); |
|
|
|
|
|
|
|
modify("stop", name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function pause(name) { |
|
|
|
|
|
|
|
console.log("-> pause("+name+")"); |
|
|
|
|
|
|
|
modify("pause", name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function unpause(name) { |
|
|
|
|
|
|
|
console.log("-> unpause("+name+")"); |
|
|
|
|
|
|
|
modify("unpause", name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function remove(name) { |
|
|
|
|
|
|
|
console.log("-> remove("+name+")"); |
|
|
|
|
|
|
|
modify("rm", name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function create(data) { |
|
|
|
|
|
|
|
console.log("-> create"); |
|
|
|
|
|
|
|
var d = new docker.Docker(); |
|
|
|
|
|
|
|
var dc = new d.Containers(); |
|
|
|
|
|
|
|
createContainer(dc.creation(data)); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function logs(name) { |
|
|
|
|
|
|
|
console.log("-> logs("+name+")"); |
|
|
|
|
|
|
|
var l = proc.spawn("docker", ["logs", "-f", name]) |
|
|
|
|
|
|
|
.on('close', function(code) { |
|
|
|
|
|
|
|
emit('logs', {name: name, type: 'done'}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
l.stdout.on('data', function(data) { |
|
|
|
|
|
|
|
emit('logs', {name: name, type: 'stdout', text: data.toString()}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
l.stderr.on('data', function(data) { |
|
|
|
|
|
|
|
emit('logs', {name: name, type: 'stderr', text: data.toString()}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var bash_connections = {}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function new_bash(name) { |
|
|
|
|
|
|
|
if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) |
|
|
|
|
|
|
|
return this.fail("illegal instance name"); |
|
|
|
|
|
|
|
if (bash_connections[name]) return; |
|
|
|
|
|
|
|
bash_connections[name] = pty.spawn("docker", ["exec", "-it", name, "bash", "-i"]); |
|
|
|
|
|
|
|
bash_connections[name].stdout.on('data', function(data) { |
|
|
|
|
|
|
|
emit('bash-data', {name: name, type: 'stdout', text: data.toString()}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
bash_connections[name].stderr.on('data', function(data) { |
|
|
|
|
|
|
|
emit('bash-data', {name: name, type: 'stderr', text: data.toString()}); |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function bash_start(name) { |
|
|
|
|
|
|
|
console.log("-> bash-start("+name+")"); |
|
|
|
|
|
|
|
new_bash(name); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function bash_input(data) { |
|
|
|
|
|
|
|
console.log("-> bash-input("+data.name+", "+data.text+")"); |
|
|
|
|
|
|
|
new_bash(data.name); |
|
|
|
|
|
|
|
bash_connections[data.name].stdin.resume(); |
|
|
|
|
|
|
|
bash_connections[data.name].stdin.write(data.text); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function bash_end(name, text) { |
|
|
|
|
|
|
|
console.log("-> bash-end("+name+")"); |
|
|
|
|
|
|
|
if (!bash_connections[name]) return; |
|
|
|
|
|
|
|
bash_connections[name].stdin.close(); |
|
|
|
|
|
|
|
delete bash_connections[name]; bash_connections[name] = null; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
socket |
|
|
|
|
|
|
|
.on("containers", containers) |
|
|
|
|
|
|
|
.on("images", images) |
|
|
|
|
|
|
|
.on("start", start) |
|
|
|
|
|
|
|
.on("stop", stop) |
|
|
|
|
|
|
|
.on("pause", pause) |
|
|
|
|
|
|
|
.on("unpause", unpause) |
|
|
|
|
|
|
|
.on("remove", remove) |
|
|
|
|
|
|
|
.on("create", create) |
|
|
|
|
|
|
|
.on('logs', logs) |
|
|
|
|
|
|
|
.on('bash-start', bash_start) |
|
|
|
|
|
|
|
.on('bash-input', bash_input) |
|
|
|
|
|
|
|
.on('bash-end', bash_end); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function stats(error, stdout, stderr) { |
|
|
|
|
|
|
|
if (error || stderr) |
|
|
|
|
|
|
|
return fail("get containers stats failed", { |
|
|
|
|
|
|
|
error: error, stderr: stderr, stdout: stdout |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
broadcast("stats", stdout); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Handle Connection
|
|
|
|
// Handle Connection Authentication
|
|
|
|
require('socketio-auth')(io, { |
|
|
|
require('socketio-auth')(io, { |
|
|
|
authenticate: function (socket, data, callback) { |
|
|
|
authenticate: function (socket, data, callback) { |
|
|
|
console.log("=> authenticate: ", data.username); |
|
|
|
console.log("=> authenticate: ", data.username); |
|
|
|
//get credentials sent by the client
|
|
|
|
|
|
|
|
authentication(data.username, data.password, |
|
|
|
authentication(data.username, data.password, |
|
|
|
function() { |
|
|
|
function() { |
|
|
|
console.log("####LOGIN-SUCESS####"); |
|
|
|
console.log("####LOGIN-SUCESS####"); |
|
|
@ -256,16 +26,6 @@ module.exports = function(app, io, docker, authentication) { |
|
|
|
timeout: "none" |
|
|
|
timeout: "none" |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// Regular Update of Images and Containers
|
|
|
|
var module = {}; |
|
|
|
setInterval(function() { |
|
|
|
|
|
|
|
updateimages(); |
|
|
|
|
|
|
|
updatecontainers(); |
|
|
|
|
|
|
|
}, 10000); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Regular Update of Stats
|
|
|
|
|
|
|
|
setInterval(function() { |
|
|
|
|
|
|
|
if (running) exec('docker stats --no-stream'+running, stats); |
|
|
|
|
|
|
|
}, 1000); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return module; |
|
|
|
return module; |
|
|
|
} |
|
|
|
} |
|
|
|