From 891d024b26f8287e240c4e4865b8d79ec9f9ce64 Mon Sep 17 00:00:00 2001 From: Luka Brecic Date: Thu, 12 Dec 2024 13:04:52 +0000 Subject: [PATCH] fix: purge Signed-off-by: Luka Brecic --- pkg/cmd/purge.go | 18 ++++++++++++ pkg/server/purge.go | 48 ++++++++++++++++++++++++++++++-- pkg/server/targets/service.go | 25 +++++++++++++++++ pkg/server/workspaces/service.go | 25 +++++++++++++++++ pkg/services/target.go | 2 ++ pkg/services/workspace.go | 2 ++ 6 files changed, 117 insertions(+), 3 deletions(-) diff --git a/pkg/cmd/purge.go b/pkg/cmd/purge.go index 1cd053d401..6d79add203 100644 --- a/pkg/cmd/purge.go +++ b/pkg/cmd/purge.go @@ -162,6 +162,24 @@ var purgeCmd = &cobra.Command{ return err } + err = server.Start() + if err != nil { + return err + } + + log.Info("Starting job runner...") + jobRunner, err := bootstrap.GetJobRunner(serverConfig, serverConfigDir, internal.Version, telemetryService) + if err != nil { + return err + } + + // TODO: context? + err = jobRunner.StartRunner(context.Background()) + if err != nil { + return err + } + log.Info("Job runner started") + errs := server.Purge(ctx, forceFlag) if len(errs) > 0 { errMessage := "" diff --git a/pkg/server/purge.go b/pkg/server/purge.go index b68b158af1..e9184d716e 100644 --- a/pkg/server/purge.go +++ b/pkg/server/purge.go @@ -29,14 +29,46 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { } } - fmt.Println("Deleting all targets...") + fmt.Println("Deleting all workspaces...") - err := server.Start() + workspaces, err := s.WorkspaceService.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{}) if err != nil { s.trackPurgeError(ctx, force, err) - return []error{err} + if !force { + return []error{err} + } + } + + if err == nil { + for _, workspace := range workspaces { + err := s.WorkspaceService.RemoveWorkspace(ctx, workspace.Id) + if err != nil { + s.trackPurgeError(ctx, force, err) + if !force { + return []error{err} + } else { + fmt.Printf("Failed to delete %s: %v\n", workspace.Name, err) + } + } else { + fmt.Printf("Workspace %s deleted\n", workspace.Name) + } + } + } else { + fmt.Printf("Failed to list workspaces: %v\n", err) } + err = s.WorkspaceService.AwaitEmptyList(ctx, time.Minute) + if err != nil { + s.trackPurgeError(ctx, force, err) + if !force { + return []error{err} + } else { + fmt.Printf("Failed to await empty workspace list: %v\n", err) + } + } + + fmt.Println("Deleting all targets...") + targets, err := s.TargetService.ListTargets(ctx, nil, services.TargetRetrievalParams{}) if err != nil { s.trackPurgeError(ctx, force, err) @@ -63,6 +95,16 @@ func (s *Server) Purge(ctx context.Context, force bool) []error { fmt.Printf("Failed to list targets: %v\n", err) } + err = s.TargetService.AwaitEmptyList(ctx, time.Minute) + if err != nil { + s.trackPurgeError(ctx, force, err) + if !force { + return []error{err} + } else { + fmt.Printf("Failed to await empty target list: %v\n", err) + } + } + fmt.Println("Purging providers...") err = s.ProviderManager.Purge() if err != nil { diff --git a/pkg/server/targets/service.go b/pkg/server/targets/service.go index fc707ae2e5..a6d84bead7 100644 --- a/pkg/server/targets/service.go +++ b/pkg/server/targets/service.go @@ -5,7 +5,9 @@ package targets import ( "context" + "errors" "io" + "time" "github.com/daytonaio/daytona/pkg/logs" "github.com/daytonaio/daytona/pkg/models" @@ -71,3 +73,26 @@ type TargetService struct { func (s *TargetService) GetTargetLogReader(targetId string) (io.Reader, error) { return s.loggerFactory.CreateTargetLogReader(targetId) } + +func (s *TargetService) AwaitEmptyList(ctx context.Context, waitTime time.Duration) error { + timeout := time.NewTimer(waitTime) + defer timeout.Stop() + + for { + select { + case <-timeout.C: + return errors.New("awaiting empty build list timed out") + default: + targets, err := s.ListTargets(ctx, nil, services.TargetRetrievalParams{}) + if err != nil { + return err + } + + if len(targets) == 0 { + return nil + } + + time.Sleep(time.Second) + } + } +} diff --git a/pkg/server/workspaces/service.go b/pkg/server/workspaces/service.go index 82f3acd1a3..2324672cfd 100644 --- a/pkg/server/workspaces/service.go +++ b/pkg/server/workspaces/service.go @@ -5,7 +5,9 @@ package workspaces import ( "context" + "errors" "io" + "time" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/logs" @@ -93,3 +95,26 @@ type WorkspaceService struct { func (s *WorkspaceService) GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) { return s.loggerFactory.CreateWorkspaceLogReader(workspaceId) } + +func (s *WorkspaceService) AwaitEmptyList(ctx context.Context, waitTime time.Duration) error { + timeout := time.NewTimer(waitTime) + defer timeout.Stop() + + for { + select { + case <-timeout.C: + return errors.New("awaiting empty build list timed out") + default: + workspaces, err := s.ListWorkspaces(ctx, services.WorkspaceRetrievalParams{}) + if err != nil { + return err + } + + if len(workspaces) == 0 { + return nil + } + + time.Sleep(time.Second) + } + } +} diff --git a/pkg/services/target.go b/pkg/services/target.go index 27130706d0..09a56310ae 100644 --- a/pkg/services/target.go +++ b/pkg/services/target.go @@ -7,6 +7,7 @@ import ( "context" "errors" "io" + "time" "github.com/daytonaio/daytona/pkg/models" "github.com/daytonaio/daytona/pkg/stores" @@ -24,6 +25,7 @@ type ITargetService interface { ForceRemoveTarget(ctx context.Context, targetId string) error HandleSuccessfulCreation(ctx context.Context, targetId string) error HandleSuccessfulRemoval(ctx context.Context, targetId string) error + AwaitEmptyList(ctx context.Context, waitTime time.Duration) error SetTargetMetadata(ctx context.Context, targetId string, metadata *models.TargetMetadata) (*models.TargetMetadata, error) } diff --git a/pkg/services/workspace.go b/pkg/services/workspace.go index 90d68d52cc..7fc32be4c6 100644 --- a/pkg/services/workspace.go +++ b/pkg/services/workspace.go @@ -7,6 +7,7 @@ import ( "context" "errors" "io" + "time" "github.com/daytonaio/daytona/pkg/gitprovider" "github.com/daytonaio/daytona/pkg/models" @@ -21,6 +22,7 @@ type IWorkspaceService interface { RemoveWorkspace(ctx context.Context, workspaceId string) error ForceRemoveWorkspace(ctx context.Context, workspaceId string) error HandleSuccessfulRemoval(ctx context.Context, workspaceId string) error + AwaitEmptyList(ctx context.Context, waitTime time.Duration) error GetWorkspaceLogReader(ctx context.Context, workspaceId string) (io.Reader, error) SetWorkspaceMetadata(ctx context.Context, workspaceId string, metadata *models.WorkspaceMetadata) (*models.WorkspaceMetadata, error)