diff --git a/app/app.js b/app/app.js index b40ecdc..34aad52 100644 --- a/app/app.js +++ b/app/app.js @@ -23,7 +23,7 @@ angular.module('dockerui', [ 'network', 'networks', 'volumes']) - .config(['$routeProvider', function ($routeProvider) { + .config(['$routeProvider', '$httpProvider', function ($routeProvider, $httpProvider) { 'use strict'; $routeProvider.when('/', { templateUrl: 'app/components/dashboard/dashboard.html', @@ -67,6 +67,22 @@ angular.module('dockerui', [ controller: 'EventsController' }); $routeProvider.otherwise({redirectTo: '/'}); + + // The Docker API likes to return plaintext errors, this catches them and disp + $httpProvider.interceptors.push(function() { + return { + 'response': function(response) { + if (typeof(response.data) === 'string' && response.data.startsWith('Conflict.')) { + $.gritter.add({ + title: 'Error', + text: response.data, + time: 10000 + }); + } + return response; + } + }; + }); }]) // This is your docker url that the api will use to make requests // You need to set this to the api endpoint without the port i.e. http://192.168.1.9 diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js index 8e485ca..0859067 100644 --- a/app/components/container/containerController.js +++ b/app/components/container/containerController.js @@ -27,10 +27,12 @@ // fill up ports $scope.newCfg.Ports = {}; angular.forEach(d.Config.ExposedPorts, function(i, port) { - if (d.HostConfig.PortBindings && port in d.HostConfig.PortBindings) + if (d.HostConfig.PortBindings && port in d.HostConfig.PortBindings) { $scope.newCfg.Ports[port] = d.HostConfig.PortBindings[port]; - else + } + else { $scope.newCfg.Ports[port] = []; + } }); // fill up bindings @@ -42,9 +44,9 @@ angular.forEach(d.HostConfig.Binds, function(binding, i) { var mountpoint = binding.split(':')[0]; var vol = binding.split(':')[1] || ''; - var ro = binding.split(':').length > 2 && binding.split(':')[2] == 'ro'; + var ro = binding.split(':').length > 2 && binding.split(':')[2] === 'ro'; var defaultBind = false; - if (vol == '') { + if (vol === '') { vol = mountpoint; mountpoint = ''; } @@ -117,23 +119,24 @@ var portBindings = angular.copy($scope.newCfg.Ports); angular.forEach(portBindings, function(item, key) { - if (item.length == 0) + if (item.length === 0) { delete portBindings[key]; + } }); var binds = []; angular.forEach($scope.newCfg.Binds, function(b) { - if (b.ContPath != '') { + if (b.ContPath !== '') { var bindLine = ''; - if (b.HostPath != '') { + if (b.HostPath !== '') { bindLine = b.HostPath + ':'; } bindLine += b.ContPath; if (b.ReadOnly) { bindLine += ':ro'; } - if (b.HostPath != '' || !b.DefaultBind) { + if (b.HostPath !== '' || !b.DefaultBind) { binds.push(bindLine); } } @@ -149,7 +152,7 @@ imageData.Config.HostConfig = angular.copy($scope.container.HostConfig); imageData.Config.HostConfig.PortBindings = portBindings; imageData.Config.HostConfig.Binds = binds; - if (imageData.Config.HostConfig.NetworkMode == 'host') { + if (imageData.Config.HostConfig.NetworkMode === 'host') { imageData.Config.Hostname = ''; } @@ -196,7 +199,7 @@ }, function (e) { update(); Messages.error("Failure", "Image failed to get." + e.data); - }) + }); } else { update(); diff --git a/app/components/containers/containers.html b/app/components/containers/containers.html index d534f84..de61fee 100644 --- a/app/components/containers/containers.html +++ b/app/components/containers/containers.html @@ -25,16 +25,46 @@
Action | -Name | -Image | -Command | -Created | -Status | ++ | + + Name + + + + | ++ + Image + + + + | ++ + Command + + + + | ++ + Created + + + + | ++ + Status + + + + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{{ container|containername}} | {{ container.Image }} | diff --git a/app/components/containers/containersController.js b/app/components/containers/containersController.js index dbd8b0d..87b3015 100644 --- a/app/components/containers/containersController.js +++ b/app/components/containers/containersController.js @@ -1,10 +1,16 @@ angular.module('containers', []) .controller('ContainersController', ['$scope', 'Container', 'Settings', 'Messages', 'ViewSpinner', function ($scope, Container, Settings, Messages, ViewSpinner) { - $scope.predicate = '-Created'; + $scope.sortType = 'Created'; + $scope.sortReverse = true; $scope.toggle = false; $scope.displayAll = Settings.displayAll; + $scope.order = function(sortType) { + $scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false; + $scope.sortType = sortType; + }; + var update = function (data) { ViewSpinner.spin(); Container.query(data, function (d) { diff --git a/app/components/images/images.html b/app/components/images/images.html index 00fc2ec..3f89048 100644 --- a/app/components/images/images.html +++ b/app/components/images/images.html @@ -21,15 +21,39 @@
Action | -Id | -Repository | -VirtualSize | -Created | ++ | + + Id + + + + | ++ + Repository + + + + | ++ + VirtualSize + + + + | ++ + Created + + + + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{{ image.Id|truncate:20}} | {{ image|repotag }} | diff --git a/app/components/images/imagesController.js b/app/components/images/imagesController.js index f73a8f1..ace6cce 100644 --- a/app/components/images/imagesController.js +++ b/app/components/images/imagesController.js @@ -1,8 +1,14 @@ angular.module('images', []) .controller('ImagesController', ['$scope', 'Image', 'ViewSpinner', 'Messages', function ($scope, Image, ViewSpinner, Messages) { + $scope.sortType = 'Created'; + $scope.sortReverse = true; $scope.toggle = false; - $scope.predicate = '-Created'; + + $scope.order = function(sortType) { + $scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false; + $scope.sortType = sortType; + }; $scope.showBuilder = function () { $('#build-modal').modal('show'); diff --git a/app/components/networks/networks.html b/app/components/networks/networks.html index 6cfe2eb..138ef70 100644 --- a/app/components/networks/networks.html +++ b/app/components/networks/networks.html @@ -9,7 +9,6 @@
Select | -Name | -Id | -Scope | -Driver | -IPAM Driver | -IPAM Subnet | -IPAM Gateway | ++ | + + Name + + + + | ++ + Id + + + + | ++ + Scope + + + + | ++ + Driver + + + + | ++ + IPAM Driver + + + + | ++ + IPAM Subnet + + + + | ++ + IPAM Gateway + + + + | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{{ network.Name|truncate:20}} | {{ network.Id }} | diff --git a/app/components/networks/networksController.js b/app/components/networks/networksController.js index fa8551c..6f0f772 100644 --- a/app/components/networks/networksController.js +++ b/app/components/networks/networksController.js @@ -1,12 +1,17 @@ angular.module('networks', []).config(['$routeProvider', function ($routeProvider) { - $routeProvider.when('/networks', { + $routeProvider.when('/networks/', { templateUrl: 'app/components/networks/networks.html', controller: 'NetworksController' }); }]).controller('NetworksController', ['$scope', 'Network', 'ViewSpinner', 'Messages', '$route', 'errorMsgFilter', function ($scope, Network, ViewSpinner, Messages, $route, errorMsgFilter) { + $scope.sortType = 'Name'; + $scope.sortReverse = true; $scope.toggle = false; - $scope.predicate = '-Created'; + $scope.order = function(sortType) { + $scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false; + $scope.sortType = sortType; + }; $scope.createNetworkConfig = { "Name": '', "Driver": '', diff --git a/app/components/volumes/volumes.html b/app/components/volumes/volumes.html index af89217..d017972 100644 --- a/app/components/volumes/volumes.html +++ b/app/components/volumes/volumes.html @@ -19,14 +19,32 @@
Select | -Name | -Driver | -Mountpoint | ++ | + + Name + + + + | ++ + Driver + + + + | ++ + Mountpoint + + + + | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
{{ volume.Name|truncate:20 }} | {{ volume.Driver }} | diff --git a/app/components/volumes/volumesController.js b/app/components/volumes/volumesController.js index bed5931..6c9dd34 100644 --- a/app/components/volumes/volumesController.js +++ b/app/components/volumes/volumesController.js @@ -1,12 +1,17 @@ angular.module('volumes', []).config(['$routeProvider', function ($routeProvider) { - $routeProvider.when('/volumes', { + $routeProvider.when('/volumes/', { templateUrl: 'app/components/volumes/volumes.html', controller: 'VolumesController' }); }]).controller('VolumesController', ['$scope', 'Volume', 'ViewSpinner', 'Messages', '$route', 'errorMsgFilter', function ($scope, Volume, ViewSpinner, Messages, $route, errorMsgFilter) { + $scope.sortType = 'Name'; + $scope.sortReverse = true; $scope.toggle = false; - $scope.predicate = '-Created'; + $scope.order = function(sortType) { + $scope.sortReverse = ($scope.sortType === sortType) ? !$scope.sortReverse : false; + $scope.sortType = sortType; + }; $scope.createVolumeConfig = { "Name": "", "Driver": "" diff --git a/dist/dockerui.js b/dist/dockerui.js index 1f747ad..4026587 100644 --- a/dist/dockerui.js +++ b/dist/dockerui.js @@ -1,9 +1,9 @@ -/*! dockerui - v0.10.0-beta - 2016-03-04 +/*! dockerui - v0.10.0-beta - 2016-03-19 * https://github.com/crosbymichael/dockerui * Copyright (c) 2016 Michael Crosby & Kevan Ahlquist; * Licensed MIT */ -function ImageViewModel(a){this.Id=a.Id,this.Tag=a.Tag,this.Repository=a.Repository,this.Created=a.Created,this.Checked=!1,this.RepoTags=a.RepoTags,this.VirtualSize=a.VirtualSize}function ContainerViewModel(a){this.Id=a.Id,this.Image=a.Image,this.Command=a.Command,this.Created=a.Created,this.SizeRw=a.SizeRw,this.Status=a.Status,this.Checked=!1,this.Names=a.Names}angular.module("dockerui",["dockerui.templates","ngRoute","dockerui.services","dockerui.filters","masthead","footer","dashboard","container","containers","containersNetwork","images","image","pullImage","startContainer","sidebar","info","builder","containerLogs","containerTop","events","stats","network","networks","volumes"]).config(["$routeProvider",function(a){"use strict";a.when("/",{templateUrl:"app/components/dashboard/dashboard.html",controller:"DashboardController"}),a.when("/containers/",{templateUrl:"app/components/containers/containers.html",controller:"ContainersController"}),a.when("/containers/:id/",{templateUrl:"app/components/container/container.html",controller:"ContainerController"}),a.when("/containers/:id/logs/",{templateUrl:"app/components/containerLogs/containerlogs.html",controller:"ContainerLogsController"}),a.when("/containers/:id/top",{templateUrl:"app/components/containerTop/containerTop.html",controller:"ContainerTopController"}),a.when("/containers/:id/stats",{templateUrl:"app/components/stats/stats.html",controller:"StatsController"}),a.when("/containers_network",{templateUrl:"app/components/containersNetwork/containersNetwork.html",controller:"ContainersNetworkController"}),a.when("/images/",{templateUrl:"app/components/images/images.html",controller:"ImagesController"}),a.when("/images/:id*/",{templateUrl:"app/components/image/image.html",controller:"ImageController"}),a.when("/info",{templateUrl:"app/components/info/info.html",controller:"InfoController"}),a.when("/events",{templateUrl:"app/components/events/events.html",controller:"EventsController"}),a.otherwise({redirectTo:"/"})}]).constant("DOCKER_ENDPOINT","dockerapi").constant("DOCKER_PORT","").constant("UI_VERSION","v0.10.0-beta"),angular.module("builder",[]).controller("BuilderController",["$scope",function(a){a.template="app/components/builder/builder.html"}]),angular.module("container",[]).controller("ContainerController",["$scope","$routeParams","$location","Container","ContainerCommit","Image","Messages","ViewSpinner","$timeout",function(a,b,c,d,e,f,g,h,i){a.changes=[],a.editEnv=!1,a.editPorts=!1,a.editBinds=!1,a.newCfg={Env:[],Ports:{}};var j=function(){h.spin(),d.get({id:b.id},function(b){a.container=b,a.container.edit=!1,a.container.newContainerName=b.Name,b.Config.Env&&(a.newCfg.Env=b.Config.Env.map(function(a){return{name:a.split("=")[0],value:a.split("=")[1]}})),a.newCfg.Ports={},angular.forEach(b.Config.ExposedPorts,function(c,d){b.HostConfig.PortBindings&&d in b.HostConfig.PortBindings?a.newCfg.Ports[d]=b.HostConfig.PortBindings[d]:a.newCfg.Ports[d]=[]}),a.newCfg.Binds=[];var c={};angular.forEach(b.Config.Volumes,function(a,b){c[b]={ContPath:b,HostPath:"",ReadOnly:!1,DefaultBind:!0}}),angular.forEach(b.HostConfig.Binds,function(b,d){var e=b.split(":")[0],f=b.split(":")[1]||"",g=b.split(":").length>2&&"ro"==b.split(":")[2],h=!1;""==f&&(f=e,e=""),f in c&&(delete c[f],h=!0),a.newCfg.Binds.push({ContPath:f,HostPath:e,ReadOnly:g,DefaultBind:h})}),angular.forEach(c,function(b){a.newCfg.Binds.push(b)}),h.stop()},function(a){404===a.status?($(".detail").hide(),g.error("Not found","Container not found.")):g.error("Failure",a.data),h.stop()})};a.start=function(){h.spin(),d.start({id:a.container.Id,HostConfig:a.container.HostConfig},function(a){j(),g.send("Container started",b.id)},function(a){j(),g.error("Failure","Container failed to start."+a.data)})},a.stop=function(){h.spin(),d.stop({id:b.id},function(a){j(),g.send("Container stopped",b.id)},function(a){j(),g.error("Failure","Container failed to stop."+a.data)})},a.kill=function(){h.spin(),d.kill({id:b.id},function(a){j(),g.send("Container killed",b.id)},function(a){j(),g.error("Failure","Container failed to die."+a.data)})},a.restartEnv=function(){var i=angular.copy(a.container.Config);i.Env=a.newCfg.Env.map(function(a){return a.name+"="+a.value});var k=angular.copy(a.newCfg.Ports);angular.forEach(k,function(a,b){0==a.length&&delete k[b]});var l=[];angular.forEach(a.newCfg.Binds,function(a){if(""!=a.ContPath){var b="";""!=a.HostPath&&(b=a.HostPath+":"),b+=a.ContPath,a.ReadOnly&&(b+=":ro"),""==a.HostPath&&a.DefaultBind||l.push(b)}}),h.spin(),e.commit({id:b.id,tag:a.container.Config.Image,config:i},function(e){if("Id"in e){var h=e.Id;f.inspect({id:h},function(e){e.Config.HostConfig=angular.copy(a.container.HostConfig),e.Config.HostConfig.PortBindings=k,e.Config.HostConfig.Binds=l,"host"==e.Config.HostConfig.NetworkMode&&(e.Config.Hostname=""),d.create(e.Config,function(e){return"Id"in e?void(a.container.State.Running?d.stop({id:b.id},function(a){g.send("Container stopped",b.id),d.start({id:e.Id},function(a){c.url("/containers/"+e.Id+"/"),g.send("Container started",b.id)},function(a){j(),g.error("Failure","Container failed to start."+a.data)})},function(a){j(),g.error("Failure","Container failed to stop."+a.data)}):d.start({id:e.Id},function(a){c.url("/containers/"+e.Id+"/"),g.send("Container started",b.id)},function(a){j(),g.error("Failure","Container failed to start."+a.data)})):void g.error("Failure","Container failed to create.")},function(a){j(),g.error("Failure","Image failed to get."+a.data)})},function(a){j(),g.error("Failure","Image failed to get."+a.data)})}else j(),g.error("Failure","Container commit failed.")},function(a){j(),g.error("Failure","Container failed to commit."+a.data)})},a.commit=function(){h.spin(),e.commit({id:b.id,repo:a.container.Config.Image},function(a){j(),g.send("Container commited",b.id)},function(a){j(),g.error("Failure","Container failed to commit."+a.data)})},a.pause=function(){h.spin(),d.pause({id:b.id},function(a){j(),g.send("Container paused",b.id)},function(a){j(),g.error("Failure","Container failed to pause."+a.data)})},a.unpause=function(){h.spin(),d.unpause({id:b.id},function(a){j(),g.send("Container unpaused",b.id)},function(a){j(),g.error("Failure","Container failed to unpause."+a.data)})},a.remove=function(){h.spin(),d.remove({id:b.id},function(a){j(),c.path("/containers"),g.send("Container removed",b.id)},function(a){j(),g.error("Failure","Container failed to remove."+a.data)})},a.restart=function(){h.spin(),d.restart({id:b.id},function(a){j(),g.send("Container restarted",b.id)},function(a){j(),g.error("Failure","Container failed to restart."+a.data)})},a.hasContent=function(a){return null!==a&&void 0!==a},a.getChanges=function(){h.spin(),d.changes({id:b.id},function(b){a.changes=b,h.stop()})},a.renameContainer=function(){d.rename({id:b.id,name:a.container.newContainerName},function(c){c.name?(a.container.Name=c.name,g.send("Container renamed",b.id)):(a.container.newContainerName=a.container.Name,g.error("Failure","Container failed to rename."))}),a.container.edit=!1},a.addEntry=function(a,b){a.push(b)},a.rmEntry=function(a,b){var c=a.indexOf(b);a.splice(c,1)},a.toggleEdit=function(){a.edit=!a.edit},j(),a.getChanges()}]),angular.module("containerLogs",[]).controller("ContainerLogsController",["$scope","$routeParams","$location","$anchorScroll","ContainerLogs","Container","ViewSpinner",function(a,b,c,d,e,f,g){function h(){g.spin(),e.get(b.id,{stdout:1,stderr:0,timestamps:a.showTimestamps,tail:a.tailLines},function(b,c,d,e){b=b.replace(/[\r]/g,"\n"),b=b.substring(8),b=b.replace(/\n(.{8})/g,"\n"),a.stdout=b,g.stop()}),e.get(b.id,{stdout:0,stderr:1,timestamps:a.showTimestamps,tail:a.tailLines},function(b,c,d,e){b=b.replace(/[\r]/g,"\n"),b=b.substring(8),b=b.replace(/\n(.{8})/g,"\n"),a.stderr=b,g.stop()})}a.stdout="",a.stderr="",a.showTimestamps=!1,a.tailLines=2e3,g.spin(),f.get({id:b.id},function(b){a.container=b,g.stop()},function(a){404===a.status?Messages.error("Not found","Container not found."):Messages.error("Failure",a.data),g.stop()}),h();var i=window.setInterval(h,5e3);a.$on("$destroy",function(){clearInterval(i)}),a.scrollTo=function(a){c.hash(a),d()},a.toggleTimestamps=function(){h()},a.toggleTail=function(){h()}}]),angular.module("containerTop",[]).controller("ContainerTopController",["$scope","$routeParams","ContainerTop","Container","ViewSpinner",function(a,b,c,d,e){a.ps_args="",a.getTop=function(){e.spin(),c.get(b.id,{ps_args:a.ps_args},function(b){a.containerTop=b,e.stop()})},d.get({id:b.id},function(b){a.containerName=b.Name.substring(1)},function(a){Messages.error("Failure",a.data)}),a.getTop()}]),angular.module("containers",[]).controller("ContainersController",["$scope","Container","Settings","Messages","ViewSpinner",function(a,b,c,d,e){a.predicate="-Created",a.toggle=!1,a.displayAll=c.displayAll;var f=function(c){e.spin(),b.query(c,function(b){a.containers=b.map(function(a){return new ContainerViewModel(a)}),e.stop()})},g=function(g,h,i){e.spin();var j=0,k=function(){j-=1,0===j&&(e.stop(),f({all:c.displayAll?1:0}))};angular.forEach(g,function(c){c.Checked&&(h===b.start?b.get({id:c.Id},function(b){c=b,j+=1,h({id:c.Id,HostConfig:c.HostConfig||{}},function(b){d.send("Container "+i,c.Id);a.containers.indexOf(c);k()},function(a){d.error("Failure",a.data),k()})},function(a){404===a.status?($(".detail").hide(),d.error("Not found","Container not found.")):d.error("Failure",a.data),k()}):(j+=1,h({id:c.Id},function(b){d.send("Container "+i,c.Id);a.containers.indexOf(c);k()},function(a){d.error("Failure",a.data),k()})))}),0===j&&e.stop()};a.toggleSelectAll=function(){angular.forEach(a.containers,function(b){b.Checked=a.toggle})},a.toggleGetAll=function(){c.displayAll=a.displayAll,f({all:c.displayAll?1:0})},a.startAction=function(){g(a.containers,b.start,"Started")},a.stopAction=function(){g(a.containers,b.stop,"Stopped")},a.restartAction=function(){g(a.containers,b.restart,"Restarted")},a.killAction=function(){g(a.containers,b.kill,"Killed")},a.pauseAction=function(){g(a.containers,b.pause,"Paused")},a.unpauseAction=function(){g(a.containers,b.unpause,"Unpaused")},a.removeAction=function(){g(a.containers,b.remove,"Removed")},f({all:c.displayAll?1:0})}]),angular.module("containersNetwork",["ngVis"]).controller("ContainersNetworkController",["$scope","$location","Container","Messages","VisDataSet",function(a,b,c,d,f){function g(a){this.Id=a.Id,this.Name=a.Name.substring(1),this.Image=a.Config.Image,this.Running=a.State.Running;var b=a.HostConfig.Links;if(null!=b){this.Links={};for(var c=0;c
Created: | \n{{ container.Created | date: \'medium\' }} | \n||||
Path: | \n{{ container.Path }} | \n||||
Args: | \n\n {{ container.Args.join(\' \') || \'None\' }}\n | \n ||||
Exposed Ports: | \n\n
| \n ||||
Environment: | \n\n \n \n \n
\n \n\n \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n | \n ||||
Labels: | \n\n
| \n ||||
Publish All: | \n{{ container.HostConfig.PublishAllPorts }} | \n||||
Ports: | \n\n \n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n | \n\n ||||
Hostname: | \n{{ container.Config.Hostname }} | \n||||
IPAddress: | \n{{ container.NetworkSettings.IPAddress }} | \n||||
Cmd: | \n{{ container.Config.Cmd }} | \n||||
Entrypoint: | \n\n {{ container.Config.Entrypoint.join(\' \') }}\n | \n ||||
Bindings: | \n\n \n \n\n \n
\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n | \n ||||
Volumes: | \n{{ container.Volumes }} | \n||||
SysInitpath: | \n{{ container.SysInitPath }} | \n||||
Image: | \n{{ container.Image }} | \n||||
State: | \n\n
| \n ||||
Logs: | \nstdout/stderr | \n||||
Stats: | \nstats | \n||||
Top: | \nTop | \n
{{stdout}}\n
{{stderr}}\n
{{title}} | \n
---|
{{processInfo}} | \n
Action | \nName | \nImage | \nCommand | \nCreated | \nStatus | \n
---|---|---|---|---|---|
\n | {{ container|containername}} | \n{{ container.Image }} | \n{{ container.Command|truncate:40 }} | \n{{ container.Created|getdate }} | \n{{ container.Status }} | \n
Event | \nFrom | \nID | \nTime | \n
---|---|---|---|
\n | \n | \n | \n |
Tags: | \n\n
| \n
Created: | \n{{ image.Created | date: \'medium\'}} | \n
Parent: | \n{{ image.Parent }} | \n
Size (Virtual Size): | \n{{ image.Size|humansize }} ({{ image.VirtualSize|humansize }}) | \n
Hostname: | \n{{ image.ContainerConfig.Hostname }} | \n
User: | \n{{ image.ContainerConfig.User }} | \n
Cmd: | \n{{ image.ContainerConfig.Cmd }} | \n
Volumes: | \n{{ image.ContainerConfig.Volumes }} | \n
Volumes from: | \n{{ image.ContainerConfig.VolumesFrom }} | \n
Built with: | \nDocker {{ image.DockerVersion }} on {{ image.Os}}, {{ image.Architecture }} | \n
Action | \nId | \nRepository | \nVirtualSize | \nCreated | \n
---|---|---|---|---|
\n | {{ image.Id|truncate:20}} | \n{{ image|repotag }} | \n{{ image.VirtualSize|humansize }} | \n{{ image.Created|getdate }} | \n
\n API Endpoint: {{ endpoint }}
\n API Version: {{ docker.ApiVersion }}
\n Docker version: {{ docker.Version }}
\n Git Commit: {{ docker.GitCommit }}
\n Go Version: {{ docker.GoVersion }}
\n
Containers: | \n{{ info.Containers }} | \n
Images: | \n{{ info.Images }} | \n
Debug: | \n{{ info.Debug }} | \n
CPUs: | \n{{ info.NCPU }} | \n
Total Memory: | \n{{ info.MemTotal|humansize }} | \n
Operating System: | \n{{ info.OperatingSystem }} | \n
Kernel Version: | \n{{ info.KernelVersion }} | \n
ID: | \n{{ info.ID }} | \n
Labels: | \n{{ info.Labels }} | \n
File Descriptors: | \n{{ info.NFd }} | \n
Goroutines: | \n{{ info.NGoroutines }} | \n
Storage Driver: | \n{{ info.Driver }} | \n
Storage Driver Status: | \n\n \n {{ val[0] }}: {{ val[1] }}\n \n | \n
Execution Driver: | \n{{ info.ExecutionDriver }} | \n
Events: | \nEvents | \n
IPv4 Forwarding: | \n{{ info.IPv4Forwarding }} | \n
Index Server Address: | \n{{ info.IndexServerAddress }} | \n
Init Path: | \n{{ info.InitPath }} | \n
Docker Root Directory: | \n{{ info.DockerRootDir }} | \n
Init SHA1 | \n{{ info.InitSha1 }} | \n
Memory Limit: | \n{{ info.MemoryLimit }} | \n
Swap Limit: | \n{{ info.SwapLimit }} | \n
Name: | \n{{ network.Name }} | \n|||||||||||
Id: | \n{{ network.Id }} | \n|||||||||||
Scope: | \n{{ network.Scope }} | \n|||||||||||
Driver: | \n{{ network.Driver }} | \n|||||||||||
IPAM: | \n\n
| \n |||||||||||
Containers: | \n\n
| \n |||||||||||
Options: | \n\n
| \n
Select | \nName | \nId | \nScope | \nDriver | \nIPAM Driver | \nIPAM Subnet | \nIPAM Gateway | \n
---|---|---|---|---|---|---|---|
\n | {{ network.Name|truncate:20}} | \n{{ network.Id }} | \n{{ network.Scope }} | \n{{ network.Driver }} | \n{{ network.IPAM.Driver }} | \n{{ network.IPAM.Config[0].Subnet }} | \n{{ network.IPAM.Config[0].Gateway }} | \n
Max usage | \n{{ data.memory_stats.max_usage | humansize }} | \n
Limit | \n{{ data.memory_stats.limit | humansize }} | \n
Fail count | \n{{ data.memory_stats.failcnt }} | \n
{{ key }} | \n{{ value }} | \n
{{ key }} | \n{{ value }} | \n
Select | \nName | \nDriver | \nMountpoint | \n
---|---|---|---|
\n | {{ volume.Name|truncate:20 }} | \n{{ volume.Driver }} | \n{{ volume.Mountpoint }} | \n
Created: | \n{{ container.Created | date: \'medium\' }} | \n||||
Path: | \n{{ container.Path }} | \n||||
Args: | \n\n {{ container.Args.join(\' \') || \'None\' }}\n | \n ||||
Exposed Ports: | \n\n
| \n ||||
Environment: | \n\n \n \n \n
\n \n\n \n\n\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n | \n ||||
Labels: | \n\n
| \n ||||
Publish All: | \n{{ container.HostConfig.PublishAllPorts }} | \n||||
Ports: | \n\n \n \n \n
\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n | \n\n ||||
Hostname: | \n{{ container.Config.Hostname }} | \n||||
IPAddress: | \n{{ container.NetworkSettings.IPAddress }} | \n||||
Cmd: | \n{{ container.Config.Cmd }} | \n||||
Entrypoint: | \n\n {{ container.Config.Entrypoint.join(\' \') }}\n | \n ||||
Bindings: | \n\n \n \n\n \n
\n \n \n \n \n \n\n \n \n \n \n \n \n \n \n \n \n \n \n | \n ||||
Volumes: | \n{{ container.Volumes }} | \n||||
SysInitpath: | \n{{ container.SysInitPath }} | \n||||
Image: | \n{{ container.Image }} | \n||||
State: | \n\n
| \n ||||
Logs: | \nstdout/stderr | \n||||
Stats: | \nstats | \n||||
Top: | \nTop | \n
{{stdout}}\n
{{stderr}}\n
{{title}} | \n
---|
{{processInfo}} | \n
\n | \n \n Name\n \n \n \n | \n\n \n Image\n \n \n \n | \n\n \n Command\n \n \n \n | \n\n \n Created\n \n \n \n | \n\n \n Status\n \n \n \n | \n
---|---|---|---|---|---|
\n | {{ container|containername}} | \n{{ container.Image }} | \n{{ container.Command|truncate:40 }} | \n{{ container.Created|getdate }} | \n{{ container.Status }} | \n
Event | \nFrom | \nID | \nTime | \n
---|---|---|---|
\n | \n | \n | \n |
Tags: | \n\n
| \n
Created: | \n{{ image.Created | date: \'medium\'}} | \n
Parent: | \n{{ image.Parent }} | \n
Size (Virtual Size): | \n{{ image.Size|humansize }} ({{ image.VirtualSize|humansize }}) | \n
Hostname: | \n{{ image.ContainerConfig.Hostname }} | \n
User: | \n{{ image.ContainerConfig.User }} | \n
Cmd: | \n{{ image.ContainerConfig.Cmd }} | \n
Volumes: | \n{{ image.ContainerConfig.Volumes }} | \n
Volumes from: | \n{{ image.ContainerConfig.VolumesFrom }} | \n
Built with: | \nDocker {{ image.DockerVersion }} on {{ image.Os}}, {{ image.Architecture }} | \n
\n | \n \n Id\n \n \n \n | \n\n \n Repository\n \n \n \n | \n\n \n VirtualSize\n \n \n \n | \n\n \n Created\n \n \n \n | \n
---|---|---|---|---|
\n | {{ image.Id|truncate:20}} | \n{{ image|repotag }} | \n{{ image.VirtualSize|humansize }} | \n{{ image.Created|getdate }} | \n
\n API Endpoint: {{ endpoint }}
\n API Version: {{ docker.ApiVersion }}
\n Docker version: {{ docker.Version }}
\n Git Commit: {{ docker.GitCommit }}
\n Go Version: {{ docker.GoVersion }}
\n
Containers: | \n{{ info.Containers }} | \n
Images: | \n{{ info.Images }} | \n
Debug: | \n{{ info.Debug }} | \n
CPUs: | \n{{ info.NCPU }} | \n
Total Memory: | \n{{ info.MemTotal|humansize }} | \n
Operating System: | \n{{ info.OperatingSystem }} | \n
Kernel Version: | \n{{ info.KernelVersion }} | \n
ID: | \n{{ info.ID }} | \n
Labels: | \n{{ info.Labels }} | \n
File Descriptors: | \n{{ info.NFd }} | \n
Goroutines: | \n{{ info.NGoroutines }} | \n
Storage Driver: | \n{{ info.Driver }} | \n
Storage Driver Status: | \n\n \n {{ val[0] }}: {{ val[1] }}\n \n | \n
Execution Driver: | \n{{ info.ExecutionDriver }} | \n
Events: | \nEvents | \n
IPv4 Forwarding: | \n{{ info.IPv4Forwarding }} | \n
Index Server Address: | \n{{ info.IndexServerAddress }} | \n
Init Path: | \n{{ info.InitPath }} | \n
Docker Root Directory: | \n{{ info.DockerRootDir }} | \n
Init SHA1 | \n{{ info.InitSha1 }} | \n
Memory Limit: | \n{{ info.MemoryLimit }} | \n
Swap Limit: | \n{{ info.SwapLimit }} | \n
Name: | \n{{ network.Name }} | \n|||||||||||
Id: | \n{{ network.Id }} | \n|||||||||||
Scope: | \n{{ network.Scope }} | \n|||||||||||
Driver: | \n{{ network.Driver }} | \n|||||||||||
IPAM: | \n\n
| \n |||||||||||
Containers: | \n\n
| \n |||||||||||
Options: | \n\n
| \n
\n | \n \n Name\n \n \n \n | \n\n \n Id\n \n \n \n | \n\n \n Scope\n \n \n \n | \n\n \n Driver\n \n \n \n | \n\n \n IPAM Driver\n \n \n \n | \n\n \n IPAM Subnet\n \n \n \n | \n\n \n IPAM Gateway\n \n \n \n | \n
---|---|---|---|---|---|---|---|
\n | {{ network.Name|truncate:20}} | \n{{ network.Id }} | \n{{ network.Scope }} | \n{{ network.Driver }} | \n{{ network.IPAM.Driver }} | \n{{ network.IPAM.Config[0].Subnet }} | \n{{ network.IPAM.Config[0].Gateway }} | \n
Max usage | \n{{ data.memory_stats.max_usage | humansize }} | \n
Limit | \n{{ data.memory_stats.limit | humansize }} | \n
Fail count | \n{{ data.memory_stats.failcnt }} | \n
{{ key }} | \n{{ value }} | \n
{{ key }} | \n{{ value }} | \n
\n | \n \n Name\n \n \n \n | \n\n \n Driver\n \n \n \n | \n\n \n Mountpoint\n \n \n \n | \n
---|---|---|---|
\n | {{ volume.Name|truncate:20 }} | \n{{ volume.Driver }} | \n{{ volume.Mountpoint }} | \n