1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 15:59:41 +02:00

Add Docker top feature

This commit is contained in:
Houssem BELHADJ AHMED 2015-03-31 23:37:03 +02:00
parent c971189286
commit ede37e2e79
8 changed files with 307 additions and 182 deletions

View file

@ -1,12 +1,34 @@
angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'images', 'image', 'startContainer', 'sidebar', 'info', '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) { .config(['$routeProvider', function ($routeProvider) {
'use strict'; 'use strict';
$routeProvider.when('/', {templateUrl: 'app/components/dashboard/dashboard.html', controller: 'DashboardController'}); $routeProvider.when('/', {
$routeProvider.when('/containers/', {templateUrl: 'app/components/containers/containers.html', controller: 'ContainersController'}); templateUrl: 'app/components/dashboard/dashboard.html',
$routeProvider.when('/containers/:id/', {templateUrl: 'app/components/container/container.html', controller: 'ContainerController'}); controller: 'DashboardController'
$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('/containers/', {
$routeProvider.when('/images/:id*/', {templateUrl: 'app/components/image/image.html', controller: 'ImageController'}); 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.when('/info', {templateUrl: 'app/components/info/info.html', controller: 'InfoController'});
$routeProvider.otherwise({redirectTo: '/'}); $routeProvider.otherwise({redirectTo: '/'});
}]) }])

View file

