|
|
|
/*! @file
|
|
|
|
|
|
|
|
@id $Id$
|
|
|
|
|
|
|
|
This is the main application as it is fully run in the user's browser.
|
|
|
|
|
|
|
|
*/
|
|
|
|
// 1 2 3 4 5 6 7 8
|
|
|
|
// 45678901234567890123456789012345678901234567890123456789012345678901234567890
|
|
|
|
|
|
|
|
var socket = null;
|
|
|
|
var docker = null;
|
|
|
|
|
|
|
|
function htmlenc(html) {
|
|
|
|
return $('<div/>').text(html).html();
|
|
|
|
}
|
|
|
|
|
|
|
|
function htmldec(data) {
|
|
|
|
return $('<div/>').html(data).text();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Show error messsage
|
|
|
|
/** Fades in an error message and logs to console.
|
|
|
|
@param data (optional) The error can be a string or any structure.
|
|
|
|
Strings are shown to the user, structures are logged only.
|
|
|
|
@param stay (optional) If not given as @c true, reloads page after 5s. */
|
|
|
|
function error(data) {
|
|
|
|
$("#status").fadeOut("slow", function() {
|
|
|
|
$("#status").addClass("error")
|
|
|
|
$("#status").removeClass("notice")
|
|
|
|
$("#status").removeClass("success")
|
|
|
|
if (data) {
|
|
|
|
if (typeof data == 'string') {
|
|
|
|
$("#status").html(data);
|
|
|
|
console.log("error: "+data);
|
|
|
|
} else {
|
|
|
|
$("#status").html('unknown error: '+JSON.stringify(data));
|
|
|
|
console.log("error: ", data);
|
|
|
|
console.log((new Error('stacktrace')));
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
$("#status").html('error');
|
|
|
|
console.log("error");
|
|
|
|
}
|
|
|
|
$("#status").fadeIn("slow");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Show notice messsage
|
|
|
|
/** Fades in an notice message and logs to console.
|
|
|
|
@param text (optional) The data is a string. */
|
|
|
|
function notice(text) {
|
|
|
|
$("#status").fadeOut("slow", function() {
|
|
|
|
$("#status").addClass("notice")
|
|
|
|
$("#status").removeClass("error")
|
|
|
|
$("#status").removeClass("success")
|
|
|
|
if (text) {
|
|
|
|
$("#status").html(text);
|
|
|
|
console.log("notice: "+text);
|
|
|
|
} else {
|
|
|
|
$("#status").html('');
|
|
|
|
console.log("notice");
|
|
|
|
}
|
|
|
|
$("#status").fadeIn("slow");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Show notice messsage
|
|
|
|
/** Fades in an success message and logs to console.
|
|
|
|
@param text (optional) The data is a string. */
|
|
|
|
function success(text) {
|
|
|
|
$("#status").fadeOut("slow", function() {
|
|
|
|
$("#status").addClass("success")
|
|
|
|
$("#status").removeClass("error")
|
|
|
|
$("#status").removeClass("notice")
|
|
|
|
if (text) {
|
|
|
|
$("#status").html(text);
|
|
|
|
console.log("success: "+text);
|
|
|
|
} else {
|
|
|
|
$("#status").html('');
|
|
|
|
console.log("success");
|
|
|
|
}
|
|
|
|
$("#status").fadeIn("slow");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Show status message in the main screen area
|
|
|
|
/** @param text Text is a message or some complex HTML from the server.
|
|
|
|
@param msg The success message text */
|
|
|
|
function status(text, msg) {
|
|
|
|
$("#main").hide();
|
|
|
|
$("#main").html(text);
|
|
|
|
if (msg) success(msg);
|
|
|
|
else setTimeout("$('#status').fadeOut('slow')", 5000);
|
|
|
|
zoom(0);
|
|
|
|
$("#main").show();
|
|
|
|
$("form input:first-child").focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
function emit(signal, data) {
|
|
|
|
console.log("<-snd "+signal, data);
|
|
|
|
socket.emit(signal, data);
|
|
|
|
}
|
|
|
|
|
|
|
|
function connect() {
|
|
|
|
$("#server").html($("#usernamefield").val()+'@'+window.location.hostname)
|
|
|
|
console.log("server connect");
|
|
|
|
$("#connectionstatus #bad").hide();
|
|
|
|
$("#connectionstatus #authentication").show();
|
|
|
|
$("#connectionstatus #good").hide();
|
|
|
|
success("login to server");
|
|
|
|
socket.emit('authentication', {
|
|
|
|
username: $("#usernamefield").val(),
|
|
|
|
password: $("#passwordfield").val()
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function authenticated() {
|
|
|
|
$("#server").html($("#usernamefield").val()+'@'+window.location.hostname)
|
|
|
|
console.log("server authenticated");
|
|
|
|
$("#connectionstatus #bad").hide();
|
|
|
|
$("#connectionstatus #authentication").hide();
|
|
|
|
$("#connectionstatus #good").show();
|
|
|
|
success("server connected");
|
|
|
|
start();
|
|
|
|
}
|
|
|
|
|
|
|
|
function unauthorized() {
|
|
|
|
$("#server").html($("#usernamefield").val()+'@'+window.location.hostname)
|
|
|
|
console.log("authentication failed");
|
|
|
|
$("#connectionstatus #good").hide();
|
|
|
|
$("#connectionstatus #authentication").hide();
|
|
|
|
$("#connectionstatus #bad").show();
|
|
|
|
error("authentication failed", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
function disconnected() {
|
|
|
|
$("#server").html($("#usernamefield").val()+'@'+window.location.hostname)
|
|
|
|
console.log("server disconnected");
|
|
|
|
$("#connectionstatus #good").hide();
|
|
|
|
$("#connectionstatus #authentication").hide();
|
|
|
|
$("#connectionstatus #bad").show();
|
|
|
|
error("server disconnected", true);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Toggle Menu Display
|
|
|
|
function togglemenu() {
|
|
|
|
$("#menu").toggle();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Upload a configuration and send it to server
|
|
|
|
function upload(evt) {
|
|
|
|
if (!window.FileReader)
|
|
|
|
return error("your browser does not support file upload", true);
|
|
|
|
for (var i=0, f; f=evt.target.files[i]; ++i) {
|
|
|
|
var file = f;
|
|
|
|
var reader = new FileReader();
|
|
|
|
reader.onload = function(evt) {
|
|
|
|
if (evt.target.error) return error("error reading file", true);
|
|
|
|
if (evt.target.readyState==0) return notice("waiting for data …");
|
|
|
|
if (evt.target.readyState==1) return notice("loading data …");
|
|
|
|
tobecreated = JSON.parse(evt.target.result);
|
|
|
|
showCreate();
|
|
|
|
}
|
|
|
|
reader.readAsText(file);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
var tobecreated = {};
|
|
|
|
function previewCreate() {
|
|
|
|
var name = $('#name').val();
|
|
|
|
var nodes = Object.create(tobecreated);
|
|
|
|
if (name != '') {
|
|
|
|
nodes[name] = {
|
|
|
|
status: docker.containers.Status.Preview,
|
|
|
|
id: null,
|
|
|
|
name: name,
|
|
|
|
image: {
|
|
|
|
name: $('#image').val(),
|
|
|
|
id: null
|
|
|
|
},
|
|
|
|
ports: $('#createports option').map(function() {return $(this).data();}).get(),
|
|
|
|
env: $('#createvars option').map(function() {return $(this).val();}).get(),
|
|
|
|
volumes: $('#createvolumes option').map(function() {return $(this).data();}).get(),
|
|
|
|
volumesfrom: $('#createvolumefroms option').map(function() {return $(this).val();}).get(),
|
|
|
|
links: $('#createlinks option').map(function() {return $(this).data();}).get(),
|
|
|
|
entrypoint: $('#createentrypoints option').map(function() {return $(this).val();}).get(),
|
|
|
|
cmd: $('#createcommands option').map(function() {return $(this).val();}).get(),
|
|
|
|
};
|
|
|
|
$('#doappend').unbind().click(function() {
|
|
|
|
tobecreated[name] = Object.create(nodes[name]);
|
|
|
|
tobecreated[name].status = docker.containers.Status.Prepared;
|
|
|
|
$('#createpreview').append('<option>'+name+'</option>');
|
|
|
|
$('#create form input[type=text]').val('');
|
|
|
|
$('#create form select.collect option').remove();
|
|
|
|
previewCreate();
|
|
|
|
});
|
|
|
|
$('#doremove').unbind().click(function() {
|
|
|
|
$(this).siblings('#createpreview').children('option:selected').each(function(a,b,c) {
|
|
|
|
delete tobecreated[b.innerHTML];
|
|
|
|
}).remove();
|
|
|
|
previewCreate();
|
|
|
|
});
|
|
|
|
$('#dosend').unbind().click(function() {
|
|
|
|
if (Object.keys(tobecreated).length>0) {
|
|
|
|
emit("docker.container.create", docker.containers.configuration(tobecreated));
|
|
|
|
tobecreated = {};
|
|
|
|
showImage();
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
if ($('#image').val()!='') {
|
|
|
|
var img = docker.images.get($('#image').val());
|
|
|
|
if (img) {
|
|
|
|
$('#portintdata').empty().append(img.ports.map(function(i) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i.replace(/\/.*/g, '');
|
|
|
|
return option;
|
|
|
|
}));
|
|
|
|
$('#varnamedata').empty().append(img.env.map(function(i) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i.replace(/=.*/g, '');
|
|
|
|
return option;
|
|
|
|
}));
|
|
|
|
$('#varvaluedata').empty().append(img.env.map(function(i) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i.replace(/^[^=]*=/g, '');
|
|
|
|
return option;
|
|
|
|
}));
|
|
|
|
$('#volumeextdata').empty();
|
|
|
|
$('#volumeintdata').empty();
|
|
|
|
for (i in img.volumes) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i;
|
|
|
|
$('#volumeextdata').append(option);
|
|
|
|
$('#volumeintdata').append(option);
|
|
|
|
}
|
|
|
|
$('#volumesfromdata').empty().append(docker.containers.names(tobecreated).map(function(i) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i;
|
|
|
|
return option;
|
|
|
|
}));
|
|
|
|
$('#linkcontainerdata').empty().append(docker.containers.names(tobecreated).map(function(i) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i;
|
|
|
|
return option;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (name=='' && nodes) for (name in nodes) break;
|
|
|
|
if (name && name!='') $('#preview').html(Viz("digraph {\n"+" rankdir="+rankdir+";\n"
|
|
|
|
+docker.containers.subgraph(name, nodes)
|
|
|
|
+"\n}"));
|
|
|
|
else $('#preview').html('');
|
|
|
|
}
|
|
|
|
|
|
|
|
function create() {
|
|
|
|
}
|
|
|
|
|
|
|
|
var zoomlevel = 0;
|
|
|
|
function zoom(incr = 0) {
|
|
|
|
zoomlevel = (zoomlevel+incr)%2;
|
|
|
|
switch (zoomlevel) {
|
|
|
|
case 0: {
|
|
|
|
$("#main svg, #preview svg").css("width", "auto");
|
|
|
|
$("#main svg, #preview svg").css("height", "auto");
|
|
|
|
$("#main svg, #preview svg").css("max-width", "100%");
|
|
|
|
$("#main svg, #preview svg").css("max-height", "100%");
|
|
|
|
} break;
|
|
|
|
case 1: {
|
|
|
|
$("#main svg, #preview svg").css("width", "100%");
|
|
|
|
$("#main svg, #preview svg").css("height", "auto");
|
|
|
|
$("#main svg, #preview svg").css("max-width", "100%");
|
|
|
|
$("#main svg, #preview svg").css("max-height", "none");
|
|
|
|
} break;
|
|
|
|
case 2: {
|
|
|
|
$("#main.svg, #preview svg").css("width", "auto");
|
|
|
|
$("#main.svg, #preview svg").css("height", "100%");
|
|
|
|
$("#main.svg, #preview svg").css("max-width", "none");
|
|
|
|
$("#main.svg, #preview svg").css("max-height", "100%");
|
|
|
|
} break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function showLogin() {
|
|
|
|
$("#close").hide();
|
|
|
|
$("#console").hide();
|
|
|
|
$("#create").hide();
|
|
|
|
$("#imagetools").hide();
|
|
|
|
$("#login").show();
|
|
|
|
$("#logs").hide();
|
|
|
|
$("#main").hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
function showImage() {
|
|
|
|
$("#close").hide();
|
|
|
|
$("#console").hide();
|
|
|
|
$("#create").hide();
|
|
|
|
$("#imagetools").show();
|
|
|
|
$("#login").hide();
|
|
|
|
$("#logs").hide();
|
|
|
|
$("#main").show();
|
|
|
|
}
|
|
|
|
|
|
|
|
function showCreate() {
|
|
|
|
$("#close").show();
|
|
|
|
$("#console").hide();
|
|
|
|
$("#create").show();
|
|
|
|
$("#imagetools").show();
|
|
|
|
$("#login").hide();
|
|
|
|
$("#logs").hide();
|
|
|
|
$("#main").hide();
|
|
|
|
previewCreate();
|
|
|
|
}
|
|
|
|
|
|
|
|
function showConsole() {
|
|
|
|
$("#close").show();
|
|
|
|
$("#console").show();
|
|
|
|
$("#create").hide();
|
|
|
|
$("#imagetools").hide();
|
|
|
|
$("#login").hide();
|
|
|
|
$("#logs").hide();
|
|
|
|
$("#main").hide();
|
|
|
|
// $("#command").focus();
|
|
|
|
// $("#command").val("");
|
|
|
|
// if ($("#screen").val()!="") $("#screen").append("\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
function showLogs() {
|
|
|
|
$("#close").show();
|
|
|
|
$("#console").hide();
|
|
|
|
$("#create").hide();
|
|
|
|
$("#imagetools").hide();
|
|
|
|
$("#login").hide();
|
|
|
|
$("#logs").show();
|
|
|
|
$("#main").hide();
|
|
|
|
}
|
|
|
|
|
|
|
|
function images(i) {
|
|
|
|
console.log("->rcv images");
|
|
|
|
docker.images.set(i);
|
|
|
|
$('#imagedata').empty().append(docker.images.tags().map(function(i) {
|
|
|
|
var option = document.createElement('option');
|
|
|
|
option.value = i;
|
|
|
|
return option;
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
|
|
|
|
function logs(data) {
|
|
|
|
console.log("->rcv logs("+data.name+")");
|
|
|
|
if (data.type=='done') {
|
|
|
|
$("#logs").append('<span class="'+data.type+'">\nDONE</span>');
|
|
|
|
} else {
|
|
|
|
$("#logs").append('<span class="'+data.type+'">'+htmlenc(data.text)+'</span>');
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function strInsert(str, pos, txt) {
|
|
|
|
return str.slice(0, pos)+txt+str.slice(pos);
|
|
|
|
}
|
|
|
|
|
|
|
|
function ansifilter(data) {
|
|
|
|
console.log("ansifilter");
|
|
|
|
var res = data;
|
|
|
|
var pos = -1;
|
|
|
|
var spans = 0;
|
|
|
|
while ((pos=res.indexOf("\x1B[")) >= 0) {
|
|
|
|
var end = res.indexOf("m", pos+2);
|
|
|
|
if (end>0) {
|
|
|
|
var control= res.slice(pos+2, end);
|
|
|
|
res = res.slice(0, pos)+res.slice(end+1);
|
|
|
|
control.split(';').forEach(function(c) {
|
|
|
|
switch (parseInt(c)) {
|
|
|
|
// set
|
|
|
|
case 1: res = strInsert(res, pos, '<span class="bold">'); ++spans; break;
|
|
|
|
case 2: res = strInsert(res, pos, '<span class="dim">'); ++spans; break;
|
|
|
|
case 4: res = strInsert(res, pos, '<span class="underlined">'); ++spans; break;
|
|
|
|
case 5: res = strInsert(res, pos, '<span class="blink">'); ++spans; break;
|
|
|
|
case 7: res = strInsert(res, pos, '<span class="reverse">'); ++spans; break;
|
|
|
|
case 8: res = strInsert(res, pos, '<span class="hidden">'); ++spans; break;
|
|
|
|
// reset
|
|
|
|
case 0: for (;spans;--spans) res = strInsert(res, pos, "</span>"); break;
|
|
|
|
case 21: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
|
|
|
|
case 22: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
|
|
|
|
case 23: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
|
|
|
|
case 25: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
|
|
|
|
case 27: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
|
|
|
|
case 28: if (spans) --spans; res = strInsert(res, pos, "</span>"); break;
|
|
|
|
// fg colors
|
|
|
|
case 39: res = strInsert(res, pos, '<span class="fgdefault">'); ++spans; break;
|
|
|
|
case 30: res = strInsert(res, pos, '<span class="fgblack">'); ++spans; break;
|
|
|
|
case 31: res = strInsert(res, pos, '<span class="fgred">'); ++spans; break;
|
|
|
|
case 32: res = strInsert(res, pos, '<span class="fggreen">'); ++spans; break;
|
|
|
|
case 33: res = strInsert(res, pos, '<span class="fgyellow">'); ++spans; break;
|
|
|
|
case 34: res = strInsert(res, pos, '<span class="fgblue">'); ++spans; break;
|
|
|
|
case 35: res = strInsert(res, pos, '<span class="fgmagenta">'); ++spans; break;
|
|
|
|
case 36: res = strInsert(res, pos, '<span class="fgcyan">'); ++spans; break;
|
|
|
|
case 37: res = strInsert(res, pos, '<span class="fglightgrey">'); ++spans; break;
|
|
|
|
case 90: res = strInsert(res, pos, '<span class="fgdarkgrey">'); ++spans; break;
|
|
|
|
case 91: res = strInsert(res, pos, '<span class="fglightred">'); ++spans; break;
|
|
|
|
case 92: res = strInsert(res, pos, '<span class="fglightgreen">'); ++spans; break;
|
|
|
|
case 93: res = strInsert(res, pos, '<span class="fglightyellow">'); ++spans; break;
|
|
|
|
case 94: res = strInsert(res, pos, '<span class="fglightblue">'); ++spans; break;
|
|
|
|
case 95: res = strInsert(res, pos, '<span class="fglightmagenta">'); ++spans; break;
|
|
|
|
case 96: res = strInsert(res, pos, '<span class="fglightcyan">'); ++spans; break;
|
|
|
|
case 97: res = strInsert(res, pos, '<span class="fgwhite">'); ++spans; break;
|
|
|
|
// bg colors
|
|
|
|
case 49: res = strInsert(res, pos, '<span class="bgdefault">'); ++spans; break;
|
|
|
|
case 40: res = strInsert(res, pos, '<span class="bgblack">'); ++spans; break;
|
|
|
|
case 41: res = strInsert(res, pos, '<span class="bgred">'); ++spans; break;
|
|
|
|
case 42: res = strInsert(res, pos, '<span class="bggreen">'); ++spans; break;
|
|
|
|
case 43: res = strInsert(res, pos, '<span class="bgyellow">'); ++spans; break;
|
|
|
|
case 44: res = strInsert(res, pos, '<span class="bgblue">'); ++spans; break;
|
|
|
|
case 45: res = strInsert(res, pos, '<span class="bgmagenta">'); ++spans; break;
|
|
|
|
case 46: res = strInsert(res, pos, '<span class="bgcyan">'); ++spans; break;
|
|
|
|
case 47: res = strInsert(res, pos, '<span class="bglightgrey">'); ++spans; break;
|
|
|
|
case 100: res = strInsert(res, pos, '<span class="bgdarkgrey">'); ++spans; break;
|
|
|
|
case 101: res = strInsert(res, pos, '<span class="bglightred">'); ++spans; break;
|
|
|
|
case 102: res = strInsert(res, pos, '<span class="bglightgreen">'); ++spans; break;
|
|
|
|
case 103: res = strInsert(res, pos, '<span class="bglightyellow">'); ++spans; break;
|
|
|
|
case 104: res = strInsert(res, pos, '<span class="bglightblue">'); ++spans; break;
|
|
|
|
case 105: res = strInsert(res, pos, '<span class="bglightmagenta">'); ++spans; break;
|
|
|
|
case 106: res = strInsert(res, pos, '<span class="bglightcyan">'); ++spans; break;
|
|
|
|
case 107: res = strInsert(res, pos, '<span class="bgwhite">'); ++spans; break;
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (;spans;--spans) res += "</span>";
|
|
|
|
console.log(res);
|
|
|
|
return res.replace(/\r\r\n/g, '\n');
|
|
|
|
}
|
|
|
|
|
|
|
|
function ascii(txt) {
|
|
|
|
var res = "";
|
|
|
|
for (i=0; i<txt.length; ++i) {
|
|
|
|
if (res) res += ",";
|
|
|
|
res += txt.charCodeAt(i).toString();
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
function bash_data(data) {
|
|
|
|
console.log("->rcv bash-data("+data.name+")", data);
|
|
|
|
if (data.type=='done') {
|
|
|
|
$("#screen").append('<span class="'+data.type+'">\nDONE</span>');
|
|
|
|
} else {
|
|
|
|
var buff = "";
|
|
|
|
console.log("ASCII: ", ascii(data.text));
|
|
|
|
for (var i=0; i<data.text.length; ++i) {
|
|
|
|
switch (data.text.charCodeAt(i)) {
|
|
|
|
case 7:
|
|
|
|
case 8:
|
|
|
|
if (buff.length) $("#screen").append(ansifilter(htmlenc(buff)));
|
|
|
|
buff = "";
|
|
|
|
$('#screen').html(function (_,txt) {
|
|
|
|
return txt.slice(0, -1);
|
|
|
|
});
|
|
|
|
break;
|
|
|
|
default: buff += data.text[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (buff.length) $("#screen").append(ansifilter(htmlenc(buff)));
|
|
|
|
}
|
|
|
|
$("#screen").animate({
|
|
|
|
scrollTop: $("#screen").prop('scrollHeight')
|
|
|
|
}, 500);
|
|
|
|
$("#screen").focus();
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Initial Function: Startup
|
|
|
|
/** To be called after login */
|
|
|
|
function start() {
|
|
|
|
$("#imagetools").hide();
|
|
|
|
$("#close").hide();
|
|
|
|
$("#popup").hide();
|
|
|
|
$("#menu").hide();
|
|
|
|
try {
|
|
|
|
status("Starting up ...");
|
|
|
|
emit("docker.images");
|
|
|
|
showImage();
|
|
|
|
} catch (m) {
|
|
|
|
error(m);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function initForms() {
|
|
|
|
$('#create form *').change(previewCreate);
|
|
|
|
$("#create form fieldset .add").unbind().click(function() {
|
|
|
|
$(this).siblings("select.collect")
|
|
|
|
.append('<option '+$(this).siblings("input")
|
|
|
|
.map(function() {
|
|
|
|
if (this.hasAttribute('data-name')) {
|
|
|
|
var res = "";
|
|
|
|
var obj = this;
|
|
|
|
this.getAttribute('data-name').split(' ').forEach(function(n) {
|
|
|
|
res += 'data-'+n+'="'+
|
|
|
|
(obj.type!='checkbox'||obj.checked
|
|
|
|
?obj.value:obj.getAttribute('data-false'))
|
|
|
|
.replace(/&/g, '&')
|
|
|
|
.replace(/"/g, '"')
|
|
|
|
+'"';
|
|
|
|
})
|
|
|
|
return res;
|
|
|
|
} 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[type=text]").val('');
|
|
|
|
previewCreate();
|
|
|
|
});
|
|
|
|
$("#create form fieldset .remove").unbind().click(function() {
|
|
|
|
$(this).siblings('select.collect').children('option:selected').remove();
|
|
|
|
previewCreate();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function init() {
|
|
|
|
socket = io.connect();
|
|
|
|
docker = new Docker(socket, '#main', error);
|
|
|
|
$("#server").html($("#usernamefield").value+'@'+window.location.hostname)
|
|
|
|
initForms();
|
|
|
|
showLogin();
|
|
|
|
socket
|
|
|
|
.io
|
|
|
|
.on("connect", connect)
|
|
|
|
.on("reconnect", connect)
|
|
|
|
.on("disconnect", disconnected)
|
|
|
|
.on("error", disconnected);
|
|
|
|
socket
|
|
|
|
.on("authenticated", authenticated)
|
|
|
|
.on("unauthorized", unauthorized)
|
|
|
|
.on("docker.images", images)
|
|
|
|
.on("docker.container.logs", logs)
|
|
|
|
.on("docker.container.bash.data", bash_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// On Load, Call @ref start
|
|
|
|
/*
|
|
|
|
$(window.onbeforeunload = function() {
|
|
|
|
return "Are you sure you want to navigate away?";
|
|
|
|
});
|
|
|
|
*/
|
|
|
|
$(init);
|