diff --git a/README.md b/README.md index ce004a2a2..89a0c7d31 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,12 @@ UI For Docker is a web interface for the Docker Remote API. The goal is to prov * Minimal dependencies - I really want to keep this project a pure html/js app. * Consistency - The web UI should be consistent with the commands found on the docker CLI. +## Supported Docker versions + +The current Docker version support policy is the following: `N` to `N-2` included where `N` is the latest version. + +At the moment, the following versions are supported: 1.9, 1.10 & 1.11. + ## Run ### Quickstart diff --git a/app/app.js b/app/app.js index 586194607..0b7d4fa58 100644 --- a/app/app.js +++ b/app/app.js @@ -144,4 +144,4 @@ angular.module('uifordocker', [ .constant('DOCKER_ENDPOINT', 'dockerapi') .constant('DOCKER_PORT', '') // Docker port, leave as an empty string if no port is requred. If you have a port, prefix it with a ':' i.e. :4243 .constant('CONFIG_ENDPOINT', '/config') - .constant('UI_VERSION', 'v1.4.0'); + .constant('UI_VERSION', 'v1.5.0'); diff --git a/app/components/dashboard/dashboard.html b/app/components/dashboard/dashboard.html index b1b80222c..61ba5f16e 100644 --- a/app/components/dashboard/dashboard.html +++ b/app/components/dashboard/dashboard.html @@ -1,76 +1,131 @@ - + + + Dashboard
-
+
- -
- -
-
{{ containerData.total }}
-
Containers
+ + + + + + + + + + + + + + + + + + + + + +
Name{{ infoData.Name }}
Docker version{{ infoData.ServerVersion }}
CPU{{ infoData.NCPU }}
Memory{{ infoData.MemTotal|humansize }}
-
+
- -
- -
-
{{ containerData.running }}
-
Running
-
-
-
-
- - -
- -
-
{{ containerData.stopped }}
-
Stopped
-
-
-
-
- - -
- -
-
{{ containerData.ghost }}
-
Ghost
+ + + + + + + + + + + + + + + + + + + + + +
Nodes{{ infoData.SystemStatus[3][1] }}
Swarm version{{ infoData.ServerVersion|swarmversion }}
Total CPU{{ infoData.NCPU }}
Total memory{{ infoData.MemTotal|humansize }}
-
- - - - -

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

