mirror of https://github.com/portainer/portainer
fix(container-creation): add default/override options (#4119)
* fix(container-creation): add default/override options * fix(container-creation): allow override with empty string on creation * fix(container-creation): add tooltip & update placeholder * fix(container-creation): add warning on duplicatepull/4173/head
parent
1b88ca2285
commit
b9c2bf487b
|
@ -7,6 +7,7 @@ angular.module('portainer.docker').component('porImageRegistry', {
|
||||||
autoComplete: '<',
|
autoComplete: '<',
|
||||||
labelClass: '@',
|
labelClass: '@',
|
||||||
inputClass: '@',
|
inputClass: '@',
|
||||||
|
onImageChange: '&',
|
||||||
},
|
},
|
||||||
require: {
|
require: {
|
||||||
form: '^form',
|
form: '^form',
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
ng-model="$ctrl.model.Image"
|
ng-model="$ctrl.model.Image"
|
||||||
name="image_name"
|
name="image_name"
|
||||||
placeholder="e.g. myImage:myTag"
|
placeholder="e.g. myImage:myTag"
|
||||||
|
ng-change="$ctrl.onImageChange()"
|
||||||
required
|
required
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -77,6 +77,8 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
CpuLimit: 0,
|
CpuLimit: 0,
|
||||||
MemoryLimit: 0,
|
MemoryLimit: 0,
|
||||||
MemoryReservation: 0,
|
MemoryReservation: 0,
|
||||||
|
CmdMode: 'default',
|
||||||
|
EntrypointMode: 'default',
|
||||||
NodeName: null,
|
NodeName: null,
|
||||||
capabilities: [],
|
capabilities: [],
|
||||||
LogDriverName: '',
|
LogDriverName: '',
|
||||||
|
@ -89,6 +91,7 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
$scope.state = {
|
$scope.state = {
|
||||||
formValidationError: '',
|
formValidationError: '',
|
||||||
actionInProgress: false,
|
actionInProgress: false,
|
||||||
|
mode: '',
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.refreshSlider = function () {
|
$scope.refreshSlider = function () {
|
||||||
|
@ -97,12 +100,18 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.onImageNameChange = function () {
|
||||||
|
$scope.formValues.CmdMode = 'default';
|
||||||
|
$scope.formValues.EntrypointMode = 'default';
|
||||||
|
};
|
||||||
|
|
||||||
$scope.config = {
|
$scope.config = {
|
||||||
Image: '',
|
Image: '',
|
||||||
Env: [],
|
Env: [],
|
||||||
Cmd: '',
|
Cmd: '',
|
||||||
MacAddress: '',
|
MacAddress: '',
|
||||||
ExposedPorts: {},
|
ExposedPorts: {},
|
||||||
|
Entrypoint: '',
|
||||||
HostConfig: {
|
HostConfig: {
|
||||||
RestartPolicy: {
|
RestartPolicy: {
|
||||||
Name: 'no',
|
Name: 'no',
|
||||||
|
@ -212,6 +221,20 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
config.Tty = tty;
|
config.Tty = tty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prepareCmd(config) {
|
||||||
|
if (_.isEmpty(config.Cmd) || $scope.formValues.CmdMode == 'default') {
|
||||||
|
delete config.Cmd;
|
||||||
|
} else {
|
||||||
|
config.Cmd = ContainerHelper.commandStringToArray(config.Cmd);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function prepareEntrypoint(config) {
|
||||||
|
if ($scope.formValues.EntrypointMode == 'default' || (_.isEmpty(config.Cmd) && _.isEmpty(config.Entrypoint))) {
|
||||||
|
config.Entrypoint = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function prepareEnvironmentVariables(config) {
|
function prepareEnvironmentVariables(config) {
|
||||||
var env = [];
|
var env = [];
|
||||||
config.Env.forEach(function (v) {
|
config.Env.forEach(function (v) {
|
||||||
|
@ -368,7 +391,8 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
|
|
||||||
function prepareConfiguration() {
|
function prepareConfiguration() {
|
||||||
var config = angular.copy($scope.config);
|
var config = angular.copy($scope.config);
|
||||||
config.Cmd = ContainerHelper.commandStringToArray(config.Cmd);
|
prepareCmd(config);
|
||||||
|
prepareEntrypoint(config);
|
||||||
prepareNetworkConfig(config);
|
prepareNetworkConfig(config);
|
||||||
prepareImageConfig(config);
|
prepareImageConfig(config);
|
||||||
preparePortBindings(config);
|
preparePortBindings(config);
|
||||||
|
@ -386,8 +410,16 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
function loadFromContainerCmd() {
|
function loadFromContainerCmd() {
|
||||||
if ($scope.config.Cmd) {
|
if ($scope.config.Cmd) {
|
||||||
$scope.config.Cmd = ContainerHelper.commandArrayToString($scope.config.Cmd);
|
$scope.config.Cmd = ContainerHelper.commandArrayToString($scope.config.Cmd);
|
||||||
} else {
|
$scope.formValues.CmdMode = 'override';
|
||||||
$scope.config.Cmd = '';
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadFromContainerEntrypoint() {
|
||||||
|
if (_.has($scope.config, 'Entrypoint')) {
|
||||||
|
if ($scope.config.Entrypoint == null) {
|
||||||
|
$scope.config.Entrypoint = '';
|
||||||
|
}
|
||||||
|
$scope.formValues.EntrypointMode = 'override';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -577,8 +609,10 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
$scope.formValues.AccessControlData.AccessControlEnabled = false;
|
$scope.formValues.AccessControlData.AccessControlEnabled = false;
|
||||||
}
|
}
|
||||||
$scope.fromContainer = fromContainer;
|
$scope.fromContainer = fromContainer;
|
||||||
|
$scope.state.mode = 'duplicate';
|
||||||
$scope.config = ContainerHelper.configFromContainer(fromContainer.Model);
|
$scope.config = ContainerHelper.configFromContainer(fromContainer.Model);
|
||||||
loadFromContainerCmd(d);
|
loadFromContainerCmd(d);
|
||||||
|
loadFromContainerEntrypoint(d);
|
||||||
loadFromContainerLogging(d);
|
loadFromContainerLogging(d);
|
||||||
loadFromContainerPortBindings(d);
|
loadFromContainerPortBindings(d);
|
||||||
loadFromContainerVolumes(d);
|
loadFromContainerVolumes(d);
|
||||||
|
@ -706,7 +740,6 @@ angular.module('portainer.docker').controller('CreateContainerController', [
|
||||||
|
|
||||||
function create() {
|
function create() {
|
||||||
var oldContainer = null;
|
var oldContainer = null;
|
||||||
|
|
||||||
HttpRequestHelper.setPortainerAgentTargetHeader($scope.formValues.NodeName);
|
HttpRequestHelper.setPortainerAgentTargetHeader($scope.formValues.NodeName);
|
||||||
return findCurrentContainer().then(setOldContainer).then(confirmCreateContainer).then(startCreationProcess).catch(notifyOnError).finally(final);
|
return findCurrentContainer().then(setOldContainer).then(confirmCreateContainer).then(startCreationProcess).catch(notifyOnError).finally(final);
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,16 @@
|
||||||
<rd-header-content> <a ui-sref="docker.containers">Containers</a> > Add container </rd-header-content>
|
<rd-header-content> <a ui-sref="docker.containers">Containers</a> > Add container </rd-header-content>
|
||||||
</rd-header>
|
</rd-header>
|
||||||
|
|
||||||
|
<information-panel title-text="Caution" ng-if="state.mode == 'duplicate'">
|
||||||
|
<span class="small">
|
||||||
|
<p class="text-muted">
|
||||||
|
<i class="fa fa-exclamation-circle orange-icon" aria-hidden="true" style="margin-right: 2px;"></i>
|
||||||
|
The new container may fail to start if the image is changed, and settings from the previous container aren't compatible. Common causes include entrypoint, cmd or
|
||||||
|
<a href="http://portainer.readthedocs.io/en/stable/agent.html" target="_blank">other settings</a> set by an image.
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
</information-panel>
|
||||||
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-lg-12 col-md-12 col-xs-12">
|
<div class="col-lg-12 col-md-12 col-xs-12">
|
||||||
<rd-widget>
|
<rd-widget>
|
||||||
|
@ -35,6 +45,7 @@
|
||||||
auto-complete="true"
|
auto-complete="true"
|
||||||
label-class="col-sm-1"
|
label-class="col-sm-1"
|
||||||
input-class="col-sm-11"
|
input-class="col-sm-11"
|
||||||
|
on-image-change="onImageNameChange()"
|
||||||
></por-image-registry>
|
></por-image-registry>
|
||||||
<!-- !image-and-registry -->
|
<!-- !image-and-registry -->
|
||||||
<!-- always-pull -->
|
<!-- always-pull -->
|
||||||
|
@ -192,15 +203,47 @@
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="container_command" class="col-sm-2 col-lg-1 control-label text-left">Command</label>
|
<label for="container_command" class="col-sm-2 col-lg-1 control-label text-left">Command</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="text" class="form-control" ng-model="config.Cmd" id="container_command" placeholder="e.g. /usr/bin/nginx -t -c /mynginx.conf" />
|
<div class="input-group">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<button class="btn btn-primary" ng-model="formValues.CmdMode" uib-btn-radio="'default'" style="margin-left: 0px;"> Default</button>
|
||||||
|
<button class="btn btn-primary" ng-model="formValues.CmdMode" uib-btn-radio="'override'">Override</button>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
ng-model="config.Cmd"
|
||||||
|
ng-disabled="formValues.CmdMode === 'default'"
|
||||||
|
id="container_command"
|
||||||
|
placeholder="e.g. '-logtostderr' '--housekeeping_interval=5s' or /usr/bin/nginx -t -c /mynginx.conf"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- !command-input -->
|
<!-- !command-input -->
|
||||||
<!-- entrypoint-input -->
|
<!-- entrypoint-input -->
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label for="container_entrypoint" class="col-sm-2 col-lg-1 control-label text-left">Entry Point</label>
|
<label for="container_entrypoint" class="col-sm-2 col-lg-1 control-label text-left">
|
||||||
|
Entrypoint
|
||||||
|
<portainer-tooltip
|
||||||
|
position="bottom"
|
||||||
|
message="When container entrypoint is entered as part of the Command field, set Entrypoint to Override mode and leave blank, else it will revert to default."
|
||||||
|
></portainer-tooltip>
|
||||||
|
</label>
|
||||||
<div class="col-sm-9">
|
<div class="col-sm-9">
|
||||||
<input type="text" class="form-control" ng-model="config.Entrypoint" id="container_entrypoint" placeholder="e.g. /bin/sh -c" />
|
<div class="input-group">
|
||||||
|
<div class="input-group-btn">
|
||||||
|
<label class="btn btn-primary" ng-model="formValues.EntrypointMode" uib-btn-radio="'default'" style="margin-left: 0px;"> Default</label>
|
||||||
|
<label class="btn btn-primary" ng-model="formValues.EntrypointMode" uib-btn-radio="'override'">Override</label>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="form-control"
|
||||||
|
ng-model="config.Entrypoint"
|
||||||
|
ng-disabled="formValues.EntrypointMode === 'default'"
|
||||||
|
id="container_entrypoint"
|
||||||
|
placeholder="e.g. /bin/sh -c"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- !entrypoint-input -->
|
<!-- !entrypoint-input -->
|
||||||
|
|
Loading…
Reference in New Issue