@ -1,9 +1,10 @@
<div class="detail"> <div class="detail">
<div ng-if="!container.edit"> <div ng-if="!container.edit">
<h4>Container: {{ container.Name }} <h4>Container: {{ container.Name }}
<button class="btn btn-primary" <button class="btn btn-primary"
ng-click="container.edit = true;">Rename</button> ng-click="container.edit = true;">Rename
</button>
</h4> </h4>
</div> </div>
<div ng-if="container.edit"> <div ng-if="container.edit">
@ -11,116 +12,126 @@
Container: Container:
<input type="text" ng-model="container.newContainerName"> <input type="text" ng-model="container.newContainerName">
<button class="btn btn-success" <button class="btn btn-success"
ng-click="renameContainer()">Edit</button> ng-click="renameContainer()">Edit
</button>
<button class="btn btn-danger" <button class="btn btn-danger"
ng-click="container.edit = false;">&times;</button> ng-click="container.edit = false;">&times;</button>
</h4> </h4>
</div> </div>
<div class="btn-group detail"> <div class="btn-group detail">
<button class="btn btn-success" <button class="btn btn-success"
ng-click="start()" ng-click="start()"
ng-show="!container.State.Running">Start</button> ng-show="!container.State.Running">Start
<button class="btn btn-warning" </button>
ng-click="stop()" <button class="btn btn-warning"
ng-show="container.State.Running && !container.State.Paused">Stop</button> ng-click="stop()"
<button class="btn btn-danger" ng-show="container.State.Running && !container.State.Paused">Stop
ng-click="kill()" </button>
ng-show="container.State.Running && !container.State.Paused">Kill</button> <button class="btn btn-danger"
<button class="btn btn-info" ng-click="kill()"
ng-click="pause()" ng-show="container.State.Running && !container.State.Paused">Kill
ng-show="container.State.Running && !container.State.Paused">Pause</button> </button>
<button class="btn btn-success" <button class="btn btn-info"
ng-click="unpause()" ng-click="pause()"
ng-show="container.State.Running && container.State.Paused">Unpause</button> 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> </div>
<table class="table table-striped"> <table class="table table-striped">
<tbody> <tbody>
<tr> <tr>
<td>Created:</td> <td>Created:</td>
<td>{{ container.Created }}</td> <td>{{ container.Created }}</td>
</tr> </tr>
<tr> <tr>
<td>Path:</td> <td>Path:</td>
<td>{{ container.Path }}</td> <td>{{ container.Path }}</td>
</tr> </tr>
<tr> <tr>
<td>Args:</td> <td>Args:</td>
<td>{{ container.Args }}</td> <td>{{ container.Args }}</td>
</tr> </tr>
<tr> <tr>
<td>Exposed Ports:</td> <td>Exposed Ports:</td>
<td> <td>
<ul> <ul>
<li ng-repeat="(k, v) in container.Config.ExposedPorts">{{ k }}</li> <li ng-repeat="(k, v) in container.Config.ExposedPorts">{{ k }}</li>
</ul> </ul>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Environment:</td> <td>Environment:</td>
<td> <td>
<ul> <ul>
<li ng-repeat="k in container.Config.Env">{{ k }}</li> <li ng-repeat="k in container.Config.Env">{{ k }}</li>
</ul> </ul>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Publish All:</td> <td>Publish All:</td>
<td>{{ container.HostConfig.PublishAllPorts }}</td> <td>{{ container.HostConfig.PublishAllPorts }}</td>
</tr> </tr>
<tr> <tr>
<td>Ports:</td> <td>Ports:</td>
<td> <td>
<ul style="display:inline-table"> <ul style="display:inline-table">
<li ng-repeat="(containerport, hostports) in container.HostConfig.PortBindings"> <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> {{ containerport }} => <span class="label label-default" ng-repeat="(k,v) in hostports">{{ v.HostIp }}:{{ v.HostPort }}</span>
</li> </li>
</ul> </ul>
</td> </td>
</tr> </tr>
<tr> <tr>
<td>Hostname:</td> <td>Hostname:</td>
<td>{{ container.Config.Hostname }}</td> <td>{{ container.Config.Hostname }}</td>
</tr> </tr>
<tr> <tr>
<td>IPAddress:</td> <td>IPAddress:</td>
<td>{{ container.NetworkSettings.IPAddress }}</td> <td>{{ container.NetworkSettings.IPAddress }}</td>
</tr> </tr>
<tr> <tr>
<td>Cmd:</td> <td>Cmd:</td>
<td>{{ container.Config.Cmd }}</td> <td>{{ container.Config.Cmd }}</td>
</tr> </tr>
<tr> <tr>
<td>Entrypoint:</td> <td>Entrypoint:</td>
<td>{{ container.Config.Entrypoint }}</td> <td>{{ container.Config.Entrypoint }}</td>
</tr> </tr>
<tr> <tr>
<td>Volumes:</td> <td>Volumes:</td>
<td>{{ container.Volumes }}</td> <td>{{ container.Volumes }}</td>
</tr> </tr>
<tr> <tr>
<td>SysInitpath:</td> <td>SysInitpath:</td>
<td>{{ container.SysInitPath }}</td> <td>{{ container.SysInitPath }}</td>
</tr> </tr>
<tr> <tr>
<td>Image:</td> <td>Image:</td>
<td><a href="#/images/{{ container.Image }}/">{{ container.Image }}</a></td> <td><a href="#/images/{{ container.Image }}/">{{ container.Image }}</a></td>
</tr> </tr>
<tr> <tr>
<td>State:</td> <td>State:</td>
<td><span class="label {{ container.State|getstatelabel }}">{{ container.State|getstatetext }}</span></td> <td><span class="label {{ container.State|getstatelabel }}">{{ container.State|getstatetext }}</span></td>
</tr> </tr>
<tr> <tr>
<td>Logs:</td> <td>Logs:</td>
<td><a href="#/containers/{{ container.Id }}/logs">stdout/stderr</a></td> <td><a href="#/containers/{{ container.Id }}/logs">stdout/stderr</a></td>
</tr> </tr>
<tr>
<td>Top:</td>
<td><a href="#/containers/{{ container.Id }}/top">Top</a></td>
</tr>
</tbody> </tbody>
</table> </table>
<div class="row-fluid"> <div class="row-fluid">
<div class="span1"> <div class="span1">
Changes: Changes:
@ -128,7 +139,7 @@
<div class="span5"> <div class="span5">
<i class="icon-refresh" style="width:32px;height:32px;" ng-click="getChanges()"></i> <i class="icon-refresh" style="width:32px;height:32px;" ng-click="getChanges()"></i>
</div> </div>
</div> </div>
<div class="well well-large"> <div class="well well-large">
<ul> <ul>
@ -138,7 +149,7 @@
</ul> </ul>
</div> </div>
<hr /> <hr/>
<div class="btn-remove"> <div class="btn-remove">
<button class="btn btn-large btn-block btn-primary btn-danger" ng-click="remove()">Remove Container</button> <button class="btn btn-large btn-block btn-primary btn-danger" ng-click="remove()">Remove Container</button>

