diff --git a/ChangeLog b/ChangeLog index eed1671..8b95d97 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,34 @@ +2015-11-26 15:51 marc + + * html/manage.php: table fixed + +2015-11-25 15:26 marc + + * html/images.php, html/index.html.in, html/overview.php, + html/rotate.svg, html/servicedock.css, html/servicedock.js, + html/zoom.svg: allow image zoom and rotate + +2015-11-20 15:14 marc + + * html/images.php, html/servicedock.css: better image overview + +2015-11-20 13:49 marc + + * html/makefile.am: typo + +2015-11-19 13:13 marc + + * ax_init_standard_project.m4, configure.ac, html/about.php.in, + html/images.php, html/index.html.in, html/makefile.am, + html/overview.php, html/servicedock.css, html/servicedock.js: + added about and images + +2015-11-18 15:54 marc + + * ChangeLog, README, html/details.php, html/manage.php, + html/overview.php, html/servicedock.css: added doku for + installatin in README + 2015-11-18 13:24 marc * configure.ac, html/details.php, html/index.html.in, diff --git a/html/makefile.am b/html/makefile.am index b851f43..870cbdb 100644 --- a/html/makefile.am +++ b/html/makefile.am @@ -12,8 +12,9 @@ EXTRA_DIST = index.html.in about.php.in wwwdir = ${pkgdatadir}/html www_DATA = index.html about.php -dist_www_DATA = servicedock.css servicedock.js jquery.js viz.js \ - menu.svg overview.php details.php manage.php \ - action.php jquery-ui.js jquery-ui.css images.php +dist_www_DATA = servicedock.css servicedock.js jquery.js viz.js \ + menu.svg overview.php details.php manage.php \ + action.php jquery-ui.js jquery-ui.css images.php \ + zoom.svg rotate.svg MAINTAINERCLEANFILES = makefile.in diff --git a/html/servicedock.js b/html/servicedock.js index 439f09f..4495fe1 100644 --- a/html/servicedock.js +++ b/html/servicedock.js @@ -124,14 +124,26 @@ function zoom(incr = 0) { case 1: { $("#main svg").css("width", "100%"); $("#main svg").css("height", "auto"); - $("#main svg").css("max-width", "100%"); + $("#main svg").css("max-width", "none"); $("#main svg").css("max-height", "none"); } break; case 2: { $("#main.svg").css("width", "auto"); $("#main.svg").css("height", "100%"); $("#main.svg").css("max-width", "none"); - $("#main.svg").css("max-height", "100%"); + $("#main.svg").css("max-height", "none"); + } break; + case 3: { + $("#main svg").css("width", "200%"); + $("#main svg").css("height", "auto"); + $("#main svg").css("max-width", "none"); + $("#main svg").css("max-height", "none"); + } break; + case 4: { + $("#main.svg").css("width", "auto"); + $("#main.svg").css("height", "200%"); + $("#main.svg").css("max-width", "none"); + $("#main.svg").css("max-height", "none"); } break; } } diff --git a/nodejs/public/javascripts/servicedock.js b/nodejs/public/javascripts/servicedock.js index d410814..ad5f0cb 100644 --- a/nodejs/public/javascripts/servicedock.js +++ b/nodejs/public/javascripts/servicedock.js @@ -9,66 +9,219 @@ // 45678901234567890123456789012345678901234567890123456789012345678901234567890 var socket = io.connect(); +var focused = null; function DockerContainers() { var Status = Object.freeze({ - Error: "red", - Terminated: "yellow", - Restarting: "lightblue", - Paused: "lightgrey", - Running: "lightgreen" + Error: {color: "red", action1: "start", action2: "remove"}, + Terminated: {color: "yellow", action1: "start", action2: "remove"}, + Restarting: {color: "lightblue", action1: "start", action2: "remove"}, + Paused: {color: "lightgrey", action1: "unpause", action2: null}, + Running: {color: "lightgreen", action1: "pause", action2: "stop"} }); var containers = []; var nodes = []; - this.graph = function() { - var res = ""; - console.log("nodes["+nodes.length+"]=", nodes); - for (name in nodes) { + function protocol(port) { + if (port.toString().match("443")) return "https://"; + if (port.toString().match("3304")) return "mysql://"; + if (port.toString().match("22")) return "ssh://"; + return "http://"; + } + this.exists = function(name) { + if (nodes[name]) return true; + return false; + } + this.contextmenu = function(selector) { + $('a[xlink\\:href^=#]').click(function(e) { + name = $(this).attr("xlink:href").replace(/^#/, ""); var n = nodes[name]; - var label = n.name+'\\n'+n.image; - res += '"'+n.name+'"' - +' [label="'+label - +'",URL="details('+"'"+n.name+"'" - +')",style=filled,fillcolor='+n.status+"];\n"; + $(selector).prepend('
') + $("#popup").empty(); + if (n.status.action1) { + $("#popup").append(''); + $("#popup1").click(function() { + socket.emit(n.status.action1, name); + }); + } + $("#popup").append(''); + $("#popup2").click(function() { + if (focused) overview(); else details(name); + }); + if (n.status.action2) { + $("#popup").append(''); + $("#popup3").click(function() { + socket.emit(n.status.action2, name); + }); + } + $("#popup").append('Name | +Ports | +Volumes | +Links | +Environments | +Image | +Command | +
---|
`; + res += JSON.stringify(containers[nodes[name].id], null, 4); + res += ` ++
"+res+""); - error("Exception Caught: "+e); - } - }}).fail(function() { - error("offline"); - }); +function details(name) { + if (name) focused = name; + else if (!focused) return overview(); + showviz(dc.subgraph(focused)); } function action(container, action) { @@ -337,11 +524,6 @@ function manage() { }); } -/** Show an Overview of all Docker Services */ -function overview() { - $("#imagetools").hide(); -} - /** Show an Overview of all Docker Images */ function imgs() { $("#imagetools").hide(); @@ -362,6 +544,14 @@ function imgs() { function containers(c) { console.log("->rcv containers"); dc.setContainers(c); + if (focused && dc.exists(focused)) + details(focused); + else + overview(); +} + +function overview() { + focused = null; showviz(dc.graph()); } @@ -380,11 +570,14 @@ function start() { } function init() { - socket.io.on("connect", connected); - socket.io.on("reconnect", connected); - socket.io.on("disconnect", disconnected); - socket.io.on("error", disconnected); - socket.on("containers", containers); + socket.io + .on("connect", connected) + .on("reconnect", connected) + .on("disconnect", disconnected) + .on("error", disconnected); + socket + .on("fail", error) + .on("containers", containers); start(); } diff --git a/nodejs/public/stylesheets/servicedock.css b/nodejs/public/stylesheets/servicedock.css index a2cb4ea..d126f0e 100644 --- a/nodejs/public/stylesheets/servicedock.css +++ b/nodejs/public/stylesheets/servicedock.css @@ -22,6 +22,8 @@ svg { max-height: 100%; width: auto; height: auto; + z-index: -1; + position: relative; } form { @@ -238,6 +240,13 @@ table.docker li+li { z-index: 0; } +#popup { + position: fixed; + background-color: lightblue; + border: .1ex solid blue; + text-align: center; +} + .clear { clear: both; } diff --git a/nodejs/sockets/index.js b/nodejs/sockets/index.js index 456bcab..a5670e3 100644 --- a/nodejs/sockets/index.js +++ b/nodejs/sockets/index.js @@ -4,13 +4,13 @@ module.exports = function() { module.connection = function(socket) { - var sys = require('sys'); - var exec = require('child_process').exec; + //var sys = require('sys'); + var proc = require('child_process'); console.log("new client"); function emit(signal, data, info) { - if (typeof data == 'string') { + if (typeof data == 'string' && !data.match("\n")) { console.log("<- signal: "+signal+"("+data+")"); } else { console.log("<- signal: "+signal); @@ -24,31 +24,86 @@ module.exports = function() { socket.broadcast.emit(signal, data); } + function exec(cmd, callback) { + console.log("== "+cmd); + proc.exec(cmd, callback); + } + + function fail(txt, data) { + console.log("** "+txt, data); + emit("fail", txt); + } + function containerinspect(error, stdout, stderr) { - console.log(error); - if (!error && !stderr) { - // var res = {}; - // JSON.parse(stdout).forEach(function(c) { - // res[c.Id] = c; - // }); - emit("containers", stdout); - } + if (error || stderr) + return fail("inspect docker containers failed", { + error: error, stderr: stderr, stdout: stdout + }); + emit("containers", stdout); } function containerlist(error, stdout, stderr) { - console.log(error); - console.log("docker inspect "+stdout.trim().replace(/\n/g, " ")); - if (!error && !stderr) - exec("docker inspect "+stdout.trim().replace(/\n/g, " "), - containerinspect); + if (error || stderr) + return fail("list docker containers failed", { + error: error, stderr: stderr, stdout: stdout + }); + exec("docker inspect "+stdout.trim().replace(/\n/g, " "), containerinspect); } - socket.on("containers", function() { + function updatecontainers(error, stdout, stderr) { + if (error || stderr) + return fail("update docker container failed", { + error: error, stderr: stderr, stdout: stdout + }); + exec("docker ps -aq", containerlist); + } + + function modify(cmd, name) { + if (!name.match(/^[a-z0-9][-_:.+a-z0-9]*$/i)) + return fail("illegal instance name", { + error: error, stderr: stderr, stdout: stdout + }); + exec("docker "+cmd+" "+name, updatecontainers); + } + + function containers() { console.log("-> containers"); - exec("docker ps -aq", - containerlist); - }); + updatecontainers(); + } + 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); + } + + socket + .on("containers", containers) + .on("start", start) + .on("stop", stop) + .on("pause", pause) + .on("unpause", unpause) + .on("remove", remove); + } return module; diff --git a/nodejs/views/index.ejs b/nodejs/views/index.ejs index 9525a4c..5934c35 100644 --- a/nodejs/views/index.ejs +++ b/nodejs/views/index.ejs @@ -43,9 +43,12 @@
start up engine, please wait ...
+ +