refactor(stack): change stack update flow to async model [BE-12741] (#2306)
This commit is contained in:
@@ -57,6 +57,7 @@ func (payload *stackGitRedeployPayload) Validate(r *http.Request) error {
|
||||
// @failure 400 "Invalid request"
|
||||
// @failure 403 "Permission denied"
|
||||
// @failure 404 "Not found"
|
||||
// @failure 409 "Conflict"
|
||||
// @failure 500 "Server error"
|
||||
// @router /stacks/{id}/git/redeploy [put]
|
||||
func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request) *httperror.HandlerError {
|
||||
@@ -76,6 +77,10 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request)
|
||||
return httperror.BadRequest("Stack is not created from git", err)
|
||||
}
|
||||
|
||||
if stack.Status == portainer.StackStatusDeploying {
|
||||
return httperror.Conflict("Unable to update stack", errors.New("Stack deployment is already in progress"))
|
||||
}
|
||||
|
||||
// TODO: this is a work-around for stacks created with Portainer version >= 1.17.1
|
||||
// The EndpointID property is not available for these stacks, this API environment(endpoint)
|
||||
// can use the optional EndpointID query parameter to associate a valid environment(endpoint) identifier to the stack.
|
||||
@@ -178,7 +183,8 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
defer clean()
|
||||
|
||||
if err := handler.deployStack(r, stack, payload.RepullImageAndRedeploy, endpoint); err != nil {
|
||||
deployGate := newDeployGate()
|
||||
if err := handler.deployStack(r, stack, payload.RepullImageAndRedeploy, endpoint, deployGate); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -202,18 +208,17 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request)
|
||||
|
||||
stack.UpdatedBy = user.Username
|
||||
stack.UpdateDate = time.Now().Unix()
|
||||
stack.Status = portainer.StackStatusActive
|
||||
// TODO: move to async job when stack update becomes async
|
||||
stack.DeploymentStatus = []portainer.StackDeploymentStatus{
|
||||
{Status: portainer.StackStatusActive, Time: time.Now().Unix()},
|
||||
}
|
||||
stackutils.PrepareStackStatusForDeployment(stack)
|
||||
|
||||
if err := handler.DataStore.UpdateTx(func(tx dataservices.DataStoreTx) error {
|
||||
return tx.Stack().Update(stack.ID, stack)
|
||||
}); err != nil {
|
||||
deployGate.abortDeploy()
|
||||
return httperror.InternalServerError("Unable to persist the stack changes inside the database", errors.Wrap(err, "failed to update the stack"))
|
||||
}
|
||||
|
||||
deployGate.startDeploy()
|
||||
|
||||
if stack.GitConfig != nil && stack.GitConfig.Authentication != nil && stack.GitConfig.Authentication.Password != "" {
|
||||
// Sanitize password in the http response to minimise possible security leaks
|
||||
stack.GitConfig.Authentication.Password = ""
|
||||
@@ -222,7 +227,7 @@ func (handler *Handler) stackGitRedeploy(w http.ResponseWriter, r *http.Request)
|
||||
return response.JSON(w, stack)
|
||||
}
|
||||
|
||||
func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, pullImage bool, endpoint *portainer.Endpoint) *httperror.HandlerError {
|
||||
func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, pullImage bool, endpoint *portainer.Endpoint, gate *deployGate) *httperror.HandlerError {
|
||||
var deploymentConfiger deployments.StackDeploymentConfiger
|
||||
|
||||
switch stack.Type {
|
||||
@@ -281,9 +286,7 @@ func (handler *Handler) deployStack(r *http.Request, stack *portainer.Stack, pul
|
||||
return httperror.InternalServerError("Unsupported stack", errors.Errorf("unsupported stack type: %v", stack.Type))
|
||||
}
|
||||
|
||||
if err := deploymentConfiger.Deploy(context.TODO()); err != nil {
|
||||
return httperror.InternalServerError(err.Error(), err)
|
||||
}
|
||||
go stackDeploy(handler.DataStore, stack.ID, deploymentConfiger, gate, nil)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user