View file

@ -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>

View file

@ -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();
}]);

View file

@ -1,56 +1,75 @@
angular.module('dockerui.services', ['ngResource']) angular.module('dockerui.services', ['ngResource'])
.factory('Container', function($resource, Settings) { .factory('Container', function ($resource, Settings) {
'use strict'; 'use strict';
// Resource for interacting with the docker containers // Resource for interacting with the docker containers
// http://docs.docker.io/en/latest/api/docker_remote_api.html#containers // http://docs.docker.io/en/latest/api/docker_remote_api.html#containers
return $resource(Settings.url + '/containers/:id/:action', { return $resource(Settings.url + '/containers/:id/:action', {
name: '@name' name: '@name'
}, { }, {
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: {id: '@id', action: 'start'}}, start: {method: 'POST', params: {id: '@id', action: 'start'}},
stop: {method: 'POST', params: {id: '@id', t: 5, action: 'stop'}}, 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'}}, kill: {method: 'POST', params: {id: '@id', action: 'kill'}},
pause: {method: 'POST', params: {id: '@id', action: 'pause'}}, pause: {method: 'POST', params: {id: '@id', action: 'pause'}},
unpause: {method: 'POST', params: {id: '@id', action: 'unpause'}}, unpause: {method: 'POST', params: {id: '@id', action: 'unpause'}},
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: {id: '@id', v:0}}, remove: {method: 'DELETE', params: {id: '@id', v: 0}},
rename: {method: 'POST', params: {id: '@id', action: 'rename'}, isArray: false} rename: {method: 'POST', params: {id: '@id', action: 'rename'}, isArray: false}
}); });
}) })
.factory('ContainerLogs', function($resource, $http, Settings) { .factory('ContainerLogs', function ($resource, $http, Settings) {
'use strict'; 'use strict';
return { return {
get: function(id, params, callback) { get: function (id, params, callback) {
$http({ $http({
method: 'GET', method: 'GET',
url: Settings.url + '/containers/'+id+'/logs', url: Settings.url + '/containers/' + id + '/logs',
params: {'stdout': params.stdout || 0, 'stderr': params.stderr || 0, 'timestamps': params.timestamps || 0, 'tail': params.tail || 'all'} params: {
}).success(callback).error(function(data, status, headers, config) { '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); 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'; 'use strict';
// 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(Settings.url + '/images/:id/:action', {}, { return $resource(Settings.url + '/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'}, isArray: true}, history: {method: 'GET', params: {action: 'history'}, isArray: true},
create: {method: 'POST', params: {action:'create'}}, create: {method: 'POST', params: {action: 'create'}},
insert: {method: 'POST', params: {id: '@id', action:'insert'}}, insert: {method: 'POST', params: {id: '@id', action: 'insert'}},
push: {method: 'POST', params: {id: '@id', action:'push'}}, push: {method: 'POST', params: {id: '@id', action: 'push'}},
tag: {method: 'POST', params: {id: '@id', action:'tag', force: 0, repo: '@repo'}}, tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo'}},
remove: {method: 'DELETE', params: {id: '@id'}, isArray: true} remove: {method: 'DELETE', params: {id: '@id'}, isArray: true}
}); });
}) })
.factory('Docker', function($resource, Settings) { .factory('Docker', function ($resource, Settings) {
'use strict'; 'use strict';
// Information for docker // Information for docker
// http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information // http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information
@ -58,7 +77,7 @@ angular.module('dockerui.services', ['ngResource'])
get: {method: 'GET'} get: {method: 'GET'}
}); });
}) })
.factory('Auth', function($resource, Settings) { .factory('Auth', function ($resource, Settings) {
'use strict'; 'use strict';
// Auto Information for docker // Auto Information for docker
// http://docs.docker.io/en/latest/api/docker_remote_api.html#set-auth-configuration // http://docs.docker.io/en/latest/api/docker_remote_api.html#set-auth-configuration
@ -67,7 +86,7 @@ angular.module('dockerui.services', ['ngResource'])
update: {method: 'POST'} update: {method: 'POST'}
}); });
}) })
.factory('System', function($resource, Settings) { .factory('System', function ($resource, Settings) {
'use strict'; 'use strict';
// System for docker // System for docker
// http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information // http://docs.docker.io/en/latest/api/docker_remote_api.html#display-system-wide-information
@ -75,7 +94,7 @@ angular.module('dockerui.services', ['ngResource'])
get: {method: 'GET'} 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'; 'use strict';
var url = DOCKER_ENDPOINT; var url = DOCKER_ENDPOINT;
if (DOCKER_PORT) { if (DOCKER_PORT) {
@ -91,52 +110,56 @@ angular.module('dockerui.services', ['ngResource'])
firstLoad: true firstLoad: true
}; };
}) })
.factory('ViewSpinner', function() { .factory('ViewSpinner', function () {
'use strict'; 'use strict';
var spinner = new Spinner(); var spinner = new Spinner();
var target = document.getElementById('view'); var target = document.getElementById('view');
return { return {
spin: function() { spinner.spin(target); }, spin: function () {
stop: function() { spinner.stop(); } spinner.spin(target);
},
stop: function () {
spinner.stop();
}
}; };
}) })
.factory('Messages', function($rootScope) { .factory('Messages', function ($rootScope) {
'use strict'; 'use strict';
return { return {
send: function(title, text) { send: function (title, text) {
$.gritter.add({ $.gritter.add({
title: title, title: title,
text: text, text: text,
time: 2000, time: 2000,
before_open: function() { before_open: function () {
if($('.gritter-item-wrapper').length === 3) { if ($('.gritter-item-wrapper').length === 3) {
return false; return false;
} }
} }
}); });
}, },
error: function(title, text) { error: function (title, text) {
$.gritter.add({ $.gritter.add({
title: title, title: title,
text: text, text: text,
time: 10000, time: 10000,
before_open: function() { before_open: function () {
if($('.gritter-item-wrapper').length === 4) { if ($('.gritter-item-wrapper').length === 4) {
return false; return false;
} }
} }
}); });
} }
}; };
}) })
.factory('Dockerfile', function(Settings) { .factory('Dockerfile', function (Settings) {
'use strict'; 'use strict';
var url = Settings.rawUrl + '/build'; var url = Settings.rawUrl + '/build';
return { return {
build: function(file, callback) { build: function (file, callback) {
var data = new FormData(); var data = new FormData();
var dockerfile = new Blob([file], { type: 'text/text' }); var dockerfile = new Blob([file], {type: 'text/text'});
data.append('Dockerfile', dockerfile); data.append('Dockerfile', dockerfile);
var request = new XMLHttpRequest(); var request = new XMLHttpRequest();
@ -146,18 +169,18 @@ angular.module('dockerui.services', ['ngResource'])
} }
}; };
}) })
.factory('LineChart', function(Settings) { .factory('LineChart', function (Settings) {
'use strict'; 'use strict';
var url = Settings.rawUrl + '/build'; var url = Settings.rawUrl + '/build';
return { return {
build: function(id, data, getkey){ build: function (id, data, getkey) {
var chart = new Chart($(id).get(0).getContext("2d")); var chart = new Chart($(id).get(0).getContext("2d"));
var map = {}; var map = {};
for (var i = 0; i < data.length; i++) { for (var i = 0; i < data.length; i++) {
var c = data[i]; var c = data[i];
var key = getkey(c); var key = getkey(c);
var count = map[key]; var count = map[key];
if (count === undefined) { if (count === undefined) {
count = 0; count = 0;
@ -176,22 +199,22 @@ angular.module('dockerui.services', ['ngResource'])
data.push(map[k]); data.push(map[k]);
} }
var dataset = { var dataset = {
fillColor : "rgba(151,187,205,0.5)", fillColor: "rgba(151,187,205,0.5)",
strokeColor : "rgba(151,187,205,1)", strokeColor: "rgba(151,187,205,1)",
pointColor : "rgba(151,187,205,1)", pointColor: "rgba(151,187,205,1)",
pointStrokeColor : "#fff", pointStrokeColor: "#fff",
data : data data: data
}; };
chart.Line({ chart.Line({
labels: labels, labels: labels,
datasets: [dataset] datasets: [dataset]
}, },
{ {
scaleStepWidth: 1, scaleStepWidth: 1,
pointDotRadius:1, pointDotRadius: 1,
scaleOverride: true, scaleOverride: true,
scaleSteps: labels.length scaleSteps: labels.length
}); });
} }
}; };
}); });

View file

@ -1,6 +1,6 @@
<!DOCTYPE html> <!DOCTYPE html>
<html lang="en" ng-app="<%= pkg.name %>"> <html lang="en" ng-app="<%= pkg.name %>">
<head> <head>
<meta charset="utf-8"> <meta charset="utf-8">
<title>DockerUI</title> <title>DockerUI</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -15,9 +15,9 @@
<!-- HTML5 shim, for IE6-8 support of HTML5 elements --> <!-- HTML5 shim, for IE6-8 support of HTML5 elements -->
<!--[if lt IE 9]> <!--[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]--> <![endif]-->
<script src="assets/js/jquery-1.11.1.min.js"></script> <script src="assets/js/jquery-1.11.1.min.js"></script>
<script src="assets/js/bootstrap.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="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" 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"> <link rel="apple-touch-icon-precomposed" href="assets/ico/apple-touch-icon-57-precomposed.png">
</head> </head>
<body> <body>
<div class="container"> <div class="container">
<div ng-include="template" ng-controller="MastheadController"></div> <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 class="container-bottom"></div>
<div ng-include="template" ng-controller="FooterController"></div> <div ng-include="template" ng-controller="FooterController"></div>
</div> </div>
</body> </body>
</html> </html>

View file

@ -1,4 +1,4 @@
describe('ContainerController', function() { describe('ContainerController', function () {
var $scope, $httpBackend, mockContainer, $routeParams; var $scope, $httpBackend, mockContainer, $routeParams;
beforeEach(module('dockerui')); beforeEach(module('dockerui'));
@ -27,7 +27,7 @@ describe('ContainerController', function() {
}); });
} }
it("a correct create request to the Docker remote API", function () { it("a correct rename request to the Docker remote API", function () {
$routeParams.id = 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f'; $routeParams.id = 'b17882378cee8ec0136f482681b764cca430befd52a9bfd1bde031f49b8bba9f';
$scope.container = { $scope.container = {
@ -41,7 +41,7 @@ describe('ContainerController', function() {
var newContainerName = "newName"; var newContainerName = "newName";
expectGetContainer(); expectGetContainer();
$httpBackend.expectGET('dockerapi/containers/changes?').respond([{"Kind":1,"Path":"/docker.sock"}]); $httpBackend.expectGET('dockerapi/containers/changes?').respond([{"Kind": 1, "Path": "/docker.sock"}]);
$httpBackend.expectPOST('dockerapi/containers/' + $routeParams.id + '/rename?name=newName'). $httpBackend.expectPOST('dockerapi/containers/' + $routeParams.id + '/rename?name=newName').
respond({ respond({

View file

@ -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();
});
});