mirror of https://github.com/portainer/portainer
Add labels to container start and display.
parent
25a4607ad6
commit
640c0b39c1
|
@ -54,7 +54,7 @@
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Created:</td>
|
<td>Created:</td>
|
||||||
<td>{{ container.Created }}</td>
|
<td>{{ container.Created | date: 'medium' }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Path:</td>
|
<td>Path:</td>
|
||||||
|
@ -62,7 +62,9 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Args:</td>
|
<td>Args:</td>
|
||||||
<td>{{ container.Args }}</td>
|
<td>
|
||||||
|
<pre>{{ container.Args.join(' ') || 'None' }}</pre>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Exposed Ports:</td>
|
<td>Exposed Ports:</td>
|
||||||
|
@ -80,6 +82,21 @@
|
||||||
</ul>
|
</ul>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>Labels:</td>
|
||||||
|
<td>
|
||||||
|
<table role="table" class="table">
|
||||||
|
<tr>
|
||||||
|
<th>Key</th>
|
||||||
|
<th>Value</th>
|
||||||
|
</tr>
|
||||||
|
<tr ng-repeat="(k, v) in container.Config.Labels">
|
||||||
|
<td>{{ k }}</td>
|
||||||
|
<td>{{ v }}</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td>Publish All:</td>
|
<td>Publish All:</td>
|
||||||
|
@ -110,7 +127,9 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Entrypoint:</td>
|
<td>Entrypoint:</td>
|
||||||
<td>{{ container.Config.Entrypoint }}</td>
|
<td>
|
||||||
|
<pre>{{ container.Config.Entrypoint.join(' ') }}</pre>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Volumes:</td>
|
<td>Volumes:</td>
|
||||||
|
@ -127,7 +146,15 @@
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>State:</td>
|
<td>State:</td>
|
||||||
<td><span class="label {{ container.State|getstatelabel }}">{{ container.State|getstatetext }}</span></td>
|
<td>
|
||||||
|
<accordion close-others="true">
|
||||||
|
<accordion-group heading="{{ container.State|getstatetext }}">
|
||||||
|
<ul>
|
||||||
|
<li ng-repeat="(key, val) in container.State">{{key}} : {{ val }}</li>
|
||||||
|
</ul>
|
||||||
|
</accordion-group>
|
||||||
|
</accordion>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Logs:</td>
|
<td>Logs:</td>
|
||||||
|
|
|
@ -11,6 +11,7 @@ angular.module('startContainer', ['ui.bootstrap'])
|
||||||
|
|
||||||
$scope.config = {
|
$scope.config = {
|
||||||
Env: [],
|
Env: [],
|
||||||
|
Labels: [],
|
||||||
Volumes: [],
|
Volumes: [],
|
||||||
SecurityOpts: [],
|
SecurityOpts: [],
|
||||||
HostConfig: {
|
HostConfig: {
|
||||||
|
@ -66,6 +67,11 @@ angular.module('startContainer', ['ui.bootstrap'])
|
||||||
config.Env = config.Env.map(function (envar) {
|
config.Env = config.Env.map(function (envar) {
|
||||||
return envar.name + '=' + envar.value;
|
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.Volumes = getNames(config.Volumes);
|
||||||
config.SecurityOpts = getNames(config.SecurityOpts);
|
config.SecurityOpts = getNames(config.SecurityOpts);
|
||||||
|
|
|
@ -148,6 +148,32 @@
|
||||||
variable
|
variable
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label>Labels:</label>
|
||||||
|
|
||||||
|
<div ng-repeat="label in config.Labels">
|
||||||
|
<div class="form-group form-inline">
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="sr-only">Key:</label>
|
||||||
|
<input type="text" ng-model="label.key" class="form-control"
|
||||||
|
placeholder="key"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<label class="sr-only">Value:</label>
|
||||||
|
<input type="text" ng-model="label.value" class="form-control"
|
||||||
|
placeholder="value"/>
|
||||||
|
</div>
|
||||||
|
<div class="form-group">
|
||||||
|
<button class="btn btn-danger btn-xs form-control"
|
||||||
|
ng-click="rmEntry(config.Labels, label)">Remove
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button type="button" class="btn btn-success btn-sm"
|
||||||
|
ng-click="addEntry(config.Labels, {key: '', value: ''})">Add Label
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</fieldset>
|
</fieldset>
|
||||||
</accordion-group>
|
</accordion-group>
|
||||||
<accordion-group heading="HostConfig options" is-open="menuStatus.hostConfigOpen">
|
<accordion-group heading="HostConfig options" is-open="menuStatus.hostConfigOpen">
|
||||||
|
|
|
@ -51,7 +51,7 @@ angular.module('dockerui.filters', [])
|
||||||
'use strict';
|
'use strict';
|
||||||
return function (state) {
|
return function (state) {
|
||||||
if (state === undefined) {
|
if (state === undefined) {
|
||||||
return '';
|
return 'label-default';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state.Ghost && state.Running) {
|
if (state.Ghost && state.Running) {
|
||||||
|
@ -60,7 +60,7 @@ angular.module('dockerui.filters', [])
|
||||||
if (state.Running) {
|
if (state.Running) {
|
||||||
return 'label-success';
|
return 'label-success';
|
||||||
}
|
}
|
||||||
return '';
|
return 'label-default';
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.filter('humansize', function () {
|
.filter('humansize', function () {
|
||||||
|
|
|
@ -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 () {
|
describe('Create and start a container with volumesFrom', function () {
|
||||||
it('should issue a correct create request to the Docker remote API', function () {
|
it('should issue a correct create request to the Docker remote API', function () {
|
||||||
var controller = createController();
|
var controller = createController();
|
||||||
|
|
|
@ -73,8 +73,8 @@ describe('filters', function () {
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getstatelabel', function () {
|
describe('getstatelabel', function () {
|
||||||
it('should return an empty string when state is undefined', inject(function (getstatelabelFilter) {
|
it('should return default when state is undefined', inject(function (getstatelabelFilter) {
|
||||||
expect(getstatelabelFilter(undefined)).toBe('');
|
expect(getstatelabelFilter(undefined)).toBe('label-default');
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should return label-important when a ghost state is detected', inject(function (getstatelabelFilter) {
|
it('should return label-important when a ghost state is detected', inject(function (getstatelabelFilter) {
|
||||||
|
|
Loading…
Reference in New Issue