diff --git a/app/app.js b/app/app.js index 7a4a4dbcc..0f87a89cf 100644 --- a/app/app.js +++ b/app/app.js @@ -38,7 +38,10 @@ angular.module('dockerui', ['dockerui.templates', 'ngRoute', 'dockerui.services' controller: 'ImageController' }); $routeProvider.when('/info', {templateUrl: 'app/components/info/info.html', controller: 'InfoController'}); - $routeProvider.when('/events', {templateUrl: 'app/components/events/events.html', controller: 'EventsController'}); + $routeProvider.when('/events', { + templateUrl: 'app/components/events/events.html', + controller: 'EventsController' + }); $routeProvider.otherwise({redirectTo: '/'}); }]) // This is your docker url that the api will use to make requests diff --git a/app/components/builder/builderController.js b/app/components/builder/builderController.js index eff32d9ca..5455aae4a 100644 --- a/app/components/builder/builderController.js +++ b/app/components/builder/builderController.js @@ -1,5 +1,5 @@ angular.module('builder', []) -.controller('BuilderController', ['$scope', 'Dockerfile', 'Messages', -function($scope, Dockerfile, Messages) { - $scope.template = 'app/components/builder/builder.html'; -}]); + .controller('BuilderController', ['$scope', 'Dockerfile', 'Messages', + function ($scope, Dockerfile, Messages) { + $scope.template = 'app/components/builder/builder.html'; + }]); diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index dbcf57376..8f46d2211 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -1,143 +1,143 @@ angular.module('container', []) -.controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'ContainerCommit', 'Messages', 'ViewSpinner', -function($scope, $routeParams, $location, Container, ContainerCommit, Messages, ViewSpinner) { - $scope.changes = []; - $scope.edit = false; + .controller('ContainerController', ['$scope', '$routeParams', '$location', 'Container', 'ContainerCommit', 'Messages', 'ViewSpinner', + function ($scope, $routeParams, $location, Container, ContainerCommit, 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) { - $('.detail').hide(); - Messages.error("Not found", "Container not found."); - } else { - Messages.error("Failure", e.data); - } - ViewSpinner.stop(); - }); - }; + 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) { + $('.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: $scope.container.Id, - HostConfig: $scope.container.HostConfig - }, function(d) { - update(); - Messages.send("Container started", $routeParams.id); - }, function(e) { - update(); - Messages.error("Failure", "Container failed to start." + e.data); - }); - }; + $scope.start = function () { + ViewSpinner.spin(); + Container.start({ + id: $scope.container.Id, + HostConfig: $scope.container.HostConfig + }, 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.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.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.commit = function() { - ViewSpinner.spin(); - ContainerCommit.commit({id: $routeParams.id, repo: $scope.container.Config.Image}, function(d) { - update(); - Messages.send("Container commited", $routeParams.id); - }, function(e) { - update(); - Messages.error("Failure", "Container failed to commit." + 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.commit = function () { + ViewSpinner.spin(); + ContainerCommit.commit({id: $routeParams.id, repo: $scope.container.Config.Image}, function (d) { + update(); + Messages.send("Container commited", $routeParams.id); + }, function (e) { + update(); + Messages.error("Failure", "Container failed to commit." + 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.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); + }); + }; + + $scope.restart = function () { + ViewSpinner.spin(); + Container.restart({id: $routeParams.id}, function (d) { + update(); + Messages.send("Container restarted", $routeParams.id); + }, function (e) { + update(); + Messages.error("Failure", "Container failed to restart." + e.data); + }); + }; + + $scope.hasContent = function (data) { + return data !== null && data !== undefined; + }; + + $scope.getChanges = function () { + ViewSpinner.spin(); + Container.changes({id: $routeParams.id}, function (d) { + $scope.changes = d; + ViewSpinner.stop(); + }); + }; + + $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; + }; - $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); - }); - }; - - $scope.restart = function() { - ViewSpinner.spin(); - Container.restart({id: $routeParams.id}, function(d) { - update(); - Messages.send("Container restarted", $routeParams.id); - }, function(e){ - update(); - Messages.error("Failure", "Container failed to restart." + e.data); - }); - }; - - $scope.hasContent = function(data) { - return data !== null && data !== undefined; - }; - - $scope.getChanges = function() { - ViewSpinner.spin(); - Container.changes({id: $routeParams.id}, function(d) { - $scope.changes = d; - ViewSpinner.stop(); - }); - }; - - $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(); -}]); + $scope.getChanges(); + }]); diff --git a/app/components/containerLogs/containerLogsController.js b/app/components/containerLogs/containerLogsController.js index 6eb6984ba..27977f11d 100644 --- a/app/components/containerLogs/containerLogsController.js +++ b/app/components/containerLogs/containerLogsController.js @@ -1,76 +1,76 @@ angular.module('containerLogs', []) -.controller('ContainerLogsController', ['$scope', '$routeParams', '$location', '$anchorScroll', 'ContainerLogs', 'Container', 'ViewSpinner', -function($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Container, ViewSpinner) { - $scope.stdout = ''; - $scope.stderr = ''; - $scope.showTimestamps = false; - $scope.tailLines = 2000; + .controller('ContainerLogsController', ['$scope', '$routeParams', '$location', '$anchorScroll', 'ContainerLogs', 'Container', 'ViewSpinner', + function ($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Container, ViewSpinner) { + $scope.stdout = ''; + $scope.stderr = ''; + $scope.showTimestamps = false; + $scope.tailLines = 2000; - ViewSpinner.spin(); - Container.get({id: $routeParams.id}, function(d) { - $scope.container = d; - ViewSpinner.stop(); - }, function(e) { - if (e.status === 404) { - Messages.error("Not found", "Container not found."); - } else { - Messages.error("Failure", e.data); - } - ViewSpinner.stop(); - }); + ViewSpinner.spin(); + Container.get({id: $routeParams.id}, function (d) { + $scope.container = d; + ViewSpinner.stop(); + }, function (e) { + if (e.status === 404) { + Messages.error("Not found", "Container not found."); + } else { + Messages.error("Failure", e.data); + } + ViewSpinner.stop(); + }); - function getLogs() { - 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(); - }); + function getLogs() { + 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, - 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(); - }); - } + 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(); + }); + } - // initial call - getLogs(); - var logIntervalId = window.setInterval(getLogs, 5000); + // initial call + getLogs(); + var logIntervalId = window.setInterval(getLogs, 5000); - $scope.$on("$destroy", function(){ - // clearing interval when view changes - clearInterval(logIntervalId); - }); + $scope.$on("$destroy", function () { + // clearing interval when view changes + clearInterval(logIntervalId); + }); - $scope.scrollTo = function(id) { - $location.hash(id); - $anchorScroll(); - }; + $scope.scrollTo = function (id) { + $location.hash(id); + $anchorScroll(); + }; - $scope.toggleTimestamps = function() { - getLogs(); - }; + $scope.toggleTimestamps = function () { + getLogs(); + }; - $scope.toggleTail = function() { - getLogs(); - }; -}]); + $scope.toggleTail = function () { + getLogs(); + }; + }]); diff --git a/app/components/containerLogs/containerlogs.html b/app/components/containerLogs/containerlogs.html index 8dfa62b8a..406d04e66 100644 --- a/app/components/containerLogs/containerlogs.html +++ b/app/components/containerLogs/containerlogs.html @@ -1,6 +1,7 @@

Logs for container: {{ container.Name }}

+
@@ -9,12 +10,12 @@
Reload logs + ng-model="tailLines" ng-keypress="($event.which === 13)? toggleTail() : 0"/>
+ ng-change="toggleTimestamps()"/>
diff --git a/app/components/containers/containers.html b/app/components/containers/containers.html index c2811581b..73d78e3f5 100644 --- a/app/components/containers/containers.html +++ b/app/components/containers/containers.html @@ -1,10 +1,10 @@ -

Containers:

