From 86522852270a6f2ac113b1f0614f86a1fdbc268c Mon Sep 17 00:00:00 2001 From: Kevan Ahlquist Date: Sat, 18 Oct 2014 21:41:26 -0500 Subject: [PATCH] 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 --- js/controllers.js | 96 +++++++++++++++++++++++++++++++--------- js/filters.js | 35 ++++++++------- js/services.js | 81 ++++++++++++++++----------------- partials/container.html | 18 ++++++-- partials/containers.html | 2 + 5 files changed, 151 insertions(+), 81 deletions(-) diff --git a/js/controllers.js b/js/controllers.js index ebd132619..ba1f6e053 100644 --- a/js/controllers.js +++ b/js/controllers.js @@ -155,34 +155,83 @@ function SettingsController($scope, System, Docker, Settings, Messages) { function ContainerController($scope, $routeParams, $location, Container, Messages, ViewSpinner) { $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(){ + ViewSpinner.spin(); Container.start({id: $routeParams.id}, function(d) { + update(); Messages.send("Container started", $routeParams.id); }, function(e) { + update(); Messages.error("Failure", "Container failed to start." + e.data); }); }; $scope.stop = function() { + ViewSpinner.spin(); Container.stop({id: $routeParams.id}, function(d) { + update(); Messages.send("Container stopped", $routeParams.id); }, function(e) { + update(); Messages.error("Failure", "Container failed to stop." + e.data); }); }; $scope.kill = function() { + ViewSpinner.spin(); Container.kill({id: $routeParams.id}, function(d) { + update(); Messages.send("Container killed", $routeParams.id); }, function(e) { + update(); 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() { + ViewSpinner.spin(); Container.remove({id: $routeParams.id}, function(d) { + update(); Messages.send("Container removed", $routeParams.id); }, function(e){ + update(); Messages.error("Failure", "Container failed to remove." + e.data); }); }; @@ -192,23 +241,15 @@ function ContainerController($scope, $routeParams, $location, Container, Message }; $scope.getChanges = function() { + ViewSpinner.spin(); Container.changes({id: $routeParams.id}, function(d) { $scope.changes = d; + ViewSpinner.stop(); }); }; - Container.get({id: $routeParams.id}, function(d) { - $scope.container = d; - }, function(e) { - if (e.status === 404) { - $('.detail').hide(); - Messages.error("Not found", "Container not found."); - } else { - Messages.error("Failure", e.data); - } - }); - - $scope.getChanges(); + update(); + $scope.getChanges(); } // Controller for the list of containers @@ -220,8 +261,8 @@ function ContainersController($scope, Container, Settings, Messages, ViewSpinner var update = function(data) { ViewSpinner.spin(); Container.query(data, function(d) { - $scope.containers = d.map(function(item) { - return new ContainerViewModel(item); }); + $scope.containers = d.map(function(item) { + return new ContainerViewModel(item); }); ViewSpinner.stop(); }); }; @@ -233,22 +274,25 @@ function ContainersController($scope, Container, Settings, Messages, ViewSpinner counter = counter -1; if (counter === 0) { ViewSpinner.stop(); + update({all: Settings.displayAll ? 1 : 0}); } }; - angular.forEach(items, function(c) { - if (c.Checked) { - counter = counter + 1; - action({id: c.Id}, function(d) { + 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); - $scope.containers.splice(index, 1); complete(); - }, function(e) { + }, function(e) { Messages.error("Failure", e.data); complete(); - }); - } + }); + } }); + if (counter === 0) { + ViewSpinner.stop(); + } }; $scope.toggleSelectAll = function() { @@ -274,6 +318,14 @@ function ContainersController($scope, Container, Settings, Messages, ViewSpinner 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() { batch($scope.containers, Container.remove, "Removed"); }; diff --git a/js/filters.js b/js/filters.js index c9c39c6f3..6c013a431 100644 --- a/js/filters.js +++ b/js/filters.js @@ -34,6 +34,9 @@ angular.module('dockerui.filters', []) if (state.Ghost && state.Running) { return 'Ghost'; } + if (state.Running && state.Paused) { + return 'Running (Paused)'; + } if (state.Running) { return 'Running'; } @@ -62,22 +65,22 @@ angular.module('dockerui.filters', []) var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[[i]]; }; - }) - .filter('containername', function() { - return function(container) { - var name = container.Names[0]; - return name.substring(1, name.length); - }; - }) - .filter('repotag', function() { - return function(image) { - if (image.RepoTags && image.RepoTags.length > 0) { - var tag = image.RepoTags[0]; - if (tag == ':') { tag = ''; } - return tag; - } - return ''; - }; + }) + .filter('containername', function() { + return function(container) { + var name = container.Names[0]; + return name.substring(1, name.length); + }; + }) + .filter('repotag', function() { + return function(image) { + if (image.RepoTags && image.RepoTags.length > 0) { + var tag = image.RepoTags[0]; + if (tag == ':') { tag = ''; } + return tag; + } + return ''; + }; }) .filter('getdate', function() { return function(data) { diff --git a/js/services.js b/js/services.js index 017d9668c..e8c5bdfce 100644 --- a/js/services.js +++ b/js/services.js @@ -5,17 +5,19 @@ angular.module('dockerui.services', ['ngResource']) // 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' + name: '@name' }, { 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'}}, stop: {method: 'POST', params: {id: '@id', t: 5, action: 'stop'}}, restart: {method: 'POST', params: {id: '@id', t: 5, action: 'restart' }}, - kill :{method: 'POST', params: {id: '@id', action:'kill'}}, - changes :{method: 'GET', params: {action:'changes'}, isArray: true}, - create :{method: 'POST', params: {action:'create'}}, - remove :{method: 'DELETE', params: {id: '@id', v:0}} + 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}} }); }) .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 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'}}, - remove :{method: 'DELETE', params: {id: '@id'}, 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) { @@ -74,52 +76,51 @@ angular.module('dockerui.services', ['ngResource']) var spinner = new Spinner(); var target = document.getElementById('view'); - return { - spin: function() { spinner.spin(target); }, - stop: function() { spinner.stop(); } - }; + return { + spin: function() { spinner.spin(target); }, + stop: function() { spinner.stop(); } + }; }) .factory('Messages', function($rootScope) { return { - send: function(title, text) { - $.gritter.add({ - title: title, - text: text, - time: 2000, - before_open: function() { - if($('.gritter-item-wrapper').length == 3) { + send: function(title, text) { + $.gritter.add({ + title: title, + text: text, + time: 2000, + 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: 6000, before_open: function() { - if($('.gritter-item-wrapper').length == 4) { + if($('.gritter-item-wrapper').length == 4) { return false; } } }); - } + } }; }) .factory('Dockerfile', function(Settings) { var url = Settings.rawUrl + '/build'; return { - build: function(file, callback) { - var data = new FormData(); - var dockerfile = new Blob([file], { type: 'text/text' }); - data.append('Dockerfile', dockerfile); + build: function(file, callback) { + var data = new FormData(); + var dockerfile = new Blob([file], { type: 'text/text' }); + data.append('Dockerfile', dockerfile); - var request = new XMLHttpRequest(); - request.onload = callback; - request.open('POST', url); - request.send(data); - } + var request = new XMLHttpRequest(); + request.onload = callback; + request.open('POST', url); + request.send(data); + } }; }); diff --git a/partials/container.html b/partials/container.html index e6fbb6468..3b4ec9969 100644 --- a/partials/container.html +++ b/partials/container.html @@ -3,9 +3,21 @@

Container: {{ container.Name }}

- - - + + + + +
diff --git a/partials/containers.html b/partials/containers.html index b26794c25..e5c36257c 100644 --- a/partials/containers.html +++ b/partials/containers.html @@ -9,6 +9,8 @@
  • Start
  • Stop
  • Kill
  • +
  • Pause
  • +
  • Unpause
  • Remove