Added pause/unpause to containers,

Auto-update /container and /containers views after performing an action,
Display spinner when container actions are being performed,
Unified style
pull/2/head
Kevan Ahlquist 10 years ago
parent 9dccf95152
commit 8652285227

@ -155,34 +155,83 @@ function SettingsController($scope, System, Docker, Settings, Messages) {
function ContainerController($scope, $routeParams, $location, Container, Messages, ViewSpinner) { function ContainerController($scope, $routeParams, $location, Container, Messages, ViewSpinner) {
$scope.changes = []; $scope.changes = [];
var update = function() {
Container.get({id: $routeParams.id}, function(d) {
$scope.container = d;
ViewSpinner.stop();
}, function(e) {
if (e.status === 404) {
$('.detail').hide();
Messages.error("Not found", "Container not found.");
} else {
Messages.error("Failure", e.data);
}
ViewSpinner.stop();
});
};
$scope.start = function(){ $scope.start = function(){
ViewSpinner.spin();
Container.start({id: $routeParams.id}, function(d) { Container.start({id: $routeParams.id}, function(d) {
update();
Messages.send("Container started", $routeParams.id); Messages.send("Container started", $routeParams.id);
}, function(e) { }, function(e) {
update();
Messages.error("Failure", "Container failed to start." + e.data); Messages.error("Failure", "Container failed to start." + e.data);
}); });
}; };
$scope.stop = function() { $scope.stop = function() {
ViewSpinner.spin();
Container.stop({id: $routeParams.id}, function(d) { Container.stop({id: $routeParams.id}, function(d) {
update();
Messages.send("Container stopped", $routeParams.id); Messages.send("Container stopped", $routeParams.id);
}, function(e) { }, function(e) {
update();
Messages.error("Failure", "Container failed to stop." + e.data); Messages.error("Failure", "Container failed to stop." + e.data);
}); });
}; };
$scope.kill = function() { $scope.kill = function() {
ViewSpinner.spin();
Container.kill({id: $routeParams.id}, function(d) { Container.kill({id: $routeParams.id}, function(d) {
update();
Messages.send("Container killed", $routeParams.id); Messages.send("Container killed", $routeParams.id);
}, function(e) { }, function(e) {
update();
Messages.error("Failure", "Container failed to die." + e.data); Messages.error("Failure", "Container failed to die." + e.data);
}); });
}; };
$scope.pause = function() {
ViewSpinner.spin();
Container.pause({id: $routeParams.id}, function(d) {
update();
Messages.send("Container paused", $routeParams.id);
}, function(e) {
update();
Messages.error("Failure", "Container failed to pause." + e.data);
});
};
$scope.unpause = function() {
ViewSpinner.spin();
Container.unpause({id: $routeParams.id}, function(d) {
update();
Messages.send("Container unpaused", $routeParams.id);
}, function(e) {
update();
Messages.error("Failure", "Container failed to unpause." + e.data);
});
};
$scope.remove = function() { $scope.remove = function() {
ViewSpinner.spin();
Container.remove({id: $routeParams.id}, function(d) { Container.remove({id: $routeParams.id}, function(d) {
update();
Messages.send("Container removed", $routeParams.id); Messages.send("Container removed", $routeParams.id);
}, function(e){ }, function(e){
update();
Messages.error("Failure", "Container failed to remove." + e.data); Messages.error("Failure", "Container failed to remove." + e.data);
}); });
}; };
@ -192,23 +241,15 @@ function ContainerController($scope, $routeParams, $location, Container, Message
}; };
$scope.getChanges = function() { $scope.getChanges = function() {
ViewSpinner.spin();
Container.changes({id: $routeParams.id}, function(d) { Container.changes({id: $routeParams.id}, function(d) {
$scope.changes = d; $scope.changes = d;
ViewSpinner.stop();
}); });
}; };
Container.get({id: $routeParams.id}, function(d) { update();
$scope.container = d; $scope.getChanges();
}, function(e) {
if (e.status === 404) {
$('.detail').hide();
Messages.error("Not found", "Container not found.");
} else {
Messages.error("Failure", e.data);
}
});
$scope.getChanges();
} }
// Controller for the list of containers // Controller for the list of containers
@ -220,8 +261,8 @@ function ContainersController($scope, Container, Settings, Messages, ViewSpinner
var update = function(data) { var update = function(data) {
ViewSpinner.spin(); ViewSpinner.spin();
Container.query(data, function(d) { Container.query(data, function(d) {
$scope.containers = d.map(function(item) { $scope.containers = d.map(function(item) {
return new ContainerViewModel(item); }); return new ContainerViewModel(item); });
ViewSpinner.stop(); ViewSpinner.stop();
}); });
}; };
@ -233,22 +274,25 @@ function ContainersController($scope, Container, Settings, Messages, ViewSpinner
counter = counter -1; counter = counter -1;
if (counter === 0) { if (counter === 0) {
ViewSpinner.stop(); ViewSpinner.stop();
update({all: Settings.displayAll ? 1 : 0});
} }
}; };
angular.forEach(items, function(c) { angular.forEach(items, function(c) {
if (c.Checked) { if (c.Checked) {
counter = counter + 1; counter = counter + 1;
action({id: c.Id}, function(d) { action({id: c.Id}, function(d) {
Messages.send("Container " + msg, c.Id); Messages.send("Container " + msg, c.Id);
var index = $scope.containers.indexOf(c); var index = $scope.containers.indexOf(c);
$scope.containers.splice(index, 1);
complete(); complete();
}, function(e) { }, function(e) {
Messages.error("Failure", e.data); Messages.error("Failure", e.data);
complete(); complete();
}); });
} }
}); });
if (counter === 0) {
ViewSpinner.stop();
}
}; };
$scope.toggleSelectAll = function() { $scope.toggleSelectAll = function() {
@ -274,6 +318,14 @@ function ContainersController($scope, Container, Settings, Messages, ViewSpinner
batch($scope.containers, Container.kill, "Killed"); batch($scope.containers, Container.kill, "Killed");
}; };
$scope.pauseAction = function() {
batch($scope.containers, Container.pause, "Paused");
};
$scope.unpauseAction = function() {
batch($scope.containers, Container.unpause, "Unpaused");
};
$scope.removeAction = function() { $scope.removeAction = function() {
batch($scope.containers, Container.remove, "Removed"); batch($scope.containers, Container.remove, "Removed");
}; };

@ -34,6 +34,9 @@ angular.module('dockerui.filters', [])
if (state.Ghost && state.Running) { if (state.Ghost && state.Running) {
return 'Ghost'; return 'Ghost';
} }
if (state.Running && state.Paused) {
return 'Running (Paused)';
}
if (state.Running) { if (state.Running) {
return 'Running'; return 'Running';
} }
@ -62,22 +65,22 @@ angular.module('dockerui.filters', [])
var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)));
return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]]; return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]];
}; };
}) })
.filter('containername', function() { .filter('containername', function() {
return function(container) { return function(container) {
var name = container.Names[0]; var name = container.Names[0];
return name.substring(1, name.length); return name.substring(1, name.length);
}; };
}) })
.filter('repotag', function() { .filter('repotag', function() {
return function(image) { return function(image) {
if (image.RepoTags && image.RepoTags.length > 0) { if (image.RepoTags && image.RepoTags.length > 0) {
var tag = image.RepoTags[0]; var tag = image.RepoTags[0];
if (tag == '<none>:<none>') { tag = ''; } if (tag == '<none>:<none>') { tag = ''; }
return tag; return tag;
} }
return ''; return '';
}; };
}) })
.filter('getdate', function() { .filter('getdate', function() {
return function(data) { return function(data) {

@ -5,17 +5,19 @@ angular.module('dockerui.services', ['ngResource'])
// 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'}},
changes :{method: 'GET', params: {action:'changes'}, isArray: true}, pause: {method: 'POST', params: {id: '@id', action: 'pause'}},
create :{method: 'POST', params: {action:'create'}}, unpause: {method: 'POST', params: {id: '@id', action: 'unpause'}},
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}}
}); });
}) })
.factory('Image', function($resource, Settings) { .factory('Image', function($resource, Settings) {
@ -23,14 +25,14 @@ angular.module('dockerui.services', ['ngResource'])
// 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) {
@ -74,52 +76,51 @@ angular.module('dockerui.services', ['ngResource'])
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() { spinner.spin(target); },
stop: function() { spinner.stop(); } stop: function() { spinner.stop(); }
}; };
}) })
.factory('Messages', function($rootScope) { .factory('Messages', function($rootScope) {
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: 6000, time: 6000,
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) {
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();
request.onload = callback; request.onload = callback;
request.open('POST', url); request.open('POST', url);
request.send(data); request.send(data);
} }
}; };
}); });

@ -3,9 +3,21 @@
<h4>Container: {{ container.Name }}</h4> <h4>Container: {{ container.Name }}</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"
<button class="btn btn-warning" ng-click="stop()">Stop</button> ng-click="start()"
<button class="btn btn-danger" ng-click="kill()">Kill</button> 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> </div>
<table class="table table-striped"> <table class="table table-striped">

@ -9,6 +9,8 @@
<li><a tabindex="-1" href="" ng-click="startAction()">Start</a></li> <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="stopAction()">Stop</a></li>
<li><a tabindex="-1" href="" ng-click="killAction()">Kill</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>
<li><a tabindex="-1" href="" ng-click="removeAction()">Remove</a></li> <li><a tabindex="-1" href="" ng-click="removeAction()">Remove</a></li>
</ul> </ul>
</li> </li>

Loading…
Cancel
Save