Compare commits

...

51 Commits

Author SHA1 Message Date
Kevan Ahlquist ae3d1c305d Bump version to 0.7.0. 2015-04-03 11:25:45 -05:00
Kevan Ahlquist d04b17efeb Build latest changes. 2015-04-02 10:01:21 -05:00
Kevan Ahlquist 0520fa739a Merge branch 'github-master' into github-dist
Latest changes from Top feature.
2015-04-02 09:50:34 -05:00
Kevan Ahlquist 964eac6d53 Merge pull request #102 from houssemba/master
Add Docker top feature
2015-04-02 09:40:01 -05:00
Houssem BELHADJ AHMED ede37e2e79 Add Docker top feature 2015-03-31 23:37:03 +02:00
Kevan Ahlquist f40d645fb3 Bump other app version. 2015-03-18 20:03:50 -05:00
Kevan Ahlquist 961b72072a Pull latest changes into dist, version bump to 0.7.0-beta 2015-03-18 19:45:51 -05:00
Kevan Ahlquist d6c524f960 Merge pull request #99 from houssemba/master
Rename feature
2015-03-18 19:28:55 -05:00
Houssem BELHADJ AHMED c971189286 Add rename feature 2015-03-12 22:28:01 +01:00
Houssem BELHADJ AHMED f29eaa28ba Jshint & test fix 2015-03-08 18:19:51 +01:00
Kevan Ahlquist 68ab1a302d Pull latest changes from master and build dist. 2015-02-25 00:33:13 -06:00
Kevan Ahlquist 9afe57e0ec Merge pull request #86 from kevana/master
Small fixes
2015-02-24 23:33:15 -06:00
Kevan Ahlquist fb0a0827b6 Merge commit '974ed1fe0598533747c2cf4c2f21d7830d484431'
Conflicts:
	app/components/containerLogs/containerLogsController.js
2015-02-24 23:32:38 -06:00
Kevan Ahlquist 22cdb94e5d Removed dist files. 2015-02-22 02:40:50 -06:00
Kevan Ahlquist 974ed1fe05 Merge pull request #77 from jonny64/logs_tail
logs page: slow on huge logs - 'show last lines' option
2015-02-21 16:03:17 -06:00
jonny64 66ba60c475 logs: added spinner during refresh 2015-02-21 18:09:12 +00:00
Kevan Ahlquist 65f7e32f94 Strip headers from logs before display, fixes #94 2015-02-18 22:56:55 -06:00
Kevan Ahlquist dd21a4025b Merge commit '1843836f229cadcdace5ca0c1b95fdb21dcfea2b'
Conflicts:
	dist/dockerui.js
	dist/templates/app.js