-
-
-
+ - + +
+
diff --git a/app/components/dashboard/dashboardController.js b/app/components/dashboard/dashboardController.js index 5c348d8fb..2b3667304 100644 --- a/app/components/dashboard/dashboardController.js +++ b/app/components/dashboard/dashboardController.js @@ -1,49 +1,83 @@ angular.module('dashboard', []) -.controller('DashboardController', ['$scope', 'Config', 'Container', 'Image', 'Settings', 'LineChart', -function ($scope, Config, Container, Image, Settings, LineChart) { +.controller('DashboardController', ['$scope', '$q', 'Config', 'Container', 'Image', 'Network', 'Volume', 'Info', +function ($scope, $q, Config, Container, Image, Network, Volume, Info) { - $scope.containerData = {}; - - var buildCharts = function (data) { - $scope.containerData.total = data.length; - LineChart.build('#containers-started-chart', data, function (c) { - return new Date(c.Created * 1000).toLocaleDateString(); - }); - var s = $scope; - Image.query({}, function (d) { - s.totalImages = d.length; - LineChart.build('#images-created-chart', d, function (c) { - return new Date(c.Created * 1000).toLocaleDateString(); - }); - }); + $scope.containerData = { + total: 0 + }; + $scope.imageData = { + total: 0 + }; + $scope.networkData = { + total: 0 + }; + $scope.volumeData = { + total: 0 }; + function prepareContainerData(d) { + var running = 0; + var stopped = 0; + + var containers = d; + if (hiddenLabels) { + containers = hideContainers(d); + } + + for (var i = 0; i < containers.length; i++) { + var item = containers[i]; + if (item.Status.indexOf('Up') !== -1) { + running += 1; + } else if (item.Status.indexOf('Exit') !== -1) { + stopped += 1; + } + } + $scope.containerData.running = running; + $scope.containerData.stopped = stopped; + $scope.containerData.total = containers.length; + } + + function prepareImageData(d) { + var images = d; + var totalImageSize = 0; + for (var i = 0; i < images.length; i++) { + var item = images[i]; + totalImageSize += item.VirtualSize; + } + $scope.imageData.total = images.length; + $scope.imageData.size = totalImageSize; + } + + function prepareVolumeData(d) { + var volumes = d.Volumes; + $scope.volumeData.total = volumes.length; + } + + function prepareNetworkData(d) { + var networks = d; + $scope.networkData.total = networks.length; + } + + function prepareInfoData(d) { + var info = d; + $scope.infoData = info; + } + function fetchDashboardData() { - Container.query({all: 1}, function (d) { - var running = 0; - var ghost = 0; - var stopped = 0; - - var containers = d; - if (hiddenLabels) { - containers = hideContainers(d); - } - - for (var i = 0; i < containers.length; i++) { - var item = containers[i]; - if (item.Status === "Ghost") { - ghost += 1; - } else if (item.Status.indexOf('Exit') !== -1) { - stopped += 1; - } else { - running += 1; - } - } - $scope.containerData.running = running; - $scope.containerData.stopped = stopped; - $scope.containerData.ghost = ghost; - - buildCharts(containers); + $('#loadingViewSpinner').show(); + $q.all([ + Container.query({all: 1}).$promise, + Image.query({}).$promise, + Volume.query({}).$promise, + Network.query({}).$promise, + Info.get({}).$promise + ]).then(function (d) { + prepareContainerData(d[0]); + prepareImageData(d[1]); + prepareVolumeData(d[2]); + prepareNetworkData(d[3]); + prepareInfoData(d[4]); + $('#loadingViewSpinner').hide(); }); } @@ -63,6 +97,7 @@ function ($scope, Config, Container, Image, Settings, LineChart) { }; Config.$promise.then(function (c) { + $scope.swarm = c.swarm; hiddenLabels = c.hiddenLabels; fetchDashboardData(); }); diff --git a/app/components/docker/docker.html b/app/components/docker/docker.html index c26680f28..a3f723781 100644 --- a/app/components/docker/docker.html +++ b/app/components/docker/docker.html @@ -45,7 +45,7 @@
- + diff --git a/app/components/images/images.html b/app/components/images/images.html index 362ee65f1..c44f1a431 100644 --- a/app/components/images/images.html +++ b/app/components/images/images.html @@ -63,7 +63,7 @@
-
+
@@ -76,7 +76,7 @@ - + diff --git a/app/components/networks/networks.html b/app/components/networks/networks.html index 38d6a6410..96add077d 100644 --- a/app/components/networks/networks.html +++ b/app/components/networks/networks.html @@ -25,7 +25,7 @@
-
- Repository + Tags @@ -101,7 +101,9 @@
{{ image.Id|truncate:20}}{{ image|repotag }} + {{ tag }} + {{ image.VirtualSize|humansize }} {{ image.Created|getdate }}
+
diff --git a/app/components/volumes/volumes.html b/app/components/volumes/volumes.html index 1d41c574e..6c66bc2f0 100644 --- a/app/components/volumes/volumes.html +++ b/app/components/volumes/volumes.html @@ -25,7 +25,7 @@
-
+
diff --git a/app/directives/widget-header.js b/app/directives/widget-header.js index ec1cb2efc..22bed24cd 100644 --- a/app/directives/widget-header.js +++ b/app/directives/widget-header.js @@ -8,7 +8,7 @@ angular icon: '@' }, transclude: true, - template: '
{{title}}
', + template: '
{{title}}
', restrict: 'E' }; return directive; diff --git a/app/shared/filters.js b/app/shared/filters.js index f1b40abfb..10fe596ff 100644 --- a/app/shared/filters.js +++ b/app/shared/filters.js @@ -130,23 +130,29 @@ angular.module('dockerui.filters', []) return _.split(container.Names[0], '/')[2]; }; }) +.filter('swarmversion', function () { + 'use strict'; + return function (text) { + return _.split(text, '/')[1]; + }; +}) .filter('swarmhostname', function () { 'use strict'; return function (container) { return _.split(container.Names[0], '/')[1]; }; }) -.filter('repotag', function () { +.filter('repotags', function () { 'use strict'; return function (image) { if (image.RepoTags && image.RepoTags.length > 0) { var tag = image.RepoTags[0]; if (tag === ':') { - tag = ''; + return []; } - return tag; + return image.RepoTags; } - return ''; + return []; }; }) .filter('getdate', function () { diff --git a/assets/css/app.css b/assets/css/app.css index 5d99a5c85..3921400ff 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -165,3 +165,23 @@ input[type="radio"] { .clickable { cursor: pointer; } + +.text-icon { + margin-right: 5px; +} + +.green-icon { + color: #23ae89; +} + +.red-icon { + color: #ae2323; +} + +.image-tag { + margin-right: 5px; +} + +.widget .widget-body table tbody .image-tag { + font-size: 90% !important; +} diff --git a/bower.json b/bower.json index f1e37a8f1..56800d37d 100644 --- a/bower.json +++ b/bower.json @@ -1,6 +1,6 @@ { "name": "uifordocker", - "version": "1.4.0", + "version": "1.5.0", "homepage": "https://github.com/kevana/ui-for-docker", "authors": [ "Michael Crosby ", diff --git a/dockerui.go b/dockerui.go index 5f995f205..3cc089dbe 100644 --- a/dockerui.go +++ b/dockerui.go @@ -221,7 +221,7 @@ func csrfWrapper(h http.Handler) http.Handler { } func main() { - kingpin.Version("1.4.0") + kingpin.Version("1.5.0") kingpin.Parse() configuration := Config{ diff --git a/package.json b/package.json index 2fa2f25f0..829adeb49 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "author": "Michael Crosby & Kevan Ahlquist", "name": "uifordocker", "homepage": "https://github.com/kevana/ui-for-docker", - "version": "1.4.0", + "version": "1.5.0", "repository": { "type": "git", "url": "git@github.com:kevana/ui-for-docker.git"