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: |
+
+
+
+ Key |
+ Value |
+
+
+ {{ 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 }} |
+
+
+
+
+
+
+ |
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:
+
+ Tags: |
+
+
+ - {{ tag }}
+
+
+
+ |
+
Created: |
- {{ image.Created }} |
+ {{ image.Created | date: 'medium'}} |
Parent: |
@@ -89,14 +99,15 @@ Containers created:
-
+
+
-
+
@@ -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/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) {