From 6bc52dd39ca1fa62ad186af5b385049d691a0628 Mon Sep 17 00:00:00 2001 From: LP B Date: Mon, 11 Nov 2024 14:02:20 +0100 Subject: [PATCH] feat(edge): kubernetes WaitForStatus support (#85) --- api/portainer.go | 25 +++++++++++++++++++ .../EdgeStacksDatatable/DeploymentCounter.tsx | 2 +- .../ListView/EdgeStacksDatatable/columns.tsx | 2 +- .../compose/internal/composeplugin/status.go | 3 ++- .../composeplugin/status_integration_test.go | 8 +++--- pkg/libstack/libstack.go | 2 +- 6 files changed, 34 insertions(+), 8 deletions(-) diff --git a/api/portainer.go b/api/portainer.go index 17bd6cf2d..5d07ac855 100644 --- a/api/portainer.go +++ b/api/portainer.go @@ -2,6 +2,7 @@ package portainer import ( "context" + "fmt" "io" "time" @@ -1722,6 +1723,30 @@ const ( EdgeStackStatusCompleted ) +var edgeStackStatusTypeStr = map[EdgeStackStatusType]string{ + EdgeStackStatusPending: "Pending", + EdgeStackStatusDeploymentReceived: "DeploymentReceived", + EdgeStackStatusError: "Error", + EdgeStackStatusAcknowledged: "Acknowledged", + EdgeStackStatusRemoved: "Removed", + EdgeStackStatusRemoteUpdateSuccess: "RemoteUpdateSuccess", + EdgeStackStatusImagesPulled: "ImagesPulled", + EdgeStackStatusRunning: "Running", + EdgeStackStatusDeploying: "Deploying", + EdgeStackStatusRemoving: "Removing", + EdgeStackStatusPausedDeploying: "PausedDeploying", + EdgeStackStatusRollingBack: "RollingBack", + EdgeStackStatusRolledBack: "RolledBack", + EdgeStackStatusCompleted: "Completed", +} + +func (s EdgeStackStatusType) String() string { + if str, ok := edgeStackStatusTypeStr[s]; ok { + return fmt.Sprintf("%d (%s)", s, str) + } + return fmt.Sprintf("%d (UNKNOWN)", s) +} + const ( _ EndpointStatus = iota // EndpointStatusUp is used to represent an available environment(endpoint) diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx index 4a24c9c8d..26c015ed1 100644 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx +++ b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/DeploymentCounter.tsx @@ -22,7 +22,7 @@ export function DeploymentCounterLink({ diff --git a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx index 623b15648..2b1a4472b 100644 --- a/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx +++ b/app/react/edge/edge-stacks/ListView/EdgeStacksDatatable/columns.tsx @@ -104,7 +104,7 @@ export const columns = _.compact([ to="edge.stacks.edit" params={{ stackId: row.original.Id, - tab: 1, + tab: 'environments', status: StatusType.Error, }} data-cy={`edge-stacks-error-${row.original.Id}`} diff --git a/pkg/libstack/compose/internal/composeplugin/status.go b/pkg/libstack/compose/internal/composeplugin/status.go index 79def8af8..45d6a4ad4 100644 --- a/pkg/libstack/compose/internal/composeplugin/status.go +++ b/pkg/libstack/compose/internal/composeplugin/status.go @@ -113,7 +113,7 @@ func aggregateStatuses(services []service) (libstack.Status, string) { } -func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, status libstack.Status) <-chan libstack.WaitResult { +func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, status libstack.Status, _ string) <-chan libstack.WaitResult { waitResultCh := make(chan libstack.WaitResult) waitResult := libstack.WaitResult{ Status: status, @@ -200,6 +200,7 @@ func (wrapper *PluginWrapper) WaitForStatus(ctx context.Context, name string, st log.Debug(). Str("project_name", name). + Str("required_status", string(status)). Str("status", string(aggregateStatus)). Msg("waiting for status") diff --git a/pkg/libstack/compose/internal/composeplugin/status_integration_test.go b/pkg/libstack/compose/internal/composeplugin/status_integration_test.go index a5051b2cc..deac33353 100644 --- a/pkg/libstack/compose/internal/composeplugin/status_integration_test.go +++ b/pkg/libstack/compose/internal/composeplugin/status_integration_test.go @@ -66,7 +66,7 @@ func TestComposeProjectStatus(t *testing.T) { time.Sleep(5 * time.Second) - status, statusMessage, err := waitForStatus(w, ctx, projectName, libstack.StatusRunning) + status, statusMessage, err := waitForStatus(w, ctx, projectName, libstack.StatusRunning, "") if err != nil { t.Fatalf("[test: %s] Failed to get compose project status: %v", testCase.TestName, err) } @@ -86,7 +86,7 @@ func TestComposeProjectStatus(t *testing.T) { time.Sleep(20 * time.Second) - status, statusMessage, err = waitForStatus(w, ctx, projectName, libstack.StatusRemoved) + status, statusMessage, err = waitForStatus(w, ctx, projectName, libstack.StatusRemoved, "") if err != nil { t.Fatalf("[test: %s] Failed to get compose project status: %v", testCase.TestName, err) } @@ -102,11 +102,11 @@ func TestComposeProjectStatus(t *testing.T) { } } -func waitForStatus(deployer libstack.Deployer, ctx context.Context, stackName string, requiredStatus libstack.Status) (libstack.Status, string, error) { +func waitForStatus(deployer libstack.Deployer, ctx context.Context, stackName string, requiredStatus libstack.Status, stackFileLocation string) (libstack.Status, string, error) { ctx, cancel := context.WithTimeout(ctx, 1*time.Minute) defer cancel() - statusCh := deployer.WaitForStatus(ctx, stackName, requiredStatus) + statusCh := deployer.WaitForStatus(ctx, stackName, requiredStatus, stackFileLocation) result := <-statusCh if result.ErrorMsg == "" { return result.Status, "", nil diff --git a/pkg/libstack/libstack.go b/pkg/libstack/libstack.go index 32cba1101..29532e244 100644 --- a/pkg/libstack/libstack.go +++ b/pkg/libstack/libstack.go @@ -14,7 +14,7 @@ type Deployer interface { Pull(ctx context.Context, filePaths []string, options Options) error Run(ctx context.Context, filePaths []string, serviceName string, options RunOptions) error Validate(ctx context.Context, filePaths []string, options Options) error - WaitForStatus(ctx context.Context, name string, status Status) <-chan WaitResult + WaitForStatus(ctx context.Context, name string, status Status, stackFileLocation string) <-chan WaitResult Config(ctx context.Context, filePaths []string, options Options) ([]byte, error) }