diff --git a/nodejs/docker/docker.js b/nodejs/docker/docker.js index a4f0fe8..03d241c 100644 --- a/nodejs/docker/docker.js +++ b/nodejs/docker/docker.js @@ -73,12 +73,13 @@ var Docker = function() { var _containers = this; - var Status = Object.freeze({ + this.Status = Object.freeze({ Error: {color: "red", action1: "start", action2: "remove", bash: false}, Terminated: {color: "yellow", action1: "start", action2: "remove", bash: false}, Restarting: {color: "lightblue", action1: "start", action2: "remove", bash: false}, - Paused: {color: "lightgrey", action1: "unpause", action2: null, bash: false}, - Running: {color: "lightgreen", action1: "pause", action2: "stop", bash: true} + Paused: {color: "grey", action1: "unpause", action2: null, bash: false}, + Running: {color: "lightgreen", action1: "pause", action2: "stop", bash: true}, + Preview: {color: "lightgrey"} }); var containers = []; var nodes = []; @@ -93,7 +94,7 @@ var Docker = function() { return false; } function getIps(n, ips) { - n.ports.forEach(function(p) { + if (n.ports) n.ports.forEach(function(p) { if (!ips[p.ip]) ips[p.ip] = []; ips[p.ip].push(p); }); @@ -119,32 +120,33 @@ var Docker = function() { res+="}\n"; return res; } - function graphNode(n) { + function graphNode(n, omitstats) { var res = ""; - var label = n.image.name+'\\n'+n.name+'\\ncpu: ????? mem: ?????'; + var label = n.image.name+'\\n'+n.name + +(omitstats?'':'\\ncpu: ????? mem: ?????'); res += '"'+n.name+'"' +' [label="'+label +'",URL="#'+n.name +'",style=filled,fillcolor='+n.status.color+"];\n"; - n.ports.forEach(function(p) { + if (n.ports) n.ports.forEach(function(p) { res += '"'+(p.ip?p.ip+":":"")+p.external+'" -> "'+n.name +'" [label="'+p.internal+'"];\n'; }); - n.links.forEach(function(l) { + if (n.links) n.links.forEach(function(l) { res += '"'+n.name+'" -> "'+l.container+'" [label="link: '+l.name+'"];\n' }); return res; } function graphVolumesInside(n) { var res = ""; - n.volumes.forEach(function(v) { + if (n.volumes) n.volumes.forEach(function(v) { res += '"'+v.id+'" [label="'+v.inside+'",shape=box];\n'; }); return res; } function graphVolumesOutside(n) { var res = ""; - n.volumes.forEach(function(v) { + if (n.volumes) n.volumes.forEach(function(v) { if (v.host) res += '"'+v.outside+'" [label="'+v.host+'",shape=box];\n'; }); @@ -152,23 +154,23 @@ var Docker = function() { } function graphVolumesConnections(n) { var res = ""; - n.volumes.forEach(function(v) { + if (n.volumes) n.volumes.forEach(function(v) { if (v.host) res += '"'+v.id+'" -> "'+v.outside+'" [label="mounted from"]\n'; res += '"'+n.name+'" -> "'+v.id+'" [label="volume/'+v.rw+'"]\n'; }); - n.volumesfrom.forEach(function(o) { + if (n.volumesfrom) n.volumesfrom.forEach(function(o) { res += '"'+n.name+'" -> "'+nodes[o].name+'" [label="volumes from"]\n'; }); return res; } - this.graph = function(n) { + this.graph = function(n, omitstats) { var res = ""; var ips = []; n = n || nodes; for (name in n) getIps(n[name], ips); res += graphIpClusters(ips); - for (name in n) res += graphNode(n[name]); + for (name in n) res += graphNode(n[name], omitstats); res += "{rank=same;\n"; for (name in n) res += graphVolumesInside(n[name]); res+="}\n"; @@ -179,28 +181,28 @@ var Docker = function() { return res; } function addNodes(ns, name) { - var n = nodes[name]; + var n = nodes[name] || ns[name]; ns[name] = n; - n.links.forEach(function(peer) { + if (n.links) n.links.forEach(function(peer) { if (!ns[peer.container]) addNodes(ns, peer.container); }); - n.usedby.forEach(function(peer) { + if (n.usedby) n.usedby.forEach(function(peer) { if (!ns[peer]) addNodes(ns, peer); }); - n.volumesfrom.forEach(function(peer) { + if (n.volumesfrom) n.volumesfrom.forEach(function(peer) { if (!ns[peer]) addNodes(ns, peer); }); - n.volumesto.forEach(function(peer) { + if (n.volumesto) n.volumesto.forEach(function(peer) { if (!ns[peer]) addNodes(ns, peer); }); } - this.subnet = function(name) { - var ns = {}; + this.subnet = function(name, nodes) { + var ns = nodes || {}; addNodes(ns, name); return ns; } - this.subgraph = function(name) { - return this.graph(this.subnet(name)); + this.subgraph = function(name, nodes) { + return this.graph(this.subnet(name, nodes), nodes); } this.configuration = function(name) { var ns = this.subnet(name); @@ -303,11 +305,11 @@ var Docker = function() { ip: ip }); } - if (c.State.Paused) nodes[name].status = Status.Paused; - else if (c.State.Running) nodes[name].status = Status.Running; - else if (c.State.Restarting) nodes[name].status = Status.Restarting; - else if (c.State.ExitCode == 0) nodes[name].status = Status.Terminated; - else nodes[name].status = Status.Error; + if (c.State.Paused) nodes[name].status = _containers.Status.Paused; + else if (c.State.Running) nodes[name].status = _containers.Status.Running; + else if (c.State.Restarting) nodes[name].status = _containers.Status.Restarting; + else if (c.State.ExitCode == 0) nodes[name].status = _containers.Status.Terminated; + else nodes[name].status = _containers.Status.Error; nodes[name].volumes = []; var volumes = c.Volumes || c.Config.Volumes; nodes[name].volumes = []; diff --git a/nodejs/public/javascripts/servicedock.js b/nodejs/public/javascripts/servicedock.js index 52591bd..b1bc549 100644 --- a/nodejs/public/javascripts/servicedock.js +++ b/nodejs/public/javascripts/servicedock.js @@ -146,11 +146,24 @@ function upload(evt) { } } +function previewCreate() { + var name = $('#name').val(); + var nodes = {}; + nodes[name] = { + status: docker.containers.Status.Preview, + id: null, + name: name, + image: { + name: $('#image').val(), + id: null + }, + links: [], + volumesfrom: [], + }; + $('#preview').html(Viz("digraph {\n"+" rankdir="+rankdir+";\n"+docker.containers.subgraph(name, nodes)+"\n}")); +} + function create() { - $("#create form fieldset input.add").click(function() { - $(this).siblings("select").append('') - }); - //$("#preview").html(Viz("digraph {\nrankdir="+rankdir+";\n"+docker.containers.graph()+"\n}")); } var zoomlevel = 0; @@ -293,10 +306,10 @@ function showCreate() { $("#main").hide(); $("#logs").hide(); $("#console").hide(); - $("#imagetools").hide(); + $("#imagetools").show(); $("#close").show(); $("#create").show(); - create(); + previewCreate(); } function showConsole() { @@ -468,6 +481,29 @@ function start() { } } +function initForms() { + $('#create form *').change(previewCreate); + $("#create form fieldset .add").click(function() { + $(this).siblings("select.collect") + .append('') + $(this).siblings("input").value(); + }); + //$("#preview").html(Viz("digraph {\nrankdir="+rankdir+";\n"+docker.containers.graph()+"\n}")); +} + function init() { socket.io .on("connect", connected) @@ -481,6 +517,7 @@ function init() { .on("stats", stats) .on("logs", logs) .on("bash-data", bash_data); + initForms(); start(); } diff --git a/nodejs/public/stylesheets/servicedock.css b/nodejs/public/stylesheets/servicedock.css index c95ed2e..17a3fa6 100644 --- a/nodejs/public/stylesheets/servicedock.css +++ b/nodejs/public/stylesheets/servicedock.css @@ -21,15 +21,19 @@ div { overflow: auto; } -svg { +#main svg, #preview svg { max-width: 100%; max-height: 100%; width: auto; height: auto; z-index: -1; position: relative; + display: block; + margin: auto; +} +#preview svg { + padding-top: 2em; } - ul li { margin-left: 1em; } @@ -55,10 +59,22 @@ fieldset { border: 1px solid black; } +select { + width: 100%; +} + .listbutton { width: 100%; } +input:invalid { + background-color: #FDD; +} +form:invalid input[type=submit] { + opacity: .5; + pointer-events: none; +} + table { width: 100%; } @@ -132,14 +148,17 @@ table.docker li+li { display: inline; } -#status { +#statusbar { position: fixed; left: 0; right: 0; bottom: 0; margin: 0; padding: 0 1em 0 1em; - text-align: right; + color: white; +} +#status: { + float: right; } @media (max-width: 45em) { #username { @@ -159,17 +178,24 @@ table.docker li+li { color: black; } -#menuicon, #imagetools img, #close { +.btn { cursor: pointer; height: 1em; width: auto; + border: 1px dotted blue; + opacity: 0.8; +} + +.btn:hover { + border: 1px dotted white; + opacity: 2.0; } #menu { clear: both; position: relative; - padding: 1em 0em 1em 0em; - margin: 0 1em 0 1em; + padding: .5em 0 .5em 0; + margin: 1em 0 0 0; float: right; background-color: lightblue; list-style-type: none; diff --git a/nodejs/views/index.ejs b/nodejs/views/index.ejs index 3c3e770..fe71df7 100644 --- a/nodejs/views/index.ejs +++ b/nodejs/views/index.ejs @@ -19,17 +19,12 @@ @@ -54,52 +49,52 @@
Name - +
Open Ports - ::
- ::
+
Environment - =
- =
+
- Volumes - ::
- ::
+
Volumes From
-
Links - :
- :
+
Entry Point
-
Image - +
Command
-
@@ -122,10 +117,15 @@ --> -
- - - +
+ + + + [unknown] + + + +