feat(service): Add editable service update configuration (#346)

* #304 Add editable service update configuration

* fix unable to use 0 for update-delay

* apply margin top to center help text
pull/407/head
Glowbal 8 years ago committed by Anthony Lapenna
parent 712b4528c0
commit 986171ecfe

@ -18,7 +18,10 @@ function ($scope, $state, Service, Volume, Network, ImageHelper, Messages) {
Volumes: [], Volumes: [],
Network: '', Network: '',
ExtraNetworks: [], ExtraNetworks: [],
Ports: [] Ports: [],
Parallelism: 1,
UpdateDelay: 0,
FailureAction: 'pause'
}; };
$scope.addPortBinding = function() { $scope.addPortBinding = function() {
@ -168,6 +171,14 @@ function ($scope, $state, Service, Volume, Network, ImageHelper, Messages) {
config.Networks = _.uniqWith(networks, _.isEqual); config.Networks = _.uniqWith(networks, _.isEqual);
} }
function prepareUpdateConfig(config, input) {
config.UpdateConfig = {
Parallelism: input.Parallelism || 0,
Delay: input.UpdateDelay || 0,
FailureAction: input.FailureAction
};
}
function prepareConfiguration() { function prepareConfiguration() {
var input = $scope.formValues; var input = $scope.formValues;
var config = { var config = {
@ -188,6 +199,7 @@ function ($scope, $state, Service, Volume, Network, ImageHelper, Messages) {
prepareLabelsConfig(config, input); prepareLabelsConfig(config, input);
prepareVolumes(config, input); prepareVolumes(config, input);
prepareNetworks(config, input); prepareNetworks(config, input);
prepareUpdateConfig(config, input);
return config; return config;
} }

@ -102,6 +102,7 @@
<li class="interactive"><a data-target="#volumes" data-toggle="tab">Volumes</a></li> <li class="interactive"><a data-target="#volumes" data-toggle="tab">Volumes</a></li>
<li class="interactive"><a data-target="#network" data-toggle="tab">Network</a></li> <li class="interactive"><a data-target="#network" data-toggle="tab">Network</a></li>
<li class="interactive"><a data-target="#labels" data-toggle="tab">Labels</a></li> <li class="interactive"><a data-target="#labels" data-toggle="tab">Labels</a></li>
<li class="interactive"><a data-target="#update-config" data-toggle="tab">Update config</a></li>
</ul> </ul>
<!-- tab-content --> <!-- tab-content -->
<div class="tab-content"> <div class="tab-content">
@ -324,7 +325,55 @@
</form> </form>
</div> </div>
<!-- !tab-labels --> <!-- !tab-labels -->
<!-- tab-update-config -->
<div class="tab-pane" id="update-config">
<form class="form-horizontal" style="margin-top: 15px;">
<!-- parallelism-input -->
<div class="form-group">
<label for="parallelism" class="col-sm-1 control-label text-left">Parallelism</label>
<div class="col-sm-1">
<input type="number" class="form-control" ng-model="formValues.Parallelism" id="parallelism" placeholder="e.g. 1">
</div>
<div class="col-sm-10">
<p class="small text-muted" style="margin-top: 10px;">
Maximum number of tasks to be updated simultaneously (0 to update all at once).
</p>
</div>
</div>
<!-- !parallelism-input -->
<!-- delay-input -->
<div class="form-group">
<label for="update-delay" class="col-sm-1 control-label text-left">Delay</label>
<div class="col-sm-2">
<input type="number" class="form-control" ng-model="formValues.UpdateDelay" id="update-delay" placeholder="e.g. 10">
</div>
<div class="col-sm-9">
<p class="small text-muted" style="margin-top: 10px;">
Amount of time between updates.
</p>
</div>
</div>
<!-- !delay-input -->
<!-- failureAction-input -->
<div class="form-group">
<label for="failure_action" class="col-sm-1 control-label text-left">Failure Action</label>
<div class="col-sm-3">
<label class="radio-inline">
<input type="radio" name="failure_action" ng-model="formValues.FailureAction" value="continue">
Continue
</label>
<label class="radio-inline">
<input type="radio" name="failure_action" ng-model="formValues.FailureAction" value="pause">
Pause
</label>
</div>
<div class="col-sm-8"></div>
</div>
<!-- !failureAction-input -->
</form>
</div>
<!-- !tab-update-config -->
<!-- tab-security --> <!-- tab-security -->
<div class="tab-pane" id="security"> <div class="tab-pane" id="security">
</div> </div>

@ -168,6 +168,52 @@
</div> </div>
</td> </td>
</tr> </tr>
<tr>
<td>Update Parallelism</td>
<td>
<span ng-if="!service.EditParallelism">
{{ service.UpdateParallelism }}
<a class="interactive" ng-click="service.EditParallelism = true;"><i class="fa fa-arrows-v" aria-hidden="true"></i> Change</a>
</span>
<span ng-if="service.EditParallelism">
<input class="input-sm" type="number" ng-model="service.newServiceUpdateParallelism" />
<a class="interactive" ng-click="service.EditParallelism = false;"><i class="fa fa-times"></i></a>
<a class="interactive" ng-click="changeParallelism(service)"><i class="fa fa-check-square-o"></i></a>
</span>
</td>
</tr>
<tr>
<td>Update Delay</td>
<td>
<span ng-if="!service.EditDelay">
{{ service.UpdateDelay }}
<a class="interactive" ng-click="service.EditDelay = true;"><i class="fa fa-arrows-v" aria-hidden="true"></i> Change</a>
</span>
<span ng-if="service.EditDelay">
<input class="input-sm" type="number" ng-model="service.newServiceUpdateDelay" />
<a class="interactive" ng-click="service.EditDelay = false;"><i class="fa fa-times"></i></a>
<a class="interactive" ng-click="changeUpdateDelay(service)"><i class="fa fa-check-square-o"></i></a>
</span>
</td>
</tr>
<tr>
<td>Update Failure Action</td>
<td>
<div class="form-group">
<div class="col-sm-3">
<label class="radio-inline">
<input type="radio" name="failure_action" ng-model="service.newServiceUpdateFailureAction" value="continue" ng-change="changeUpdateFailureAction(service)">
Continue
</label>
<label class="radio-inline">
<input type="radio" name="failure_action" ng-model="service.newServiceUpdateFailureAction" value="pause" ng-change="changeUpdateFailureAction(service)">
Pause
</label>
</div>
<div class="col-sm-8"></div>
</div>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</rd-widget-body> </rd-widget-body>

@ -60,6 +60,18 @@ function ($scope, $stateParams, $state, Service, ServiceHelper, Task, Node, Mess
service.hasChanges = service.hasChanges || removedElement !== null; service.hasChanges = service.hasChanges || removedElement !== null;
}; };
$scope.changeParallelism = function changeParallelism(service) {
updateServiceAttribute(service, 'UpdateParallelism', service.newServiceUpdateParallelism);
service.EditParallelism = false;
};
$scope.changeUpdateDelay = function changeUpdateDelay(service) {
updateServiceAttribute(service, 'UpdateDelay', service.newServiceUpdateDelay);
service.EditDelay = false;
};
$scope.changeUpdateFailureAction = function changeUpdateFailureAction(service) {
updateServiceAttribute(service, 'UpdateFailureAction', service.newServiceUpdateFailureAction);
};
$scope.cancelChanges = function changeServiceImage(service) { $scope.cancelChanges = function changeServiceImage(service) {
Object.keys(previousServiceValues).forEach(function(attribute) { Object.keys(previousServiceValues).forEach(function(attribute) {
service[attribute] = previousServiceValues[attribute]; // reset service values service[attribute] = previousServiceValues[attribute]; // reset service values
@ -86,6 +98,12 @@ function ($scope, $stateParams, $state, Service, ServiceHelper, Task, Node, Mess
config.Mode.Replicated.Replicas = service.Replicas; config.Mode.Replicated.Replicas = service.Replicas;
} }
config.UpdateConfig = {
Parallelism: service.newServiceUpdateParallelism,
Delay: service.newServiceUpdateDelay,
FailureAction: service.newServiceUpdateFailureAction
};
Service.update({ id: service.Id, version: service.Version }, config, function (data) { Service.update({ id: service.Id, version: service.Version }, config, function (data) {
$('#loadServicesSpinner').hide(); $('#loadServicesSpinner').hide();
Messages.send("Service successfully updated", "Service updated"); Messages.send("Service successfully updated", "Service updated");
@ -121,6 +139,10 @@ function ($scope, $stateParams, $state, Service, ServiceHelper, Task, Node, Mess
service.newServiceName = service.Name; service.newServiceName = service.Name;
service.newServiceImage = service.Image; service.newServiceImage = service.Image;
service.newServiceReplicas = service.Replicas; service.newServiceReplicas = service.Replicas;
service.newServiceUpdateParallelism = service.UpdateParallelism;
service.newServiceUpdateDelay = service.UpdateDelay;
service.newServiceUpdateFailureAction = service.UpdateFailureAction;
service.EnvironmentVariables = translateEnvironmentVariables(service.Env); service.EnvironmentVariables = translateEnvironmentVariables(service.Env);
service.ServiceLabels = translateLabelsToServiceLabels(service.Labels); service.ServiceLabels = translateLabelsToServiceLabels(service.Labels);
service.ServiceContainerLabels = translateLabelsToServiceLabels(service.ContainerLabels); service.ServiceContainerLabels = translateLabelsToServiceLabels(service.ContainerLabels);

@ -45,6 +45,16 @@ function ServiceViewModel(data) {
if (data.Endpoint.Ports) { if (data.Endpoint.Ports) {
this.Ports = data.Endpoint.Ports; this.Ports = data.Endpoint.Ports;
} }
if (data.Spec.UpdateConfig) {
this.UpdateParallelism = (typeof data.Spec.UpdateConfig.Parallelism !== undefined) ? data.Spec.UpdateConfig.Parallelism || 0 : 1;
this.UpdateDelay = data.Spec.UpdateConfig.Delay || 0;
this.UpdateFailureAction = data.Spec.UpdateConfig.FailureAction || 'pause';
} else {
this.UpdateParallelism = 1;
this.UpdateDelay = 0;
this.UpdateFailureAction = 'pause';
}
this.Checked = false; this.Checked = false;
this.Scale = false; this.Scale = false;
this.EditName = false; this.EditName = false;

Loading…
Cancel
Save