more of create
This commit is contained in:
		@@ -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 = [];
 | 
			
		||||
 
 | 
			
		||||
@@ -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('<option>'+$(this).siblings("input").map(function() {return $(this).text()}).get().join(':'))+'</option>')
 | 
			
		||||
    });
 | 
			
		||||
    //$("#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('<option '+$(this).siblings("input")
 | 
			
		||||
                    .map(function() {
 | 
			
		||||
                        if (this.hasAttribute('data-name')) {
 | 
			
		||||
                            return this.getAttribute('data-name')+'="'+this.value.replace(/"/g, '"')+'"';
 | 
			
		||||
                        } else return '';
 | 
			
		||||
                    }).get().join(' ')+'>'+$(this).siblings("input")
 | 
			
		||||
                    .map(function() {
 | 
			
		||||
                        var val = this.value;
 | 
			
		||||
                        var sep = this.getAttribute('data-separator') || '';
 | 
			
		||||
                        if (this.type=='checkbox' && !this.checked) {
 | 
			
		||||
                            val=''; sep=''
 | 
			
		||||
                        }
 | 
			
		||||
                        return sep+val;
 | 
			
		||||
                    }).get().join('')+'</option>')
 | 
			
		||||
        $(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();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -19,17 +19,12 @@
 | 
			
		||||
    <div id="header" class="header">
 | 
			
		||||
      <h1>ServiceDock <%= packageversion %> - Docker as a Service</h1>
 | 
			
		||||
      <div id="togglemenu">
 | 
			
		||||
        <span id="username">[unknown]</span>
 | 
			
		||||
        <span id="connectionstatus">
 | 
			
		||||
          <span id="good" title="connected" style="display: none">✔</span>
 | 
			
		||||
          <span id="bad" title="disconnected">✘</span>
 | 
			
		||||
        </span>
 | 
			
		||||
        <span id="imagetools" style="display: none">
 | 
			
		||||
          <img onclick="zoom(1)" src="images/zoom.svg" />
 | 
			
		||||
          <img onclick="rotateviz()" src="images/rotate.svg" />
 | 
			
		||||
          <img class="btn" onclick="zoom(1)" src="images/zoom.svg" />
 | 
			
		||||
          <img class="btn" onclick="rotateviz()" src="images/rotate.svg" />
 | 
			
		||||
        </span>
 | 
			
		||||
        <span id="close" onclick="showImage()" style="display: none">×</span>
 | 
			
		||||
        <img id="menuicon" onclick="togglemenu()" onmouseover="$('#menu').show();" src="images/menu.svg" />
 | 
			
		||||
        <span class="btn" id="close" onclick="showImage()" style="display: none">×</span>
 | 
			
		||||
        <img class="btn" id="menuicon" onclick="togglemenu()" src="images/menu.svg" />
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
@@ -54,52 +49,52 @@
 | 
			
		||||
      <form>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Name</legend>
 | 
			
		||||
          <input placeholder="name" type="text" id="name" size="20" />
 | 
			
		||||
          <input placeholder="name" type="text" id="name" pattern="^[-_a-zA-Z0-9]*$" size="20" required />
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Open Ports</legend>
 | 
			
		||||
          <input placeholder="ip" type="text" pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$" id="portip" size="15" style="width: 13ex" />:<input placeholder="ext" type="number" id="portext" size="4" style="width: 6ex" />:<input placeholder="int" type="number" id="portint" size="3" style="width: 6ex" /><button id="portadd" type="button" class="add">+</button><button id="portremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createports">
 | 
			
		||||
          <input placeholder="ip" type="text" pattern="^([0-9]{1,3}\.){3}[0-9]{1,3}$" id="portip" size="15" style="width: 13ex" data-name="ip" />:<input placeholder="ext" type="number" id="portext" size="4" style="width: 6ex" data-name="external" data-separator=":" />:<input placeholder="int" type="number" id="portint" size="3" style="width: 6ex" data-name="internal" data-separator=":" /><button id="portadd" type="button" class="add">+</button><button id="portremove" type="button">-</button><br/>
 | 
			
		||||
          <select class="collect" size="5" id="createports">
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Environment</legend>
 | 
			
		||||
          <input placeholder="name" type="text" id="varname" size="10" />=<input placeholder="value" type="text" id="varvalue" size="10" /><button id="varadd" type="button" class="add">+</button><button id="varremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createvars">
 | 
			
		||||
          <input placeholder="name" type="text" id="varname" size="10" />=<input placeholder="value" type="text" id="varvalue" size="10" data-separator="=" /><button id="varadd" type="button" class="add">+</button><button id="varremove" type="button">-</button><br/>
 | 
			
		||||
          <select class="collect" size="5" id="createvars">
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Volumes</legend>
 | 
			
		||||
          <input placeholder="on host" type="text" id="volumeext" size="10" />:<input placeholder="inside container" type="text" id="volumeint" size="10" />:<input placeholder="ro" type="checkbox" id="volumero" /><label for="volumero" >ro</label><button id="volumeadd" type="button" class="add">+</button><button id="volumeremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createvolumes">
 | 
			
		||||
          <legend>Mount Volumes</legend>
 | 
			
		||||
          <input placeholder="on host" type="text" id="volumeext" size="10" data-name="outside" />:<input placeholder="inside container" type="text" id="volumeint" size="10" data-name="inside" data-separator=":" />:<input placeholder="ro" value="ro" type="checkbox" id="volumero" data-name="rw" data-separator=":" /><label for="volumero" >ro</label><button id="volumeadd" type="button" class="add">+</button><button id="volumeremove" type="button">-</button><br/>
 | 
			
		||||
          <select class="collect" size="5" id="createvolumes">
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Volumes From</legend>
 | 
			
		||||
          <input placeholder="container" type="text" id="volumesfrom" size="10" /><button id="volumesfromadd" type="button" class="add">+</button><button id="volumesfromremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createcolumesfroms">
 | 
			
		||||
          <select class="collect" size="5" id="createcolumesfroms" >
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Links</legend>
 | 
			
		||||
          <input placeholder="container" type="text" id="linkcontainer" size="10" />:<input placeholder="name" type="text" id="linkname" size="10" /><button id="linkadd" type="button" class="add">+</button><button id="linkremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createlinks">
 | 
			
		||||
          <input placeholder="container" type="text" id="linkcontainer" size="10" data-name="container" />:<input placeholder="name" type="text" id="linkname" size="10" data-name="name" data-separator=":" /><button id="linkadd" type="button" class="add">+</button><button id="linkremove" type="button">-</button><br/>
 | 
			
		||||
          <select class="collect" size="5" id="createlinks">
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Entry Point</legend>
 | 
			
		||||
          <input placeholder="entrypoint" type="text" id="entrypoint" size="10" /><button id="entrypointadd" type="button" class="add">+</button><button id="entrypointremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createentrypoints">
 | 
			
		||||
          <select class="collect" size="5" id="createentrypoints">
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Image</legend>
 | 
			
		||||
          <input placeholder="image" type="text" id="image" size="20" required />
 | 
			
		||||
          <input placeholder="image" type="text" id="image" size="20" pattern="^[-_:/a-zA-Z0-9]*$" required />
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
          <legend>Command</legend>
 | 
			
		||||
          <input placeholder="command" type="text" id="command" size="10" /><button id="commandadd" type="button" class="add">+</button><button id="commandremove" type="button">-</button><br/>
 | 
			
		||||
          <select size="5" id="createcommands">
 | 
			
		||||
          <select class="collect" size="5" id="createcommands">
 | 
			
		||||
          </select>
 | 
			
		||||
        </fieldset>
 | 
			
		||||
        <fieldset>
 | 
			
		||||
@@ -122,10 +117,15 @@
 | 
			
		||||
      </form> -->
 | 
			
		||||
    </div>
 | 
			
		||||
 | 
			
		||||
    <div id="status">
 | 
			
		||||
      
 | 
			
		||||
      <noscript>JavaScript is required for the interface.</noscript>
 | 
			
		||||
 | 
			
		||||
    <div id="statusbar">
 | 
			
		||||
      <span id="status">
 | 
			
		||||
        <noscript>JavaScript is required for the interface.</noscript>
 | 
			
		||||
      </span>
 | 
			
		||||
      <span id="username">[unknown]</span>
 | 
			
		||||
      <span id="connectionstatus">
 | 
			
		||||
        <span id="good" title="connected" style="display: none">✔</span>
 | 
			
		||||
        <span id="bad" title="disconnected">✘</span>
 | 
			
		||||
      </span>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
  </body>
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user