2015-02-18 22:46:37 -06:00
Kevan Ahlquist 2223c8f1d1 Merge branch 'dist' of https://github.com/crosbymichael/dockerui into dist 2015-02-18 01:08:03 -06:00
Kevan Ahlquist 3635e95138 Adding latest build to dist. 2015-02-18 01:06:23 -06:00
Kevan Ahlquist 1843836f22 Fixed release target in Makefile. 2015-02-18 01:05:51 -06:00
Kevan Ahlquist 059115e523 Adding latest build to dist. 2015-02-18 01:04:26 -06:00
Kevan Ahlquist 44ba4e8bb8 Merge commit '22287e6a56c5a8824da94f2f6b9a464fa3da4192' 2015-02-18 00:55:40 -06:00
Kevan Ahlquist 2adaa33fdb Remove dist folder from master. 2015-02-17 22:48:23 -06:00
jonny64 b257216194 logs: reload button 2015-02-16 18:42:46 +00:00
jonny64 df5e7bc867 logs: removed debugging 2015-02-16 18:18:34 +00:00
jonny64 53041efaf1 logs: tail also STDERR 2015-02-16 17:42:02 +00:00
jonny64 87131f4ae3 Merge remote-tracking branch 'origin/master' into logs_tail 2015-02-16 17:37:04 +00:00
Kevan Ahlquist f66bcfd4ea Merge latest changes from crosbymichael/dockerui. 2015-02-14 14:23:48 -06:00
Kevan Ahlquist 1fb7338838 Merge pull request #90 from dasJ/dropdown
Add nice cursor for dropdown menus
2015-02-14 14:10:33 -06:00
Kevan Ahlquist da60a70f43 Merge pull request #92 from dasJ/image
Fix values on images page
2015-02-14 14:08:55 -06:00
Kevan Ahlquist 8848d2d53c Merge pull request #89 from dasJ/master
Improve settings page
2015-02-14 14:02:43 -06:00
Janne Heß ad6e0acab1 Correctly humanize RAM size on info page 2015-02-13 21:35:57 +01:00
Janne Heß 14d4397868 Rename settings page to info
You can't change any settings in the settings page, so the title is
missleading.
2015-02-13 21:35:57 +01:00
Janne Heß f32aadedfb Add more information to the settings page
Now shows all information we can get from the info object.
Exceptions: Name and NEventsListener, those don't seem to work.
2015-02-13 21:35:57 +01:00
Janne Heß b888081f54 Fix values on images page
Update to current Docker API and add virtual size of the image.
Also replace the deprecated Comment with some informations about the
build machine.
2015-02-13 21:22:08 +01:00
Kevan Ahlquist b00b61ce25 Merge pull request #91 from dasJ/checkbox
Make text next to "Display All" clickable
2015-02-13 09:10:07 -06:00
Janne Heß 9284e4b451 Make text next to "Display All" clickable 2015-02-13 14:32:03 +01:00
Janne Heß 716e25703e Add nice cursor for dropdown menus 2015-02-13 14:18:36 +01:00
Kevan Ahlquist 65d0b0110d Consume image IDs that contain slashes, fix container port labels, be nicer about old browsers. 2015-02-13 01:13:04 -06:00
Kevan Ahlquist 9baa85f2e4 Merge pull request #82 from kevana/master
Added restart to container list actions.
2015-02-13 01:00:32 -06:00
William McGann 22287e6a56 Using centurylink's golang-builder to create tiny docker image, going from ~400MB to 5.4MB. 2015-02-13 01:11:50 -05:00
Kevan Ahlquist 0d4274fdeb Added restart to container list actions. 2015-02-09 23:10:05 -06:00
Kevan Ahlquist 4d9d66e9f9 Merge pull request #81 from kevana/master
Add timestamp option to stderr
2015-02-09 23:02:01 -06:00
Kevan Ahlquist c7ebe9d881 Added timestamp option to stderr. 2015-02-09 23:00:34 -06:00
Kevan Ahlquist c798a95fb3 Merge pull request #9 from crosbymichael/master
Pull latest changes
2015-02-09 22:48:32 -06:00
Kevan Ahlquist d11c849a0f Merge pull request #79 from Slamper/master
Fix of HostConfig being lost when starting containers from the list
2015-02-09 22:45:00 -06:00
Hendrik Hofstadt 8abb445bd4 nicer solution for checking the action 2015-02-09 20:06:28 +01:00
Hendrik Hofstadt dabb1926a5 fixed all HostConfigs being lost when starting from the list 2015-02-08 19:59:26 +01:00
Hendrik Hofstadt 829ff5da73 fixed loss of hostconfig when starting with batch 2015-02-07 23:02:35 +01:00
jonny64 aead1fcc29 logs page: slow on huge logs - 'show last lines' option 2015-02-05 19:23:57 +00:00
37 changed files with 1384 additions and 677 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
logs/*
!.gitkeep
dockerui
*.esproj/*
node_modules
.idea
*.iml
+5 -6
View File
@@ -1,8 +1,7 @@
FROM crosbymichael/golang
FROM scratch
COPY dockerui /
COPY dist /
COPY dockerui.go /app/
COPY dist/ /app/
WORKDIR /app/
RUN go build dockerui.go
EXPOSE 9000
ENTRYPOINT ["./dockerui"]
ENTRYPOINT ["/dockerui"]
+4 -2
View File
@@ -7,14 +7,16 @@ PORT ?= 9000
install:
npm install -g grunt-cli
npm install
build:
grunt build
docker build --rm -t dockerui .
build-release:
grunt release
docker build --rm -t dockerui .
grunt build
docker run --rm -v $(shell pwd):/src centurylink/golang-builder
shasum dockerui > dockerui-checksum.txt
test:
grunt
+1 -1
View File
@@ -55,7 +55,7 @@ The DockerUI code is licensed under the MIT license.
**DockerUI:**
Copyright (c) 2014 Michael Crosby. crosbymichael.com
Copyright (c) 2014-2015 Michael Crosby (crosbymichael.com), Kevan Ahlquist (kevanahlquist.com)
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
+32 -10
View File
@@ -1,18 +1,40 @@
angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'images', 'image', 'startContainer', 'sidebar', 'settings', 'builder', 'containerLogs'])
angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'images', 'image', 'startContainer', 'sidebar', 'info', 'builder', 'containerLogs', 'containerTop'])
.config(['$routeProvider', function ($routeProvider) {
'use strict';
$routeProvider.when('/', {templateUrl: 'app/components/dashboard/dashboard.html', controller: 'DashboardController'});
$routeProvider.when('/containers/', {templateUrl: 'app/components/containers/containers.html', controller: 'ContainersController'});
$routeProvider.when('/containers/:id/', {templateUrl: 'app/components/container/container.html', controller: 'ContainerController'});
$routeProvider.when('/containers/:id/logs/', {templateUrl: 'app/components/containerLogs/containerlogs.html', controller: 'ContainerLogsController'});
$routeProvider.when('/images/', {templateUrl: 'app/components/images/images.html', controller: 'ImagesController'});
$routeProvider.when('/images/:id/', {templateUrl: 'app/components/image/image.html', controller: 'ImageController'});
$routeProvider.when('/settings', {templateUrl: 'app/components/settings/settings.html', controller: 'SettingsController'});
$routeProvider.when('/', {
templateUrl: 'app/components/dashboard/dashboard.html',
controller: 'DashboardController'
});
$routeProvider.when('/containers/', {
templateUrl: 'app/components/containers/containers.html',
controller: 'ContainersController'
});
$routeProvider.when('/containers/:id/', {
templateUrl: 'app/components/container/container.html',
controller: 'ContainerController'
});
$routeProvider.when('/containers/:id/logs/', {
templateUrl: 'app/components/containerLogs/containerlogs.html',
controller: 'ContainerLogsController'
});
$routeProvider.when('/containers/:id/top', {
templateUrl: 'app/components/containerTop/containerTop.html',
controller: 'ContainerTopController'
});
$routeProvider.when('/images/', {
templateUrl: 'app/components/images/images.html',
controller: 'ImagesController'
});
$routeProvider.when('/images/:id*/', {
templateUrl: 'app/components/image/image.html',
controller: 'ImageController'
});
$routeProvider.when('/info', {templateUrl: 'app/components/info/info.html', controller: 'InfoController'});
$routeProvider.otherwise({redirectTo: '/'});
}])
// This is your docker url that the api will use to make requests
// You need to set this to the api endpoint without the port i.e. http://192.168.1.9
.constant('DOCKER_ENDPOINT', 'dockerapi')
.constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243
.constant('UI_VERSION', 'v0.6.0')
.constant('DOCKER_API_VERSION', 'v1.16');
.constant('UI_VERSION', 'v0.7.0')
.constant('DOCKER_API_VERSION', 'v1.17');
+125 -99
View File
@@ -1,111 +1,137 @@
<div class="detail">
<h4>Container: {{ container.Name }}</h4>
<div ng-if="!container.edit">
<h4>Container: {{ container.Name }}
<button class="btn btn-primary"
ng-click="container.edit = true;">Rename
</button>
</h4>
</div>
<div ng-if="container.edit">
<h4>
Container:
<input type="text" ng-model="container.newContainerName">
<button class="btn btn-success"
ng-click="renameContainer()">Edit
</button>
<button class="btn btn-danger"
ng-click="container.edit = false;">&times;</button>
</h4>
</div>
<div class="btn-group detail">
<button class="btn btn-success"
ng-click="start()"
ng-show="!container.State.Running">Start</button>
<button class="btn btn-warning"
ng-click="stop()"
ng-show="container.State.Running && !container.State.Paused">Stop</button>
<button class="btn btn-danger"
ng-click="kill()"
ng-show="container.State.Running && !container.State.Paused">Kill</button>
<button class="btn btn-info"
ng-click="pause()"
ng-show="container.State.Running && !container.State.Paused">Pause</button>
<button class="btn btn-success"
ng-click="unpause()"
ng-show="container.State.Running && container.State.Paused">Unpause</button>
<button class="btn btn-success"
ng-click="start()"
ng-show="!container.State.Running">Start
</button>
<button class="btn btn-warning"
ng-click="stop()"
ng-show="container.State.Running && !container.State.Paused">Stop
</button>
<button class="btn btn-danger"
ng-click="kill()"
ng-show="container.State.Running && !container.State.Paused">Kill
</button>
<button class="btn btn-info"
ng-click="pause()"
ng-show="container.State.Running && !container.State.Paused">Pause
</button>
<button class="btn btn-success"
ng-click="unpause()"
ng-show="container.State.Running && container.State.Paused">Unpause
</button>
</div>
<table class="table table-striped">
<tbody>
<tr>
<td>Created:</td>
<td>{{ container.Created }}</td>
</tr>
<tr>
<td>Path:</td>
<td>{{ container.Path }}</td>
</tr>
<tr>
<td>Args:</td>
<td>{{ container.Args }}</td>
</tr>
<tr>
<td>Exposed Ports:</td>
<td>
<ul>
<li ng-repeat="(k, v) in container.Config.ExposedPorts">{{ k }}</li>
</ul>
</td>
</tr>
<tr>
<td>Environment:</td>
<td>
<ul>
<li ng-repeat="k in container.Config.Env">{{ k }}</li>
</ul>
</td>
</tr>
<tbody>
<tr>
<td>Created:</td>
<td>{{ container.Created }}</td>
</tr>
<tr>
<td>Path:</td>
<td>{{ container.Path }}</td>
</tr>
<tr>
<td>Args:</td>
<td>{{ container.Args }}</td>
</tr>
<tr>
<td>Exposed Ports:</td>
<td>
<ul>
<li ng-repeat="(k, v) in container.Config.ExposedPorts">{{ k }}</li>
</ul>
</td>
</tr>
<tr>
<td>Environment:</td>
<td>
<ul>
<li ng-repeat="k in container.Config.Env">{{ k }}</li>
</ul>
</td>
</tr>
<tr>
<td>Publish All:</td>
<td>{{ container.HostConfig.PublishAllPorts }}</td>
</tr>
<tr>
<td>Ports:</td>
<td>
<ul style="display:inline-table">
<li ng-repeat="(containerport, hostports) in container.HostConfig.PortBindings">
{{ containerport }} => <span class="label" ng-repeat="(k,v) in hostports">{{ v.HostIp }}:{{ v.HostPort }}</span>
</li>
</ul>
</td>
<tr>
<td>Publish All:</td>
<td>{{ container.HostConfig.PublishAllPorts }}</td>
</tr>
<tr>
<td>Ports:</td>
<td>
<ul style="display:inline-table">
<li ng-repeat="(containerport, hostports) in container.HostConfig.PortBindings">
{{ containerport }} => <span class="label label-default" ng-repeat="(k,v) in hostports">{{ v.HostIp }}:{{ v.HostPort }}</span>
</li>
</ul>
</td>
</tr>
<tr>
<td>Hostname:</td>
<td>{{ container.Config.Hostname }}</td>
</tr>
<tr>
<td>IPAddress:</td>
<td>{{ container.NetworkSettings.IPAddress }}</td>
</tr>
<tr>
<td>Cmd:</td>
<td>{{ container.Config.Cmd }}</td>
</tr>
<tr>
<td>Entrypoint:</td>
<td>{{ container.Config.Entrypoint }}</td>
</tr>
<tr>
<td>Volumes:</td>
<td>{{ container.Volumes }}</td>
</tr>
</tr>
<tr>
<td>Hostname:</td>
<td>{{ container.Config.Hostname }}</td>
</tr>
<tr>
<td>IPAddress:</td>
<td>{{ container.NetworkSettings.IPAddress }}</td>
</tr>
<tr>
<td>Cmd:</td>
<td>{{ container.Config.Cmd }}</td>
</tr>
<tr>
<td>Entrypoint:</td>
<td>{{ container.Config.Entrypoint }}</td>
</tr>
<tr>
<td>Volumes:</td>
<td>{{ container.Volumes }}</td>
</tr>
<tr>
<td>SysInitpath:</td>
<td>{{ container.SysInitPath }}</td>
</tr>
<tr>
<td>Image:</td>
<td><a href="#/images/{{ container.Image }}/">{{ container.Image }}</a></td>
</tr>
<tr>
<td>State:</td>
<td><span class="label {{ container.State|getstatelabel }}">{{ container.State|getstatetext }}</span></td>
</tr>
<tr>
<td>Logs:</td>
<td><a href="#/containers/{{ container.Id }}/logs">stdout/stderr</a></td>
</tr>
<tr>
<td>SysInitpath:</td>
<td>{{ container.SysInitPath }}</td>
</tr>
<tr>
<td>Image:</td>
<td><a href="#/images/{{ container.Image }}/">{{ container.Image }}</a></td>
</tr>
<tr>
<td>State:</td>
<td><span class="label {{ container.State|getstatelabel }}">{{ container.State|getstatetext }}</span></td>
</tr>
<tr>
<td>Logs:</td>
<td><a href="#/containers/{{ container.Id }}/logs">stdout/stderr</a></td>
</tr>
<tr>
<td>Top:</td>
<td><a href="#/containers/{{ container.Id }}/top">Top</a></td>
</tr>
</tbody>
</table>
<div class="row-fluid">
<div class="span1">
Changes:
@@ -113,7 +139,7 @@
<div class="span5">
<i class="icon-refresh" style="width:32px;height:32px;" ng-click="getChanges()"></i>
</div>
</div>
</div>
<div class="well well-large">
<ul>
@@ -123,7 +149,7 @@
</ul>
</div>
<hr />
<hr/>
<div class="btn-remove">
<button class="btn btn-large btn-block btn-primary btn-danger" ng-click="remove()">Remove Container</button>
@@ -2,11 +2,14 @@ angular.module('container', [])
.controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'Messages', 'ViewSpinner',
function($scope, $routeParams, $location, Container, Messages, ViewSpinner) {
$scope.changes = [];
$scope.edit = false;
var update = function() {
ViewSpinner.spin();
Container.get({id: $routeParams.id}, function(d) {
$scope.container = d;
$scope.container.edit = false;
$scope.container.newContainerName = d.Name;
ViewSpinner.stop();
}, function(e) {
if (e.status === 404) {
@@ -100,6 +103,20 @@ function($scope, $routeParams, $location, Container, Messages, ViewSpinner) {
});
};
$scope.renameContainer = function () {
// #FIXME fix me later to handle http status to show the correct error message
Container.rename({id: $routeParams.id, 'name': $scope.container.newContainerName}, function(data){
if (data.name){
$scope.container.Name = data.name;
Messages.send("Container renamed", $routeParams.id);
}else {
$scope.container.newContainerName = $scope.container.Name;
Messages.error("Failure", "Container failed to rename.");
}
});
$scope.container.edit = false;
};
update();
$scope.getChanges();
}]);
@@ -4,6 +4,7 @@ function($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Containe
$scope.stdout = '';
$scope.stderr = '';
$scope.showTimestamps = false;
$scope.tailLines = 2000;
ViewSpinner.spin();
Container.get({id: $routeParams.id}, function(d) {
@@ -19,12 +20,35 @@ function($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Containe
});
function getLogs() {
ContainerLogs.get($routeParams.id, {stdout: 1, stderr: 0, timestamps: $scope.showTimestamps}, function(data, status, headers, config) {
// Replace carriage returns twith newlines to clean up output
$scope.stdout = data.replace(/[\r]/g, '\n');
ViewSpinner.spin();
ContainerLogs.get($routeParams.id, {
stdout: 1,
stderr: 0,
timestamps: $scope.showTimestamps,
tail: $scope.tailLines
}, function(data, status, headers, config) {
// Replace carriage returns with newlines to clean up output
data = data.replace(/[\r]/g, '\n');
// Strip 8 byte header from each line of output
data = data.substring(8);
data = data.replace(/\n(.{8})/g, '\n');
$scope.stdout = data;
ViewSpinner.stop();
});
ContainerLogs.get($routeParams.id, {stdout: 0, stderr: 1}, function(data, status, headers, config) {
$scope.stderr = data.replace(/[\r]/g, '\n');
ContainerLogs.get($routeParams.id, {
stdout: 0,
stderr: 1,
timestamps: $scope.showTimestamps,
tail: $scope.tailLines
}, function(data, status, headers, config) {
// Replace carriage returns with newlines to clean up output
data = data.replace(/[\r]/g, '\n');
// Strip 8 byte header from each line of output
data = data.substring(8);
data = data.replace(/\n(.{8})/g, '\n');
$scope.stderr = data;
ViewSpinner.stop();
});
}
@@ -45,4 +69,8 @@ function($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Containe
$scope.toggleTimestamps = function() {
getLogs();
};
$scope.toggleTail = function() {
getLogs();
};
}]);
@@ -5,9 +5,17 @@
<button class="btn btn-info" ng-click="scrollTo('stdout')">stdout</button>
<button class="btn btn-warning" ng-click="scrollTo('stderr')">stderr</button>
</div>
<div class="pull-right">
<input id="timestampToggle" type="checkbox" ng-model="showTimestamps"
ng-change="toggleTimestamps()"/> <label for="timestampToggle">Display Timestamps</label>
<div class="pull-right col-xs-6">
<div class="col-xs-6">
<a class="btn btn-primary" ng-click="toggleTail()" role="button">Reload logs</a>
<input id="tailLines" type="number" ng-style="{width: '45px'}"
ng-model="tailLines" ng-keypress="($event.which === 13)? toggleTail() : 0"/>
<label for="tailLines">lines</label>
</div>
<div class="col-xs-4">
<input id="timestampToggle" type="checkbox" ng-model="showTimestamps"
ng-change="toggleTimestamps()"/> <label for="timestampToggle">Timestamps</label>
</div>
</div>
</div>
@@ -0,0 +1,19 @@
<div class="containerTop">
<div class="form-group col-xs-2">
<input type="text" class="form-control" placeholder="[options] (aux)" ng-model="ps_args">
</div>
<button type="button" class="btn btn-default" ng-click="getTop()">Submit</button>
<table class="table table-striped">
<thead>
<tr>
<th ng-repeat="title in containerTop.Titles">{{title}}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="processInfos in containerTop.Processes">
<td ng-repeat="processInfo in processInfos track by $index">{{processInfo}}</td>
</tr>
</tbody>
</table>
</div>
@@ -0,0 +1,19 @@
angular.module('containerTop', [])
.controller('ContainerTopController', ['$scope', '$routeParams', 'ContainerTop', 'ViewSpinner', function ($scope, $routeParams, ContainerTop, ViewSpinner) {
$scope.ps_args = '';
/**
* Get container processes
*/
$scope.getTop = function () {
ViewSpinner.spin();
ContainerTop.get($routeParams.id, {
ps_args: $scope.ps_args
}, function (data) {
$scope.containerTop = data;
ViewSpinner.stop();
});
};
$scope.getTop();
}]);
+2 -2
View File
@@ -8,6 +8,7 @@
<ul id="menu1" class="dropdown-menu" role="menu" aria-labelledby="drop4">
<li><a tabindex="-1" href="" ng-click="startAction()">Start</a></li>
<li><a tabindex="-1" href="" ng-click="stopAction()">Stop</a></li>
<li><a tabindex="-1" href="" ng-click="restartAction()">Restart</a></li>
<li><a tabindex="-1" href="" ng-click="killAction()">Kill</a></li>
<li><a tabindex="-1" href="" ng-click="pauseAction()">Pause</a></li>
<li><a tabindex="-1" href="" ng-click="unpauseAction()">Unpause</a></li>
@@ -17,8 +18,7 @@
</ul>
<div class="pull-right">
<input type="checkbox" ng-model="displayAll"
ng-change="toggleGetAll()"/> Display All
<input type="checkbox" ng-model="displayAll" id="displayAll" ng-change="toggleGetAll()"/> <label for="displayAll">Display All</label>
</div>
</div>
<table class="table table-striped">
@@ -26,15 +26,41 @@ function($scope, Container, Settings, Messages, ViewSpinner) {
};
angular.forEach(items, function(c) {
if (c.Checked) {
counter = counter + 1;
action({id: c.Id}, function(d) {
Messages.send("Container " + msg, c.Id);
var index = $scope.containers.indexOf(c);
complete();
}, function(e) {
Messages.error("Failure", e.data);
complete();
});
if(action === Container.start){
Container.get({id: c.Id}, function(d) {
c = d;
counter = counter + 1;
action({id: c.Id, HostConfig: c.HostConfig || {}}, function(d) {
Messages.send("Container " + msg, c.Id);
var index = $scope.containers.indexOf(c);
complete();
}, function(e) {
Messages.error("Failure", e.data);
complete();
});
}, function(e) {
if (e.status === 404) {
$('.detail').hide();
Messages.error("Not found", "Container not found.");
} else {
Messages.error("Failure", e.data);
}
complete();
});
}
else{
counter = counter + 1;
action({id: c.Id}, function(d) {
Messages.send("Container " + msg, c.Id);
var index = $scope.containers.indexOf(c);
complete();
}, function(e) {
Messages.error("Failure", e.data);
complete();
});
}
}
});
if (counter === 0) {
@@ -61,6 +87,10 @@ function($scope, Container, Settings, Messages, ViewSpinner) {
batch($scope.containers, Container.stop, "Stopped");
};
$scope.restartAction = function() {
batch($scope.containers, Container.restart, "Restarted");
};
$scope.killAction = function() {
batch($scope.containers, Container.kill, "Killed");
};
+3 -3
View File
@@ -27,7 +27,7 @@
<div class="col-xs-5 text-right">
<h3>Status</h3>
<canvas id="containers-chart" class="pull-right">
Get a better browser... Your holding everyone back.
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
</canvas>
<div id="chart-legend"></div>
</div>
@@ -38,11 +38,11 @@
<div class="col-xs-10" id="stats">
<h4>Containers created</h4>
<canvas id="containers-started-chart" width="700">
Get a better browser... You're holding everyone back.
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
</canvas>
<h4>Images created</h4>
<canvas id="images-created-chart" width="700">
Get a better browser... You're holding everyone back.
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
</canvas>
</div>
</div>
+12 -12
View File
@@ -15,7 +15,7 @@
<div>
<h4>Containers created:</h4>
<canvas id="containers-started-chart" width="750">
Get a better broswer... Your holding everyone back.
<p class="browserupgrade">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
</canvas>
</div>
@@ -23,40 +23,40 @@
<tbody>
<tr>
<td>Created:</td>
<td>{{ image.created }}</td>
<td>{{ image.Created }}</td>
</tr>
<tr>
<td>Parent:</td>
<td><a href="#/images/{{ image.parent }}/">{{ image.parent }}</a></td>
<td><a href="#/images/{{ image.Parent }}/">{{ image.Parent }}</a></td>
</tr>
<tr>
<td>Size:</td>
<td>{{ image.Size|humansize }}</td>
<td>Size (Virtual Size):</td>
<td>{{ image.Size|humansize }} ({{ image.VirtualSize|humansize }})</td>
</tr>
<tr>
<td>Hostname:</td>
<td>{{ image.container_config.Hostname }}</td>
<td>{{ image.ContainerConfig.Hostname }}</td>
</tr>
<tr>
<td>User:</td>
<td>{{ image.container_config.User }}</td>
<td>{{ image.ContainerConfig.User }}</td>
</tr>
<tr>
<td>Cmd:</td>
<td>{{ image.container_config.Cmd }}</td>
<td>{{ image.ContainerConfig.Cmd }}</td>
</tr>
<tr>
<td>Volumes:</td>
<td>{{ image.container_config.Volumes }}</td>
<td>{{ image.ContainerConfig.Volumes }}</td>
</tr>
<tr>
<td>Volumes from:</td>
<td>{{ image.container_config.VolumesFrom }}</td>
<td>{{ image.ContainerConfig.VolumesFrom }}</td>
</tr>
<tr>
<td>Comment:</td>
<td>{{ image.comment }}</td>
<td>Built with:</td>
<td>Docker {{ image.DockerVersion }} on {{ image.Os}}, {{ image.Architecture }}</td>
</tr>
</tbody>
+101
View File
@@ -0,0 +1,101 @@
<div class="detail">
<h2>Docker Information</h2>
<div>
<p class="lead">
<strong>Endpoint: </strong>{{ endpoint }}<br />
<strong>Api Version: </strong>{{ apiVersion }}<br />
<strong>Version: </strong>{{ docker.Version }}<br />
<strong>Git Commit: </strong>{{ docker.GitCommit }}<br />
<strong>Go Version: </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>CPUs:</td>
<td>{{ info.NCPU }}</td>
</tr>
<tr>
<td>Total Memory:</td>
<td>{{ info.MemTotal|humansize }}</td>
</tr>
<tr>
<td>Operating System:</td>
<td>{{ info.OperatingSystem }}</td>
</tr>
<tr>
<td>Kernel Version:</td>
<td>{{ info.KernelVersion }}</td>
</tr>
<tr>
<td>ID:</td>
<td>{{ info.ID }}</td>
</tr>
<tr>
<td>Labels:</td>
<td>{{ info.Labels }}</td>
</tr>
<tr>
<td>File Descriptors:</td>
<td>{{ info.NFd }}</td>
</tr>
<tr>
<td>Goroutines:</td>
<td>{{ info.NGoroutines }}</td>
</tr>
<tr>
<td>Storage Driver:</td>
<td>{{ info.Driver }}</td>
</tr>
<tr>
<td>Storage Driver Status:</td>
<td>{{ info.DriverStatus }}</td>
</tr>
<tr>
<td>Execution Driver:</td>
<td>{{ info.ExecutionDriver }}</td>
</tr>
<tr>
<td>IPv4 Forwarding:</td>
<td>{{ info.IPv4Forwarding }}</td>
</tr>
<tr>
<td>Index Server Address:</td>
<td>{{ info.IndexServerAddress }}</td>
</tr>
<tr>
<td>Init Path:</td>
<td>{{ info.InitPath }}</td>
</tr>
<tr>
<td>Docker Root Directory:</td>
<td>{{ info.DockerRootDir }}</td>
</tr>
<tr>
<td>Init SHA1</td>
<td>{{ info.InitSha1 }}</td>
</tr>
<tr>
<td>Memory Limit:</td>
<td>{{ info.MemoryLimit }}</td>
</tr>
<tr>
<td>Swap Limit:</td>
<td>{{ info.SwapLimit }}</td>
</tr>
</tbody>
</table>
</div>
@@ -1,5 +1,5 @@
angular.module('settings', [])
.controller('SettingsController', ['$scope', 'System', 'Docker', 'Settings', 'Messages',
angular.module('info', [])
.controller('InfoController', ['$scope', 'System', 'Docker', 'Settings', 'Messages',
function($scope, System, Docker, Settings, Messages) {
$scope.info = {};
$scope.docker = {};
+1 -1
View File
@@ -4,6 +4,6 @@
<li><a href="#">Dashboard</a></li>
<li><a href="#/containers/">Containers</a></li>
<li><a href="#/images/">Images</a></li>
<li><a href="#/settings/">Settings</a></li>
<li><a href="#/info/">Info</a></li>
</ul>
</div>
-49
View File
@@ -1,49 +0,0 @@
<div class="detail">
<h2>Docker Information</h2>
<div>
<p class="lead">
<strong>Endpoint: </strong>{{ endpoint }}<br />
<strong>Api Version: </strong>{{ apiVersion }}<br />
<strong>Version: </strong>{{ docker.Version }}<br />
<strong>Git Commit: </strong>{{ docker.GitCommit }}<br />
<strong>Go Version: </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>
</div>
+84 -60
View File
@@ -1,55 +1,75 @@
angular.module('dockerui.services', ['ngResource'])
.factory('Container', function($resource, Settings) {
.factory('Container', function ($resource, Settings) {
'use strict';
// Resource for interacting with the docker containers
// http://docs.docker.io/en/latest/api/docker_remote_api.html#containers
return $resource(Settings.url + '/containers/:id/:action', {
name: '@name'
}, {
query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true},
get: {method: 'GET', params: { action:'json'}},
query: {method: 'GET', params: {all: 0, action: 'json'}, isArray: true},
get: {method: 'GET', params: {action: 'json'}},
start: {method: 'POST', params: {id: '@id', action: 'start'}},
stop: {method: 'POST', params: {id: '@id', t: 5, action: 'stop'}},
restart: {method: 'POST', params: {id: '@id', t: 5, action: 'restart' }},
restart: {method: 'POST', params: {id: '@id', t: 5, action: 'restart'}},
kill: {method: 'POST', params: {id: '@id', action: 'kill'}},
pause: {method: 'POST', params: {id: '@id', action: 'pause'}},
unpause: {method: 'POST', params: {id: '@id', action: 'unpause'}},
changes: {method: 'GET', params: {action:'changes'}, isArray: true},
create: {method: 'POST', params: {action:'create'}},
remove: {method: 'DELETE', params: {id: '@id', v:0}}
changes: {method: 'GET', params: {action: 'changes'}, isArray: true},
create: {method: 'POST', params: {action: 'create'}},
remove: {method: 'DELETE', params: {id: '@id', v: 0}},
rename: {method: 'POST', params: {id: '@id', action: 'rename'}, isArray: false}
});
})
.factory('ContainerLogs', function($resource, $http, Settings) {
.factory('ContainerLogs', function ($resource, $http, Settings) {
'use strict';
return {
get: function(id, params, callback) {
get: function (id, params, callback) {
$http({
method: 'GET',
url: Settings.url + '/containers/'+id+'/logs',
params: {'stdout': params.stdout || 0, 'stderr': params.stderr || 0, 'timestamps': params.timestamps || 0, 'tail': params.tail || 'all'}
}).success(callback).error(function(data, status, headers, config) {
url: Settings.url + '/containers/' + id + '/logs',
params: {
'stdout': params.stdout || 0,
'stderr': params.stderr || 0,
'timestamps': params.timestamps || 0,
'tail': params.tail || 'all'
}
}).success(callback).error(function (data, status, headers, config) {
console.log(error, data);
});
}
};
})
.factory('Image', function($resource, Settings) {
.factory('ContainerTop', function ($http, Settings) {
'use strict';
return {
get: function (id, params, callback, errorCallback) {
$http({
method: 'GET',
url: Settings.url + '/containers/' + id + '/top',
params: {
ps_args: params.ps_args
}
}).success(callback);
}
};
})
.factory('Image', function ($resource, Settings) {
'use strict';
// Resource for docker images
// http://docs.docker.io/en/latest/api/docker_remote_api.html#images
return $resource(Settings.url + '/images/:id/:action', {}, {
query: {method: 'GET', params:{ all: 0, action: 'json'}, isArray: true},
get: {method: 'GET', params: { action:'json'}},
search: {method: 'GET', params: { action:'search'}},
history: {method: 'GET', params: { action:'history'}, isArray: true},
create: {method: 'POST', params: {action:'create'}},
insert: {method: 'POST', params: {id: '@id', action:'insert'}},
push: {method: 'POST', params: {id: '@id', action:'push'}},
tag: {method: 'POST', params: {id: '@id', action:'tag', force: 0, repo: '@repo'}},
query: {method: 'GET', params: {all: 0, action: 'json'}, isArray: true},
get: {method: 'GET', params: {action: 'json'}},
search: {method: 'GET', params: {action: 'search'}},
history: {method: 'GET', params: {action: 'history'}, isArray: true},
create: {method: 'POST', params: {action: 'create'}},
insert: {method: 'POST', params: {id: '@id', action: 'insert'}},
push: {method: 'POST', params: {id: '@id', action: 'push'}},
tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo'}},
remove: {method: 'DELETE', params: {id: '@id'}, isArray: true}
});
})
.factory('Docker', function($resource, Settings) {
.factory('Docker', function ($resource, Settings) {
'use strict';
// Information for docker
// http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information
@@ -57,7 +77,7 @@ angular.module('dockerui.services', ['ngResource'])
get: {method: 'GET'}
});
})
.factory('Auth', function($resource, Settings) {
.factory('Auth', function ($resource, Settings) {
'use strict';
// Auto Information for docker
// http://docs.docker.io/en/latest/api/docker_remote_api.html#set-auth-configuration
@@ -66,7 +86,7 @@ angular.module('dockerui.services', ['ngResource'])
update: {method: 'POST'}
});
})
.factory('System', function($resource, Settings) {
.factory('System', function ($resource, Settings) {
'use strict';
// System for docker
// http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information
@@ -74,7 +94,7 @@ angular.module('dockerui.services', ['ngResource'])
get: {method: 'GET'}
});
})
.factory('Settings', function(DOCKER_ENDPOINT, DOCKER_PORT, DOCKER_API_VERSION, UI_VERSION) {
.factory('Settings', function (DOCKER_ENDPOINT, DOCKER_PORT, DOCKER_API_VERSION, UI_VERSION) {
'use strict';
var url = DOCKER_ENDPOINT;
if (DOCKER_PORT) {
@@ -90,52 +110,56 @@ angular.module('dockerui.services', ['ngResource'])
firstLoad: true
};
})
.factory('ViewSpinner', function() {
.factory('ViewSpinner', function () {
'use strict';
var spinner = new Spinner();
var target = document.getElementById('view');
return {
spin: function() { spinner.spin(target); },
stop: function() { spinner.stop(); }
spin: function () {
spinner.spin(target);
},
stop: function () {
spinner.stop();
}
};
})
.factory('Messages', function($rootScope) {
.factory('Messages', function ($rootScope) {
'use strict';
return {
send: function(title, text) {
send: function (title, text) {
$.gritter.add({
title: title,
text: text,
time: 2000,
before_open: function() {
if($('.gritter-item-wrapper').length === 3) {
before_open: function () {
if ($('.gritter-item-wrapper').length === 3) {
return false;
}
}
}
});
});
},
error: function(title, text) {
error: function (title, text) {
$.gritter.add({
title: title,
text: text,
time: 10000,
before_open: function() {
if($('.gritter-item-wrapper').length === 4) {
before_open: function () {
if ($('.gritter-item-wrapper').length === 4) {
return false;
}
}
}
});
}
};
})
.factory('Dockerfile', function(Settings) {
.factory('Dockerfile', function (Settings) {
'use strict';
var url = Settings.rawUrl + '/build';
var url = Settings.rawUrl + '/build';
return {
build: function(file, callback) {
build: function (file, callback) {
var data = new FormData();
var dockerfile = new Blob([file], { type: 'text/text' });
var dockerfile = new Blob([file], {type: 'text/text'});
data.append('Dockerfile', dockerfile);
var request = new XMLHttpRequest();
@@ -145,18 +169,18 @@ angular.module('dockerui.services', ['ngResource'])
}
};
})
.factory('LineChart', function(Settings) {
.factory('LineChart', function (Settings) {
'use strict';
var url = Settings.rawUrl + '/build';
var url = Settings.rawUrl + '/build';
return {
build: function(id, data, getkey){
build: function (id, data, getkey) {
var chart = new Chart($(id).get(0).getContext("2d"));
var map = {};
for (var i = 0; i < data.length; i++) {
var c = data[i];
var key = getkey(c);
var count = map[key];
if (count === undefined) {
count = 0;
@@ -175,22 +199,22 @@ angular.module('dockerui.services', ['ngResource'])
data.push(map[k]);
}
var dataset = {
fillColor : "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)",
pointStrokeColor : "#fff",
data : data
fillColor: "rgba(151,187,205,0.5)",
strokeColor: "rgba(151,187,205,1)",
pointColor: "rgba(151,187,205,1)",
pointStrokeColor: "#fff",
data: data
};
chart.Line({
labels: labels,
datasets: [dataset]
},
{
scaleStepWidth: 1,
pointDotRadius:1,
scaleOverride: true,
scaleSteps: labels.length
});
labels: labels,
datasets: [dataset]
},
{
scaleStepWidth: 1,
pointDotRadius: 1,
scaleOverride: true,
scaleSteps: labels.length
});
}
};
});
+5
View File
@@ -113,3 +113,8 @@ body {
.inline-four .form-control {
max-width: 25%;
}
.dropdown {
cursor: pointer;
}
-1
View File
@@ -1 +0,0 @@
Generated with `grunt build`
+5
View File
@@ -113,3 +113,8 @@ body {
.inline-four .form-control {
max-width: 25%;
}
.dropdown {
cursor: pointer;
}
+4
View File
@@ -113,4 +113,8 @@ body {
.inline-four .form-control {
max-width: 25%;
}
.dropdown {
cursor: pointer;
}
+485 -236
View File
File diff suppressed because it is too large Load Diff
+12 -12
View File
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="en" ng-app="dockerui">
<head>
<head>
<meta charset="utf-8">
<title>DockerUI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -15,9 +15,9 @@
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="assets/js/jquery-1.11.1.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
@@ -36,19 +36,19 @@
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
</head>
</head>
<body>
<body>
<div class="container">
<div ng-include="template" ng-controller="MastheadController"></div>
<div class="container">
<div ng-include="template" ng-controller="MastheadController"></div>
<div id="view" ng-view></div>
<div id="view" ng-view></div>
<div class="container-bottom"></div>
<div ng-include="template" ng-controller="FooterController"></div>
</div>
<div class="container-bottom"></div>
<div ng-include="template" ng-controller="FooterController"></div>
</div>
</body>
</body>
</html>
+253 -144
View File
@@ -1,4 +1,4 @@
angular.module('dockerui.templates', ['app/components/builder/builder.html', 'app/components/container/container.html', 'app/components/containerLogs/containerlogs.html', 'app/components/containers/containers.html', 'app/components/dashboard/dashboard.html', 'app/components/footer/statusbar.html', 'app/components/image/image.html', 'app/components/images/images.html', 'app/components/masthead/masthead.html', 'app/components/settings/settings.html', 'app/components/sidebar/sidebar.html', 'app/components/startContainer/startcontainer.html']);
angular.module('dockerui.templates', ['app/components/builder/builder.html', 'app/components/container/container.html', 'app/components/containerLogs/containerlogs.html', 'app/components/containerTop/containerTop.html', 'app/components/containers/containers.html', 'app/components/dashboard/dashboard.html', 'app/components/footer/statusbar.html', 'app/components/image/image.html', 'app/components/images/images.html', 'app/components/info/info.html', 'app/components/masthead/masthead.html', 'app/components/sidebar/sidebar.html', 'app/components/startContainer/startcontainer.html']);
angular.module("app/components/builder/builder.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/builder/builder.html",
@@ -25,113 +25,139 @@ angular.module("app/components/builder/builder.html", []).run(["$templateCache",
angular.module("app/components/container/container.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/container/container.html",
"<div class=\"detail\">\n" +
" \n" +
" <h4>Container: {{ container.Name }}</h4>\n" +
"\n" +
" <div ng-if=\"!container.edit\">\n" +
" <h4>Container: {{ container.Name }}\n" +
" <button class=\"btn btn-primary\"\n" +
" ng-click=\"container.edit = true;\">Rename\n" +
" </button>\n" +
" </h4>\n" +
" </div>\n" +
" <div ng-if=\"container.edit\">\n" +
" <h4>\n" +
" Container:\n" +
" <input type=\"text\" ng-model=\"container.newContainerName\">\n" +
" <button class=\"btn btn-success\"\n" +
" ng-click=\"renameContainer()\">Edit\n" +
" </button>\n" +
" <button class=\"btn btn-danger\"\n" +
" ng-click=\"container.edit = false;\">&times;</button>\n" +
" </h4>\n" +
" </div>\n" +
"\n" +
" <div class=\"btn-group detail\">\n" +
" <button class=\"btn btn-success\"\n" +
" ng-click=\"start()\"\n" +
" ng-show=\"!container.State.Running\">Start</button>\n" +
" <button class=\"btn btn-warning\"\n" +
" ng-click=\"stop()\"\n" +
" ng-show=\"container.State.Running && !container.State.Paused\">Stop</button>\n" +
" <button class=\"btn btn-danger\"\n" +
" ng-click=\"kill()\"\n" +
" ng-show=\"container.State.Running && !container.State.Paused\">Kill</button>\n" +
" <button class=\"btn btn-info\"\n" +
" ng-click=\"pause()\"\n" +
" ng-show=\"container.State.Running && !container.State.Paused\">Pause</button>\n" +
" <button class=\"btn btn-success\"\n" +
" ng-click=\"unpause()\"\n" +
" ng-show=\"container.State.Running && container.State.Paused\">Unpause</button>\n" +
" <button class=\"btn btn-success\"\n" +
" ng-click=\"start()\"\n" +
" ng-show=\"!container.State.Running\">Start\n" +
" </button>\n" +
" <button class=\"btn btn-warning\"\n" +
" ng-click=\"stop()\"\n" +
" ng-show=\"container.State.Running && !container.State.Paused\">Stop\n" +
" </button>\n" +
" <button class=\"btn btn-danger\"\n" +
" ng-click=\"kill()\"\n" +
" ng-show=\"container.State.Running && !container.State.Paused\">Kill\n" +
" </button>\n" +
" <button class=\"btn btn-info\"\n" +
" ng-click=\"pause()\"\n" +
" ng-show=\"container.State.Running && !container.State.Paused\">Pause\n" +
" </button>\n" +
" <button class=\"btn btn-success\"\n" +
" ng-click=\"unpause()\"\n" +
" ng-show=\"container.State.Running && container.State.Paused\">Unpause\n" +
" </button>\n" +
" </div>\n" +
"\n" +
" <table class=\"table table-striped\">\n" +
" <tbody>\n" +
" <tr>\n" +
" <td>Created:</td>\n" +
" <td>{{ container.Created }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Path:</td>\n" +
" <td>{{ container.Path }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Args:</td>\n" +
" <td>{{ container.Args }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Exposed Ports:</td>\n" +
" <td>\n" +
" <ul>\n" +
" <li ng-repeat=\"(k, v) in container.Config.ExposedPorts\">{{ k }}</li>\n" +
" </ul>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Environment:</td>\n" +
" <td>\n" +
" <ul>\n" +
" <li ng-repeat=\"k in container.Config.Env\">{{ k }}</li>\n" +
" </ul>\n" +
" </td>\n" +
" </tr>\n" +
" <tbody>\n" +
" <tr>\n" +
" <td>Created:</td>\n" +
" <td>{{ container.Created }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Path:</td>\n" +
" <td>{{ container.Path }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Args:</td>\n" +
" <td>{{ container.Args }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Exposed Ports:</td>\n" +
" <td>\n" +
" <ul>\n" +
" <li ng-repeat=\"(k, v) in container.Config.ExposedPorts\">{{ k }}</li>\n" +
" </ul>\n" +
" </td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Environment:</td>\n" +
" <td>\n" +
" <ul>\n" +
" <li ng-repeat=\"k in container.Config.Env\">{{ k }}</li>\n" +
" </ul>\n" +
" </td>\n" +
" </tr>\n" +
"\n" +
" <tr>\n" +
" <td>Publish All:</td>\n" +
" <td>{{ container.HostConfig.PublishAllPorts }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Ports:</td>\n" +
" <td>\n" +
" <ul style=\"display:inline-table\">\n" +
" <li ng-repeat=\"(containerport, hostports) in container.HostConfig.PortBindings\">\n" +
" {{ containerport }} => <span class=\"label\" ng-repeat=\"(k,v) in hostports\">{{ v.HostIp }}:{{ v.HostPort }}</span>\n" +
" </li>\n" +
" </ul>\n" +
" </td>\n" +
" <tr>\n" +
" <td>Publish All:</td>\n" +
" <td>{{ container.HostConfig.PublishAllPorts }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Ports:</td>\n" +
" <td>\n" +
" <ul style=\"display:inline-table\">\n" +
" <li ng-repeat=\"(containerport, hostports) in container.HostConfig.PortBindings\">\n" +
" {{ containerport }} => <span class=\"label label-default\" ng-repeat=\"(k,v) in hostports\">{{ v.HostIp }}:{{ v.HostPort }}</span>\n" +
" </li>\n" +
" </ul>\n" +
" </td>\n" +
"\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Hostname:</td>\n" +
" <td>{{ container.Config.Hostname }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>IPAddress:</td>\n" +
" <td>{{ container.NetworkSettings.IPAddress }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Cmd:</td>\n" +
" <td>{{ container.Config.Cmd }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Entrypoint:</td>\n" +
" <td>{{ container.Config.Entrypoint }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Volumes:</td>\n" +
" <td>{{ container.Volumes }}</td>\n" +
" </tr>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Hostname:</td>\n" +
" <td>{{ container.Config.Hostname }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>IPAddress:</td>\n" +
" <td>{{ container.NetworkSettings.IPAddress }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Cmd:</td>\n" +
" <td>{{ container.Config.Cmd }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Entrypoint:</td>\n" +
" <td>{{ container.Config.Entrypoint }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Volumes:</td>\n" +
" <td>{{ container.Volumes }}</td>\n" +
" </tr>\n" +
"\n" +
" <tr>\n" +
" <td>SysInitpath:</td>\n" +
" <td>{{ container.SysInitPath }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Image:</td>\n" +
" <td><a href=\"#/images/{{ container.Image }}/\">{{ container.Image }}</a></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>State:</td>\n" +
" <td><span class=\"label {{ container.State|getstatelabel }}\">{{ container.State|getstatetext }}</span></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Logs:</td>\n" +
" <td><a href=\"#/containers/{{ container.Id }}/logs\">stdout/stderr</a></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>SysInitpath:</td>\n" +
" <td>{{ container.SysInitPath }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Image:</td>\n" +
" <td><a href=\"#/images/{{ container.Image }}/\">{{ container.Image }}</a></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>State:</td>\n" +
" <td><span class=\"label {{ container.State|getstatelabel }}\">{{ container.State|getstatetext }}</span></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Logs:</td>\n" +
" <td><a href=\"#/containers/{{ container.Id }}/logs\">stdout/stderr</a></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Top:</td>\n" +
" <td><a href=\"#/containers/{{ container.Id }}/top\">Top</a></td>\n" +
" </tr>\n" +
" </tbody>\n" +
" </table>\n" +
" \n" +
"\n" +
" <div class=\"row-fluid\">\n" +
" <div class=\"span1\">\n" +
" Changes:\n" +
@@ -139,7 +165,7 @@ angular.module("app/components/container/container.html", []).run(["$templateCac
" <div class=\"span5\">\n" +
" <i class=\"icon-refresh\" style=\"width:32px;height:32px;\" ng-click=\"getChanges()\"></i>\n" +
" </div>\n" +
" </div> \n" +
" </div>\n" +
"\n" +
" <div class=\"well well-large\">\n" +
" <ul>\n" +
@@ -149,7 +175,7 @@ angular.module("app/components/container/container.html", []).run(["$templateCac
" </ul>\n" +
" </div>\n" +
"\n" +
" <hr />\n" +
" <hr/>\n" +
"\n" +
" <div class=\"btn-remove\">\n" +
" <button class=\"btn btn-large btn-block btn-primary btn-danger\" ng-click=\"remove()\">Remove Container</button>\n" +
@@ -167,9 +193,17 @@ angular.module("app/components/containerLogs/containerlogs.html", []).run(["$tem
" <button class=\"btn btn-info\" ng-click=\"scrollTo('stdout')\">stdout</button>\n" +
" <button class=\"btn btn-warning\" ng-click=\"scrollTo('stderr')\">stderr</button>\n" +
" </div>\n" +
" <div class=\"pull-right\">\n" +
" <input id=\"timestampToggle\" type=\"checkbox\" ng-model=\"showTimestamps\" \n" +
" ng-change=\"toggleTimestamps()\"/> <label for=\"timestampToggle\">Display Timestamps</label>\n" +
" <div class=\"pull-right col-xs-6\">\n" +
" <div class=\"col-xs-6\">\n" +
" <a class=\"btn btn-primary\" ng-click=\"toggleTail()\" role=\"button\">Reload logs</a>\n" +
" <input id=\"tailLines\" type=\"number\" ng-style=\"{width: '45px'}\"\n" +
" ng-model=\"tailLines\" ng-keypress=\"($event.which === 13)? toggleTail() : 0\"/>\n" +
" <label for=\"tailLines\">lines</label>\n" +
" </div>\n" +
" <div class=\"col-xs-4\">\n" +
" <input id=\"timestampToggle\" type=\"checkbox\" ng-model=\"showTimestamps\"\n" +
" ng-change=\"toggleTimestamps()\"/> <label for=\"timestampToggle\">Timestamps</label>\n" +
" </div>\n" +
" </div>\n" +
" </div>\n" +
"\n" +
@@ -197,6 +231,29 @@ angular.module("app/components/containerLogs/containerlogs.html", []).run(["$tem
"");
}]);
angular.module("app/components/containerTop/containerTop.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/containerTop/containerTop.html",
"<div class=\"containerTop\">\n" +
" <div class=\"form-group col-xs-2\">\n" +
" <input type=\"text\" class=\"form-control\" placeholder=\"[options] (aux)\" ng-model=\"ps_args\">\n" +
" </div>\n" +
" <button type=\"button\" class=\"btn btn-default\" ng-click=\"getTop()\">Submit</button>\n" +
"\n" +
" <table class=\"table table-striped\">\n" +
" <thead>\n" +
" <tr>\n" +
" <th ng-repeat=\"title in containerTop.Titles\">{{title}}</th>\n" +
" </tr>\n" +
" </thead>\n" +
" <tbody>\n" +
" <tr ng-repeat=\"processInfos in containerTop.Processes\">\n" +
" <td ng-repeat=\"processInfo in processInfos track by $index\">{{processInfo}}</td>\n" +
" </tr>\n" +
" </tbody>\n" +
" </table>\n" +
"</div>");
}]);
angular.module("app/components/containers/containers.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/containers/containers.html",
"\n" +
@@ -209,6 +266,7 @@ angular.module("app/components/containers/containers.html", []).run(["$templateC
" <ul id=\"menu1\" class=\"dropdown-menu\" role=\"menu\" aria-labelledby=\"drop4\">\n" +
" <li><a tabindex=\"-1\" href=\"\" ng-click=\"startAction()\">Start</a></li>\n" +
" <li><a tabindex=\"-1\" href=\"\" ng-click=\"stopAction()\">Stop</a></li>\n" +
" <li><a tabindex=\"-1\" href=\"\" ng-click=\"restartAction()\">Restart</a></li>\n" +
" <li><a tabindex=\"-1\" href=\"\" ng-click=\"killAction()\">Kill</a></li>\n" +
" <li><a tabindex=\"-1\" href=\"\" ng-click=\"pauseAction()\">Pause</a></li>\n" +
" <li><a tabindex=\"-1\" href=\"\" ng-click=\"unpauseAction()\">Unpause</a></li>\n" +
@@ -218,8 +276,7 @@ angular.module("app/components/containers/containers.html", []).run(["$templateC
" </ul>\n" +
"\n" +
" <div class=\"pull-right\">\n" +
" <input type=\"checkbox\" ng-model=\"displayAll\" \n" +
" ng-change=\"toggleGetAll()\"/> Display All\n" +
" <input type=\"checkbox\" ng-model=\"displayAll\" id=\"displayAll\" ng-change=\"toggleGetAll()\"/> <label for=\"displayAll\">Display All</label>\n" +
" </div>\n" +
"</div>\n" +
"<table class=\"table table-striped\">\n" +
@@ -278,7 +335,7 @@ angular.module("app/components/dashboard/dashboard.html", []).run(["$templateCac
" <div class=\"col-xs-5 text-right\">\n" +
" <h3>Status</h3>\n" +
" <canvas id=\"containers-chart\" class=\"pull-right\">\n" +
" Get a better browser... Your holding everyone back.\n" +
" <p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"http://browsehappy.com/\">upgrade your browser</a> to improve your experience.</p>\n" +
" </canvas>\n" +
" <div id=\"chart-legend\"></div>\n" +
" </div>\n" +
@@ -289,11 +346,11 @@ angular.module("app/components/dashboard/dashboard.html", []).run(["$templateCac
" <div class=\"col-xs-10\" id=\"stats\">\n" +
" <h4>Containers created</h4>\n" +
" <canvas id=\"containers-started-chart\" width=\"700\">\n" +
" Get a better browser... You're holding everyone back.\n" +
" <p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"http://browsehappy.com/\">upgrade your browser</a> to improve your experience.</p>\n" +
" </canvas>\n" +
" <h4>Images created</h4>\n" +
" <canvas id=\"images-created-chart\" width=\"700\">\n" +
" Get a better browser... You're holding everyone back.\n" +
" <p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"http://browsehappy.com/\">upgrade your browser</a> to improve your experience.</p>\n" +
" </canvas>\n" +
" </div>\n" +
" </div>\n" +
@@ -328,7 +385,7 @@ angular.module("app/components/image/image.html", []).run(["$templateCache", fun
" <div>\n" +
" <h4>Containers created:</h4>\n" +
" <canvas id=\"containers-started-chart\" width=\"750\">\n" +
" Get a better broswer... Your holding everyone back.\n" +
" <p class=\"browserupgrade\">You are using an <strong>outdated</strong> browser. Please <a href=\"http://browsehappy.com/\">upgrade your browser</a> to improve your experience.</p>\n" +
" </canvas>\n" +
" </div>\n" +
"\n" +
@@ -336,40 +393,40 @@ angular.module("app/components/image/image.html", []).run(["$templateCache", fun
" <tbody>\n" +
" <tr>\n" +
" <td>Created:</td>\n" +
" <td>{{ image.created }}</td>\n" +
" <td>{{ image.Created }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Parent:</td>\n" +
" <td><a href=\"#/images/{{ image.parent }}/\">{{ image.parent }}</a></td>\n" +
" <td><a href=\"#/images/{{ image.Parent }}/\">{{ image.Parent }}</a></td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Size:</td>\n" +
" <td>{{ image.Size|humansize }}</td>\n" +
" <td>Size (Virtual Size):</td>\n" +
" <td>{{ image.Size|humansize }} ({{ image.VirtualSize|humansize }})</td>\n" +
" </tr>\n" +
"\n" +
" <tr>\n" +
" <td>Hostname:</td>\n" +
" <td>{{ image.container_config.Hostname }}</td>\n" +
" <td>{{ image.ContainerConfig.Hostname }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>User:</td>\n" +
" <td>{{ image.container_config.User }}</td>\n" +
" <td>{{ image.ContainerConfig.User }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Cmd:</td>\n" +
" <td>{{ image.container_config.Cmd }}</td>\n" +
" <td>{{ image.ContainerConfig.Cmd }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Volumes:</td>\n" +
" <td>{{ image.container_config.Volumes }}</td>\n" +
" <td>{{ image.ContainerConfig.Volumes }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Volumes from:</td>\n" +
" <td>{{ image.container_config.VolumesFrom }}</td>\n" +
" <td>{{ image.ContainerConfig.VolumesFrom }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Comment:</td>\n" +
" <td>{{ image.comment }}</td>\n" +
" <td>Built with:</td>\n" +
" <td>Docker {{ image.DockerVersion }} on {{ image.Os}}, {{ image.Architecture }}</td>\n" +
" </tr>\n" +
"\n" +
" </tbody>\n" +
@@ -459,22 +516,8 @@ angular.module("app/components/images/images.html", []).run(["$templateCache", f
"");
}]);
angular.module("app/components/masthead/masthead.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/masthead/masthead.html",
" <div class=\"masthead\">\n" +
" <h3 class=\"text-muted\">DockerUI</h3>\n" +
" <ul class=\"nav well\">\n" +
" <li><a href=\"#\">Dashboard</a></li>\n" +
" <li><a href=\"#/containers/\">Containers</a></li>\n" +
" <li><a href=\"#/images/\">Images</a></li>\n" +
" <li><a href=\"#/settings/\">Settings</a></li>\n" +
" </ul>\n" +
" </div>\n" +
"");
}]);
angular.module("app/components/settings/settings.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/settings/settings.html",
angular.module("app/components/info/info.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/info/info.html",
"<div class=\"detail\">\n" +
" <h2>Docker Information</h2>\n" +
" <div>\n" +
@@ -502,31 +545,97 @@ angular.module("app/components/settings/settings.html", []).run(["$templateCache
" <td>{{ info.Debug }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>NFd:</td>\n" +
" <td>CPUs:</td>\n" +
" <td>{{ info.NCPU }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Total Memory:</td>\n" +
" <td>{{ info.MemTotal|humansize }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Operating System:</td>\n" +
" <td>{{ info.OperatingSystem }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Kernel Version:</td>\n" +
" <td>{{ info.KernelVersion }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>ID:</td>\n" +
" <td>{{ info.ID }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Labels:</td>\n" +
" <td>{{ info.Labels }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>File Descriptors:</td>\n" +
" <td>{{ info.NFd }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>NGoroutines:</td>\n" +
" <td>Goroutines:</td>\n" +
" <td>{{ info.NGoroutines }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>MemoryLimit:</td>\n" +
" <td>Storage Driver:</td>\n" +
" <td>{{ info.Driver }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Storage Driver Status:</td>\n" +
" <td>{{ info.DriverStatus }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Execution Driver:</td>\n" +
" <td>{{ info.ExecutionDriver }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>IPv4 Forwarding:</td>\n" +
" <td>{{ info.IPv4Forwarding }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Index Server Address:</td>\n" +
" <td>{{ info.IndexServerAddress }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Init Path:</td>\n" +
" <td>{{ info.InitPath }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Docker Root Directory:</td>\n" +
" <td>{{ info.DockerRootDir }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Init SHA1</td>\n" +
" <td>{{ info.InitSha1 }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>Memory Limit:</td>\n" +
" <td>{{ info.MemoryLimit }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>SwapLimit:</td>\n" +
" <td>Swap Limit:</td>\n" +
" <td>{{ info.SwapLimit }}</td>\n" +
" </tr>\n" +
" <tr>\n" +
" <td>NFd:</td>\n" +
" <td>{{ info.NFd }}</td>\n" +
" </tr>\n" +
" </tbody>\n" +
" </table>\n" +
"</div>\n" +
"");
}]);
angular.module("app/components/masthead/masthead.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/masthead/masthead.html",
" <div class=\"masthead\">\n" +
" <h3 class=\"text-muted\">DockerUI</h3>\n" +
" <ul class=\"nav well\">\n" +
" <li><a href=\"#\">Dashboard</a></li>\n" +
" <li><a href=\"#/containers/\">Containers</a></li>\n" +
" <li><a href=\"#/images/\">Images</a></li>\n" +
" <li><a href=\"#/info/\">Info</a></li>\n" +
" </ul>\n" +
" </div>\n" +
"");
}]);
angular.module("app/components/sidebar/sidebar.html", []).run(["$templateCache", function($templateCache) {
$templateCache.put("app/components/sidebar/sidebar.html",
"<div class=\"well\">\n" +
Executable
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
2f09b03e7ec281dff6597424729080a1715e6627 dockerui
+1 -1
View File
@@ -1,4 +1,4 @@
package main
package main // import "github.com/crosbymichael/dockerui"
import (
"flag"
+12 -12
View File
@@ -1,6 +1,6 @@
<!DOCTYPE html>
<html lang="en" ng-app="<%= pkg.name %>">
<head>
<head>
<meta charset="utf-8">
<title>DockerUI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@@ -15,9 +15,9 @@
<!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script src="assets/js/jquery-1.11.1.min.js"></script>
<script src="assets/js/bootstrap.min.js"></script>
@@ -36,19 +36,19 @@
<link rel="apple-touch-icon-precomposed" sizes="114x114" href="assets/ico/apple-touch-icon-114-precomposed.png">
<link rel="apple-touch-icon-precomposed" sizes="72x72" href="assets/ico/apple-touch-icon-72-precomposed.png">
<link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
</head>
</head>
<body>
<body>
<div class="container">
<div ng-include="template" ng-controller="MastheadController"></div>
<div class="container">
<div ng-include="template" ng-controller="MastheadController"></div>
<div id="view" ng-view></div>
<div id="view" ng-view></div>
<div class="container-bottom"></div>
<div ng-include="template" ng-controller="FooterController"></div>
</div>
<div class="container-bottom"></div>
<div ng-include="template" ng-controller="FooterController"></div>
</div>
</body>
</body>
</html>
+1 -1
View File
@@ -2,7 +2,7 @@
"author": "Michael Crosby & Kevan Ahlquist",
"name": "dockerui",
"homepage": "https://github.com/crosbymichael/dockerui",
"version": "0.6.0",
"version": "0.7.0",
"repository": {
"type": "git",
"url": "git@github.com:crosbymichael/dockerui.git"
@@ -0,0 +1,57 @@
describe('ContainerController', function () {
var $scope, $httpBackend, mockContainer, $routeParams;
beforeEach(module('dockerui'));
beforeEach(inject(function ($rootScope, $controller, _$routeParams_) {
$scope = $rootScope.$new();
$routeParams = _$routeParams_;
$controller('ContainerController', {
$scope: $scope
});
angular.mock.inject(function (_$httpBackend_, _Container_) {
mockContainer = _Container_;
$httpBackend = _$httpBackend_;
});
}));
function expectGetContainer() {
$httpBackend.expectGET('dockerapi/containers/json?').respond({
'Created': 1421817232,
'id': 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f',
'Image': 'dockerui:latest',
'Name': '/dockerui'
});
}
it("a correct rename request to the Docker remote API", function () {
$routeParams.id = 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f';
$scope.container = {
'Created': 1421817232,
'id': 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f',
'Image': 'dockerui:latest',
'Name': '/dockerui'
};
$scope.container.newContainerName = "newName";
var newContainerName = "newName";
expectGetContainer();
$httpBackend.expectGET('dockerapi/containers/changes?').respond([{"Kind": 1, "Path": "/docker.sock"}]);
$httpBackend.expectPOST('dockerapi/containers/' + $routeParams.id + '/rename?name=newName').
respond({
'name': newContainerName
});
$scope.renameContainer();
$httpBackend.flush();
expect($scope.container.Name).toBe(newContainerName);
expect($scope.container.edit).toBeFalsy();
});
});
@@ -0,0 +1,31 @@
describe("ContainerTopController", function () {
var $scope, $httpBackend, $routeParams;
beforeEach(angular.mock.module('dockerui'));
beforeEach(inject(function (_$rootScope_, _$httpBackend_, $controller, _$routeParams_) {
$scope = _$rootScope_.$new();
$httpBackend = _$httpBackend_;
$routeParams = _$routeParams_;
$routeParams.id = 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f';
$controller('ContainerTopController', {
'$scope': $scope,
'$routeParams': $routeParams
});
}));
it("should test controller initialize", function () {
$httpBackend.expectGET('dockerapi/containers/b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f/top?ps_args=').respond(200);
expect($scope.ps_args).toBeDefined();
$httpBackend.flush();
});
it("a correct top request to the Docker remote API", function () {
$httpBackend.expectGET('dockerapi/containers/' + $routeParams.id + '/top?ps_args=').respond(200);
$routeParams.id = '123456789123456789123456789';
$scope.ps_args = 'aux';
$httpBackend.expectGET('dockerapi/containers/' + $routeParams.id + '/top?ps_args=' + $scope.ps_args).respond(200);
$scope.getTop();
$httpBackend.flush();
});
});
@@ -41,15 +41,15 @@ describe('startContainerController', function() {
var expectedBody = {
'name': 'container-name',
'ExposedPorts': {
'9000/tcp': {},
'9000/tcp': {}
},
'HostConfig': {
'PortBindings': {
'9000/tcp': [{
'HostPort': '9999',
'HostIp': '10.20.10.15',
'HostIp': '10.20.10.15'
}]
},
}
}
};
@@ -69,7 +69,7 @@ describe('startContainerController', function() {
ip: '10.20.10.15',
extPort: '9999',
intPort: '9000'
}]
}];
scope.create();
$httpBackend.flush();
@@ -150,7 +150,7 @@ describe('filters', function () {
describe('getdate', function () {
it('should convert the Docker date to a human readable form', inject(function(getdateFilter) {
expect(getdateFilter(1420424998)).toBe('Sun Jan 04 2015');
expect(getdateFilter(1420424998)).toBe('Mon Jan 05 2015');
}));
});
+1
View File
@@ -8,6 +8,7 @@ files = [
'assets/js/jquery-1.11.1.min.js',
'assets/js/jquery.gritter.min.js',
'assets/js/bootstrap.min.js',
'assets/js/spin.js',
'assets/js/angularjs/1.2.6/angular.min.js',
'assets/js/angularjs/1.2.6/angular-route.min.js',
'assets/js/angularjs/1.2.6/angular-resource.min.js',