diff --git a/app/components/container/container.html b/app/components/container/container.html index ee9bd26..6617f50 100644 --- a/app/components/container/container.html +++ b/app/components/container/container.html @@ -54,7 +54,7 @@

Created: - {{ container.Created }} + {{ container.Created | date: 'medium' }} Path: @@ -62,7 +62,9 @@

Args: - {{ container.Args }} + +
{{ container.Args.join(' ') || 'None' }}
+ Exposed Ports: @@ -80,6 +82,21 @@

+ + Labels: + + + + + + + + + + +
KeyValue
{{ k }}{{ v }}
+ + Publish All: @@ -110,7 +127,9 @@

Entrypoint: - {{ container.Config.Entrypoint }} + +
{{ container.Config.Entrypoint.join(' ') }}
+ Volumes: @@ -127,7 +146,15 @@

State: - {{ container.State|getstatetext }} + + + +
    +
  • {{key}} : {{ val }}
  • +
+
+
+ Logs: diff --git a/app/components/image/image.html b/app/components/image/image.html index 5390e6c..da77ead 100644 --- a/app/components/image/image.html +++ b/app/components/image/image.html @@ -6,10 +6,10 @@
-

Image: {{ tag }}

+

Image: {{ id }}

- +
@@ -22,9 +22,19 @@

Containers created:

+ + + + - + @@ -89,14 +99,15 @@

Containers created:

Tag image
- + +
- + @@ -104,6 +115,6 @@

Containers created:


