mirror of https://github.com/portainer/portainer
feat(stack): detach git based stacks from git EE-2143 (#6307)
* feat(stack): detach git based stacks from gitpull/6400/head
parent
125d84cbd1
commit
9ff8f42a66
|
@ -49,7 +49,7 @@ func (payload *updateSwarmStackPayload) Validate(r *http.Request) error {
|
||||||
|
|
||||||
// @id StackUpdate
|
// @id StackUpdate
|
||||||
// @summary Update a stack
|
// @summary Update a stack
|
||||||
// @description Update a stack.
|
// @description Update a stack, only for file based stacks.
|
||||||
// @description **Access policy**: authenticated
|
// @description **Access policy**: authenticated
|
||||||
// @tags stacks
|
// @tags stacks
|
||||||
// @security ApiKeyAuth
|
// @security ApiKeyAuth
|
||||||
|
@ -123,6 +123,15 @@ func (handler *Handler) stackUpdate(w http.ResponseWriter, r *http.Request) *htt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Must not be git based stack. stop the auto update job if there is any
|
||||||
|
if stack.AutoUpdate != nil {
|
||||||
|
stopAutoupdate(stack.ID, stack.AutoUpdate.JobID, *handler.Scheduler)
|
||||||
|
stack.AutoUpdate = nil
|
||||||
|
}
|
||||||
|
if stack.GitConfig != nil {
|
||||||
|
stack.FromAppTemplate = true
|
||||||
|
}
|
||||||
|
|
||||||
updateError := handler.updateAndDeployStack(r, stack, endpoint)
|
updateError := handler.updateAndDeployStack(r, stack, endpoint)
|
||||||
if updateError != nil {
|
if updateError != nil {
|
||||||
return updateError
|
return updateError
|
||||||
|
|
|
@ -115,6 +115,21 @@ export function confirmDeletion(message: string, callback: ConfirmCallback) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function confirmDetachment(message: string, callback: ConfirmCallback) {
|
||||||
|
const messageSanitized = sanitize(message);
|
||||||
|
confirm({
|
||||||
|
title: 'Are you sure ?',
|
||||||
|
message: messageSanitized,
|
||||||
|
buttons: {
|
||||||
|
confirm: {
|
||||||
|
label: 'Detach',
|
||||||
|
className: 'btn-danger',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
callback,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
export function confirmDeassociate(callback: ConfirmCallback) {
|
export function confirmDeassociate(callback: ConfirmCallback) {
|
||||||
const message =
|
const message =
|
||||||
'<p>De-associating this Edge environment will mark it as non associated and will clear the registered Edge ID.</p>' +
|
'<p>De-associating this Edge environment will mark it as non associated and will clear the registered Edge ID.</p>' +
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
confirmAsync,
|
confirmAsync,
|
||||||
confirmDeassociate,
|
confirmDeassociate,
|
||||||
confirmDeletion,
|
confirmDeletion,
|
||||||
|
confirmDetachment,
|
||||||
confirmDeletionAsync,
|
confirmDeletionAsync,
|
||||||
confirmEndpointSnapshot,
|
confirmEndpointSnapshot,
|
||||||
confirmImageExport,
|
confirmImageExport,
|
||||||
|
@ -45,6 +46,7 @@ export function ModalServiceAngular() {
|
||||||
confirmImageForceRemoval,
|
confirmImageForceRemoval,
|
||||||
cancelRegistryRepositoryAction,
|
cancelRegistryRepositoryAction,
|
||||||
confirmDeletion,
|
confirmDeletion,
|
||||||
|
confirmDetachment,
|
||||||
confirmDeassociate,
|
confirmDeassociate,
|
||||||
confirmUpdate,
|
confirmUpdate,
|
||||||
confirmRedeploy,
|
confirmRedeploy,
|
||||||
|
|
|
@ -71,6 +71,18 @@
|
||||||
<i class="fa fa-plus space-right" aria-hidden="true"></i>
|
<i class="fa fa-plus space-right" aria-hidden="true"></i>
|
||||||
Create template from stack
|
Create template from stack
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
authorization="PortainerStackUpdate"
|
||||||
|
ng-if="regular && stackFileContent && !stack.FromAppTemplate && stack.GitConfig"
|
||||||
|
ng-disabled="state.actionInProgress"
|
||||||
|
ng-click="detachStackFromGit()"
|
||||||
|
button-spinner="state.actionInProgress"
|
||||||
|
class="btn btn-primary btn-xs"
|
||||||
|
>
|
||||||
|
<i class="fa fa-arrow-right space-right" aria-hidden="true"></i>
|
||||||
|
<span ng-hide="state.actionInProgress">Detach from Git</span>
|
||||||
|
<span ng-show="state.actionInProgress">Detachment in progress...</span>
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- !stack-details -->
|
<!-- !stack-details -->
|
||||||
|
@ -101,8 +113,12 @@
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<!-- !associate -->
|
<!-- !associate -->
|
||||||
|
<stack-redeploy-git-form
|
||||||
<stack-redeploy-git-form ng-if="stack.GitConfig && !stack.FromAppTemplate" model="stack.GitConfig" stack="stack" authorization="PortainerStackUpdate">
|
ng-if="stack.GitConfig && !stack.FromAppTemplate && !state.actionInProgress"
|
||||||
|
model="stack.GitConfig"
|
||||||
|
stack="stack"
|
||||||
|
authorization="PortainerStackUpdate"
|
||||||
|
>
|
||||||
</stack-redeploy-git-form>
|
</stack-redeploy-git-form>
|
||||||
<stack-duplication-form
|
<stack-duplication-form
|
||||||
ng-if="regular && endpoints.length > 0"
|
ng-if="regular && endpoints.length > 0"
|
||||||
|
|
|
@ -137,6 +137,15 @@ angular.module('portainer.app').controller('StackController', [
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$scope.detachStackFromGit = function () {
|
||||||
|
ModalService.confirmDetachment('Do you want to detach the stack from Git?', function onConfirm(confirmed) {
|
||||||
|
if (!confirmed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$scope.deployStack();
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
function migrateStack(name, targetEndpointId) {
|
function migrateStack(name, targetEndpointId) {
|
||||||
const stack = $scope.stack;
|
const stack = $scope.stack;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue