fix(edge-stack): add completed status EE-6210 (#11632)

pull/11743/head
cmeng 7 months ago committed by GitHub
parent 7479302043
commit a9ead542b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -627,6 +627,7 @@ func getEdgeStackStatusParam(r *http.Request) (*portainer.EdgeStackStatusType, e
portainer.EdgeStackStatusRunning,
portainer.EdgeStackStatusDeploying,
portainer.EdgeStackStatusRemoving,
portainer.EdgeStackStatusCompleted,
}, edgeStackStatus) {
return nil, errors.New("invalid edgeStackStatus parameter")
}

@ -1728,6 +1728,8 @@ const (
EdgeStackStatusRollingBack
// EdgeStackStatusRolledBack represents an Edge stack which has rolled back
EdgeStackStatusRolledBack
// EdgeStackStatusCompleted represents a completed Edge stack
EdgeStackStatusCompleted
)
const (

@ -68,6 +68,8 @@ function getLabel(type: StatusType): ReactNode {
switch (type) {
case StatusType.Running:
return 'deployments running';
case StatusType.Completed:
return 'deployments completed';
case StatusType.DeploymentReceived:
return 'deployments received';
case StatusType.Error:

@ -84,6 +84,16 @@ function getStatus(
};
}
const allCompleted = envStatus.every((s) => s.Type === StatusType.Completed);
if (allCompleted) {
return {
label: 'Completed',
icon: CheckCircle,
mode: 'success',
};
}
const allRunning = envStatus.every(
(s) =>
s.Type === StatusType.Running ||

@ -44,6 +44,8 @@ export enum StatusType {
RollingBack,
/** PausedRemoving represents an Edge stack which has been rolled back */
RolledBack,
/** Completed represents a completed Edge stack */
Completed,
}
export interface DeploymentStatus {

@ -51,7 +51,12 @@ func getServiceStatus(service service) (libstack.Status, string) {
return libstack.StatusRunning, ""
case "removing":
return libstack.StatusRemoving, ""
case "exited", "dead":
case "exited":
if service.ExitCode != 0 {
return libstack.StatusError, fmt.Sprintf("service %s exited with code %d", service.Name, service.ExitCode)
}
return libstack.StatusCompleted, ""
case "dead":
if service.ExitCode != 0 {
return libstack.StatusError, fmt.Sprintf("service %s exited with code %d", service.Name, service.ExitCode)
}
@ -94,7 +99,9 @@ func aggregateStatuses(services []service) (libstack.Status, string) {
return libstack.StatusStarting, ""
case statusCounts[libstack.StatusRemoving] > 0:
return libstack.StatusRemoving, ""
case statusCounts[libstack.StatusRunning] == servicesCount:
case statusCounts[libstack.StatusCompleted] == servicesCount:
return libstack.StatusCompleted, ""
case statusCounts[libstack.StatusRunning]+statusCounts[libstack.StatusCompleted] == servicesCount:
return libstack.StatusRunning, ""
case statusCounts[libstack.StatusStopped] == servicesCount:
return libstack.StatusStopped, ""
@ -106,15 +113,19 @@ func aggregateStatuses(services []service) (libstack.Status, string) {
}
func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, status libstack.Status) <-chan string {
errorMessageCh := make(chan string)
func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, status libstack.Status) <-chan libstack.WaitResult {
waitResultCh := make(chan libstack.WaitResult)
waitResult := libstack.WaitResult{
Status: status,
}
go func() {
OUTER:
for {
select {
case <-ctx.Done():
errorMessageCh <- fmt.Sprintf("failed to wait for status: %s", ctx.Err().Error())
waitResult.ErrorMsg = fmt.Sprintf("failed to wait for status: %s", ctx.Err().Error())
waitResultCh <- waitResult
default:
}
@ -129,7 +140,7 @@ func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, st
Msg("no output from docker compose ps")
if status == libstack.StatusRemoved {
errorMessageCh <- ""
waitResultCh <- waitResult
return
}
@ -165,18 +176,25 @@ func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, st
}
if len(services) == 0 && status == libstack.StatusRemoved {
errorMessageCh <- ""
waitResultCh <- waitResult
return
}
aggregateStatus, errorMessage := aggregateStatuses(services)
if aggregateStatus == status {
errorMessageCh <- ""
waitResultCh <- waitResult
return
}
if status == libstack.StatusRunning && aggregateStatus == libstack.StatusCompleted {
waitResult.Status = libstack.StatusCompleted
waitResultCh <- waitResult
return
}
if errorMessage != "" {
errorMessageCh <- errorMessage
waitResult.ErrorMsg = errorMessage
waitResultCh <- waitResult
return
}
@ -188,5 +206,5 @@ func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, st
}
}()
return errorMessageCh
return waitResultCh
}

@ -108,9 +108,9 @@ func waitForStatus(deployer libstack.Deployer, ctx context.Context, stackName st
statusCh := deployer.WaitForStatus(ctx, stackName, requiredStatus)
result := <-statusCh
if result == "" {
return requiredStatus, "", nil
if result.ErrorMsg == "" {
return result.Status, "", nil
}
return libstack.StatusError, result, nil
return libstack.StatusError, result.ErrorMsg, nil
}

@ -13,7 +13,7 @@ type Deployer interface {
Remove(ctx context.Context, projectName string, filePaths []string, options Options) error
Pull(ctx context.Context, filePaths []string, options Options) error
Validate(ctx context.Context, filePaths []string, options Options) error
WaitForStatus(ctx context.Context, name string, status Status) <-chan string
WaitForStatus(ctx context.Context, name string, status Status) <-chan WaitResult
}
type Status string
@ -26,8 +26,14 @@ const (
StatusError Status = "error"
StatusRemoving Status = "removing"
StatusRemoved Status = "removed"
StatusCompleted Status = "completed"
)
type WaitResult struct {
Status Status
ErrorMsg string
}
type Options struct {
WorkingDir string
Host string

Loading…
Cancel
Save