fix(stack): EE-4213 Allow latest image to be pulled for stacks (#7653)

pull/7661/head
congs 2022-09-14 10:17:32 +12:00 committed by GitHub
parent 0242c8e4ef
commit 1a9d793f2f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 51 additions and 58 deletions

View File

@ -102,33 +102,35 @@ class StackRedeployGitFormController {
}
async submit() {
const tplCrop =
'<div>Any changes to this stack or application made locally in Portainer will be overridden, which may cause service interruption. Do you wish to continue?</div>' +
'<div"><div style="position: absolute; right: 5px; top: 84px; z-index: 999">' +
'<be-feature-indicator feature="stackPullImageFeature"></be-feature-indicator></div></div>';
const template = angular.element(tplCrop);
const html = this.$compile(template)(this.$scope);
this.ModalService.confirmStackUpdate(html, true, false, 'btn-warning', async (result) => {
if (!result) {
return;
const isSwarmStack = this.stack.Type === 1;
const that = this;
this.ModalService.confirmStackUpdate(
'Any changes to this stack or application made locally in Portainer will be overridden, which may cause service interruption. Do you wish to continue?',
isSwarmStack,
'btn-warning',
async function (result) {
if (!result) {
return;
}
try {
that.state.redeployInProgress = true;
await that.StackService.updateGit(
that.stack.Id,
that.stack.EndpointId,
that.FormHelper.removeInvalidEnvVars(that.formValues.Env),
that.formValues.Option.Prune,
that.formValues,
!!result[0]
);
that.Notifications.success('Success', 'Pulled and redeployed stack successfully');
that.$state.reload();
} catch (err) {
that.Notifications.error('Failure', err, 'Failed redeploying stack');
} finally {
that.state.redeployInProgress = false;
}
}
try {
this.state.redeployInProgress = true;
await this.StackService.updateGit(
this.stack.Id,
this.stack.EndpointId,
this.FormHelper.removeInvalidEnvVars(this.formValues.Env),
this.formValues.Option.Prune,
this.formValues
);
this.Notifications.success('Success', 'Pulled and redeployed stack successfully');
this.$state.reload();
} catch (err) {
this.Notifications.error('Failure', err, 'Failed redeploying stack');
} finally {
this.state.redeployInProgress = false;
}
});
);
}
async saveGitSettings() {

View File

@ -266,8 +266,17 @@ angular.module('portainer.app').factory('StackService', [
return deferred.promise;
};
service.updateStack = function (stack, stackFile, env, prune) {
return Stack.update({ endpointId: stack.EndpointId }, { id: stack.Id, StackFileContent: stackFile, Env: env, Prune: prune }).$promise;
service.updateStack = function (stack, stackFile, env, prune, pullImage) {
return Stack.update(
{ endpointId: stack.EndpointId },
{
id: stack.Id,
StackFileContent: stackFile,
Env: env,
Prune: prune,
PullImage: pullImage,
}
).$promise;
};
service.updateKubeStack = function (stack, stackFile, gitConfig) {
@ -436,7 +445,7 @@ angular.module('portainer.app').factory('StackService', [
return Stack.stop({ id }).$promise;
}
function updateGit(id, endpointId, env, prune, gitConfig) {
function updateGit(id, endpointId, env, prune, gitConfig, pullImage) {
return Stack.updateGit(
{ endpointId, id },
{
@ -446,6 +455,7 @@ angular.module('portainer.app').factory('StackService', [
RepositoryAuthentication: gitConfig.RepositoryAuthentication,
RepositoryUsername: gitConfig.RepositoryUsername,
RepositoryPassword: gitConfig.RepositoryPassword,
PullImage: pullImage,
}
).$promise;
}

View File

@ -162,45 +162,31 @@ export function confirmServiceForceUpdate(
export function confirmStackUpdate(
message: string,
defaultDisabled: boolean,
defaultToggle: boolean,
confirmButtonClassName: string | undefined,
confirmButtonClass: string | undefined,
callback: PromptCallback
) {
const sanitizedMessage =
typeof message === 'string' ? sanitize(message) : message;
const sanitizedMessage = sanitize(message);
const box = prompt({
title: buildTitle('Are you sure?'),
inputType: 'checkbox',
inputOptions: [
{
text: 'Pull latest image version<i></i>',
text: 'Re-pull image and redeploy<i></i>',
value: '1',
},
],
buttons: {
confirm: {
label: 'Update',
className: confirmButtonClassName || 'btn-primary',
className: 'btn-primary',
},
},
callback,
});
box.find('.bootbox-body').prepend(sanitizedMessage);
const checkbox = box.find('.bootbox-input-checkbox');
checkbox.prop('checked', defaultToggle);
checkbox.prop('disabled', defaultDisabled);
const checkboxDiv = box.find('.checkbox');
checkboxDiv.removeClass('checkbox');
checkboxDiv.prop(
'style',
'position: relative; display: block; margin-top: 10px; margin-bottom: 10px;'
);
const checkboxLabel = box.find('.form-check-label');
checkboxLabel.addClass('switch box-selector-item limited business mt-4');
checkboxLabel.prop('style', 'width: 100%');
const switchEle = checkboxLabel.find('i');
switchEle.prop('style', 'margin-left:20px');
customizeCheckboxPrompt(box, sanitizedMessage, defaultToggle);
}
function customizeCheckboxPrompt(

View File

@ -244,13 +244,8 @@ angular.module('portainer.app').controller('StackController', [
$scope.deployStack = function () {
const stack = $scope.stack;
const tplCrop =
'<div>Do you want to force an update of the stack?</div>' +
'<div style="position: absolute; right: 5px; top: 50px; z-index: 999"><be-feature-indicator feature="stackPullImageFeature"></be-feature-indicator></div>';
const template = angular.element(tplCrop);
const html = $compile(template)($scope);
// 'Do you want to force an update of the stack?'
ModalService.confirmStackUpdate(html, true, false, null, function (result) {
const isSwarmStack = stack.Type === 1;
ModalService.confirmStackUpdate('Do you want to force an update of the stack?', isSwarmStack, null, function (result) {
if (!result) {
return;
}
@ -267,7 +262,7 @@ angular.module('portainer.app').controller('StackController', [
}
$scope.state.actionInProgress = true;
StackService.updateStack(stack, stackFile, env, prune)
StackService.updateStack(stack, stackFile, env, prune, !!result[0])
.then(function success() {
Notifications.success('Success', 'Stack successfully deployed');
$scope.state.isEditorDirty = false;