new feature: download and upload historic data, provide view to uploaded data
This commit is contained in:
@@ -1,8 +1,8 @@
|
|||||||
var socket = io.connect()
|
var socket = io.connect()
|
||||||
var docker = new Docker(socket, error, sigstack, sigcontainer)
|
var docker = new Docker(socket, error, sigstack, sigcontainer)
|
||||||
var parameters = docker.graphics.parameters
|
var parameters = docker.graphics.parameters
|
||||||
var showstack = true
|
var stack = null
|
||||||
var showcontainer = true
|
var standalone = null
|
||||||
|
|
||||||
function showdate() {
|
function showdate() {
|
||||||
$('#clock').text((new Date()).toLocaleString())
|
$('#clock').text((new Date()).toLocaleString())
|
||||||
@@ -14,19 +14,30 @@ function error(e) {
|
|||||||
$('#error').html('<h1>Error</h1><p>'+(new Date()).toLocaleString()+'</p><p>'+e.msg+'</p><pre>'+e.data+'</pre>').show()
|
$('#error').html('<h1>Error</h1><p>'+(new Date()).toLocaleString()+'</p><p>'+e.msg+'</p><pre>'+e.data+'</pre>').show()
|
||||||
}
|
}
|
||||||
|
|
||||||
function sigstack() {
|
|
||||||
if (!showstack) return;
|
function update() {
|
||||||
showdate()
|
var data = {
|
||||||
$('#status').removeClass().addClass('wait')
|
'containers': docker.containers.get(),
|
||||||
var dot = docker.graphics.stack(parameters)
|
'volumes': docker.volumes.get(),
|
||||||
|
'nodes': docker.nodes.get(),
|
||||||
|
'services': docker.services.get(),
|
||||||
|
'tasks': docker.tasks.get()
|
||||||
|
}
|
||||||
|
$('a#data').attr('href', 'data:application/json;base64,'+btoa(JSON.stringify(data)))
|
||||||
|
.attr('target', '_blank')
|
||||||
|
.attr('download', window.location.hostname+'.json')
|
||||||
|
var dot = docker.graphics.header(parameters)
|
||||||
|
if (stack) dot += stack;
|
||||||
|
if (standalone) dot += standalone;
|
||||||
|
dot += docker.graphics.footer()
|
||||||
$('a#dot').attr('href', 'data:text/vnd.graphviz;base64,'+btoa(dot))
|
$('a#dot').attr('href', 'data:text/vnd.graphviz;base64,'+btoa(dot))
|
||||||
.attr('target', '_blank')
|
.attr('target', '_blank')
|
||||||
.attr('download', window.location.hostname+'.dot')
|
.attr('download', window.location.hostname+'.dot')
|
||||||
$('#error').hide()
|
$('#error').hide()
|
||||||
showdate()
|
showdate()
|
||||||
try {
|
try {
|
||||||
var svg = docker.graphics.viz(dot)
|
var svg = docker.graphics.viz(dot)
|
||||||
$('#stacks').html(svg)
|
$('#wizard').html(svg)
|
||||||
$('#status').removeClass().addClass('success')
|
$('#status').removeClass().addClass('success')
|
||||||
$('a#svg').attr('href', 'data:image/svg;base64,'+btoa(svg))
|
$('a#svg').attr('href', 'data:image/svg;base64,'+btoa(svg))
|
||||||
.attr('target', '_blank')
|
.attr('target', '_blank')
|
||||||
@@ -37,32 +48,18 @@ function sigstack() {
|
|||||||
showdate()
|
showdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
function sigcontainer() {
|
function sigstack() {
|
||||||
if (!showcontainer) return;
|
|
||||||
console.log(docker.containers.get())
|
|
||||||
showdate()
|
showdate()
|
||||||
$('#status').removeClass().addClass('wait')
|
$('#status').removeClass().addClass('wait')
|
||||||
var dot = docker.graphics.standalone(parameters)
|
stack = docker.graphics.stack()
|
||||||
/*
|
update()
|
||||||
$('a#dot').attr('href', 'data:text/vnd.graphviz;base64,'+btoa(dot))
|
}
|
||||||
.attr('target', '_blank')
|
|
||||||
.attr('download', window.location.hostname+'.dot')
|
function sigcontainer() {
|
||||||
*/
|
|
||||||
$('#error').hide()
|
|
||||||
showdate()
|
|
||||||
try {
|
|
||||||
var svg = docker.graphics.viz(dot)
|
|
||||||
$('#standalone').html(svg)
|
|
||||||
$('#status').removeClass().addClass('success')
|
|
||||||
/*
|
|
||||||
$('a#svg').attr('href', 'data:image/svg;base64,'+btoa(svg))
|
|
||||||
.attr('target', '_blank')
|
|
||||||
.attr('download', window.location.hostname+'.svg')
|
|
||||||
*/
|
|
||||||
} catch (e) {
|
|
||||||
error(e)
|
|
||||||
}
|
|
||||||
showdate()
|
showdate()
|
||||||
|
$('#status').removeClass().addClass('wait')
|
||||||
|
standalone = docker.graphics.standalone()
|
||||||
|
update()
|
||||||
}
|
}
|
||||||
|
|
||||||
function setParameters() {
|
function setParameters() {
|
||||||
@@ -77,12 +74,13 @@ else
|
|||||||
--localStorage.rankdir
|
--localStorage.rankdir
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
// status and parameters
|
||||||
showdate()
|
showdate()
|
||||||
$('#status').removeClass().addClass('wait')
|
$('#status').removeClass().addClass('wait')
|
||||||
setParameters()
|
setParameters()
|
||||||
$('#orientation').on('click', () => {
|
$('#orientation').on('click', () => {
|
||||||
setParameters()
|
setParameters()
|
||||||
sigstack()
|
update()
|
||||||
})
|
})
|
||||||
if (localStorage.position)
|
if (localStorage.position)
|
||||||
$('body').removeClass().addClass(localStorage.position)
|
$('body').removeClass().addClass(localStorage.position)
|
||||||
@@ -90,6 +88,32 @@ function init() {
|
|||||||
.on('dragstart', (event) => {
|
.on('dragstart', (event) => {
|
||||||
event.originalEvent.dataTransfer.setData("text", "");
|
event.originalEvent.dataTransfer.setData("text", "");
|
||||||
})
|
})
|
||||||
|
// restart on click on status
|
||||||
|
$('#status').on('click', () => {
|
||||||
|
docker.unpause()
|
||||||
|
})
|
||||||
|
// data file upload
|
||||||
|
$('#upload').on('change', (ev) => {
|
||||||
|
for (var i = 0, file; file = ev.currentTarget.files[i]; ++i) {
|
||||||
|
if (file.type=='application/json') {
|
||||||
|
var reader = new FileReader()
|
||||||
|
reader.onload = (e) => {
|
||||||
|
if (e.target.error) return error('cannot upload file', file);
|
||||||
|
if (e.target.readyState==0||e.target.readyState==1) return;
|
||||||
|
try {
|
||||||
|
var data = JSON.parse(e.target.result)
|
||||||
|
if (docker.upload(data))
|
||||||
|
$('#status').removeClass().addClass('paused')
|
||||||
|
} catch (e) {
|
||||||
|
error(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
reader.readAsText(file)
|
||||||
|
$('#upload').val('')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// drag and drop
|
||||||
$('*').on('dragover', (event) => {
|
$('*').on('dragover', (event) => {
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
var e = event.originalEvent
|
var e = event.originalEvent
|
||||||
|
@@ -10,7 +10,7 @@
|
|||||||
"child_process": "^1.0.2",
|
"child_process": "^1.0.2",
|
||||||
"cookie-parser": "*",
|
"cookie-parser": "*",
|
||||||
"debug": "*",
|
"debug": "*",
|
||||||
"docker.js": "^1.4.12",
|
"docker.js": "^1.4.15",
|
||||||
"dockerode": "^2.5.7",
|
"dockerode": "^2.5.7",
|
||||||
"express": "*",
|
"express": "*",
|
||||||
"jquery": "^3.1.1",
|
"jquery": "^3.1.1",
|
||||||
|
@@ -36,12 +36,15 @@ header
|
|||||||
padding: 0
|
padding: 0
|
||||||
border: 1px solid black
|
border: 1px solid black
|
||||||
z-index: 100
|
z-index: 100
|
||||||
a
|
.menu
|
||||||
margin: 0
|
margin: 0
|
||||||
padding: .5em
|
padding: .5em
|
||||||
|
label::after
|
||||||
|
content: ':'
|
||||||
|
padding-right: 1ex
|
||||||
&:hover
|
&:hover
|
||||||
background-color: #eee
|
background-color: #eee
|
||||||
a + a
|
.menu + .menu
|
||||||
border-top: 1px solid black
|
border-top: 1px solid black
|
||||||
&:hover
|
&:hover
|
||||||
display: block
|
display: block
|
||||||
@@ -70,6 +73,10 @@ header
|
|||||||
&::before
|
&::before
|
||||||
content: "✔"
|
content: "✔"
|
||||||
color: green
|
color: green
|
||||||
|
&.paused
|
||||||
|
&::before
|
||||||
|
content: "⏯"
|
||||||
|
color: gray
|
||||||
#orientation
|
#orientation
|
||||||
margin: 0.5em
|
margin: 0.5em
|
||||||
&.lr
|
&.lr
|
||||||
@@ -131,13 +138,13 @@ header
|
|||||||
left: 0
|
left: 0
|
||||||
width: 100vh
|
width: 100vh
|
||||||
height: 2em
|
height: 2em
|
||||||
transform: translate(-50%) translate(1em) rotate(270deg) translate(-50%) translate(1em)
|
transform-origin: right top
|
||||||
|
transform: translate(-100%) rotate(270deg)
|
||||||
#orientation
|
#orientation
|
||||||
transform: rotate(90deg)
|
transform: rotate(90deg)
|
||||||
#menu
|
#menu
|
||||||
position: absolute
|
transform-origin: top left
|
||||||
left: -3em
|
transform: rotate(90deg) translate(0, -100%)
|
||||||
transform: rotate(90deg) translate(50%) translate(-2em)
|
|
||||||
main
|
main
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 0
|
top: 0
|
||||||
@@ -152,13 +159,13 @@ header
|
|||||||
right: 0
|
right: 0
|
||||||
width: 100vh
|
width: 100vh
|
||||||
height: 2em
|
height: 2em
|
||||||
transform: translate(50%) translate(-1em) rotate(90deg) translate(50%) translate(-1em)
|
transform-origin: left top
|
||||||
|
transform: translate(100%) rotate(90deg)
|
||||||
#orientation
|
#orientation
|
||||||
transform: rotate(270deg)
|
transform: rotate(270deg)
|
||||||
#menu
|
#menu
|
||||||
position: absolute
|
transform-origin: top left
|
||||||
left: -3em
|
transform: rotate(270deg) translate(-100%)
|
||||||
transform: rotate(270deg) translate(-50%) translate(2em)
|
|
||||||
main
|
main
|
||||||
position: absolute
|
position: absolute
|
||||||
top: 0
|
top: 0
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
extends layout
|
extends layout
|
||||||
|
|
||||||
block content
|
block content
|
||||||
div.imagecontainer#stacks
|
div.imagecontainer#wizard
|
||||||
div#loading loading...
|
div#loading loading...
|
||||||
noscript
|
noscript
|
||||||
p.error this site requires javascript
|
p.error this site requires javascript
|
||||||
div.imagecontainer#standalone
|
|
||||||
div#loading loading...
|
|
||||||
|
@@ -16,8 +16,12 @@ html
|
|||||||
header#header
|
header#header
|
||||||
h1 ServiceDock
|
h1 ServiceDock
|
||||||
nav#menu
|
nav#menu
|
||||||
a#svg download image
|
a.menu#svg download image
|
||||||
a#dot download source
|
a.menu#dot download source
|
||||||
|
a.menu#data download data
|
||||||
|
div.menu
|
||||||
|
label(for="upload") upload data
|
||||||
|
input(type="file", name="upload")#upload
|
||||||
div#info
|
div#info
|
||||||
div#orientation
|
div#orientation
|
||||||
div#clock= (new Date()).toLocaleString()
|
div#clock= (new Date()).toLocaleString()
|
||||||
|
Reference in New Issue
Block a user