- +
diff --git a/app/components/image/imageController.js b/app/components/image/imageController.js index 5228cda..2bae9d3 100644 --- a/app/components/image/imageController.js +++ b/app/components/image/imageController.js @@ -2,11 +2,22 @@ angular.module('image', []) .controller('ImageController', ['$scope', '$q', '$routeParams', '$location', 'Image', 'Container', 'Messages', 'LineChart', function ($scope, $q, $routeParams, $location, Image, Container, Messages, LineChart) { $scope.history = []; - $scope.tag = {repo: '', force: false}; + $scope.tagInfo = {repo: '', version: '', force: false}; + $scope.id = ''; + $scope.repoTags = []; - $scope.remove = function () { - Image.remove({id: $routeParams.id}, function (d) { - Messages.send("Image Removed", $routeParams.id); + $scope.removeImage = function (id) { + Image.remove({id: id}, function (d) { + d.forEach(function(msg){ + var key = Object.keys(msg)[0]; + Messages.send(key, msg[key]); + }); + // If last message key is 'Deleted' then assume the image is gone and send to images page + if (d[d.length-1].Deleted) { + $location.path('/images'); + } else { + $location.path('/images/' + $scope.id); // Refresh the current page. + } }, function (e) { $scope.error = e.data; $('#error-message').show(); @@ -19,24 +30,30 @@ angular.module('image', []) }); }; - $scope.updateTag = function () { - var tag = $scope.tag; - Image.tag({id: $routeParams.id, repo: tag.repo, force: tag.force ? 1 : 0}, function (d) { + $scope.addTag = function () { + var tag = $scope.tagInfo; + Image.tag({ + id: $routeParams.id, + repo: tag.repo, + tag: tag.version, + force: tag.force ? 1 : 0 + }, function (d) { Messages.send("Tag Added", $routeParams.id); + $location.path('/images/' + $scope.id); }, function (e) { $scope.error = e.data; $('#error-message').show(); }); }; - function getContainersFromImage($q, Container, tag) { + function getContainersFromImage($q, Container, imageId) { var defer = $q.defer(); Container.query({all: 1, notruc: 1}, function (d) { var containers = []; for (var i = 0; i < d.length; i++) { var c = d[i]; - if (c.Image === tag) { + if (c.ImageID === imageId) { containers.push(new ContainerViewModel(c)); } } @@ -48,18 +65,14 @@ angular.module('image', []) Image.get({id: $routeParams.id}, function (d) { $scope.image = d; - $scope.tag = d.id; - var t = $routeParams.tag; - if (t && t !== ":") { - $scope.tag = t; - var promise = getContainersFromImage($q, Container, t); + $scope.id = d.Id; + $scope.RepoTags = d.RepoTags; - promise.then(function (containers) { - LineChart.build('#containers-started-chart', containers, function (c) { - return new Date(c.Created * 1000).toLocaleDateString(); - }); + getContainersFromImage($q, Container, $scope.id).then(function (containers) { + LineChart.build('#containers-started-chart', containers, function (c) { + return new Date(c.Created * 1000).toLocaleDateString(); }); - } + }); }, function (e) { if (e.status === 404) { $('.detail').hide(); diff --git a/app/components/startContainer/startContainerController.js b/app/components/startContainer/startContainerController.js index 46d8ba7..354d2d6 100644 --- a/app/components/startContainer/startContainerController.js +++ b/app/components/startContainer/startContainerController.js @@ -11,6 +11,7 @@ angular.module('startContainer', ['ui.bootstrap']) $scope.config = { Env: [], + Labels: [], Volumes: [], SecurityOpts: [], HostConfig: { @@ -66,6 +67,11 @@ angular.module('startContainer', ['ui.bootstrap']) config.Env = config.Env.map(function (envar) { return envar.name + '=' + envar.value; }); + var labels = {}; + config.Labels = config.Labels.forEach(function(label) { + labels[label.key] = label.value; + }); + config.Labels = labels; config.Volumes = getNames(config.Volumes); config.SecurityOpts = getNames(config.SecurityOpts); diff --git a/app/components/startContainer/startcontainer.html b/app/components/startContainer/startcontainer.html index 1164729..26b3f17 100644 --- a/app/components/startContainer/startcontainer.html +++ b/app/components/startContainer/startcontainer.html @@ -148,6 +148,32 @@

Create And Start Container From Image

variable +
+ + +
+
+
+ + +
+
+ + +
+
+ +
+
+
+ +
diff --git a/app/shared/filters.js b/app/shared/filters.js index d4f18e2..894d754 100644 --- a/app/shared/filters.js +++ b/app/shared/filters.js @@ -51,7 +51,7 @@ angular.module('dockerui.filters', []) 'use strict'; return function (state) { if (state === undefined) { - return ''; + return 'label-default'; } if (state.Ghost && state.Running) { @@ -60,7 +60,7 @@ angular.module('dockerui.filters', []) if (state.Running) { return 'label-success'; } - return ''; + return 'label-default'; }; }) .filter('humansize', function () { diff --git a/app/shared/services.js b/app/shared/services.js index b947517..780726f 100644 --- a/app/shared/services.js +++ b/app/shared/services.js @@ -91,7 +91,7 @@ angular.module('dockerui.services', ['ngResource']) }, 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'}}, + tag: {method: 'POST', params: {id: '@id', action: 'tag', force: 0, repo: '@repo', tag: '@tag'}}, remove: {method: 'DELETE', params: {id: '@id'}, isArray: true} }); }]) diff --git a/dist/dockerui.js b/dist/dockerui.js index a75c110..d367d21 100644 --- a/dist/dockerui.js +++ b/dist/dockerui.js @@ -1,8 +1,8 @@ -/*! dockerui - v0.8.0 - 2015-11-26 +/*! dockerui - v0.8.0 - 2015-12-06 * https://github.com/crosbymichael/dockerui * Copyright (c) 2015 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"]).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.8.0").constant("DOCKER_API_VERSION","v1.20"),angular.module("builder",[]).controller("BuilderController",["$scope","Dockerfile","Messages",function(a,b,c){a.template="app/components/builder/builder.html"}]),angular.module("container",[]).controller("ContainerController",["$scope","$routeParams","$location","Container","ContainerCommit","Messages","ViewSpinner",function(a,b,c,d,e,f,g){a.changes=[],a.edit=!1;var h=function(){g.spin(),d.get({id:b.id},function(b){a.container=b,a.container.edit=!1,a.container.newContainerName=b.Name,g.stop()},function(a){404===a.status?($(".detail").hide(),f.error("Not found","Container not found.")):f.error("Failure",a.data),g.stop()})};a.start=function(){g.spin(),d.start({id:a.container.Id,HostConfig:a.container.HostConfig},function(a){h(),f.send("Container started",b.id)},function(a){h(),f.error("Failure","Container failed to start."+a.data)})},a.stop=function(){g.spin(),d.stop({id:b.id},function(a){h(),f.send("Container stopped",b.id)},function(a){h(),f.error("Failure","Container failed to stop."+a.data)})},a.kill=function(){g.spin(),d.kill({id:b.id},function(a){h(),f.send("Container killed",b.id)},function(a){h(),f.error("Failure","Container failed to die."+a.data)})},a.commit=function(){g.spin(),e.commit({id:b.id,repo:a.container.Config.Image},function(a){h(),f.send("Container commited",b.id)},function(a){h(),f.error("Failure","Container failed to commit."+a.data)})},a.pause=function(){g.spin(),d.pause({id:b.id},function(a){h(),f.send("Container paused",b.id)},function(a){h(),f.error("Failure","Container failed to pause."+a.data)})},a.unpause=function(){g.spin(),d.unpause({id:b.id},function(a){h(),f.send("Container unpaused",b.id)},function(a){h(),f.error("Failure","Container failed to unpause."+a.data)})},a.remove=function(){g.spin(),d.remove({id:b.id},function(a){h(),f.send("Container removed",b.id)},function(a){h(),f.error("Failure","Container failed to remove."+a.data)})},a.restart=function(){g.spin(),d.restart({id:b.id},function(a){h(),f.send("Container restarted",b.id)},function(a){h(),f.error("Failure","Container failed to restart."+a.data)})},a.hasContent=function(a){return null!==a&&void 0!==a},a.getChanges=function(){g.spin(),d.changes({id:b.id},function(b){a.changes=b,g.stop()})},a.renameContainer=function(){d.rename({id:b.id,name:a.container.newContainerName},function(c){c.name?(a.container.Name=c.name,f.send("Container renamed",b.id)):(a.container.newContainerName=a.container.Name,f.error("Failure","Container failed to rename."))}),a.container.edit=!1},h(),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","ViewSpinner",function(a,b,c,d){a.ps_args="",a.getTop=function(){d.spin(),c.get(b.id,{ps_args:a.ps_args},function(b){a.containerTop=b,d.stop()})},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
  • ID: '+a.Id+"
  • Image: "+a.Image+"
  • ",color:a.Running?"#8888ff":"#cccccc"})},this.hasEdge=function(a,b){return this.edges.getIds({filter:function(c){return c.from===a.Id&&c.to===b.Id}}).length>0},this.addLinkEdgeIfExists=function(a,b){null==a.Links||null==a.Links[b.Name]||this.hasEdge(a,b)||this.edges.add({from:a.Id,to:b.Id,label:a.Links[b.Name]})},this.addVolumeEdgeIfExists=function(a,b){null==a.VolumesFrom||null==a.VolumesFrom[b.Id]&&null==a.VolumesFrom[b.Name]||this.hasEdge(a,b)||this.edges.add({from:a.Id,to:b.Id,color:{color:"#A0A0A0",highlight:"#A0A0A0",hover:"#848484"}})},this.removeContainersNodes=function(a){this.nodes.remove(a)}}function i(){this.data=new h,this.containers={},this.selectedContainersIds=[],this.shownContainersIds=[],this.events={select:function(b){a.network.selectedContainersIds=b.nodes,a.$apply(function(){a.query=""})},doubleClick:function(c){a.$apply(function(){b.path("/containers/"+c.nodes[0])})}},this.options={navigation:!0,keyboard:!0,height:"500px",width:"700px",nodes:{shape:"box"},edges:{style:"arrow"},physics:{barnesHut:{springLength:200}}},this.addContainer=function(a){var b=new g(a);this.containers[b.Id]=b,this.shownContainersIds.push(b.Id),this.data.addContainerNode(b);for(var c in this.containers){var d=this.containers[c];this.data.addLinkEdgeIfExists(b,d),this.data.addLinkEdgeIfExists(d,b),this.data.addVolumeEdgeIfExists(b,d),this.data.addVolumeEdgeIfExists(d,b)}},this.selectContainers=function(a){null!=this.component&&(this.selectedContainersIds=this.searchContainers(a),this.component.selectNodes(this.selectedContainersIds))},this.searchContainers=function(a){if(""===a.trim())return[];for(var b=[],c=0;c-1||d.Image.indexOf(a)>-1||d.Id.indexOf(a)>-1)&&b.push(d.Id)}return b},this.hideSelected=function(){for(var b=0;b-1?this.shownContainersIds.splice(b,1):b++;this.data.removeContainersNodes(this.selectedContainersIds),a.query="",this.selectedContainersIds=[]},this.searchDownstream=function(a,b){if(!(b.indexOf(a)>-1)){b.push(a);var c=this.containers[a];if(null!=c.Links||null!=c.VolumesFrom)for(var d in this.containers){var e=this.containers[d];null!=c.Links&&null!=c.Links[e.Name]?this.searchDownstream(e.Id,b):null!=c.VolumesFrom&&null!=c.VolumesFrom[e.Id]&&this.searchDownstream(e.Id,b)}}},this.updateShownContainers=function(a){for(var b in this.containers)a.indexOf(b)>-1&&-1===this.shownContainersIds.indexOf(b)?this.data.addContainerNode(this.containers[b]):-1===a.indexOf(b)&&this.shownContainersIds.indexOf(b)>-1&&this.data.removeContainersNodes(b);this.shownContainersIds=a},this.showSelectedDownstream=function(){for(var a=[],b=0;b-1)){b.push(a);var c=this.containers[a];for(var d in this.containers){var e=this.containers[d];null!=e.Links&&null!=e.Links[c.Name]?this.searchUpstream(e.Id,b):null!=e.VolumesFrom&&null!=e.VolumesFrom[c.Id]&&this.searchUpstream(e.Id,b)}}},this.showSelectedUpstream=function(){for(var a=[],b=0;b"+c.id):a.error=b.data,$("#error-message").show()}),a.getHistory()}]),angular.module("images",[]).controller("ImagesController",["$scope","Image","ViewSpinner","Messages",function(a,b,c,d){a.toggle=!1,a.predicate="-Created",a.showBuilder=function(){$("#build-modal").modal("show")},a.removeAction=function(){c.spin();var e=0,f=function(){e-=1,0===e&&c.stop()};angular.forEach(a.images,function(c){c.Checked&&(e+=1,b.remove({id:c.Id},function(b){angular.forEach(b,function(a){d.send("Image deleted",a.Deleted)});var e=a.images.indexOf(c);a.images.splice(e,1),f()},function(a){d.error("Failure",a.data),f()}))})},a.toggleSelectAll=function(){angular.forEach(a.images,function(b){b.Checked=a.toggle})},c.spin(),b.query({},function(b){a.images=b.map(function(a){return new ImageViewModel(a)}),c.stop()},function(a){d.error("Failure",a.data),c.stop()})}]),angular.module("info",[]).controller("InfoController",["$scope","System","Docker","Settings","Messages",function(a,b,c,d,e){a.info={},a.docker={},a.endpoint=d.endpoint,a.apiVersion=d.version,c.get({},function(b){a.docker=b}),b.get({},function(b){a.info=b})}]),angular.module("masthead",[]).controller("MastheadController",["$scope",function(a){a.template="app/components/masthead/masthead.html"}]),angular.module("pullImage",[]).controller("PullImageController",["$scope","$log","Dockerfile","Messages","Image","ViewSpinner",function(a,b,c,d,e,f){a.template="app/components/pullImage/pullImage.html",a.init=function(){a.config={registry:"",repo:"",fromImage:"",tag:"latest"}},a.init(),a.pull=function(){$("#error-message").hide();var b=angular.copy(a.config),c=(b.registry?b.registry+"/":"")+(b.repo?b.repo+"/":"")+b.fromImage+(b.tag?":"+b.tag:"");f.spin(),$("#pull-modal").modal("hide"),e.create(b,function(b){if(f.stop(),b.constructor===Array){var e=b.length>0&&b[b.length-1].hasOwnProperty("error");if(e){var g=b[b.length-1];a.error="Cannot pull image "+c+" Reason: "+g.error,$("#pull-modal").modal("show"),$("#error-message").show()}else d.send("Image Added",c),a.init()}else d.send("Image Added",c),a.init()},function(b){f.stop(),a.error="Cannot pull image "+c+" Reason: "+b.data,$("#pull-modal").modal("show"),$("#error-message").show()})}}]),angular.module("sidebar",[]).controller("SideBarController",["$scope","Container","Settings",function(a,b,c){a.template="partials/sidebar.html",a.containers=[],a.endpoint=c.endpoint,b.query({all:0},function(b){a.containers=b})}]),angular.module("startContainer",["ui.bootstrap"]).controller("StartContainerController",["$scope","$routeParams","$location","Container","Messages","containernameFilter","errorMsgFilter",function(a,b,c,d,e,f,g){function h(a,b){b.error("Error",g(a))}function i(a){for(var b in a)(null===a[b]||void 0===a[b]||""===a[b]||$.isEmptyObject(a[b])||0===a[b].length)&&delete a[b]}function j(a){return a.map(function(a){return a.name})}a.template="app/components/startContainer/startcontainer.html",d.query({all:1},function(b){a.containerNames=b.map(function(a){return f(a)})}),a.config={Env:[],Volumes:[],SecurityOpts:[],HostConfig:{PortBindings:[],Binds:[],Links:[],Dns:[],DnsSearch:[],VolumesFrom:[],CapAdd:[],CapDrop:[],Devices:[],LxcConf:[],ExtraHosts:[]}},a.menuStatus={containerOpen:!0,hostConfigOpen:!1},a.create=function(){var f=angular.copy(a.config);f.Image=b.id,f.Cmd&&"["===f.Cmd[0]?f.Cmd=angular.fromJson(f.Cmd):f.Cmd&&(f.Cmd=f.Cmd.split(" ")),f.Env=f.Env.map(function(a){return a.name+"="+a.value}),f.Volumes=j(f.Volumes),f.SecurityOpts=j(f.SecurityOpts),f.HostConfig.VolumesFrom=j(f.HostConfig.VolumesFrom),f.HostConfig.Binds=j(f.HostConfig.Binds),f.HostConfig.Links=j(f.HostConfig.Links),f.HostConfig.Dns=j(f.HostConfig.Dns),f.HostConfig.DnsSearch=j(f.HostConfig.DnsSearch),f.HostConfig.CapAdd=j(f.HostConfig.CapAdd),f.HostConfig.CapDrop=j(f.HostConfig.CapDrop),f.HostConfig.LxcConf=f.HostConfig.LxcConf.reduce(function(a,b,c){return a[b.name]=b.value,a},{}),f.HostConfig.ExtraHosts=f.HostConfig.ExtraHosts.map(function(a){return a.host+":"+a.ip});var g={},k={};f.HostConfig.PortBindings.forEach(function(a){var b=a.intPort+"/tcp";"udp"===a.protocol&&(b=a.intPort+"/udp");var c={HostIp:a.ip,HostPort:a.extPort};a.intPort?(g[b]={},b in k?k[b].push(c):k[b]=[c]):e.send("Warning","Internal port must be specified for PortBindings")}),f.ExposedPorts=g,f.HostConfig.PortBindings=k,i(f.HostConfig),i(f);var l=d,m=c;d.create(f,function(a){if(a.Id){var b=f.HostConfig||{};b.id=a.Id,l.start(b,function(b){b.id?(e.send("Container Started",a.Id),$("#create-modal").modal("hide"),m.path("/containers/"+a.Id+"/")):(h(b,e),l.remove({id:a.Id},function(){e.send("Container Removed",a.Id)}))},function(a){h(a,e)})}else h(a,e)},function(a){h(a,e)})},a.addEntry=function(a,b){a.push(b)},a.rmEntry=function(a,b){var c=a.indexOf(b);a.splice(c,1)}}]),angular.module("stats",[]).controller("StatsController",["Settings","$scope","Messages","$timeout","Container","$routeParams","humansizeFilter","$sce",function(a,b,c,d,e,f,g,h){function i(){e.stats({id:f.id},function(a){var e=Object.keys(a).map(function(b){return a[b]});return-1!==e.join("").indexOf("no such id")?void c.error("Unable to retrieve stats","Is this container running?"):(b.data=a,j(a),k(a),l(a),void(D=d(i,2e3)))},function(){c.error("Unable to retrieve stats","Is this container running?")})}function j(a){console.log("updateCpuChart",a),A.addData([m(a)],new Date(a.read).toLocaleTimeString()),A.removeData()}function k(a){console.log("updateMemoryChart",a),B.addData([a.memory_stats.usage],new Date(a.read).toLocaleTimeString()),B.removeData()}function l(a){var b=0,c=0;(0!==E||0!==F)&&(b=a.network.rx_bytes-E,c=a.network.tx_bytes-F),E=a.network.rx_bytes,F=a.network.tx_bytes,console.log("updateNetworkChart",a),C.addData([b,c],new Date(a.read).toLocaleTimeString()),C.removeData()}function m(a){var b=a.precpu_stats,c=a.cpu_stats,d=0,e=c.cpu_usage.total_usage-b.cpu_usage.total_usage,f=c.system_cpu_usage-b.system_cpu_usage;return f>0&&e>0&&(d=e/f*c.cpu_usage.percpu_usage.length*100),d}for(var n=[],o=[],p=[],q=[],r=[],s=[],t=[],u=0;20>u;u++)n.push(""),o.push(0),p.push(""),q.push(0),r.push(""),s.push(0),t.push(0);var v={fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:o},w={fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:q},x={label:"Rx Bytes",fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:t},y={label:"Tx Bytes",fillColor:"rgba(255,180,174,0.5)",strokeColor:"rgba(255,180,174,1)",pointColor:"rgba(255,180,174,1)",pointStrokeColor:"#fff",data:s},z=[{color:"rgba(151,187,205,0.5)",title:"Rx Data"},{color:"rgba(255,180,174,0.5)",title:"Rx Data"}];legend($("#network-legend").get(0),z),Chart.defaults.global.animationSteps=30;var A=new Chart($("#cpu-stats-chart").get(0).getContext("2d")).Line({labels:n,datasets:[v]},{responsive:!0}),B=new Chart($("#memory-stats-chart").get(0).getContext("2d")).Line({labels:p,datasets:[w]},{scaleLabel:function(a){return g(parseInt(a.value,10))},responsive:!0}),C=new Chart($("#network-stats-chart").get(0).getContext("2d")).Line({labels:r,datasets:[x,y]},{scaleLabel:function(a){return g(parseInt(a.value,10))},responsive:!0});b.networkLegend=h.trustAsHtml(C.generateLegend());var D;b.$on("$destroy",function(){d.cancel(D)}),i();var E=0,F=0}]),angular.module("dockerui.filters",[]).filter("truncate",function(){"use strict";return function(a,b,c){return isNaN(b)&&(b=10),void 0===c&&(c="..."),a.length<=b||a.length-c.length<=b?a:String(a).substring(0,b-c.length)+c}}).filter("statusbadge",function(){"use strict";return function(a){return"Ghost"===a?"important":-1!==a.indexOf("Exit")&&"Exit 0"!==a?"warning":"success"}}).filter("getstatetext",function(){"use strict";return function(a){return void 0===a?"":a.Ghost&&a.Running?"Ghost":a.Running&&a.Paused?"Running (Paused)":a.Running?"Running":"Stopped"}}).filter("getstatelabel",function(){"use strict";return function(a){return void 0===a?"":a.Ghost&&a.Running?"label-important":a.Running?"label-success":""}}).filter("humansize",function(){"use strict";return function(a){var b=["Bytes","KB","MB","GB","TB"];if(0===a)return"n/a";var c=parseInt(Math.floor(Math.log(a)/Math.log(1024)),10),d=a/Math.pow(1024,c),e=1>c?0:c-1;return d.toFixed(e)+" "+b[[c]]}}).filter("containername",function(){"use strict";return function(a){var b=a.Names[0];return b.substring(1,b.length)}}).filter("repotag",function(){"use strict";return function(a){if(a.RepoTags&&a.RepoTags.length>0){var b=a.RepoTags[0];return":"===b&&(b=""),b}return""}}).filter("getdate",function(){"use strict";return function(a){var b=new Date(1e3*a);return b.toDateString()}}).filter("errorMsg",function(){return function(a){for(var b=0,c="";a[b]&&"string"==typeof a[b];)c+=a[b],b++;return c}}),angular.module("dockerui.services",["ngResource"]).factory("Container",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/containers/:id/:action",{name:"@name"},{query:{method:"GET",params:{all:0,action:"json"},isArray:!0},get:{method:"GET",params:{action:"json"}},start:{method:"POST",params:{id:"@id",action:"start"}},stop:{method:"POST",params:{id:"@id",t:5,action:"stop"}},restart:{method:"POST",params:{id:"@id",t:5,action:"restart"}},kill:{method:"POST",params:{id:"@id",action:"kill"}},pause:{method:"POST",params:{id:"@id",action:"pause"}},unpause:{method:"POST",params:{id:"@id",action:"unpause"}},changes:{method:"GET",params:{action:"changes"},isArray:!0},create:{method:"POST",params:{action:"create"}},remove:{method:"DELETE",params:{id:"@id",v:0}},rename:{method:"POST",params:{id:"@id",action:"rename"},isArray:!1},stats:{method:"GET",params:{id:"@id",stream:!1,action:"stats"},timeout:2e3}})}]).factory("ContainerCommit",["$resource","$http","Settings",function(a,b,c){"use strict";return{commit:function(a,d){b({method:"POST",url:c.url+"/commit",params:{container:a.id,repo:a.repo}}).success(d).error(function(a,b,c,d){console.log(error,a)})}}}]).factory("ContainerLogs",["$resource","$http","Settings",function(a,b,c){"use strict";return{get:function(a,d,e){b({method:"GET",url:c.url+"/containers/"+a+"/logs",params:{stdout:d.stdout||0,stderr:d.stderr||0,timestamps:d.timestamps||0,tail:d.tail||"all"}}).success(e).error(function(a,b,c,d){console.log(error,a)})}}}]).factory("ContainerTop",["$http","Settings",function(a,b){"use strict";return{get:function(c,d,e,f){a({method:"GET",url:b.url+"/containers/"+c+"/top",params:{ps_args:d.ps_args}}).success(e)}}}]).factory("Image",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/images/:id/:action",{},{query:{method:"GET",params:{all:0,action:"json"},isArray:!0},get:{method:"GET",params:{action:"json"}},search:{method:"GET",params:{action:"search"}},history:{method:"GET",params:{action:"history"},isArray:!0},create:{method:"POST",isArray:!0,transformResponse:[function(a){var b=a.replace(/\n/g," ").replace(/\}\W*\{/g,"}, {");return angular.fromJson("["+b+"]")}],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"}},remove:{method:"DELETE",params:{id:"@id"},isArray:!0}})}]).factory("Docker",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/version",{},{get:{method:"GET"}})}]).factory("Auth",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/auth",{},{get:{method:"GET"},update:{method:"POST"}})}]).factory("System",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/info",{},{get:{method:"GET"}})}]).factory("Settings",["DOCKER_ENDPOINT","DOCKER_PORT","DOCKER_API_VERSION","UI_VERSION",function(a,b,c,d){"use strict";var e=a;return b&&(e=e+b+"\\"+b),{displayAll:!1,endpoint:a,version:c,rawUrl:a+b+"/"+c,uiVersion:d,url:e,firstLoad:!0}}]).factory("ViewSpinner",function(){"use strict";var a=new Spinner,b=document.getElementById("view");return{spin:function(){a.spin(b)},stop:function(){a.stop()}}}).factory("Messages",["$rootScope",function(a){"use strict";return{send:function(a,b){$.gritter.add({title:a,text:b,time:2e3,before_open:function(){return 3===$(".gritter-item-wrapper").length?!1:void 0}})},error:function(a,b){$.gritter.add({title:a,text:b,time:1e4,before_open:function(){return 4===$(".gritter-item-wrapper").length?!1:void 0}})}}}]).factory("Dockerfile",["Settings",function(a){"use strict";var b=a.rawUrl+"/build";return{build:function(a,c){var d=new FormData,e=new Blob([a],{type:"text/text"});d.append("Dockerfile",e);var f=new XMLHttpRequest;f.onload=c,f.open("POST",b),f.send(d)}}}]).factory("LineChart",["Settings",function(a){"use strict";return{build:function(a,b,c){for(var d=new Chart($(a).get(0).getContext("2d")),e={},f=0;f-1;f--){var m=k[f];j.push(m),b.push(e[m]),e[m]>l&&(l=e[m])}var n={fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:b};d.Line({labels:j,datasets:[n]},{scaleStepWidth:1,pointDotRadius:1,scaleOverride:!0,scaleSteps:l})}}}]),angular.module("dockerui.templates",["app/components/builder/builder.html","app/components/container/container.html","app/components/containerLogs/containerlogs.html","app/components/containerTop/containerTop.html","app/components/containers/containers.html","app/components/containersNetwork/containersNetwork.html","app/components/dashboard/dashboard.html","app/components/events/events.html","app/components/footer/statusbar.html","app/components/image/image.html","app/components/images/images.html","app/components/info/info.html","app/components/masthead/masthead.html","app/components/pullImage/pullImage.html","app/components/sidebar/sidebar.html","app/components/startContainer/startcontainer.html","app/components/stats/stats.html"]),angular.module("app/components/builder/builder.html",[]).run(["$templateCache",function(a){a.put("app/components/builder/builder.html",'\n')}]),angular.module("app/components/container/container.html",[]).run(["$templateCache",function(a){a.put("app/components/container/container.html",'
    \n\n
    \n

    Container: {{ container.Name }}\n \n

    \n
    \n
    \n

    \n Container:\n \n \n \n

    \n
    \n\n
    \n \n \n \n \n \n \n \n
    \n\n
    Tags: +
      +
    • {{ tag }} + +
    • +
    +
    Created:{{ image.Created }}{{ image.Created | date: 'medium'}}
    Parent:
    \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 \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 \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    Created:{{ container.Created }}
    Path:{{ container.Path }}
    Args:{{ container.Args }}
    Exposed Ports:\n
      \n
    • {{ k }}
    • \n
    \n
    Environment:\n
      \n
    • {{ k }}
    • \n
    \n
    Publish All:{{ container.HostConfig.PublishAllPorts }}
    Ports:\n
      \n
    • \n {{ containerport }} => {{ v.HostIp }}:{{ v.HostPort }}\n
    • \n
    \n
    Hostname:{{ container.Config.Hostname }}
    IPAddress:{{ container.NetworkSettings.IPAddress }}
    Cmd:{{ container.Config.Cmd }}
    Entrypoint:{{ container.Config.Entrypoint }}
    Volumes:{{ container.Volumes }}
    SysInitpath:{{ container.SysInitPath }}
    Image:{{ container.Image }}
    State:{{ container.State|getstatetext }}
    Logs:stdout/stderr
    Stats:stats
    Top:Top
    \n\n
    \n
    \n Changes:\n
    \n
    \n \n
    \n
    \n\n
    \n
      \n
    • \n {{ change.Path }} {{ change.Kind }}\n
    • \n
    \n
    \n\n
    \n\n
    \n \n
    \n
    \n'); -}]),angular.module("app/components/containerLogs/containerlogs.html",[]).run(["$templateCache",function(a){a.put("app/components/containerLogs/containerlogs.html",'
    \n
    \n

    Logs for container: {{ container.Name }}

    \n\n
    \n \n \n
    \n
    \n
    \n Reload logs\n \n \n
    \n
    \n \n
    \n
    \n
    \n\n
    \n
    \n
    \n

    STDOUT

    \n
    \n
    \n
    {{stdout}}
    \n
    \n
    \n
    \n
    \n
    \n
    \n

    STDERR

    \n
    \n
    \n
    {{stderr}}
    \n
    \n
    \n
    \n
    \n')}]),angular.module("app/components/containerTop/containerTop.html",[]).run(["$templateCache",function(a){a.put("app/components/containerTop/containerTop.html",'
    \n
    \n \n
    \n \n\n \n \n \n \n \n \n \n \n \n \n \n
    {{title}}
    {{processInfo}}
    \n
    ')}]),angular.module("app/components/containers/containers.html",[]).run(["$templateCache",function(a){a.put("app/components/containers/containers.html",'\n

    Containers:

    \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 \n \n
    ActionNameImageCommandCreatedStatus
    {{ container|containername}}{{ container.Image }}{{ container.Command|truncate:40 }}{{ container.Created|getdate }}{{ container.Status }}
    \n')}]),angular.module("app/components/containersNetwork/containersNetwork.html",[]).run(["$templateCache",function(a){a.put("app/components/containersNetwork/containersNetwork.html",'
    \n

    Containers Network

    \n\n
    \n
    \n \n \n
    \n
    \n
    \n
    \n \n \n \n \n
    \n Include stopped containers\n
    \n
    \n \n
    \n
    \n')}]),angular.module("app/components/dashboard/dashboard.html",[]).run(["$templateCache",function(a){a.put("app/components/dashboard/dashboard.html",'
    \n \n
    \n \n
    \n\n
    \n
    \n
    \n

    Running Containers

    \n \n
    \n
    \n

    Status

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n

    Containers created

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \n
    \n

    Images created

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \n
    \n
    \n
    \n
    \n')}]),angular.module("app/components/events/events.html",[]).run(["$templateCache",function(a){a.put("app/components/events/events.html",'
    \n
    \n

    Events

    \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
    EventFromIDTime
    \n \n \n \n
    \n
    \n
    \n')}]),angular.module("app/components/footer/statusbar.html",[]).run(["$templateCache",function(a){a.put("app/components/footer/statusbar.html",'
    \n

    \n Docker API Version: {{ apiVersion }} UI Version: {{ uiVersion }} dockerui\n

    \n
    \n')}]),angular.module("app/components/image/image.html",[]).run(["$templateCache",function(a){a.put("app/components/image/image.html",'
    \n\n\n\n
    \n\n

    Image: {{ tag }}

    \n\n
    \n \n
    \n\n
    \n

    Containers created:

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \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 \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n
    Created:{{ image.Created }}
    Parent:{{ image.Parent }}
    Size (Virtual Size):{{ image.Size|humansize }} ({{ image.VirtualSize|humansize }})
    Hostname:{{ image.ContainerConfig.Hostname }}
    User:{{ image.ContainerConfig.User }}
    Cmd:{{ image.ContainerConfig.Cmd }}
    Volumes:{{ image.ContainerConfig.Volumes }}
    Volumes from:{{ image.ContainerConfig.VolumesFrom }}
    Built with:Docker {{ image.DockerVersion }} on {{ image.Os}}, {{ image.Architecture }}
    \n\n
    \n
    \n History:\n
    \n
    \n \n
    \n
    \n\n
    \n
      \n
    • \n {{ change.Id }}: Created: {{ change.Created|getdate }} Created by: {{ change.CreatedBy\n }}\n
    • \n
    \n
    \n\n
    \n\n
    \n
    \n
    \n Tag image\n
    \n \n \n
    \n
    \n \n
    \n \n
    \n
    \n
    \n\n
    \n\n
    \n \n
    \n
    \n')}]),angular.module("app/components/images/images.html",[]).run(["$templateCache",function(a){a.put("app/components/images/images.html",'
    \n
    \n\n

    Images:

    \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
    ActionIdRepositoryVirtualSizeCreated
    {{ image.Id|truncate:20}}{{ image|repotag }}{{ image.VirtualSize|humansize }}{{ image.Created|getdate }}
    \n')}]),angular.module("app/components/info/info.html",[]).run(["$templateCache",function(a){a.put("app/components/info/info.html",'
    \n

    Docker Information

    \n\n
    \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

    \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 \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 \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 \n \n \n \n \n \n \n
    Containers:{{ info.Containers }}
    Images:{{ info.Images }}
    Debug:{{ info.Debug }}
    CPUs:{{ info.NCPU }}
    Total Memory:{{ info.MemTotal|humansize }}
    Operating System:{{ info.OperatingSystem }}
    Kernel Version:{{ info.KernelVersion }}
    ID:{{ info.ID }}
    Labels:{{ info.Labels }}
    File Descriptors:{{ info.NFd }}
    Goroutines:{{ info.NGoroutines }}
    Storage Driver:{{ info.Driver }}
    Storage Driver Status:\n

    \n {{ val[0] }}: {{ val[1] }}\n

    \n
    Execution Driver:{{ info.ExecutionDriver }}
    Events:Events
    IPv4 Forwarding:{{ info.IPv4Forwarding }}
    Index Server Address:{{ info.IndexServerAddress }}
    Init Path:{{ info.InitPath }}
    Docker Root Directory:{{ info.DockerRootDir }}
    Init SHA1{{ info.InitSha1 }}
    Memory Limit:{{ info.MemoryLimit }}
    Swap Limit:{{ info.SwapLimit }}
    \n
    \n')}]),angular.module("app/components/masthead/masthead.html",[]).run(["$templateCache",function(a){a.put("app/components/masthead/masthead.html",'
    \n

    DockerUI

    \n \n
    \n')}]),angular.module("app/components/pullImage/pullImage.html",[]).run(["$templateCache",function(a){a.put("app/components/pullImage/pullImage.html",'\n')}]),angular.module("app/components/sidebar/sidebar.html",[]).run(["$templateCache",function(a){a.put("app/components/sidebar/sidebar.html",'
    \n Running containers:\n
    \n Endpoint: {{ endpoint }}\n \n
    \n')}]),angular.module("app/components/startContainer/startcontainer.html",[]).run(["$templateCache",function(a){a.put("app/components/startContainer/startcontainer.html",'\n'); +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"]).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.8.0").constant("DOCKER_API_VERSION","v1.20"),angular.module("builder",[]).controller("BuilderController",["$scope","Dockerfile","Messages",function(a,b,c){a.template="app/components/builder/builder.html"}]),angular.module("container",[]).controller("ContainerController",["$scope","$routeParams","$location","Container","ContainerCommit","Messages","ViewSpinner",function(a,b,c,d,e,f,g){a.changes=[],a.edit=!1;var h=function(){g.spin(),d.get({id:b.id},function(b){a.container=b,a.container.edit=!1,a.container.newContainerName=b.Name,g.stop()},function(a){404===a.status?($(".detail").hide(),f.error("Not found","Container not found.")):f.error("Failure",a.data),g.stop()})};a.start=function(){g.spin(),d.start({id:a.container.Id,HostConfig:a.container.HostConfig},function(a){h(),f.send("Container started",b.id)},function(a){h(),f.error("Failure","Container failed to start."+a.data)})},a.stop=function(){g.spin(),d.stop({id:b.id},function(a){h(),f.send("Container stopped",b.id)},function(a){h(),f.error("Failure","Container failed to stop."+a.data)})},a.kill=function(){g.spin(),d.kill({id:b.id},function(a){h(),f.send("Container killed",b.id)},function(a){h(),f.error("Failure","Container failed to die."+a.data)})},a.commit=function(){g.spin(),e.commit({id:b.id,repo:a.container.Config.Image},function(a){h(),f.send("Container commited",b.id)},function(a){h(),f.error("Failure","Container failed to commit."+a.data)})},a.pause=function(){g.spin(),d.pause({id:b.id},function(a){h(),f.send("Container paused",b.id)},function(a){h(),f.error("Failure","Container failed to pause."+a.data)})},a.unpause=function(){g.spin(),d.unpause({id:b.id},function(a){h(),f.send("Container unpaused",b.id)},function(a){h(),f.error("Failure","Container failed to unpause."+a.data)})},a.remove=function(){g.spin(),d.remove({id:b.id},function(a){h(),f.send("Container removed",b.id)},function(a){h(),f.error("Failure","Container failed to remove."+a.data)})},a.restart=function(){g.spin(),d.restart({id:b.id},function(a){h(),f.send("Container restarted",b.id)},function(a){h(),f.error("Failure","Container failed to restart."+a.data)})},a.hasContent=function(a){return null!==a&&void 0!==a},a.getChanges=function(){g.spin(),d.changes({id:b.id},function(b){a.changes=b,g.stop()})},a.renameContainer=function(){d.rename({id:b.id,name:a.container.newContainerName},function(c){c.name?(a.container.Name=c.name,f.send("Container renamed",b.id)):(a.container.newContainerName=a.container.Name,f.error("Failure","Container failed to rename."))}),a.container.edit=!1},h(),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","ViewSpinner",function(a,b,c,d){a.ps_args="",a.getTop=function(){d.spin(),c.get(b.id,{ps_args:a.ps_args},function(b){a.containerTop=b,d.stop()})},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
  • ID: '+a.Id+"
  • Image: "+a.Image+"
  • ",color:a.Running?"#8888ff":"#cccccc"})},this.hasEdge=function(a,b){return this.edges.getIds({filter:function(c){return c.from===a.Id&&c.to===b.Id}}).length>0},this.addLinkEdgeIfExists=function(a,b){null==a.Links||null==a.Links[b.Name]||this.hasEdge(a,b)||this.edges.add({from:a.Id,to:b.Id,label:a.Links[b.Name]})},this.addVolumeEdgeIfExists=function(a,b){null==a.VolumesFrom||null==a.VolumesFrom[b.Id]&&null==a.VolumesFrom[b.Name]||this.hasEdge(a,b)||this.edges.add({from:a.Id,to:b.Id,color:{color:"#A0A0A0",highlight:"#A0A0A0",hover:"#848484"}})},this.removeContainersNodes=function(a){this.nodes.remove(a)}}function i(){this.data=new h,this.containers={},this.selectedContainersIds=[],this.shownContainersIds=[],this.events={select:function(b){a.network.selectedContainersIds=b.nodes,a.$apply(function(){a.query=""})},doubleClick:function(c){a.$apply(function(){b.path("/containers/"+c.nodes[0])})}},this.options={navigation:!0,keyboard:!0,height:"500px",width:"700px",nodes:{shape:"box"},edges:{style:"arrow"},physics:{barnesHut:{springLength:200}}},this.addContainer=function(a){var b=new g(a);this.containers[b.Id]=b,this.shownContainersIds.push(b.Id),this.data.addContainerNode(b);for(var c in this.containers){var d=this.containers[c];this.data.addLinkEdgeIfExists(b,d),this.data.addLinkEdgeIfExists(d,b),this.data.addVolumeEdgeIfExists(b,d),this.data.addVolumeEdgeIfExists(d,b)}},this.selectContainers=function(a){null!=this.component&&(this.selectedContainersIds=this.searchContainers(a),this.component.selectNodes(this.selectedContainersIds))},this.searchContainers=function(a){if(""===a.trim())return[];for(var b=[],c=0;c-1||d.Image.indexOf(a)>-1||d.Id.indexOf(a)>-1)&&b.push(d.Id)}return b},this.hideSelected=function(){for(var b=0;b-1?this.shownContainersIds.splice(b,1):b++;this.data.removeContainersNodes(this.selectedContainersIds),a.query="",this.selectedContainersIds=[]},this.searchDownstream=function(a,b){if(!(b.indexOf(a)>-1)){b.push(a);var c=this.containers[a];if(null!=c.Links||null!=c.VolumesFrom)for(var d in this.containers){var e=this.containers[d];null!=c.Links&&null!=c.Links[e.Name]?this.searchDownstream(e.Id,b):null!=c.VolumesFrom&&null!=c.VolumesFrom[e.Id]&&this.searchDownstream(e.Id,b)}}},this.updateShownContainers=function(a){for(var b in this.containers)a.indexOf(b)>-1&&-1===this.shownContainersIds.indexOf(b)?this.data.addContainerNode(this.containers[b]):-1===a.indexOf(b)&&this.shownContainersIds.indexOf(b)>-1&&this.data.removeContainersNodes(b);this.shownContainersIds=a},this.showSelectedDownstream=function(){for(var a=[],b=0;b-1)){b.push(a);var c=this.containers[a];for(var d in this.containers){var e=this.containers[d];null!=e.Links&&null!=e.Links[c.Name]?this.searchUpstream(e.Id,b):null!=e.VolumesFrom&&null!=e.VolumesFrom[c.Id]&&this.searchUpstream(e.Id,b)}}},this.showSelectedUpstream=function(){for(var a=[],b=0;b"+c.id):a.error=b.data,$("#error-message").show()}),a.getHistory()}]),angular.module("images",[]).controller("ImagesController",["$scope","Image","ViewSpinner","Messages",function(a,b,c,d){a.toggle=!1,a.predicate="-Created",a.showBuilder=function(){$("#build-modal").modal("show")},a.removeAction=function(){c.spin();var e=0,f=function(){e-=1,0===e&&c.stop()};angular.forEach(a.images,function(c){c.Checked&&(e+=1,b.remove({id:c.Id},function(b){angular.forEach(b,function(a){d.send("Image deleted",a.Deleted)});var e=a.images.indexOf(c);a.images.splice(e,1),f()},function(a){d.error("Failure",a.data),f()}))})},a.toggleSelectAll=function(){angular.forEach(a.images,function(b){b.Checked=a.toggle})},c.spin(),b.query({},function(b){a.images=b.map(function(a){return new ImageViewModel(a)}),c.stop()},function(a){d.error("Failure",a.data),c.stop()})}]),angular.module("info",[]).controller("InfoController",["$scope","System","Docker","Settings","Messages",function(a,b,c,d,e){a.info={},a.docker={},a.endpoint=d.endpoint,a.apiVersion=d.version,c.get({},function(b){a.docker=b}),b.get({},function(b){a.info=b})}]),angular.module("masthead",[]).controller("MastheadController",["$scope",function(a){a.template="app/components/masthead/masthead.html"}]),angular.module("pullImage",[]).controller("PullImageController",["$scope","$log","Dockerfile","Messages","Image","ViewSpinner",function(a,b,c,d,e,f){a.template="app/components/pullImage/pullImage.html",a.init=function(){a.config={registry:"",repo:"",fromImage:"",tag:"latest"}},a.init(),a.pull=function(){$("#error-message").hide();var b=angular.copy(a.config),c=(b.registry?b.registry+"/":"")+(b.repo?b.repo+"/":"")+b.fromImage+(b.tag?":"+b.tag:"");f.spin(),$("#pull-modal").modal("hide"),e.create(b,function(b){if(f.stop(),b.constructor===Array){var e=b.length>0&&b[b.length-1].hasOwnProperty("error");if(e){var g=b[b.length-1];a.error="Cannot pull image "+c+" Reason: "+g.error,$("#pull-modal").modal("show"),$("#error-message").show()}else d.send("Image Added",c),a.init()}else d.send("Image Added",c),a.init()},function(b){f.stop(),a.error="Cannot pull image "+c+" Reason: "+b.data,$("#pull-modal").modal("show"),$("#error-message").show()})}}]),angular.module("sidebar",[]).controller("SideBarController",["$scope","Container","Settings",function(a,b,c){a.template="partials/sidebar.html",a.containers=[],a.endpoint=c.endpoint,b.query({all:0},function(b){a.containers=b})}]),angular.module("startContainer",["ui.bootstrap"]).controller("StartContainerController",["$scope","$routeParams","$location","Container","Messages","containernameFilter","errorMsgFilter",function(a,b,c,d,e,f,g){function h(a,b){b.error("Error",g(a))}function i(a){for(var b in a)(null===a[b]||void 0===a[b]||""===a[b]||$.isEmptyObject(a[b])||0===a[b].length)&&delete a[b]}function j(a){return a.map(function(a){return a.name})}a.template="app/components/startContainer/startcontainer.html",d.query({all:1},function(b){a.containerNames=b.map(function(a){return f(a)})}),a.config={Env:[],Labels:[],Volumes:[],SecurityOpts:[],HostConfig:{PortBindings:[],Binds:[],Links:[],Dns:[],DnsSearch:[],VolumesFrom:[],CapAdd:[],CapDrop:[],Devices:[],LxcConf:[],ExtraHosts:[]}},a.menuStatus={containerOpen:!0,hostConfigOpen:!1},a.create=function(){var f=angular.copy(a.config);f.Image=b.id,f.Cmd&&"["===f.Cmd[0]?f.Cmd=angular.fromJson(f.Cmd):f.Cmd&&(f.Cmd=f.Cmd.split(" ")),f.Env=f.Env.map(function(a){return a.name+"="+a.value});var g={};f.Labels=f.Labels.forEach(function(a){g[a.key]=a.value}),f.Labels=g,f.Volumes=j(f.Volumes),f.SecurityOpts=j(f.SecurityOpts),f.HostConfig.VolumesFrom=j(f.HostConfig.VolumesFrom),f.HostConfig.Binds=j(f.HostConfig.Binds),f.HostConfig.Links=j(f.HostConfig.Links),f.HostConfig.Dns=j(f.HostConfig.Dns),f.HostConfig.DnsSearch=j(f.HostConfig.DnsSearch),f.HostConfig.CapAdd=j(f.HostConfig.CapAdd),f.HostConfig.CapDrop=j(f.HostConfig.CapDrop),f.HostConfig.LxcConf=f.HostConfig.LxcConf.reduce(function(a,b,c){return a[b.name]=b.value,a},{}),f.HostConfig.ExtraHosts=f.HostConfig.ExtraHosts.map(function(a){return a.host+":"+a.ip});var k={},l={};f.HostConfig.PortBindings.forEach(function(a){var b=a.intPort+"/tcp";"udp"===a.protocol&&(b=a.intPort+"/udp");var c={HostIp:a.ip,HostPort:a.extPort};a.intPort?(k[b]={},b in l?l[b].push(c):l[b]=[c]):e.send("Warning","Internal port must be specified for PortBindings")}),f.ExposedPorts=k,f.HostConfig.PortBindings=l,i(f.HostConfig),i(f);var m=d,n=c;d.create(f,function(a){if(a.Id){var b=f.HostConfig||{};b.id=a.Id,m.start(b,function(b){b.id?(e.send("Container Started",a.Id),$("#create-modal").modal("hide"),n.path("/containers/"+a.Id+"/")):(h(b,e),m.remove({id:a.Id},function(){e.send("Container Removed",a.Id)}))},function(a){h(a,e)})}else h(a,e)},function(a){h(a,e)})},a.addEntry=function(a,b){a.push(b)},a.rmEntry=function(a,b){var c=a.indexOf(b);a.splice(c,1)}}]),angular.module("stats",[]).controller("StatsController",["Settings","$scope","Messages","$timeout","Container","$routeParams","humansizeFilter","$sce",function(a,b,c,d,e,f,g,h){function i(){e.stats({id:f.id},function(a){var e=Object.keys(a).map(function(b){return a[b]});return-1!==e.join("").indexOf("no such id")?void c.error("Unable to retrieve stats","Is this container running?"):(b.data=a,j(a),k(a),l(a),void(D=d(i,2e3)))},function(){c.error("Unable to retrieve stats","Is this container running?")})}function j(a){console.log("updateCpuChart",a),A.addData([m(a)],new Date(a.read).toLocaleTimeString()),A.removeData()}function k(a){console.log("updateMemoryChart",a),B.addData([a.memory_stats.usage],new Date(a.read).toLocaleTimeString()),B.removeData()}function l(a){var b=0,c=0;(0!==E||0!==F)&&(b=a.network.rx_bytes-E,c=a.network.tx_bytes-F),E=a.network.rx_bytes,F=a.network.tx_bytes,console.log("updateNetworkChart",a),C.addData([b,c],new Date(a.read).toLocaleTimeString()),C.removeData()}function m(a){var b=a.precpu_stats,c=a.cpu_stats,d=0,e=c.cpu_usage.total_usage-b.cpu_usage.total_usage,f=c.system_cpu_usage-b.system_cpu_usage;return f>0&&e>0&&(d=e/f*c.cpu_usage.percpu_usage.length*100),d}for(var n=[],o=[],p=[],q=[],r=[],s=[],t=[],u=0;20>u;u++)n.push(""),o.push(0),p.push(""),q.push(0),r.push(""),s.push(0),t.push(0);var v={fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:o},w={fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:q},x={label:"Rx Bytes",fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:t},y={label:"Tx Bytes",fillColor:"rgba(255,180,174,0.5)",strokeColor:"rgba(255,180,174,1)",pointColor:"rgba(255,180,174,1)",pointStrokeColor:"#fff",data:s},z=[{color:"rgba(151,187,205,0.5)",title:"Rx Data"},{color:"rgba(255,180,174,0.5)",title:"Rx Data"}];legend($("#network-legend").get(0),z),Chart.defaults.global.animationSteps=30;var A=new Chart($("#cpu-stats-chart").get(0).getContext("2d")).Line({labels:n,datasets:[v]},{responsive:!0}),B=new Chart($("#memory-stats-chart").get(0).getContext("2d")).Line({labels:p,datasets:[w]},{scaleLabel:function(a){return g(parseInt(a.value,10))},responsive:!0}),C=new Chart($("#network-stats-chart").get(0).getContext("2d")).Line({labels:r,datasets:[x,y]},{scaleLabel:function(a){return g(parseInt(a.value,10))},responsive:!0});b.networkLegend=h.trustAsHtml(C.generateLegend());var D;b.$on("$destroy",function(){d.cancel(D)}),i();var E=0,F=0}]),angular.module("dockerui.filters",[]).filter("truncate",function(){"use strict";return function(a,b,c){return isNaN(b)&&(b=10),void 0===c&&(c="..."),a.length<=b||a.length-c.length<=b?a:String(a).substring(0,b-c.length)+c}}).filter("statusbadge",function(){"use strict";return function(a){return"Ghost"===a?"important":-1!==a.indexOf("Exit")&&"Exit 0"!==a?"warning":"success"}}).filter("getstatetext",function(){"use strict";return function(a){return void 0===a?"":a.Ghost&&a.Running?"Ghost":a.Running&&a.Paused?"Running (Paused)":a.Running?"Running":"Stopped"}}).filter("getstatelabel",function(){"use strict";return function(a){return void 0===a?"label-default":a.Ghost&&a.Running?"label-important":a.Running?"label-success":"label-default"}}).filter("humansize",function(){"use strict";return function(a){var b=["Bytes","KB","MB","GB","TB"];if(0===a)return"n/a";var c=parseInt(Math.floor(Math.log(a)/Math.log(1024)),10),d=a/Math.pow(1024,c),e=1>c?0:c-1;return d.toFixed(e)+" "+b[[c]]}}).filter("containername",function(){"use strict";return function(a){var b=a.Names[0];return b.substring(1,b.length)}}).filter("repotag",function(){"use strict";return function(a){if(a.RepoTags&&a.RepoTags.length>0){var b=a.RepoTags[0];return":"===b&&(b=""),b}return""}}).filter("getdate",function(){"use strict";return function(a){var b=new Date(1e3*a);return b.toDateString()}}).filter("errorMsg",function(){return function(a){for(var b=0,c="";a[b]&&"string"==typeof a[b];)c+=a[b],b++;return c}}),angular.module("dockerui.services",["ngResource"]).factory("Container",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/containers/:id/:action",{name:"@name"},{query:{method:"GET",params:{all:0,action:"json"},isArray:!0},get:{method:"GET",params:{action:"json"}},start:{method:"POST",params:{id:"@id",action:"start"}},stop:{method:"POST",params:{id:"@id",t:5,action:"stop"}},restart:{method:"POST",params:{id:"@id",t:5,action:"restart"}},kill:{method:"POST",params:{id:"@id",action:"kill"}},pause:{method:"POST",params:{id:"@id",action:"pause"}},unpause:{method:"POST",params:{id:"@id",action:"unpause"}},changes:{method:"GET",params:{action:"changes"},isArray:!0},create:{method:"POST",params:{action:"create"}},remove:{method:"DELETE",params:{id:"@id",v:0}},rename:{method:"POST",params:{id:"@id",action:"rename"},isArray:!1},stats:{method:"GET",params:{id:"@id",stream:!1,action:"stats"},timeout:2e3}})}]).factory("ContainerCommit",["$resource","$http","Settings",function(a,b,c){"use strict";return{commit:function(a,d){b({method:"POST",url:c.url+"/commit",params:{container:a.id,repo:a.repo}}).success(d).error(function(a,b,c,d){console.log(error,a)})}}}]).factory("ContainerLogs",["$resource","$http","Settings",function(a,b,c){"use strict";return{get:function(a,d,e){b({method:"GET",url:c.url+"/containers/"+a+"/logs",params:{stdout:d.stdout||0,stderr:d.stderr||0,timestamps:d.timestamps||0,tail:d.tail||"all"}}).success(e).error(function(a,b,c,d){console.log(error,a)})}}}]).factory("ContainerTop",["$http","Settings",function(a,b){"use strict";return{get:function(c,d,e,f){a({method:"GET",url:b.url+"/containers/"+c+"/top",params:{ps_args:d.ps_args}}).success(e)}}}]).factory("Image",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/images/:id/:action",{},{query:{method:"GET",params:{all:0,action:"json"},isArray:!0},get:{method:"GET",params:{action:"json"}},search:{method:"GET",params:{action:"search"}},history:{method:"GET",params:{action:"history"},isArray:!0},create:{method:"POST",isArray:!0,transformResponse:[function(a){var b=a.replace(/\n/g," ").replace(/\}\W*\{/g,"}, {");return angular.fromJson("["+b+"]")}],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",tag:"@tag"}},remove:{method:"DELETE",params:{id:"@id"},isArray:!0}})}]).factory("Docker",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/version",{},{get:{method:"GET"}})}]).factory("Auth",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/auth",{},{get:{method:"GET"},update:{method:"POST"}})}]).factory("System",["$resource","Settings",function(a,b){"use strict";return a(b.url+"/info",{},{get:{method:"GET"}})}]).factory("Settings",["DOCKER_ENDPOINT","DOCKER_PORT","DOCKER_API_VERSION","UI_VERSION",function(a,b,c,d){"use strict";var e=a;return b&&(e=e+b+"\\"+b),{displayAll:!1,endpoint:a,version:c,rawUrl:a+b+"/"+c,uiVersion:d,url:e,firstLoad:!0}}]).factory("ViewSpinner",function(){"use strict";var a=new Spinner,b=document.getElementById("view");return{spin:function(){a.spin(b)},stop:function(){a.stop()}}}).factory("Messages",["$rootScope",function(a){"use strict";return{send:function(a,b){$.gritter.add({title:a,text:b,time:2e3,before_open:function(){return 3===$(".gritter-item-wrapper").length?!1:void 0}})},error:function(a,b){$.gritter.add({title:a,text:b,time:1e4,before_open:function(){return 4===$(".gritter-item-wrapper").length?!1:void 0}})}}}]).factory("Dockerfile",["Settings",function(a){"use strict";var b=a.rawUrl+"/build";return{build:function(a,c){var d=new FormData,e=new Blob([a],{type:"text/text"});d.append("Dockerfile",e);var f=new XMLHttpRequest;f.onload=c,f.open("POST",b),f.send(d)}}}]).factory("LineChart",["Settings",function(a){"use strict";return{build:function(a,b,c){for(var d=new Chart($(a).get(0).getContext("2d")),e={},f=0;f-1;f--){var m=k[f];j.push(m),b.push(e[m]),e[m]>l&&(l=e[m])}var n={fillColor:"rgba(151,187,205,0.5)",strokeColor:"rgba(151,187,205,1)",pointColor:"rgba(151,187,205,1)",pointStrokeColor:"#fff",data:b};d.Line({labels:j,datasets:[n]},{scaleStepWidth:1,pointDotRadius:1,scaleOverride:!0,scaleSteps:l})}}}]),angular.module("dockerui.templates",["app/components/builder/builder.html","app/components/container/container.html","app/components/containerLogs/containerlogs.html","app/components/containerTop/containerTop.html","app/components/containers/containers.html","app/components/containersNetwork/containersNetwork.html","app/components/dashboard/dashboard.html","app/components/events/events.html","app/components/footer/statusbar.html","app/components/image/image.html","app/components/images/images.html","app/components/info/info.html","app/components/masthead/masthead.html","app/components/pullImage/pullImage.html","app/components/sidebar/sidebar.html","app/components/startContainer/startcontainer.html","app/components/stats/stats.html"]),angular.module("app/components/builder/builder.html",[]).run(["$templateCache",function(a){a.put("app/components/builder/builder.html",'\n')}]),angular.module("app/components/container/container.html",[]).run(["$templateCache",function(a){a.put("app/components/container/container.html",'
    \n\n
    \n

    Container: {{ container.Name }}\n \n

    \n
    \n
    \n

    \n Container:\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 \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 \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 \n \n \n \n \n \n \n \n \n \n \n \n
    Created:{{ container.Created | date: \'medium\' }}
    Path:{{ container.Path }}
    Args:\n
    {{ container.Args.join(\' \') || \'None\' }}
    \n
    Exposed Ports:\n
      \n
    • {{ k }}
    • \n
    \n
    Environment:\n
      \n
    • {{ k }}
    • \n
    \n
    Labels:\n \n \n \n \n \n \n \n \n \n
    KeyValue
    {{ k }}{{ v }}
    \n
    Publish All:{{ container.HostConfig.PublishAllPorts }}
    Ports:\n
      \n
    • \n {{ containerport }} => {{ v.HostIp }}:{{ v.HostPort }}\n
    • \n
    \n
    Hostname:{{ container.Config.Hostname }}
    IPAddress:{{ container.NetworkSettings.IPAddress }}
    Cmd:{{ container.Config.Cmd }}
    Entrypoint:\n
    {{ container.Config.Entrypoint.join(\' \') }}
    \n
    Volumes:{{ container.Volumes }}
    SysInitpath:{{ container.SysInitPath }}
    Image:{{ container.Image }}
    State:\n \n \n
      \n
    • {{key}} : {{ val }}
    • \n
    \n
    \n
    \n
    Logs:stdout/stderr
    Stats:stats
    Top:Top
    \n\n
    \n
    \n Changes:\n
    \n
    \n \n
    \n
    \n\n
    \n
      \n
    • \n {{ change.Path }} {{ change.Kind }}\n
    • \n
    \n
    \n\n
    \n\n
    \n \n
    \n
    \n'); +}]),angular.module("app/components/containerLogs/containerlogs.html",[]).run(["$templateCache",function(a){a.put("app/components/containerLogs/containerlogs.html",'
    \n
    \n

    Logs for container: {{ container.Name }}

    \n\n
    \n \n \n
    \n
    \n
    \n Reload logs\n \n \n
    \n
    \n \n
    \n
    \n
    \n\n
    \n
    \n
    \n

    STDOUT

    \n
    \n
    \n
    {{stdout}}
    \n
    \n
    \n
    \n
    \n
    \n
    \n

    STDERR

    \n
    \n
    \n
    {{stderr}}
    \n
    \n
    \n
    \n
    \n')}]),angular.module("app/components/containerTop/containerTop.html",[]).run(["$templateCache",function(a){a.put("app/components/containerTop/containerTop.html",'
    \n
    \n \n
    \n \n\n \n \n \n \n \n \n \n \n \n \n \n
    {{title}}
    {{processInfo}}
    \n
    ')}]),angular.module("app/components/containers/containers.html",[]).run(["$templateCache",function(a){a.put("app/components/containers/containers.html",'\n

    Containers:

    \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 \n \n
    ActionNameImageCommandCreatedStatus
    {{ container|containername}}{{ container.Image }}{{ container.Command|truncate:40 }}{{ container.Created|getdate }}{{ container.Status }}
    \n')}]),angular.module("app/components/containersNetwork/containersNetwork.html",[]).run(["$templateCache",function(a){a.put("app/components/containersNetwork/containersNetwork.html",'
    \n

    Containers Network

    \n\n
    \n
    \n \n \n
    \n
    \n
    \n
    \n \n \n \n \n
    \n Include stopped containers\n
    \n
    \n \n
    \n
    \n')}]),angular.module("app/components/dashboard/dashboard.html",[]).run(["$templateCache",function(a){a.put("app/components/dashboard/dashboard.html",'
    \n \n
    \n \n
    \n\n
    \n
    \n
    \n

    Running Containers

    \n \n
    \n
    \n

    Status

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \n
    \n
    \n
    \n
    \n
    \n\n
    \n
    \n

    Containers created

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \n
    \n

    Images created

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \n
    \n
    \n
    \n
    \n')}]),angular.module("app/components/events/events.html",[]).run(["$templateCache",function(a){a.put("app/components/events/events.html",'
    \n
    \n

    Events

    \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
    EventFromIDTime
    \n \n \n \n
    \n
    \n
    \n')}]),angular.module("app/components/footer/statusbar.html",[]).run(["$templateCache",function(a){a.put("app/components/footer/statusbar.html",'
    \n

    \n Docker API Version: {{ apiVersion }} UI Version: {{ uiVersion }} dockerui\n

    \n
    \n')}]),angular.module("app/components/image/image.html",[]).run(["$templateCache",function(a){a.put("app/components/image/image.html",'
    \n\n\n\n
    \n\n

    Image: {{ id }}

    \n\n
    \n \n
    \n\n
    \n

    Containers created:

    \n \n

    You are using an outdated browser. Please upgrade your browser to improve your experience.

    \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 \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n \n
    Tags:\n
      \n
    • {{ tag }}\n \n
    • \n
    \n
    Created:{{ image.Created | date: \'medium\'}}
    Parent:{{ image.Parent }}
    Size (Virtual Size):{{ image.Size|humansize }} ({{ image.VirtualSize|humansize }})
    Hostname:{{ image.ContainerConfig.Hostname }}
    User:{{ image.ContainerConfig.User }}
    Cmd:{{ image.ContainerConfig.Cmd }}
    Volumes:{{ image.ContainerConfig.Volumes }}
    Volumes from:{{ image.ContainerConfig.VolumesFrom }}
    Built with:Docker {{ image.DockerVersion }} on {{ image.Os}}, {{ image.Architecture }}
    \n\n
    \n
    \n History:\n
    \n
    \n \n
    \n
    \n\n
    \n
      \n
    • \n {{ change.Id }}: Created: {{ change.Created|getdate }} Created by: {{ change.CreatedBy\n }}\n
    • \n
    \n
    \n\n
    \n\n
    \n
    \n
    \n Tag image\n
    \n \n \n \n
    \n
    \n \n
    \n \n
    \n
    \n
    \n\n
    \n\n
    \n \n
    \n
    \n')}]),angular.module("app/components/images/images.html",[]).run(["$templateCache",function(a){a.put("app/components/images/images.html",'
    \n
    \n\n

    Images:

    \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
    ActionIdRepositoryVirtualSizeCreated
    {{ image.Id|truncate:20}}{{ image|repotag }}{{ image.VirtualSize|humansize }}{{ image.Created|getdate }}
    \n')}]),angular.module("app/components/info/info.html",[]).run(["$templateCache",function(a){a.put("app/components/info/info.html",'
    \n

    Docker Information

    \n\n
    \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

    \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 \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 \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 \n \n \n \n \n \n \n
    Containers:{{ info.Containers }}
    Images:{{ info.Images }}
    Debug:{{ info.Debug }}
    CPUs:{{ info.NCPU }}
    Total Memory:{{ info.MemTotal|humansize }}
    Operating System:{{ info.OperatingSystem }}
    Kernel Version:{{ info.KernelVersion }}
    ID:{{ info.ID }}
    Labels:{{ info.Labels }}
    File Descriptors:{{ info.NFd }}
    Goroutines:{{ info.NGoroutines }}
    Storage Driver:{{ info.Driver }}
    Storage Driver Status:\n

    \n {{ val[0] }}: {{ val[1] }}\n

    \n
    Execution Driver:{{ info.ExecutionDriver }}
    Events:Events
    IPv4 Forwarding:{{ info.IPv4Forwarding }}
    Index Server Address:{{ info.IndexServerAddress }}
    Init Path:{{ info.InitPath }}
    Docker Root Directory:{{ info.DockerRootDir }}
    Init SHA1{{ info.InitSha1 }}
    Memory Limit:{{ info.MemoryLimit }}
    Swap Limit:{{ info.SwapLimit }}
    \n
    \n')}]),angular.module("app/components/masthead/masthead.html",[]).run(["$templateCache",function(a){a.put("app/components/masthead/masthead.html",'
    \n

    DockerUI

    \n \n
    \n')}]),angular.module("app/components/pullImage/pullImage.html",[]).run(["$templateCache",function(a){a.put("app/components/pullImage/pullImage.html",'\n')}]),angular.module("app/components/sidebar/sidebar.html",[]).run(["$templateCache",function(a){a.put("app/components/sidebar/sidebar.html",'
    \n Running containers:\n
    \n Endpoint: {{ endpoint }}\n \n
    \n')}]),angular.module("app/components/startContainer/startcontainer.html",[]).run(["$templateCache",function(a){a.put("app/components/startContainer/startcontainer.html",'\n'); }]),angular.module("app/components/stats/stats.html",[]).run(["$templateCache",function(a){a.put("app/components/stats/stats.html",'
    \n
    \n

    Stats

    \n\n

    CPU

    \n\n
    \n
    \n \n
    \n
    \n\n

    Memory

    \n\n
    \n
    \n \n
    \n
    \n \n \n \n \n \n \n \n \n \n \n \n \n \n
    Max usage{{ data.memory_stats.max_usage | humansize }}
    Limit{{ data.memory_stats.limit | humansize }}
    Fail count{{ data.memory_stats.failcnt }}
    \n \n \n \n \n \n \n \n
    {{ key }}{{ value }}
    \n
    \n
    \n
    \n
    \n\n

    Network

    \n
    \n
    \n \n
    \n
    \n
    \n \n \n \n \n \n \n \n
    {{ key }}{{ value }}
    \n
    \n
    \n
    \n
    \n
    \n
    \n')}]); \ No newline at end of file diff --git a/test/unit/app/components/startContainerController.spec.js b/test/unit/app/components/startContainerController.spec.js index 57d898d..2988b90 100644 --- a/test/unit/app/components/startContainerController.spec.js +++ b/test/unit/app/components/startContainerController.spec.js @@ -111,6 +111,43 @@ describe('startContainerController', function () { }); }); + describe('Create and start a container with labels', function () { + it('should issue a correct create request to the Docker remote API', function () { + var controller = createController(); + var id = '6abd8bfba81cf8a05a76a4bdefcb36c4b66cd02265f4bfcd0e236468696ebc6c'; + var expectedBody = { + 'name': 'container-name', + 'Labels': { + "org.foo.bar": "Baz", + "com.biz.baz": "Boo" + } + }; + + expectGetContainers(); + + $httpBackend.expectPOST('dockerapi/containers/create?name=container-name', expectedBody).respond({ + 'Id': id, + 'Warnings': null + }); + $httpBackend.expectPOST('dockerapi/containers/' + id + '/start').respond({ + 'id': id, + 'Warnings': null + }); + + scope.config.name = 'container-name'; + scope.config.Labels = [{ + key: 'org.foo.bar', + value: 'Baz' + }, { + key: 'com.biz.baz', + value: 'Boo' + }]; + + scope.create(); + $httpBackend.flush(); + }); + }); + 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(); diff --git a/test/unit/app/shared/filters.spec.js b/test/unit/app/shared/filters.spec.js index 6ebfabe..8005572 100644 --- a/test/unit/app/shared/filters.spec.js +++ b/test/unit/app/shared/filters.spec.js @@ -73,8 +73,8 @@ describe('filters', function () { }); describe('getstatelabel', function () { - it('should return an empty string when state is undefined', inject(function (getstatelabelFilter) { - expect(getstatelabelFilter(undefined)).toBe(''); + it('should return default when state is undefined', inject(function (getstatelabelFilter) { + expect(getstatelabelFilter(undefined)).toBe('label-default'); })); it('should return label-important when a ghost state is detected', inject(function (getstatelabelFilter) {