- - - - - - - - + + + + + + + + - - - - - - - - + + + + + + + +
ActionNameImageCommandCreatedStatus
ActionNameImageCommandCreatedStatus
{{ container|containername}}{{ container.Image }}{{ container.Command|truncate:40 }}{{ container.Created|getdate }}{{ container.Status }}
{{ container|containername}}{{ container.Image }}{{ container.Command|truncate:40 }}{{ container.Created|getdate }}{{ container.Status }}
diff --git a/app/components/containers/containersController.js b/app/components/containers/containersController.js index 3a88987ab..dbd8b0d75 100644 --- a/app/components/containers/containersController.js +++ b/app/components/containers/containersController.js @@ -1,111 +1,112 @@ angular.module('containers', []) -.controller('ContainersController', ['$scope', 'Container', 'Settings', 'Messages', 'ViewSpinner', -function($scope, Container, Settings, Messages, ViewSpinner) { - $scope.predicate = '-Created'; - $scope.toggle = false; - $scope.displayAll = Settings.displayAll; + .controller('ContainersController', ['$scope', 'Container', 'Settings', 'Messages', 'ViewSpinner', + function ($scope, Container, Settings, Messages, ViewSpinner) { + $scope.predicate = '-Created'; + $scope.toggle = false; + $scope.displayAll = Settings.displayAll; - var update = function(data) { - ViewSpinner.spin(); - Container.query(data, function(d) { - $scope.containers = d.map(function(item) { - return new ContainerViewModel(item); }); - ViewSpinner.stop(); - }); - }; - - var batch = function(items, action, msg) { - ViewSpinner.spin(); - var counter = 0; - var complete = function() { - counter = counter -1; - if (counter === 0) { - ViewSpinner.stop(); - update({all: Settings.displayAll ? 1 : 0}); - } - }; - angular.forEach(items, function(c) { - if (c.Checked) { - 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(); + var update = function (data) { + ViewSpinner.spin(); + Container.query(data, function (d) { + $scope.containers = d.map(function (item) { + return new ContainerViewModel(item); }); - }, function(e) { - if (e.status === 404) { - $('.detail').hide(); - Messages.error("Not found", "Container not found."); - } else { - Messages.error("Failure", e.data); - } - complete(); - }); + ViewSpinner.stop(); + }); + }; + + var batch = function (items, action, msg) { + ViewSpinner.spin(); + var counter = 0; + var complete = function () { + counter = counter - 1; + if (counter === 0) { + ViewSpinner.stop(); + update({all: Settings.displayAll ? 1 : 0}); + } + }; + angular.forEach(items, function (c) { + if (c.Checked) { + 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) { + ViewSpinner.stop(); } - 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(); - }); + }; - } + $scope.toggleSelectAll = function () { + angular.forEach($scope.containers, function (i) { + i.Checked = $scope.toggle; + }); + }; - } - }); - if (counter === 0) { - ViewSpinner.stop(); - } - }; + $scope.toggleGetAll = function () { + Settings.displayAll = $scope.displayAll; + update({all: Settings.displayAll ? 1 : 0}); + }; - $scope.toggleSelectAll = function() { - angular.forEach($scope.containers, function(i) { - i.Checked = $scope.toggle; - }); - }; + $scope.startAction = function () { + batch($scope.containers, Container.start, "Started"); + }; - $scope.toggleGetAll = function() { - Settings.displayAll = $scope.displayAll; - update({all: Settings.displayAll ? 1 : 0}); - }; + $scope.stopAction = function () { + batch($scope.containers, Container.stop, "Stopped"); + }; - $scope.startAction = function() { - batch($scope.containers, Container.start, "Started"); - }; + $scope.restartAction = function () { + batch($scope.containers, Container.restart, "Restarted"); + }; - $scope.stopAction = function() { - batch($scope.containers, Container.stop, "Stopped"); - }; + $scope.killAction = function () { + batch($scope.containers, Container.kill, "Killed"); + }; - $scope.restartAction = function() { - batch($scope.containers, Container.restart, "Restarted"); - }; + $scope.pauseAction = function () { + batch($scope.containers, Container.pause, "Paused"); + }; - $scope.killAction = function() { - batch($scope.containers, Container.kill, "Killed"); - }; + $scope.unpauseAction = function () { + batch($scope.containers, Container.unpause, "Unpaused"); + }; - $scope.pauseAction = function() { - batch($scope.containers, Container.pause, "Paused"); - }; + $scope.removeAction = function () { + batch($scope.containers, Container.remove, "Removed"); + }; - $scope.unpauseAction = function() { - batch($scope.containers, Container.unpause, "Unpaused"); - }; - - $scope.removeAction = function() { - batch($scope.containers, Container.remove, "Removed"); - }; - - update({all: Settings.displayAll ? 1 : 0}); -}]); + update({all: Settings.displayAll ? 1 : 0}); + }]); diff --git a/app/components/containersNetwork/containersNetwork.html b/app/components/containersNetwork/containersNetwork.html index f213de493..ba265e880 100644 --- a/app/components/containersNetwork/containersNetwork.html +++ b/app/components/containersNetwork/containersNetwork.html @@ -15,7 +15,8 @@
- +
" + + this.addContainerNode = function (container) { + this.nodes.add({ + id: container.Id, + label: container.Name, + title: "", - color: (container.Running ? "#8888ff" : "#cccccc") - }); - }; - - this.hasEdge = function(from, to) { - return this.edges.getIds({ - filter: function (item) { - return item.from == from.Id && item.to == to.Id; - } }).length > 0; - }; - - this.addLinkEdgeIfExists = function(from, to) { - if (from.Links != null && from.Links[to.Name] != null && !this.hasEdge(from, to)) { - this.edges.add({ - from: from.Id, - to: to.Id, - label: from.Links[to.Name] }); - } - }; - - this.addVolumeEdgeIfExists = function(from, to) { - if (from.VolumesFrom != null && (from.VolumesFrom[to.Id] != null || from.VolumesFrom[to.Name] != null) && !this.hasEdge(from, to)) { - this.edges.add({ - from: from.Id, - to: to.Id, - color: { color: '#A0A0A0', highlight: '#A0A0A0', hover: '#848484'}}); - } - }; - - this.removeContainersNodes = function(containersIds) { - this.nodes.remove(containersIds); - }; - } - - function ContainersNetwork() { - this.data = new ContainersNetworkData(); - this.containers = {}; - this.selectedContainersIds = []; - this.shownContainersIds = []; - this.events = { - select : function(event) { - $scope.network.selectedContainersIds = event.nodes; - $scope.$apply( function() { - $scope.query = ''; + color: (container.Running ? "#8888ff" : "#cccccc") }); - }, - doubleClick : function(event) { - $scope.$apply( function() { - $location.path('/containers/' + event.nodes[0]); - }); - } - }; - this.options = { - navigation: true, - keyboard: true, - height: '500px', width: '700px', - nodes: { - shape: 'box' - }, - edges: { - style: 'arrow' - }, - physics: { - barnesHut : { - springLength: 200 + }; + + this.hasEdge = function (from, to) { + return this.edges.getIds({ + filter: function (item) { + return item.from == from.Id && item.to == to.Id; + } + }).length > 0; + }; + + this.addLinkEdgeIfExists = function (from, to) { + if (from.Links != null && from.Links[to.Name] != null && !this.hasEdge(from, to)) { + this.edges.add({ + from: from.Id, + to: to.Id, + label: from.Links[to.Name] + }); } - } - }; + }; - this.addContainer = function(data) { - var container = new ContainerNode(data); - this.containers[container.Id] = container; - this.shownContainersIds.push(container.Id); - this.data.addContainerNode(container); - for (var otherContainerId in this.containers) { - var otherContainer = this.containers[otherContainerId]; - this.data.addLinkEdgeIfExists(container, otherContainer); - this.data.addLinkEdgeIfExists(otherContainer, container); - this.data.addVolumeEdgeIfExists(container, otherContainer); - this.data.addVolumeEdgeIfExists(otherContainer, container); - } - }; - - this.selectContainers = function(query) { - if (this.component != null) { - this.selectedContainersIds = this.searchContainers(query); - this.component.selectNodes(this.selectedContainersIds); - } - }; - - this.searchContainers = function(query) { - if (query.trim() === "") { - return []; - } - var selectedContainersIds = []; - for (var i=0; i < this.shownContainersIds.length; i++) { - var container = this.containers[this.shownContainersIds[i]]; - if (container.Name.indexOf(query) > -1 || - container.Image.indexOf(query) > -1 || - container.Id.indexOf(query) > -1) { - selectedContainersIds.push(container.Id); + this.addVolumeEdgeIfExists = function (from, to) { + if (from.VolumesFrom != null && (from.VolumesFrom[to.Id] != null || from.VolumesFrom[to.Name] != null) && !this.hasEdge(from, to)) { + this.edges.add({ + from: from.Id, + to: to.Id, + color: {color: '#A0A0A0', highlight: '#A0A0A0', hover: '#848484'} + }); } - } - return selectedContainersIds; - }; + }; - this.hideSelected = function() { - var i=0; - while ( i < this.shownContainersIds.length ) { - if (this.selectedContainersIds.indexOf(this.shownContainersIds[i]) > -1) { - this.shownContainersIds.splice(i, 1); - } else { - i++; - } - } - this.data.removeContainersNodes(this.selectedContainersIds); - $scope.query = ''; + this.removeContainersNodes = function (containersIds) { + this.nodes.remove(containersIds); + }; + } + + function ContainersNetwork() { + this.data = new ContainersNetworkData(); + this.containers = {}; this.selectedContainersIds = []; - }; + this.shownContainersIds = []; + this.events = { + select: function (event) { + $scope.network.selectedContainersIds = event.nodes; + $scope.$apply(function () { + $scope.query = ''; + }); + }, + doubleClick: function (event) { + $scope.$apply(function () { + $location.path('/containers/' + event.nodes[0]); + }); + } + }; + this.options = { + navigation: true, + keyboard: true, + height: '500px', width: '700px', + nodes: { + shape: 'box' + }, + edges: { + style: 'arrow' + }, + physics: { + barnesHut: { + springLength: 200 + } + } + }; - this.searchDownstream = function(containerId, downstreamContainersIds) { - if (downstreamContainersIds.indexOf(containerId) > -1) { - return; - } - downstreamContainersIds.push(containerId); - var container = this.containers[containerId]; - if (container.Links == null && container.VolumesFrom == null) { - return; - } - for (var otherContainerId in this.containers) { - var otherContainer = this.containers[otherContainerId]; - if (container.Links != null && container.Links[otherContainer.Name] != null) { - this.searchDownstream(otherContainer.Id, downstreamContainersIds); - } else if (container.VolumesFrom != null && + this.addContainer = function (data) { + var container = new ContainerNode(data); + this.containers[container.Id] = container; + this.shownContainersIds.push(container.Id); + this.data.addContainerNode(container); + for (var otherContainerId in this.containers) { + var otherContainer = this.containers[otherContainerId]; + this.data.addLinkEdgeIfExists(container, otherContainer); + this.data.addLinkEdgeIfExists(otherContainer, container); + this.data.addVolumeEdgeIfExists(container, otherContainer); + this.data.addVolumeEdgeIfExists(otherContainer, container); + } + }; + + this.selectContainers = function (query) { + if (this.component != null) { + this.selectedContainersIds = this.searchContainers(query); + this.component.selectNodes(this.selectedContainersIds); + } + }; + + this.searchContainers = function (query) { + if (query.trim() === "") { + return []; + } + var selectedContainersIds = []; + for (var i = 0; i < this.shownContainersIds.length; i++) { + var container = this.containers[this.shownContainersIds[i]]; + if (container.Name.indexOf(query) > -1 || + container.Image.indexOf(query) > -1 || + container.Id.indexOf(query) > -1) { + selectedContainersIds.push(container.Id); + } + } + return selectedContainersIds; + }; + + this.hideSelected = function () { + var i = 0; + while (i < this.shownContainersIds.length) { + if (this.selectedContainersIds.indexOf(this.shownContainersIds[i]) > -1) { + this.shownContainersIds.splice(i, 1); + } else { + i++; + } + } + this.data.removeContainersNodes(this.selectedContainersIds); + $scope.query = ''; + this.selectedContainersIds = []; + }; + + this.searchDownstream = function (containerId, downstreamContainersIds) { + if (downstreamContainersIds.indexOf(containerId) > -1) { + return; + } + downstreamContainersIds.push(containerId); + var container = this.containers[containerId]; + if (container.Links == null && container.VolumesFrom == null) { + return; + } + for (var otherContainerId in this.containers) { + var otherContainer = this.containers[otherContainerId]; + if (container.Links != null && container.Links[otherContainer.Name] != null) { + this.searchDownstream(otherContainer.Id, downstreamContainersIds); + } else if (container.VolumesFrom != null && container.VolumesFrom[otherContainer.Id] != null) { - this.searchDownstream(otherContainer.Id, downstreamContainersIds); + this.searchDownstream(otherContainer.Id, downstreamContainersIds); + } } - } - }; + }; - this.updateShownContainers = function(newShownContainersIds) { - for (var containerId in this.containers) { - if (newShownContainersIds.indexOf(containerId) > -1 && + this.updateShownContainers = function (newShownContainersIds) { + for (var containerId in this.containers) { + if (newShownContainersIds.indexOf(containerId) > -1 && this.shownContainersIds.indexOf(containerId) === -1) { - this.data.addContainerNode(this.containers[containerId]); - } else if (newShownContainersIds.indexOf(containerId) === -1 && + this.data.addContainerNode(this.containers[containerId]); + } else if (newShownContainersIds.indexOf(containerId) === -1 && this.shownContainersIds.indexOf(containerId) > -1) { - this.data.removeContainersNodes(containerId); + this.data.removeContainersNodes(containerId); + } } - } - this.shownContainersIds = newShownContainersIds; - }; + this.shownContainersIds = newShownContainersIds; + }; - this.showSelectedDownstream = function() { - var downstreamContainersIds = []; - for (var i=0; i < this.selectedContainersIds.length; i++) { - this.searchDownstream(this.selectedContainersIds[i], downstreamContainersIds); - } - this.updateShownContainers(downstreamContainersIds); - }; + this.showSelectedDownstream = function () { + var downstreamContainersIds = []; + for (var i = 0; i < this.selectedContainersIds.length; i++) { + this.searchDownstream(this.selectedContainersIds[i], downstreamContainersIds); + } + this.updateShownContainers(downstreamContainersIds); + }; - this.searchUpstream = function(containerId, upstreamContainersIds) { - if (upstreamContainersIds.indexOf(containerId) > -1) { - return; - } - upstreamContainersIds.push(containerId); - var container = this.containers[containerId]; - for (var otherContainerId in this.containers) { - var otherContainer = this.containers[otherContainerId]; - if (otherContainer.Links != null && otherContainer.Links[container.Name] != null) { - this.searchUpstream(otherContainer.Id, upstreamContainersIds); - } else if (otherContainer.VolumesFrom != null && + this.searchUpstream = function (containerId, upstreamContainersIds) { + if (upstreamContainersIds.indexOf(containerId) > -1) { + return; + } + upstreamContainersIds.push(containerId); + var container = this.containers[containerId]; + for (var otherContainerId in this.containers) { + var otherContainer = this.containers[otherContainerId]; + if (otherContainer.Links != null && otherContainer.Links[container.Name] != null) { + this.searchUpstream(otherContainer.Id, upstreamContainersIds); + } else if (otherContainer.VolumesFrom != null && otherContainer.VolumesFrom[container.Id] != null) { - this.searchUpstream(otherContainer.Id, upstreamContainersIds); + this.searchUpstream(otherContainer.Id, upstreamContainersIds); + } } - } - }; + }; - this.showSelectedUpstream = function() { - var upstreamContainersIds = []; - for (var i=0; i < this.selectedContainersIds.length; i++) { - this.searchUpstream(this.selectedContainersIds[i], upstreamContainersIds); - } - this.updateShownContainers(upstreamContainersIds); - }; - - this.showAll = function() { - for (var containerId in this.containers) { - if (this.shownContainersIds.indexOf(containerId) === -1) { - this.data.addContainerNode(this.containers[containerId]); - this.shownContainersIds.push(containerId); + this.showSelectedUpstream = function () { + var upstreamContainersIds = []; + for (var i = 0; i < this.selectedContainersIds.length; i++) { + this.searchUpstream(this.selectedContainersIds[i], upstreamContainersIds); } - } + this.updateShownContainers(upstreamContainersIds); + }; + + this.showAll = function () { + for (var containerId in this.containers) { + if (this.shownContainersIds.indexOf(containerId) === -1) { + this.data.addContainerNode(this.containers[containerId]); + this.shownContainersIds.push(containerId); + } + } + }; + + } + + $scope.network = new ContainersNetwork(); + + var showFailure = function (event) { + Messages.error('Failure', e.data); }; - } + var addContainer = function (container) { + $scope.network.addContainer(container); + }; - $scope.network = new ContainersNetwork(); + var update = function (data) { + Container.query(data, function (d) { + for (var i = 0; i < d.length; i++) { + Container.get({id: d[i].Id}, addContainer, showFailure); + } + }); + }; + update({all: 0}); - var showFailure = function (event) { - Messages.error('Failure', e.data); - }; + $scope.includeStopped = false; + $scope.toggleIncludeStopped = function () { + $scope.network.updateShownContainers([]); + update({all: $scope.includeStopped ? 1 : 0}); + }; - var addContainer = function (container) { - $scope.network.addContainer(container); - }; - - var update = function (data) { - Container.query(data, function(d) { - for (var i = 0; i < d.length; i++) { - Container.get({id: d[i].Id}, addContainer, showFailure); - } - }); - }; - update({all: 0}); - - $scope.includeStopped = false; - $scope.toggleIncludeStopped = function() { - $scope.network.updateShownContainers([]); - update({all: $scope.includeStopped ? 1 : 0}); - }; - -}]); + }]); diff --git a/app/components/dashboard/dashboard.html b/app/components/dashboard/dashboard.html index 7dd6f34dc..8b2209e6d 100644 --- a/app/components/dashboard/dashboard.html +++ b/app/components/dashboard/dashboard.html @@ -1,4 +1,3 @@ -
- +
- +
- +
- +
diff --git a/app/components/pullImage/pullImageController.js b/app/components/pullImage/pullImageController.js index 9fc242fb5..32990689c 100644 --- a/app/components/pullImage/pullImageController.js +++ b/app/components/pullImage/pullImageController.js @@ -1,9 +1,9 @@ angular.module('pullImage', []) .controller('PullImageController', ['$scope', '$log', 'Dockerfile', 'Messages', 'Image', 'ViewSpinner', - function($scope, $log, Dockerfile, Messages, Image, ViewSpinner) { + function ($scope, $log, Dockerfile, Messages, Image, ViewSpinner) { $scope.template = 'app/components/pullImage/pullImage.html'; - $scope.init = function() { + $scope.init = function () { $scope.config = { registry: '', repo: '', @@ -18,7 +18,7 @@ angular.module('pullImage', []) Messages.error('Error', errorMsgFilter(e)); } - $scope.pull = function() { + $scope.pull = function () { $('#error-message').hide(); var config = angular.copy($scope.config); var imageName = (config.registry ? config.registry + '/' : '' ) + @@ -28,10 +28,10 @@ angular.module('pullImage', []) ViewSpinner.spin(); $('#pull-modal').modal('hide'); - Image.create(config, function(data) { + Image.create(config, function (data) { ViewSpinner.stop(); if (data.constructor === Array) { - var f = data.length > 0 && data[data.length-1].hasOwnProperty('error'); + var f = data.length > 0 && data[data.length - 1].hasOwnProperty('error'); //check for error if (f) { var d = data[data.length - 1]; @@ -46,7 +46,7 @@ angular.module('pullImage', []) Messages.send("Image Added", imageName); $scope.init(); } - }, function(e) { + }, function (e) { ViewSpinner.stop(); $scope.error = "Cannot pull image " + imageName + " Reason: " + e.data; $('#pull-modal').modal('show'); diff --git a/app/components/sidebar/sidebar.html b/app/components/sidebar/sidebar.html index e7b559ec3..b93b8e5e3 100644 --- a/app/components/sidebar/sidebar.html +++ b/app/components/sidebar/sidebar.html @@ -1,11 +1,11 @@
Running containers: -
+
Endpoint: {{ endpoint }}
diff --git a/app/components/sidebar/sidebarController.js b/app/components/sidebar/sidebarController.js index f182a3481..3f58d675e 100644 --- a/app/components/sidebar/sidebarController.js +++ b/app/components/sidebar/sidebarController.js @@ -1,11 +1,11 @@ angular.module('sidebar', []) -.controller('SideBarController', ['$scope', 'Container', 'Settings', -function($scope, Container, Settings) { - $scope.template = 'partials/sidebar.html'; - $scope.containers = []; - $scope.endpoint = Settings.endpoint; + .controller('SideBarController', ['$scope', 'Container', 'Settings', + function ($scope, Container, Settings) { + $scope.template = 'partials/sidebar.html'; + $scope.containers = []; + $scope.endpoint = Settings.endpoint; - Container.query({all: 0}, function(d) { - $scope.containers = d; - }); -}]); + Container.query({all: 0}, function (d) { + $scope.containers = d; + }); + }]); diff --git a/app/components/startContainer/startContainerController.js b/app/components/startContainer/startContainerController.js index 571a360ad..46d8ba710 100644 --- a/app/components/startContainer/startContainerController.js +++ b/app/components/startContainer/startContainerController.js @@ -1,147 +1,153 @@ angular.module('startContainer', ['ui.bootstrap']) -.controller('StartContainerController', ['$scope', '$routeParams', '$location', 'Container', 'Messages', 'containernameFilter', 'errorMsgFilter', -function($scope, $routeParams, $location, Container, Messages, containernameFilter, errorMsgFilter) { - $scope.template = 'app/components/startContainer/startcontainer.html'; + .controller('StartContainerController', ['$scope', '$routeParams', '$location', 'Container', 'Messages', 'containernameFilter', 'errorMsgFilter', + function ($scope, $routeParams, $location, Container, Messages, containernameFilter, errorMsgFilter) { + $scope.template = 'app/components/startContainer/startcontainer.html'; - Container.query({all: 1}, function(d) { - $scope.containerNames = d.map(function(container){ - return containernameFilter(container); - }); - }); + Container.query({all: 1}, function (d) { + $scope.containerNames = d.map(function (container) { + return containernameFilter(container); + }); + }); - $scope.config = { - Env: [], - Volumes: [], - SecurityOpts: [], - HostConfig: { - PortBindings: [], - Binds: [], - Links: [], - Dns: [], - DnsSearch: [], - VolumesFrom: [], - CapAdd: [], - CapDrop: [], - Devices: [], - LxcConf: [], - ExtraHosts: [] - } - }; - - $scope.menuStatus = { - containerOpen: true, - hostConfigOpen: false - }; - - function failedRequestHandler(e, Messages) { - Messages.error('Error', errorMsgFilter(e)); - } - - function rmEmptyKeys(col) { - for (var key in col) { - if (col[key] === null || col[key] === undefined || col[key] === '' || $.isEmptyObject(col[key]) || col[key].length === 0) { - delete col[key]; - } - } - } - - function getNames(arr) { - return arr.map(function(item) {return item.name;}); - } - - $scope.create = function() { - // Copy the config before transforming fields to the remote API format - var config = angular.copy($scope.config); - - config.Image = $routeParams.id; - - if (config.Cmd && config.Cmd[0] === "[") { - config.Cmd = angular.fromJson(config.Cmd); - } else if (config.Cmd) { - config.Cmd = config.Cmd.split(' '); - } - - config.Env = config.Env.map(function(envar) {return envar.name + '=' + envar.value;}); - - config.Volumes = getNames(config.Volumes); - config.SecurityOpts = getNames(config.SecurityOpts); - - config.HostConfig.VolumesFrom = getNames(config.HostConfig.VolumesFrom); - config.HostConfig.Binds = getNames(config.HostConfig.Binds); - config.HostConfig.Links = getNames(config.HostConfig.Links); - config.HostConfig.Dns = getNames(config.HostConfig.Dns); - config.HostConfig.DnsSearch = getNames(config.HostConfig.DnsSearch); - config.HostConfig.CapAdd = getNames(config.HostConfig.CapAdd); - config.HostConfig.CapDrop = getNames(config.HostConfig.CapDrop); - config.HostConfig.LxcConf = config.HostConfig.LxcConf.reduce(function(prev, cur, idx){ - prev[cur.name] = cur.value; - return prev; - }, {}); - config.HostConfig.ExtraHosts = config.HostConfig.ExtraHosts.map(function(entry) {return entry.host + ':' + entry.ip;}); - - var ExposedPorts = {}; - var PortBindings = {}; - config.HostConfig.PortBindings.forEach(function(portBinding) { - var intPort = portBinding.intPort + "/tcp"; - if (portBinding.protocol === "udp") { - intPort = portBinding.intPort + "/udp"; - } - var binding = { - HostIp: portBinding.ip, - HostPort: portBinding.extPort + $scope.config = { + Env: [], + Volumes: [], + SecurityOpts: [], + HostConfig: { + PortBindings: [], + Binds: [], + Links: [], + Dns: [], + DnsSearch: [], + VolumesFrom: [], + CapAdd: [], + CapDrop: [], + Devices: [], + LxcConf: [], + ExtraHosts: [] + } }; - if (portBinding.intPort) { - ExposedPorts[intPort] = {}; - if (intPort in PortBindings) { - PortBindings[intPort].push(binding); - } else { - PortBindings[intPort] = [binding]; - } - } else { - Messages.send('Warning', 'Internal port must be specified for PortBindings'); + + $scope.menuStatus = { + containerOpen: true, + hostConfigOpen: false + }; + + function failedRequestHandler(e, Messages) { + Messages.error('Error', errorMsgFilter(e)); } - }); - config.ExposedPorts = ExposedPorts; - config.HostConfig.PortBindings = PortBindings; - // Remove empty fields from the request to avoid overriding defaults - rmEmptyKeys(config.HostConfig); - rmEmptyKeys(config); - - var ctor = Container; - var loc = $location; - var s = $scope; - Container.create(config, function(d) { - if (d.Id) { - var reqBody = config.HostConfig || {}; - reqBody.id = d.Id; - ctor.start(reqBody, function(cd) { - if (cd.id) { - Messages.send('Container Started', d.Id); - $('#create-modal').modal('hide'); - loc.path('/containers/' + d.Id + '/'); - } else { - failedRequestHandler(cd, Messages); - ctor.remove({id: d.Id}, function() { - Messages.send('Container Removed', d.Id); - }); - } - }, function(e) { - failedRequestHandler(e, Messages); - }); - } else { - failedRequestHandler(d, Messages); + function rmEmptyKeys(col) { + for (var key in col) { + if (col[key] === null || col[key] === undefined || col[key] === '' || $.isEmptyObject(col[key]) || col[key].length === 0) { + delete col[key]; + } } - }, function(e) { - failedRequestHandler(e, Messages); - }); - }; + } - $scope.addEntry = function(array, entry) { - array.push(entry); - }; - $scope.rmEntry = function(array, entry) { - var idx = array.indexOf(entry); - array.splice(idx, 1); - }; -}]); + function getNames(arr) { + return arr.map(function (item) { + return item.name; + }); + } + + $scope.create = function () { + // Copy the config before transforming fields to the remote API format + var config = angular.copy($scope.config); + + config.Image = $routeParams.id; + + if (config.Cmd && config.Cmd[0] === "[") { + config.Cmd = angular.fromJson(config.Cmd); + } else if (config.Cmd) { + config.Cmd = config.Cmd.split(' '); + } + + config.Env = config.Env.map(function (envar) { + return envar.name + '=' + envar.value; + }); + + config.Volumes = getNames(config.Volumes); + config.SecurityOpts = getNames(config.SecurityOpts); + + config.HostConfig.VolumesFrom = getNames(config.HostConfig.VolumesFrom); + config.HostConfig.Binds = getNames(config.HostConfig.Binds); + config.HostConfig.Links = getNames(config.HostConfig.Links); + config.HostConfig.Dns = getNames(config.HostConfig.Dns); + config.HostConfig.DnsSearch = getNames(config.HostConfig.DnsSearch); + config.HostConfig.CapAdd = getNames(config.HostConfig.CapAdd); + config.HostConfig.CapDrop = getNames(config.HostConfig.CapDrop); + config.HostConfig.LxcConf = config.HostConfig.LxcConf.reduce(function (prev, cur, idx) { + prev[cur.name] = cur.value; + return prev; + }, {}); + config.HostConfig.ExtraHosts = config.HostConfig.ExtraHosts.map(function (entry) { + return entry.host + ':' + entry.ip; + }); + + var ExposedPorts = {}; + var PortBindings = {}; + config.HostConfig.PortBindings.forEach(function (portBinding) { + var intPort = portBinding.intPort + "/tcp"; + if (portBinding.protocol === "udp") { + intPort = portBinding.intPort + "/udp"; + } + var binding = { + HostIp: portBinding.ip, + HostPort: portBinding.extPort + }; + if (portBinding.intPort) { + ExposedPorts[intPort] = {}; + if (intPort in PortBindings) { + PortBindings[intPort].push(binding); + } else { + PortBindings[intPort] = [binding]; + } + } else { + Messages.send('Warning', 'Internal port must be specified for PortBindings'); + } + }); + config.ExposedPorts = ExposedPorts; + config.HostConfig.PortBindings = PortBindings; + + // Remove empty fields from the request to avoid overriding defaults + rmEmptyKeys(config.HostConfig); + rmEmptyKeys(config); + + var ctor = Container; + var loc = $location; + var s = $scope; + Container.create(config, function (d) { + if (d.Id) { + var reqBody = config.HostConfig || {}; + reqBody.id = d.Id; + ctor.start(reqBody, function (cd) { + if (cd.id) { + Messages.send('Container Started', d.Id); + $('#create-modal').modal('hide'); + loc.path('/containers/' + d.Id + '/'); + } else { + failedRequestHandler(cd, Messages); + ctor.remove({id: d.Id}, function () { + Messages.send('Container Removed', d.Id); + }); + } + }, function (e) { + failedRequestHandler(e, Messages); + }); + } else { + failedRequestHandler(d, Messages); + } + }, function (e) { + failedRequestHandler(e, Messages); + }); + }; + + $scope.addEntry = function (array, entry) { + array.push(entry); + }; + $scope.rmEntry = function (array, entry) { + var idx = array.indexOf(entry); + array.splice(idx, 1); + }; + }]); diff --git a/app/components/startContainer/startcontainer.html b/app/components/startContainer/startcontainer.html index eaa774f88..cdfc1a6fd 100644 --- a/app/components/startContainer/startcontainer.html +++ b/app/components/startContainer/startcontainer.html @@ -6,301 +6,413 @@

Create And Start Container From Image

diff --git a/app/components/stats/statsController.js b/app/components/stats/statsController.js index 4f620c33b..7a9e8412d 100644 --- a/app/components/stats/statsController.js +++ b/app/components/stats/statsController.js @@ -12,7 +12,9 @@ angular.module('stats', []) function updateStats() { Container.stats({id: $routeParams.id}, function (d) { console.log(d); - var arr = Object.keys(d).map(function (key) {return d[key];}); + var arr = Object.keys(d).map(function (key) { + return d[key]; + }); if (arr.join('').indexOf('no such id') !== -1) { Messages.error('Unable to retrieve container stats', 'Has this container been removed?'); return; diff --git a/app/shared/filters.js b/app/shared/filters.js index f0b7c6daa..e993bc23a 100644 --- a/app/shared/filters.js +++ b/app/shared/filters.js @@ -1,12 +1,12 @@ angular.module('dockerui.filters', []) - .filter('truncate', function() { + .filter('truncate', function () { 'use strict'; - return function(text, length, end) { + return function (text, length, end) { if (isNaN(length)) { length = 10; } - if (end === undefined){ + if (end === undefined) { end = '...'; } @@ -18,9 +18,9 @@ angular.module('dockerui.filters', []) } }; }) - .filter('statusbadge', function() { + .filter('statusbadge', function () { 'use strict'; - return function(text) { + return function (text) { if (text === 'Ghost') { return 'important'; } else if (text.indexOf('Exit') !== -1 && text !== 'Exit 0') { @@ -29,9 +29,9 @@ angular.module('dockerui.filters', []) return 'success'; }; }) - .filter('getstatetext', function() { + .filter('getstatetext', function () { 'use strict'; - return function(state) { + return function (state) { if (state === undefined) { return ''; } @@ -47,9 +47,9 @@ angular.module('dockerui.filters', []) return 'Stopped'; }; }) - .filter('getstatelabel', function() { + .filter('getstatelabel', function () { 'use strict'; - return function(state) { + return function (state) { if (state === undefined) { return ''; } @@ -63,45 +63,47 @@ angular.module('dockerui.filters', []) return ''; }; }) - .filter('humansize', function() { + .filter('humansize', function () { 'use strict'; - return function(bytes) { + return function (bytes) { var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']; if (bytes === 0) { return 'n/a'; } var i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)), 10); - 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 () { 'use strict'; - return function(container) { + return function (container) { var name = container.Names[0]; return name.substring(1, name.length); }; }) - .filter('repotag', function() { + .filter('repotag', function () { 'use strict'; - return function(image) { + return function (image) { if (image.RepoTags && image.RepoTags.length > 0) { var tag = image.RepoTags[0]; - if (tag === ':') { tag = ''; } + if (tag === ':') { + tag = ''; + } return tag; } - return ''; + return ''; }; }) - .filter('getdate', function() { + .filter('getdate', function () { 'use strict'; - return function(data) { + return function (data) { //Multiply by 1000 for the unix format var date = new Date(data * 1000); return date.toDateString(); }; }) - .filter('errorMsg', function() { - return function(object) { + .filter('errorMsg', function () { + return function (object) { var idx = 0; var msg = ''; while (object[idx] && typeof(object[idx]) === 'string') { diff --git a/app/shared/services.js b/app/shared/services.js index 41c809342..7722ba7c2 100644 --- a/app/shared/services.js +++ b/app/shared/services.js @@ -25,16 +25,16 @@ angular.module('dockerui.services', ['ngResource']) 'use strict'; return { commit: function (params, callback) { - $http({ - method: 'POST', - url: Settings.url + '/commit', - params: { - 'container': params.id, - 'repo': params.repo - } - }).success(callback).error(function (data, status, headers, config) { - console.log(error, data); - }); + $http({ + method: 'POST', + url: Settings.url + '/commit', + params: { + 'container': params.id, + 'repo': params.repo + } + }).success(callback).error(function (data, status, headers, config) { + console.log(error, data); + }); } }; }) @@ -80,11 +80,13 @@ angular.module('dockerui.services', ['ngResource']) get: {method: 'GET', params: {action: 'json'}}, search: {method: 'GET', params: {action: 'search'}}, history: {method: 'GET', params: {action: 'history'}, isArray: true}, - create: {method: 'POST', isArray: true, transformResponse: [function f(data) { - var str = data.replace(/\n/g, " ").replace(/\}\W*\{/g, "}, {"); - return angular.fromJson("[" + str + "]"); - }], - params: {action: 'create', fromImage: '@fromImage', repo: '@repo', tag: '@tag', registry: '@registry'}}, + create: { + method: 'POST', isArray: true, transformResponse: [function f(data) { + var str = data.replace(/\n/g, " ").replace(/\}\W*\{/g, "}, {"); + return angular.fromJson("[" + str + "]"); + }], + params: {action: 'create', fromImage: '@fromImage', repo: '@repo', tag: '@tag', registry: '@registry'} + }, 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'}}, diff --git a/app/shared/viewmodel.js b/app/shared/viewmodel.js index 319214aea..617d497d5 100644 --- a/app/shared/viewmodel.js +++ b/app/shared/viewmodel.js @@ -1,4 +1,3 @@ - function ImageViewModel(data) { this.Id = data.Id; this.Tag = data.Tag; @@ -10,12 +9,12 @@ function ImageViewModel(data) { } function ContainerViewModel(data) { - this.Id = data.Id; - this.Image = data.Image; - this.Command = data.Command; - this.Created = data.Created; - this.SizeRw = data.SizeRw; - this.Status = data.Status; - this.Checked = false; - this.Names = data.Names; + this.Id = data.Id; + this.Image = data.Image; + this.Command = data.Command; + this.Created = data.Created; + this.SizeRw = data.SizeRw; + this.Status = data.Status; + this.Checked = false; + this.Names = data.Names; } diff --git a/gruntFile.js b/gruntFile.js index a81483254..3cf502473 100644 --- a/gruntFile.js +++ b/gruntFile.js @@ -11,19 +11,19 @@ module.exports = function (grunt) { grunt.loadNpmTasks('grunt-html2js'); // Default task. - grunt.registerTask('default', ['jshint','build','karma:unit']); - grunt.registerTask('build', ['clean','html2js','concat','recess:build', 'copy']); - grunt.registerTask('release', ['clean','html2js','uglify','jshint','karma:unit','concat:index', 'recess:min', 'copy']); + grunt.registerTask('default', ['jshint', 'build', 'karma:unit']); + grunt.registerTask('build', ['clean', 'html2js', 'concat', 'recess:build', 'copy']); + grunt.registerTask('release', ['clean', 'html2js', 'uglify', 'jshint', 'karma:unit', 'concat:index', 'recess:min', 'copy']); grunt.registerTask('test-watch', ['karma:watch']); // Print a timestamp (useful for when watching) - grunt.registerTask('timestamp', function() { + grunt.registerTask('timestamp', function () { grunt.log.subhead(Date()); }); - var karmaConfig = function(configFile, customOptions) { - var options = { configFile: configFile, keepalive: true }; - var travisOptions = process.env.TRAVIS && { browsers: ['Firefox'], reporters: 'dots' }; + var karmaConfig = function (configFile, customOptions) { + var options = {configFile: configFile, keepalive: true}; + var travisOptions = process.env.TRAVIS && {browsers: ['Firefox'], reporters: 'dots'}; return grunt.util._.extend(options, customOptions, travisOptions); }; @@ -31,8 +31,7 @@ module.exports = function (grunt) { grunt.initConfig({ distdir: 'dist', pkg: grunt.file.readJSON('package.json'), - banner: - '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + + banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - <%= grunt.template.today("yyyy-mm-dd") %>\n' + '<%= pkg.homepage ? " * " + pkg.homepage + "\\n" : "" %>' + ' * Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author %>;\n' + ' * Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %>\n */\n', @@ -50,12 +49,12 @@ module.exports = function (grunt) { clean: ['<%= distdir %>/*'], copy: { assets: { - files: [{ dest: '<%= distdir %>/assets', src : '**', expand: true, cwd: 'assets/' }] + files: [{dest: '<%= distdir %>/assets', src: '**', expand: true, cwd: 'assets/'}] } }, karma: { - unit: { options: karmaConfig('test/unit/karma.conf.js') }, - watch: { options: karmaConfig('test/unit/karma.conf.js', { singleRun:false, autoWatch: true}) } + unit: {options: karmaConfig('test/unit/karma.conf.js')}, + watch: {options: karmaConfig('test/unit/karma.conf.js', {singleRun: false, autoWatch: true})} }, html2js: { app: { @@ -67,14 +66,14 @@ module.exports = function (grunt) { module: '<%= pkg.name %>.templates' } }, - concat:{ - dist:{ + concat: { + dist: { options: { banner: "<%= banner %>", process: true }, - src:['<%= src.js %>', '<%= src.jsTpl %>'], - dest:'<%= distdir %>/<%= pkg.name %>.js' + src: ['<%= src.js %>', '<%= src.jsTpl %>'], + dest: '<%= distdir %>/<%= pkg.name %>.js' }, index: { src: ['index.html'], @@ -84,32 +83,32 @@ module.exports = function (grunt) { } }, angular: { - src:['assets/js/angularjs/1.3.15/angular.min.js', - 'assets/js/angularjs/1.3.15/angular-route.min.js', - 'assets/js/angularjs/1.3.15/angular-resource.min.js', - 'assets/js/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.min.js', - 'assets/js/angular-oboe.min.js'], + src: ['assets/js/angularjs/1.3.15/angular.min.js', + 'assets/js/angularjs/1.3.15/angular-route.min.js', + 'assets/js/angularjs/1.3.15/angular-resource.min.js', + 'assets/js/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.min.js', + 'assets/js/angular-oboe.min.js'], dest: '<%= distdir %>/angular.js' } }, uglify: { - dist:{ + dist: { options: { banner: "<%= banner %>" }, - src:['<%= src.js %>' ,'<%= src.jsTpl %>'], - dest:'<%= distdir %>/<%= pkg.name %>.js' + src: ['<%= src.js %>', '<%= src.jsTpl %>'], + dest: '<%= distdir %>/<%= pkg.name %>.js' }, angular: { - src:['<%= concat.angular.src %>'], + src: ['<%= concat.angular.src %>'], dest: '<%= distdir %>/angular.js' } }, recess: { build: { files: { - '<%= distdir %>/<%= pkg.name %>.css': - ['<%= src.css %>'] }, + '<%= distdir %>/<%= pkg.name %>.css': ['<%= src.css %>'] + }, options: { compile: true, noOverqualifying: false // TODO: Added because of .nav class, rename @@ -124,29 +123,29 @@ module.exports = function (grunt) { } } }, - watch:{ + watch: { all: { - files:['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl.app %>', '<%= src.tpl.common %>', '<%= src.html %>'], - tasks:['default','timestamp'] + files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl.app %>', '<%= src.tpl.common %>', '<%= src.html %>'], + tasks: ['default', 'timestamp'] }, build: { - files:['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl.app %>', '<%= src.tpl.common %>', '<%= src.html %>'], - tasks:['build','timestamp'] + files: ['<%= src.js %>', '<%= src.specs %>', '<%= src.css %>', '<%= src.tpl.app %>', '<%= src.tpl.common %>', '<%= src.html %>'], + tasks: ['build', 'timestamp'] } }, - jshint:{ - files:['gruntFile.js', '<%= src.js %>', '<%= src.jsTpl %>', '<%= src.specs %>', '<%= src.scenarios %>'], - options:{ - curly:true, - eqeqeq:true, - immed:true, - latedef:true, - newcap:true, - noarg:true, - sub:true, - boss:true, - eqnull:true, - globals:{ + jshint: { + files: ['gruntFile.js', '<%= src.js %>', '<%= src.jsTpl %>', '<%= src.specs %>', '<%= src.scenarios %>'], + options: { + curly: true, + eqeqeq: true, + immed: true, + latedef: true, + newcap: true, + noarg: true, + sub: true, + boss: true, + eqnull: true, + globals: { angular: false, '$': false } diff --git a/package.json b/package.json index 168ece42e..6e510053b 100644 --- a/package.json +++ b/package.json @@ -1,35 +1,35 @@ { - "author": "Michael Crosby & Kevan Ahlquist", - "name": "dockerui", - "homepage": "https://github.com/crosbymichael/dockerui", - "version": "0.6.0", - "repository": { - "type": "git", - "url": "git@github.com:crosbymichael/dockerui.git" - }, - "bugs": { - "url": "https://github.com/crosbymichael/dockerui/issues" - }, - "licenses": [ - { - "type": "MIT", - "url": "https://raw.githubusercontent.com/crosbymichael/dockerui/master/LICENSE" - } - ], - "engines": { - "node": ">= 0.8.4" - }, - "dependencies": {}, - "devDependencies": { - "grunt": "~0.4.0", - "grunt-recess": "~0.3", - "grunt-contrib-clean": "~0.4.0", - "grunt-contrib-copy": "~0.4.0", - "grunt-contrib-jshint": "~0.2.0", - "grunt-contrib-concat": "~0.1.3", - "grunt-contrib-uglify": "~0.1.1", - "grunt-karma": "~0.4.4", - "grunt-html2js": "~0.1.0", - "grunt-contrib-watch": "~0.3.1" + "author": "Michael Crosby & Kevan Ahlquist", + "name": "dockerui", + "homepage": "https://github.com/crosbymichael/dockerui", + "version": "0.6.0", + "repository": { + "type": "git", + "url": "git@github.com:crosbymichael/dockerui.git" + }, + "bugs": { + "url": "https://github.com/crosbymichael/dockerui/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "https://raw.githubusercontent.com/crosbymichael/dockerui/master/LICENSE" } + ], + "engines": { + "node": ">= 0.8.4" + }, + "dependencies": {}, + "devDependencies": { + "grunt": "~0.4.0", + "grunt-recess": "~0.3", + "grunt-contrib-clean": "~0.4.0", + "grunt-contrib-copy": "~0.4.0", + "grunt-contrib-jshint": "~0.2.0", + "grunt-contrib-concat": "~0.1.3", + "grunt-contrib-uglify": "~0.1.1", + "grunt-karma": "~0.4.4", + "grunt-html2js": "~0.1.0", + "grunt-contrib-watch": "~0.3.1" + } } diff --git a/test/unit/app/components/startContainerController.spec.js b/test/unit/app/components/startContainerController.spec.js index 5d7b11c2a..57d898de1 100644 --- a/test/unit/app/components/startContainerController.spec.js +++ b/test/unit/app/components/startContainerController.spec.js @@ -1,19 +1,19 @@ -describe('startContainerController', function() { +describe('startContainerController', function () { var scope, $location, createController, mockContainer, $httpBackend; beforeEach(angular.mock.module('dockerui')); - beforeEach(inject(function($rootScope, $controller, _$location_) { + beforeEach(inject(function ($rootScope, $controller, _$location_) { $location = _$location_; scope = $rootScope.$new(); - createController = function() { + createController = function () { return $controller('StartContainerController', { '$scope': scope }); }; - angular.mock.inject(function(_Container_, _$httpBackend_) { + angular.mock.inject(function (_Container_, _$httpBackend_) { mockContainer = _Container_; $httpBackend = _$httpBackend_; }); @@ -34,8 +34,9 @@ describe('startContainerController', function() { 'Status': 'Up 2 minutes' }]); } - describe('Create and start a container with port bindings', function() { - it('should issue a correct create request to the Docker remote API', function() { + + describe('Create and start a container with port bindings', function () { + it('should issue a correct create request to the Docker remote API', function () { var controller = createController(); var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c'; var expectedBody = { @@ -76,8 +77,8 @@ describe('startContainerController', function() { }); }); - describe('Create and start a container with environment variables', function() { - it('should issue a correct create request to the Docker remote API', function() { + describe('Create and start a container with environment variables', function () { + it('should issue a correct create request to the Docker remote API', function () { var controller = createController(); var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c'; var expectedBody = { @@ -110,8 +111,8 @@ describe('startContainerController', function() { }); }); - describe('Create and start a container with volumesFrom', function() { - it('should issue a correct create request to the Docker remote API', function() { + describe('Create and start a container with volumesFrom', function () { + it('should issue a correct create request to the Docker remote API', function () { var controller = createController(); var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c'; var expectedBody = { @@ -133,15 +134,15 @@ describe('startContainerController', function() { }); scope.config.name = 'container-name'; - scope.config.HostConfig.VolumesFrom = [{name: 'parent'}, {name:'other:ro'}]; + scope.config.HostConfig.VolumesFrom = [{name: 'parent'}, {name: 'other:ro'}]; scope.create(); $httpBackend.flush(); }); }); - - describe('Create and start a container with multiple options', function() { - it('should issue a correct create request to the Docker remote API', function() { + + describe('Create and start a container with multiple options', function () { + it('should issue a correct create request to the Docker remote API', function () { var controller = createController(); var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c'; var expectedBody = { @@ -154,8 +155,12 @@ describe('startContainerController', function() { DnsSearch: ['example.com'], CapAdd: ['cap_sys_admin'], CapDrop: ['cap_foo_bar'], - Devices: [{ 'PathOnHost': '/dev/deviceName', 'PathInContainer': '/dev/deviceName', 'CgroupPermissions': 'mrw'}], - LxcConf: {'lxc.utsname':'docker'}, + Devices: [{ + 'PathOnHost': '/dev/deviceName', + 'PathInContainer': '/dev/deviceName', + 'CgroupPermissions': 'mrw' + }], + LxcConf: {'lxc.utsname': 'docker'}, ExtraHosts: ['hostname:127.0.0.1'], RestartPolicy: {name: 'always', MaximumRetryCount: 5} }, @@ -190,7 +195,11 @@ describe('startContainerController', function() { scope.config.HostConfig.PublishAllPorts = true; scope.config.HostConfig.Privileged = true; scope.config.HostConfig.RestartPolicy = {name: 'always', MaximumRetryCount: 5}; - scope.config.HostConfig.Devices = [{ 'PathOnHost': '/dev/deviceName', 'PathInContainer': '/dev/deviceName', 'CgroupPermissions': 'mrw'}]; + scope.config.HostConfig.Devices = [{ + 'PathOnHost': '/dev/deviceName', + 'PathInContainer': '/dev/deviceName', + 'CgroupPermissions': 'mrw' + }]; scope.config.HostConfig.LxcConf = [{name: 'lxc.utsname', value: 'docker'}]; scope.config.HostConfig.ExtraHosts = [{host: 'hostname', ip: '127.0.0.1'}]; diff --git a/test/unit/app/shared/filters.spec.js b/test/unit/app/shared/filters.spec.js index f48640783..48a0f54bc 100644 --- a/test/unit/app/shared/filters.spec.js +++ b/test/unit/app/shared/filters.spec.js @@ -2,40 +2,40 @@ describe('filters', function () { beforeEach(module('dockerui.filters')); describe('truncate', function () { - it('should truncate the string to 10 characters ending in "..." by default', inject(function(truncateFilter) { + it('should truncate the string to 10 characters ending in "..." by default', inject(function (truncateFilter) { expect(truncateFilter('this is 20 chars long')).toBe('this is...'); })); - it('should truncate the string to 7 characters ending in "..."', inject(function(truncateFilter) { + it('should truncate the string to 7 characters ending in "..."', inject(function (truncateFilter) { expect(truncateFilter('this is 20 chars long', 7)).toBe('this...'); })); - it('should truncate the string to 10 characters ending in "???"', inject(function(truncateFilter) { + it('should truncate the string to 10 characters ending in "???"', inject(function (truncateFilter) { expect(truncateFilter('this is 20 chars long', 10, '???')).toBe('this is???'); })); }); describe('statusbadge', function () { - it('should be "important" when input is "Ghost"', inject(function(statusbadgeFilter) { + it('should be "important" when input is "Ghost"', inject(function (statusbadgeFilter) { expect(statusbadgeFilter('Ghost')).toBe('important'); })); - it('should be "success" when input is "Exit 0"', inject(function(statusbadgeFilter) { + it('should be "success" when input is "Exit 0"', inject(function (statusbadgeFilter) { expect(statusbadgeFilter('Exit 0')).toBe('success'); })); - it('should be "warning" when exit code is non-zero', inject(function(statusbadgeFilter) { + it('should be "warning" when exit code is non-zero', inject(function (statusbadgeFilter) { expect(statusbadgeFilter('Exit 1')).toBe('warning'); })); }); describe('getstatetext', function () { - it('should return an empty string when state is undefined', inject(function(getstatetextFilter) { + it('should return an empty string when state is undefined', inject(function (getstatetextFilter) { expect(getstatetextFilter(undefined)).toBe(''); })); - it('should detect a Ghost state', inject(function(getstatetextFilter) { + it('should detect a Ghost state', inject(function (getstatetextFilter) { var state = { Ghost: true, Running: true, @@ -44,7 +44,7 @@ describe('filters', function () { expect(getstatetextFilter(state)).toBe('Ghost'); })); - it('should detect a Paused state', inject(function(getstatetextFilter) { + it('should detect a Paused state', inject(function (getstatetextFilter) { var state = { Ghost: false, Running: true, @@ -53,7 +53,7 @@ describe('filters', function () { expect(getstatetextFilter(state)).toBe('Running (Paused)'); })); - it('should detect a Running state', inject(function(getstatetextFilter) { + it('should detect a Running state', inject(function (getstatetextFilter) { var state = { Ghost: false, Running: true, @@ -62,7 +62,7 @@ describe('filters', function () { expect(getstatetextFilter(state)).toBe('Running'); })); - it('should detect a Stopped state', inject(function(getstatetextFilter) { + it('should detect a Stopped state', inject(function (getstatetextFilter) { var state = { Ghost: false, Running: false, @@ -73,11 +73,11 @@ describe('filters', function () { }); describe('getstatelabel', function () { - it('should return an empty string when state is undefined', inject(function(getstatelabelFilter) { + it('should return an empty string when state is undefined', inject(function (getstatelabelFilter) { expect(getstatelabelFilter(undefined)).toBe(''); })); - it('should return label-important when a ghost state is detected', inject(function(getstatelabelFilter) { + it('should return label-important when a ghost state is detected', inject(function (getstatelabelFilter) { var state = { Ghost: true, Running: true, @@ -86,7 +86,7 @@ describe('filters', function () { expect(getstatelabelFilter(state)).toBe('label-important'); })); - it('should return label-success when a running state is detected', inject(function(getstatelabelFilter) { + it('should return label-success when a running state is detected', inject(function (getstatelabelFilter) { var state = { Ghost: false, Running: true, @@ -97,33 +97,33 @@ describe('filters', function () { }); describe('humansize', function () { - it('should return n/a when size is zero', inject(function(humansizeFilter) { + it('should return n/a when size is zero', inject(function (humansizeFilter) { expect(humansizeFilter(0)).toBe('n/a'); })); - it('should handle Bytes values', inject(function(humansizeFilter) { + it('should handle Bytes values', inject(function (humansizeFilter) { expect(humansizeFilter(512)).toBe('512 Bytes'); })); - it('should handle KB values', inject(function(humansizeFilter) { + it('should handle KB values', inject(function (humansizeFilter) { expect(humansizeFilter(5120)).toBe('5 KB'); })); - it('should handle MB values', inject(function(humansizeFilter) { + it('should handle MB values', inject(function (humansizeFilter) { expect(humansizeFilter(5 * Math.pow(10, 6))).toBe('5 MB'); })); - it('should handle GB values', inject(function(humansizeFilter) { + it('should handle GB values', inject(function (humansizeFilter) { expect(humansizeFilter(5 * Math.pow(10, 9))).toBe('5 GB'); })); - it('should handle TB values', inject(function(humansizeFilter) { + it('should handle TB values', inject(function (humansizeFilter) { expect(humansizeFilter(5 * Math.pow(10, 12))).toBe('5 TB'); })); }); describe('containername', function () { - it('should strip the leading slash from container name', inject(function(containernameFilter) { + it('should strip the leading slash from container name', inject(function (containernameFilter) { var container = { Names: ['/elegant_ardinghelli'] }; @@ -133,14 +133,14 @@ describe('filters', function () { }); describe('repotag', function () { - it('should not display empty repo tag', inject(function(repotagFilter) { + it('should not display empty repo tag', inject(function (repotagFilter) { var image = { RepoTags: [':'] }; expect(repotagFilter(image)).toBe(''); })); - it('should display a normal repo tag', inject(function(repotagFilter) { + it('should display a normal repo tag', inject(function (repotagFilter) { var image = { RepoTags: ['ubuntu:latest'] }; @@ -149,17 +149,207 @@ describe('filters', function () { }); describe('getdate', function () { - it('should convert the Docker date to a human readable form', inject(function(getdateFilter) { + it('should convert the Docker date to a human readable form', inject(function (getdateFilter) { expect(getdateFilter(1420424998)).toBe('Sun Jan 04 2015'); })); }); - describe('errorMsgFilter', function() { + describe('errorMsgFilter', function () { it('should convert the $resource object to a string message', - inject(function(errorMsgFilter) { - var response = {'0':'C','1':'o','2':'n','3':'f','4':'l','5':'i','6':'c','7':'t','8':',','9':' ','10':'T','11':'h','12':'e','13':' ','14':'n','15':'a','16':'m','17':'e','18':' ','19':'u','20':'b','21':'u','22':'n','23':'t','24':'u','25':'-','26':'s','27':'l','28':'e','29':'e','30':'p','31':'-','32':'r','33':'u','34':'n','35':'t','36':'i','37':'m','38':'e','39':' ','40':'i','41':'s','42':' ','43':'a','44':'l','45':'r','46':'e','47':'a','48':'d','49':'y','50':' ','51':'a','52':'s','53':'s','54':'i','55':'g','56':'n','57':'e','58':'d','59':' ','60':'t','61':'o','62':' ','63':'b','64':'6','65':'9','66':'e','67':'5','68':'3','69':'a','70':'6','71':'2','72':'2','73':'c','74':'8','75':'.','76':' ','77':'Y','78':'o','79':'u','80':' ','81':'h','82':'a','83':'v','84':'e','85':' ','86':'t','87':'o','88':' ','89':'d','90':'e','91':'l','92':'e','93':'t','94':'e','95':' ','96':'(','97':'o','98':'r','99':' ','100':'r','101':'e','102':'n','103':'a','104':'m','105':'e','106':')','107':' ','108':'t','109':'h','110':'a','111':'t','112':' ','113':'c','114':'o','115':'n','116':'t','117':'a','118':'i','119':'n','120':'e','121':'r','122':' ','123':'t','124':'o','125':' ','126':'b','127':'e','128':' ','129':'a','130':'b','131':'l','132':'e','133':' ','134':'t','135':'o','136':' ','137':'a','138':'s','139':'s','140':'i','141':'g','142':'n','143':' ','144':'u','145':'b','146':'u','147':'n','148':'t','149':'u','150':'-','151':'s','152':'l','153':'e','154':'e','155':'p','156':'-','157':'r','158':'u','159':'n','160':'t','161':'i','162':'m','163':'e','164':' ','165':'t','166':'o','167':' ','168':'a','169':' ','170':'c','171':'o','172':'n','173':'t','174':'a','175':'i','176':'n','177':'e','178':'r','179':' ','180':'a','181':'g','182':'a','183':'i','184':'n','185':'.','186':'\n','$promise':{},'$resolved':true}; + inject(function (errorMsgFilter) { + var response = { + '0': 'C', + '1': 'o', + '2': 'n', + '3': 'f', + '4': 'l', + '5': 'i', + '6': 'c', + '7': 't', + '8': ',', + '9': ' ', + '10': 'T', + '11': 'h', + '12': 'e', + '13': ' ', + '14': 'n', + '15': 'a', + '16': 'm', + '17': 'e', + '18': ' ', + '19': 'u', + '20': 'b', + '21': 'u', + '22': 'n', + '23': 't', + '24': 'u', + '25': '-', + '26': 's', + '27': 'l', + '28': 'e', + '29': 'e', + '30': 'p', + '31': '-', + '32': 'r', + '33': 'u', + '34': 'n', + '35': 't', + '36': 'i', + '37': 'm', + '38': 'e', + '39': ' ', + '40': 'i', + '41': 's', + '42': ' ', + '43': 'a', + '44': 'l', + '45': 'r', + '46': 'e', + '47': 'a', + '48': 'd', + '49': 'y', + '50': ' ', + '51': 'a', + '52': 's', + '53': 's', + '54': 'i', + '55': 'g', + '56': 'n', + '57': 'e', + '58': 'd', + '59': ' ', + '60': 't', + '61': 'o', + '62': ' ', + '63': 'b', + '64': '6', + '65': '9', + '66': 'e', + '67': '5', + '68': '3', + '69': 'a', + '70': '6', + '71': '2', + '72': '2', + '73': 'c', + '74': '8', + '75': '.', + '76': ' ', + '77': 'Y', + '78': 'o', + '79': 'u', + '80': ' ', + '81': 'h', + '82': 'a', + '83': 'v', + '84': 'e', + '85': ' ', + '86': 't', + '87': 'o', + '88': ' ', + '89': 'd', + '90': 'e', + '91': 'l', + '92': 'e', + '93': 't', + '94': 'e', + '95': ' ', + '96': '(', + '97': 'o', + '98': 'r', + '99': ' ', + '100': 'r', + '101': 'e', + '102': 'n', + '103': 'a', + '104': 'm', + '105': 'e', + '106': ')', + '107': ' ', + '108': 't', + '109': 'h', + '110': 'a', + '111': 't', + '112': ' ', + '113': 'c', + '114': 'o', + '115': 'n', + '116': 't', + '117': 'a', + '118': 'i', + '119': 'n', + '120': 'e', + '121': 'r', + '122': ' ', + '123': 't', + '124': 'o', + '125': ' ', + '126': 'b', + '127': 'e', + '128': ' ', + '129': 'a', + '130': 'b', + '131': 'l', + '132': 'e', + '133': ' ', + '134': 't', + '135': 'o', + '136': ' ', + '137': 'a', + '138': 's', + '139': 's', + '140': 'i', + '141': 'g', + '142': 'n', + '143': ' ', + '144': 'u', + '145': 'b', + '146': 'u', + '147': 'n', + '148': 't', + '149': 'u', + '150': '-', + '151': 's', + '152': 'l', + '153': 'e', + '154': 'e', + '155': 'p', + '156': '-', + '157': 'r', + '158': 'u', + '159': 'n', + '160': 't', + '161': 'i', + '162': 'm', + '163': 'e', + '164': ' ', + '165': 't', + '166': 'o', + '167': ' ', + '168': 'a', + '169': ' ', + '170': 'c', + '171': 'o', + '172': 'n', + '173': 't', + '174': 'a', + '175': 'i', + '176': 'n', + '177': 'e', + '178': 'r', + '179': ' ', + '180': 'a', + '181': 'g', + '182': 'a', + '183': 'i', + '184': 'n', + '185': '.', + '186': '\n', + '$promise': {}, + '$resolved': true + }; var message = 'Conflict, The name ubuntu-sleep-runtime is already assigned to b69e53a622c8. You have to delete (or rename) that container to be able to assign ubuntu-sleep-runtime to a container again.\n'; expect(errorMsgFilter(response)).toBe(message); - })); + })); }); }); \ No newline at end of file diff --git a/test/unit/karma.conf.js b/test/unit/karma.conf.js index 31230fda2..805ccefca 100644 --- a/test/unit/karma.conf.js +++ b/test/unit/karma.conf.js @@ -3,19 +3,19 @@ basePath = '../..'; // list of files / patterns to load in the browser files = [ - JASMINE, - JASMINE_ADAPTER, - 'assets/js/jquery-1.11.1.min.js', - 'assets/js/jquery.gritter.min.js', - 'assets/js/bootstrap.min.js', - 'assets/js/spin.js', - 'dist/angular.js', - 'assets/js/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.min.js', - 'assets/js/angular-vis.js', - 'test/assets/angular/angular-mocks.js', - 'app/**/*.js', - 'test/unit/**/*.spec.js', - 'dist/templates/**/*.js' + JASMINE, + JASMINE_ADAPTER, + 'assets/js/jquery-1.11.1.min.js', + 'assets/js/jquery.gritter.min.js', + 'assets/js/bootstrap.min.js', + 'assets/js/spin.js', + 'dist/angular.js', + 'assets/js/ui-bootstrap/ui-bootstrap-custom-tpls-0.12.0.min.js', + 'assets/js/angular-vis.js', + 'test/assets/angular/angular-mocks.js', + 'app/**/*.js', + 'test/unit/**/*.spec.js', + 'dist/templates/**/*.js' ]; // use dots reporter, as travis terminal does not support escaping sequences