mirror of
https://github.com/portainer/portainer.git
synced 2025-07-19 13:29:41 +02:00
Merge branch 'dev'
This commit is contained in:
commit
1b531a3079
12 changed files with 534 additions and 134 deletions
9
Makefile
9
Makefile
|
@ -1,9 +0,0 @@
|
||||||
REF = HEAD
|
|
||||||
VERSION = $(shell git describe --always $(REF))
|
|
||||||
|
|
||||||
all: less
|
|
||||||
|
|
||||||
less:
|
|
||||||
less css/*.less > css/app.css
|
|
||||||
|
|
||||||
.PHONY: all less
|
|
|
@ -6,7 +6,7 @@ DockerUI is a web interface to interact with the Remote API. The goal is to pro
|
||||||

|

|
||||||
|
|
||||||
###Installation
|
###Installation
|
||||||
Open js/app.(ts/js - js file if you don't want to compile typescript) and change the DOCKER_ENDPOINT constant to your docker ip and port. Then host the site like any other html/js application.
|
Open js/app.js and change the DOCKER_ENDPOINT constant to your docker ip and port. Then host the site like any other html/js application.
|
||||||
|
|
||||||
|
|
||||||
.constant('DOCKER_ENDPOINT', 'http://192.168.1.9:4243\:4243');
|
.constant('DOCKER_ENDPOINT', 'http://192.168.1.9:4243\:4243');
|
||||||
|
@ -14,7 +14,6 @@ Open js/app.(ts/js - js file if you don't want to compile typescript) and change
|
||||||
|
|
||||||
###Stack
|
###Stack
|
||||||
* Angular.js
|
* Angular.js
|
||||||
* Less
|
|
||||||
* Flatstrap ( Flat Twitter Bootstrap )
|
* Flatstrap ( Flat Twitter Bootstrap )
|
||||||
|
|
||||||
|
|
||||||
|
|
85
css/app.less
85
css/app.less
|
@ -1,85 +0,0 @@
|
||||||
body {
|
|
||||||
padding-top: 20px;
|
|
||||||
padding-bottom: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Custom container */
|
|
||||||
.container {
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 1000px;
|
|
||||||
}
|
|
||||||
.container > hr {
|
|
||||||
margin: 60px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Main marketing message and sign up button */
|
|
||||||
.jumbotron {
|
|
||||||
margin: 80px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.jumbotron h1 {
|
|
||||||
font-size: 100px;
|
|
||||||
line-height: 1;
|
|
||||||
}
|
|
||||||
.jumbotron .lead {
|
|
||||||
font-size: 24px;
|
|
||||||
line-height: 1.25;
|
|
||||||
}
|
|
||||||
.jumbotron .btn {
|
|
||||||
font-size: 21px;
|
|
||||||
padding: 14px 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Supporting marketing content */
|
|
||||||
.marketing {
|
|
||||||
margin: 60px 0;
|
|
||||||
}
|
|
||||||
.marketing p + h4 {
|
|
||||||
margin-top: 28px;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Customize the navbar links to be fill the entire space of the .navbar */
|
|
||||||
.navbar .navbar-inner {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
.navbar .nav {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
.navbar .nav li {
|
|
||||||
display: table-cell;
|
|
||||||
width: 1%;
|
|
||||||
float: none;
|
|
||||||
}
|
|
||||||
.navbar .nav li a {
|
|
||||||
font-weight: bold;
|
|
||||||
text-align: center;
|
|
||||||
border-left: 1px solid rgba(255,255,255,.75);
|
|
||||||
border-right: 1px solid rgba(0,0,0,.1);
|
|
||||||
}
|
|
||||||
.navbar .nav li:first-child a {
|
|
||||||
border-left: 0;
|
|
||||||
border-radius: 3px 0 0 3px;
|
|
||||||
}
|
|
||||||
.navbar .nav li:last-child a {
|
|
||||||
border-right: 0;
|
|
||||||
border-radius: 0 3px 3px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-group button {
|
|
||||||
margin: 3px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.detail {
|
|
||||||
width: 80%;
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.btn-remove {
|
|
||||||
margin: 0 auto;
|
|
||||||
max-width: 70%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
margin: 0 auto;
|
|
||||||
}
|
|
|
@ -1,4 +1,5 @@
|
||||||
|
|
||||||
|
// Controller for the top masthead
|
||||||
function MastheadController($scope) {
|
function MastheadController($scope) {
|
||||||
$scope.template = 'partials/masthead.html';
|
$scope.template = 'partials/masthead.html';
|
||||||
|
|
||||||
|
@ -13,6 +14,7 @@ function MastheadController($scope) {
|
||||||
$scope.iclass = '';
|
$scope.iclass = '';
|
||||||
$scope.sclass = '';
|
$scope.sclass = '';
|
||||||
|
|
||||||
|
//This is shitty, I need help with this crap.
|
||||||
switch(link) {
|
switch(link) {
|
||||||
case 'home':
|
case 'home':
|
||||||
$scope.hclass = 'active';
|
$scope.hclass = 'active';
|
||||||
|
@ -32,40 +34,124 @@ function MastheadController($scope) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
function SideBarController($scope, Container) {
|
|
||||||
$scope.template = 'partials/sidebar.html';
|
|
||||||
|
|
||||||
Container.query({}, function(d) {
|
|
||||||
$scope.containers = d;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
function HomeController() {
|
function HomeController() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function SettingsController() {
|
function SettingsController($scope, Auth, System, Docker, Settings) {
|
||||||
|
$scope.auth = {};
|
||||||
|
$scope.info = {};
|
||||||
|
$scope.docker = {};
|
||||||
|
|
||||||
|
$('#response').hide();
|
||||||
|
$scope.alertClass = 'block';
|
||||||
|
|
||||||
|
var showAndHide = function(hide) {
|
||||||
|
$('#response').show();
|
||||||
|
if (hide) {
|
||||||
|
setTimeout(function() { $('#response').hide();}, 5000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.updateAuthInfo = function() {
|
||||||
|
if ($scope.auth.password != $scope.auth.cpassword) {
|
||||||
|
$scope.response = 'Your passwords do not match.';
|
||||||
|
showAndHide(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Auth.update(
|
||||||
|
{username: $scope.auth.username, email: $scope.auth.email, password: $scope.auth.password}, function(d) {
|
||||||
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Auth information updated.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Auth.get({}, function(d) {
|
||||||
|
$scope.auth = d;
|
||||||
|
});
|
||||||
|
|
||||||
|
Docker.get({}, function(d) {
|
||||||
|
$scope.docker = d;
|
||||||
|
});
|
||||||
|
|
||||||
|
System.get({}, function(d) {
|
||||||
|
$scope.info = d;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function ContainerController($scope, $routeParams, Container) {
|
// Controls the page that displays a single container and actions on that container.
|
||||||
|
function ContainerController($scope, $routeParams, $location, Container) {
|
||||||
|
$('#response').hide();
|
||||||
|
$scope.alertClass = 'block';
|
||||||
|
|
||||||
|
var showAndHide = function(hide) {
|
||||||
|
$('#response').show();
|
||||||
|
if (hide) {
|
||||||
|
setTimeout(function() { $('#response').hide();}, 5000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$scope.start = function(){
|
$scope.start = function(){
|
||||||
Container.start({id: $routeParams.id}, function(d) {
|
Container.start({id: $routeParams.id}, function(d) {
|
||||||
$scope.response = d;
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Container started.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.stop = function() {
|
$scope.stop = function() {
|
||||||
Container.stop({id: $routeParams.id}, function(d) {
|
Container.stop({id: $routeParams.id}, function(d) {
|
||||||
$scope.response = d;
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Container stopped.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.kill = function() {
|
||||||
|
Container.kill({id: $routeParams.id}, function(d) {
|
||||||
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Container killed.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.remove = function() {
|
$scope.remove = function() {
|
||||||
if (confirm("Are you sure you want to remove the container?")) {
|
if (confirm("Are you sure you want to remove the container?")) {
|
||||||
Container.remove({id: $routeParams.id}, function(d) {
|
Container.remove({id: $routeParams.id}, function(d) {
|
||||||
$scope.response = d;
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Container removed.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e){
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -80,13 +166,149 @@ function ContainerController($scope, $routeParams, Container) {
|
||||||
|
|
||||||
Container.get({id: $routeParams.id}, function(d) {
|
Container.get({id: $routeParams.id}, function(d) {
|
||||||
$scope.container = d;
|
$scope.container = d;
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$location.path('/containers/');
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.getChanges();
|
$scope.getChanges();
|
||||||
}
|
}
|
||||||
|
|
||||||
function ContainersController($scope, Container) {
|
// Controller for the list of containers
|
||||||
Container.query({}, function(d) {
|
function ContainersController($scope, Container, Settings) {
|
||||||
|
$scope.displayAll = Settings.displayAll;
|
||||||
|
$scope.predicate = '-Created';
|
||||||
|
|
||||||
|
var update = function(data) {
|
||||||
|
Container.query(data, function(d) {
|
||||||
$scope.containers = d;
|
$scope.containers = d;
|
||||||
});
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.toggleGetAll = function() {
|
||||||
|
Settings.displayAll = $scope.displayAll;
|
||||||
|
var u = update;
|
||||||
|
var data = {all: 0};
|
||||||
|
|
||||||
|
if ($scope.displayAll) {
|
||||||
|
data.all = 1;
|
||||||
|
}
|
||||||
|
u(data);
|
||||||
|
};
|
||||||
|
|
||||||
|
update({all: $scope.displayAll ? 1 : 0});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller for the list of images
|
||||||
|
function ImagesController($scope, Image) {
|
||||||
|
$scope.predicate = '-Created';
|
||||||
|
|
||||||
|
Image.query({}, function(d) {
|
||||||
|
$scope.images = d;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Controller for a single image and actions on that image
|
||||||
|
function ImageController($scope, $routeParams, $location, Image) {
|
||||||
|
$scope.history = [];
|
||||||
|
$scope.tag = {repo: '', force: false};
|
||||||
|
|
||||||
|
$('#response').hide();
|
||||||
|
$scope.alertClass = 'block';
|
||||||
|
|
||||||
|
var showAndHide = function(hide) {
|
||||||
|
$('#response').show();
|
||||||
|
if (hide) {
|
||||||
|
setTimeout(function() { $('#response').hide();}, 5000);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.remove = function() {
|
||||||
|
if (confirm("Are you sure you want to delete this image?")) {
|
||||||
|
Image.remove({id: $routeParams.id}, function(d) {
|
||||||
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Image removed.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.getHistory = function() {
|
||||||
|
Image.history({id: $routeParams.id}, function(d) {
|
||||||
|
$scope.history = d;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
$scope.updateTag = function() {
|
||||||
|
var tag = $scope.tag;
|
||||||
|
Image.tag({id: $routeParams.id, repo: tag.repo, force: tag.force ? 1 : 0}, function(d) {
|
||||||
|
console.log(d);
|
||||||
|
$scope.alertClass = 'success';
|
||||||
|
$scope.response = 'Tag added.';
|
||||||
|
showAndHide(true);
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.alertClass = 'error';
|
||||||
|
$scope.response = e.data;
|
||||||
|
showAndHide(false);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
Image.get({id: $routeParams.id}, function(d) {
|
||||||
|
$scope.image = d;
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$location.path('/images/');
|
||||||
|
});
|
||||||
|
|
||||||
|
$scope.getHistory();
|
||||||
|
}
|
||||||
|
|
||||||
|
function StartContainerController($scope, $routeParams, $location, Container) {
|
||||||
|
$scope.template = 'partials/startcontainer.html';
|
||||||
|
$scope.memory = 0;
|
||||||
|
$scope.memorySwap = 0;
|
||||||
|
$scope.env = '';
|
||||||
|
$scope.dns = '';
|
||||||
|
$scope.volumesFrom = '';
|
||||||
|
$scope.commands = '';
|
||||||
|
|
||||||
|
$scope.launchContainer = function() {
|
||||||
|
var cmds = null;
|
||||||
|
if ($scope.commands !== '') {
|
||||||
|
cmds = $scope.commands.split('\n');
|
||||||
|
}
|
||||||
|
var id = $routeParams.id;
|
||||||
|
var ctor = Container;
|
||||||
|
var loc = $location;
|
||||||
|
var s = $scope;
|
||||||
|
|
||||||
|
Container.create({
|
||||||
|
Image: id,
|
||||||
|
Memory: $scope.memory,
|
||||||
|
MemorySwap: $scope.memorySwap,
|
||||||
|
Cmd: cmds,
|
||||||
|
VolumesFrom: $scope.volumesFrom
|
||||||
|
}, function(d) {
|
||||||
|
console.log(d);
|
||||||
|
if (d.Id) {
|
||||||
|
ctor.start({id: d.Id}, function(cd) {
|
||||||
|
console.log(cd);
|
||||||
|
loc.path('/containers/' + d.Id + '/');
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
s.resonse = e.data;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, function(e) {
|
||||||
|
console.log(e);
|
||||||
|
$scope.response = e.data;
|
||||||
|
});
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,42 @@ angular.module('dockerui.filters', [])
|
||||||
return function(text) {
|
return function(text) {
|
||||||
if (text === 'Ghost') {
|
if (text === 'Ghost') {
|
||||||
return 'important';
|
return 'important';
|
||||||
|
} else if (text.indexOf('Exit') != -1 && text !== 'Exit 0') {
|
||||||
|
return 'warning';
|
||||||
}
|
}
|
||||||
return 'success';
|
return 'success';
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
.filter('getstatetext', function() {
|
||||||
|
return function(state) {
|
||||||
|
if (state == undefined) return '';
|
||||||
|
|
||||||
|
if (state.Ghost && state.Running) {
|
||||||
|
return 'Ghost';
|
||||||
|
}
|
||||||
|
if (state.Running) {
|
||||||
|
return 'Running';
|
||||||
|
}
|
||||||
|
return 'Stopped';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter('getstatelabel', function() {
|
||||||
|
return function(state) {
|
||||||
|
if (state == undefined) return '';
|
||||||
|
|
||||||
|
if (state.Ghost && state.Running) {
|
||||||
|
return 'label-important';
|
||||||
|
}
|
||||||
|
if (state.Running) {
|
||||||
|
return 'label-success';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
};
|
||||||
|
})
|
||||||
|
.filter('getdate', function() {
|
||||||
|
return function(data) {
|
||||||
|
//Multiply by 1000 for the unix format
|
||||||
|
var date = new Date(data * 1000);
|
||||||
|
return date.toDateString();
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,27 +7,54 @@ angular.module('dockerui.services', ['ngResource'])
|
||||||
return $resource(DOCKER_ENDPOINT + '/containers/:id/:action', {}, {
|
return $resource(DOCKER_ENDPOINT + '/containers/:id/:action', {}, {
|
||||||
query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true},
|
query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true},
|
||||||
get :{method: 'GET', params: { action:'json'}},
|
get :{method: 'GET', params: { action:'json'}},
|
||||||
start: {method: 'POST', params: { action: 'start'}},
|
start: {method: 'POST', params: {id: '@id', action: 'start'}},
|
||||||
stop: {method: 'POST', params: {t: 5, action: 'stop'}},
|
stop: {method: 'POST', params: {id: '@id', t: 5, action: 'stop'}},
|
||||||
restart: {method: 'POST', params: {t: 5, action: 'restart' }},
|
restart: {method: 'POST', params: {id: '@id', t: 5, action: 'restart' }},
|
||||||
kill :{method: 'POST', params: {action:'kill'}},
|
kill :{method: 'POST', params: {id: '@id', action:'kill'}},
|
||||||
changes :{method: 'GET', params: {action:'changes'}, isArray: true},
|
changes :{method: 'GET', params: {action:'changes'}, isArray: true},
|
||||||
create :{method: 'POST', params: {action:'create'}},
|
create :{method: 'POST', params: {action:'create'}},
|
||||||
remove :{method: 'DELETE', params: {v:0}}
|
remove :{method: 'DELETE', params: {id: '@id', v:0}}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.factory('Image', function($resource, DOCKER_ENDPOINT) {
|
.factory('Image', function($resource, DOCKER_ENDPOINT) {
|
||||||
// Resource for docker images
|
// Resource for docker images
|
||||||
// http://docs.docker.io/en/latest/api/docker_remote_api.html#images
|
// http://docs.docker.io/en/latest/api/docker_remote_api.html#images
|
||||||
return $resource(DOCKER_ENDPOINT + '/images/:name/:action', {}, {
|
return $resource(DOCKER_ENDPOINT + '/images/:id/:action', {}, {
|
||||||
query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true},
|
query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true},
|
||||||
get :{method: 'GET', params: { action:'json'}},
|
get :{method: 'GET', params: { action:'json'}},
|
||||||
search :{method: 'GET', params: { action:'search'}},
|
search :{method: 'GET', params: { action:'search'}},
|
||||||
history :{method: 'GET', params: { action:'history'}},
|
history :{method: 'GET', params: { action:'history'}, isArray: true},
|
||||||
create :{method: 'POST', params: {action:'create'}},
|
create :{method: 'POST', params: {action:'create'}},
|
||||||
insert :{method: 'POST', params: {action:'insert'}},
|
insert :{method: 'POST', params: {id: '@id', action:'insert'}},
|
||||||
push :{method: 'POST', params: {action:'push'}},
|
push :{method: 'POST', params: {id: '@id', action:'push'}},
|
||||||
tag :{method: 'POST', params: {action:'tag'}},
|
tag :{method: 'POST', params: {id: '@id', action:'tag'}},
|
||||||
delete :{method: 'DELETE'}
|
delete :{id: '@id', method: 'DELETE'}
|
||||||
});
|
});
|
||||||
|
})
|
||||||
|
.factory('Docker', function($resource, DOCKER_ENDPOINT) {
|
||||||
|
// Information for docker
|
||||||
|
// http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information
|
||||||
|
return $resource(DOCKER_ENDPOINT + '/version', {}, {
|
||||||
|
get: {method: 'GET'}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.factory('Auth', function($resource, DOCKER_ENDPOINT) {
|
||||||
|
// Auto Information for docker
|
||||||
|
// http://docs.docker.io/en/latest/api/docker_remote_api.html#set-auth-configuration
|
||||||
|
return $resource(DOCKER_ENDPOINT + '/auth', {}, {
|
||||||
|
get: {method: 'GET'},
|
||||||
|
update: {method: 'POST'}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.factory('System', function($resource, DOCKER_ENDPOINT) {
|
||||||
|
// System for docker
|
||||||
|
// http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information
|
||||||
|
return $resource(DOCKER_ENDPOINT + '/info', {}, {
|
||||||
|
get: {method: 'GET'}
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.factory('Settings', function() {
|
||||||
|
return {
|
||||||
|
displayAll: false
|
||||||
|
};
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
|
||||||
<div class="detail">
|
<div class="detail">
|
||||||
|
<div id="response" class="alert alert-{{ alertClass }}">
|
||||||
|
{{ response }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<h4>Container: {{ container.Id }}</h4>
|
<h4>Container: {{ container.Id }}</h4>
|
||||||
|
|
||||||
<div class="btn-group detail">
|
<div class="btn-group detail">
|
||||||
<button class="btn btn-success" ng-click="start()">Start</button>
|
<button class="btn btn-success" ng-click="start()">Start</button>
|
||||||
<button class="btn btn-warning" ng-click="stop()">Stop</button>
|
<button class="btn btn-warning" ng-click="stop()">Stop</button>
|
||||||
|
<button class="btn btn-danger" ng-click="kill()">Kill</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
|
@ -27,11 +31,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Image:</td>
|
<td>Image:</td>
|
||||||
<td><a href="#">{{ container.Image }}</a></td>
|
<td><a href="/#/images/{{ container.Image }}/">{{ container.Image }}</a></td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Running:</td>
|
<td>State:</td>
|
||||||
<td>{{ container.State.Running }}</td>
|
<td><span class="label {{ container.State|getstatelabel }}">{{ container.State|getstatetext }}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
|
|
||||||
<h2>Containers:</h2>
|
<h2>Containers:</h2>
|
||||||
|
|
||||||
|
<div style="float:right;">
|
||||||
|
<input type="checkbox" ng-model="displayAll" ng-click="toggleGetAll()"/> Display All
|
||||||
|
</div>
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -12,11 +15,11 @@
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr ng-repeat="container in containers">
|
<tr ng-repeat="container in containers|orderBy:predicate">
|
||||||
<td><a href="/#/containers/{{ container.Id }}/">{{ container.Id|truncate:10}}</a></td>
|
<td><a href="/#/containers/{{ container.Id }}/">{{ container.Id|truncate:10}}</a></td>
|
||||||
<td>{{ container.Image }}</td>
|
<td><a href="/#/images/{{ container.Image }}/">{{ container.Image }}</a></td>
|
||||||
<td>{{ container.Command }}</td>
|
<td>{{ container.Command|truncate:40 }}</td>
|
||||||
<td>{{ container.Created }}</td>
|
<td>{{ container.Created|getdate }}</td>
|
||||||
<td><span class="label label-{{ container.Status|statusbadge }}">{{ container.Status }}</span></td>
|
<td><span class="label label-{{ container.Status|statusbadge }}">{{ container.Status }}</span></td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|
89
partials/image.html
Normal file
89
partials/image.html
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
<div class="detail">
|
||||||
|
|
||||||
|
<div id="response" class="alert alert-{{ alertClass }}">
|
||||||
|
{{ response }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h4>Image: {{ image.id }}</h4>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Created:</td>
|
||||||
|
<td>{{ image.created }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Parent:</td>
|
||||||
|
<td><a href="/#/images/{{ image.parent }}/">{{ image.parent }}</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Container:</td>
|
||||||
|
<td><a href="/#/containers/{{ image.container }}/">{{ image.container }}</a></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Hostname:</td>
|
||||||
|
<td>{{ image.container_config.Hostname }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>User:</td>
|
||||||
|
<td>{{ image.container_config.User }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Cmd:</td>
|
||||||
|
<td>{{ image.container_config.Cmd }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Volumes:</td>
|
||||||
|
<td>{{ image.container_config.Volumes }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Volumes from:</td>
|
||||||
|
<td>{{ image.container_config.VolumesFrom }}</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
<div class="span1">
|
||||||
|
History:
|
||||||
|
</div>
|
||||||
|
<div class="span5">
|
||||||
|
<i class="icon-refresh" style="width:32px;height:32px;" ng-click="getHistory()"></i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="well well-large">
|
||||||
|
<ul>
|
||||||
|
<li ng-repeat="change in history">
|
||||||
|
<strong>{{ change.Id }}</strong>: Created: {{ change.Created|getdate }} Created by: {{ change.CreatedBy }}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="row-fluid">
|
||||||
|
<form>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Tag to Repo</legend>
|
||||||
|
<label>Repo:</label>
|
||||||
|
<input type="text" placeholder="Repo..." ng-model="tag.repo" required>
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" ng-model="tag.force"/> Force?
|
||||||
|
</label>
|
||||||
|
<input type="button" ng-click="updateTag()" value="Update" class="btn btn-info"/>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div ng-include="template" ng-controller="StartContainerController"></div>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="btn-remove">
|
||||||
|
<button class="btn btn-large btn-block btn-primary btn-danger" ng-click="remove()">Remove Image</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
21
partials/images.html
Normal file
21
partials/images.html
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
<h2>Images:</h2>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Id</th>
|
||||||
|
<th>Tag</th>
|
||||||
|
<th>Repository</th>
|
||||||
|
<th>Created</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<tr ng-repeat="image in images | orderBy:predicate">
|
||||||
|
<td><a href="/#/images/{{ image.Id }}/">{{ image.Id|truncate:10}}</a></td>
|
||||||
|
<td>{{ image.Tag }}</td>
|
||||||
|
<td>{{ image.Repository }}</td>
|
||||||
|
<td>{{ image.Created|getdate }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
67
partials/settings.html
Normal file
67
partials/settings.html
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
<div class="detail">
|
||||||
|
<div id="response" class="alert alert-{{ alertClass }}">
|
||||||
|
{{ response }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3>Docker Information</h3>
|
||||||
|
<div>
|
||||||
|
<p class="lead">
|
||||||
|
<strong>Version</strong>{{ docker.Version }}<br />
|
||||||
|
<strong>GitCommit</strong>{{ docker.GitCommit }}<br />
|
||||||
|
<strong>GoVersion</strong>{{ docker.GoVersion }}<br />
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table class="table table-striped">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td>Containers:</td>
|
||||||
|
<td>{{ info.Containers }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Images:</td>
|
||||||
|
<td>{{ info.Images }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Debug:</td>
|
||||||
|
<td>{{ info.Debug }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>NFd:</td>
|
||||||
|
<td>{{ info.NFd }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>NGoroutines:</td>
|
||||||
|
<td>{{ info.NGoroutines }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>MemoryLimit:</td>
|
||||||
|
<td>{{ info.MemoryLimit }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>SwapLimit:</td>
|
||||||
|
<td>{{ info.SwapLimit }}</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>NFd:</td>
|
||||||
|
<td>{{ info.NFd }}</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Auth Information</legend>
|
||||||
|
<label>Username:</label>
|
||||||
|
<input type="text" ng-model="auth.username" required>
|
||||||
|
<label>Email:</label>
|
||||||
|
<input type="text" ng-model="auth.email" required>
|
||||||
|
<label>Password:</label>
|
||||||
|
<input type="password" ng-model="auth.password" required>
|
||||||
|
<label>Confirm Password:</label>
|
||||||
|
<input type="password" ng-model="auth.cpassword" required>
|
||||||
|
<br />
|
||||||
|
<input type="button" ng-click="updateAuthInfo()" value="Update"/>
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
||||||
|
</div>
|
27
partials/startcontainer.html
Normal file
27
partials/startcontainer.html
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{{ response }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<form>
|
||||||
|
<fieldset>
|
||||||
|
<legend>Start container from Image</legend>
|
||||||
|
|
||||||
|
<label>Cmd:</label>
|
||||||
|
<textarea ng-model="commands" rows="6"></textarea>
|
||||||
|
<small>Place each command on a new line</small>
|
||||||
|
|
||||||
|
<label>Memory:</label>
|
||||||
|
<input type="number" ng-model="memory"/>
|
||||||
|
|
||||||
|
<label>Memory Swap:</label>
|
||||||
|
<input type="number" ng-model="memorySwap"/>
|
||||||
|
|
||||||
|
<label>Volumes From:</label>
|
||||||
|
<input type="text" ng-model="volumesFrom"/>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<input type="button" ng-click="launchContainer()" value="Launch" />
|
||||||
|
</fieldset>
|
||||||
|
</form>
|
Loading…
Add table
Add a link
Reference in a new issue