Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
64 changes: 55 additions & 9 deletions pkg/cmd/recreate/recreate.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,11 @@ type recreateStore interface {
DeleteWorkspace(workspaceID string) (*entity.Workspace, error)
}

const (
createRetryWindow = 5 * time.Minute
createRetryDelay = 10 * time.Second
)

func NewCmdRecreate(t *terminal.Terminal, store recreateStore) *cobra.Command {
cmd := &cobra.Command{
Use: "recreate",
Expand Down Expand Up @@ -75,20 +80,49 @@ func hardResetProcess(workspaceName string, t *terminal.Terminal, recreateStore
}

t.Vprint(t.Yellow("Deleting instance - %s.", deletedWorkspace.Name))

t.Vprint(t.Yellow("Waiting for delete to complete before creating new instance...\n"))
time.Sleep(10 * time.Second)

if len(deletedWorkspace.GitRepo) != 0 {
err := hardResetCreateWorkspaceFromRepo(t, recreateStore, deletedWorkspace)
if err != nil {
return breverrors.WrapAndTrace(err)
createErr := runCreateWithRetry(t, recreateStore, deletedWorkspace)
if createErr != nil {
return createErr
}
return nil
}

// isRetriableCreateError returns true for errors that may succeed on retry.
func isRetriableCreateError(err error) bool {
if err == nil {
return false
}
msg := err.Error()
if strings.Contains(msg, "unexpected EOF") || strings.Contains(msg, "duplicate workspace") {
return true
}
return false
}

func runCreateWithRetry(t *terminal.Terminal, recreateStore recreateStore, deletedWorkspace *entity.Workspace) error {
deadline := time.Now().Add(createRetryWindow)
var lastErr error
for time.Now().Before(deadline) {
if lastErr != nil {
time.Sleep(createRetryDelay)
}
} else {
err := hardResetCreateEmptyWorkspace(t, recreateStore, deletedWorkspace)
if err != nil {
return breverrors.WrapAndTrace(err)
if len(deletedWorkspace.GitRepo) != 0 {
lastErr = hardResetCreateWorkspaceFromRepo(t, recreateStore, deletedWorkspace)
} else {
lastErr = hardResetCreateEmptyWorkspace(t, recreateStore, deletedWorkspace)
}
if lastErr == nil {
return nil
}
if !isRetriableCreateError(lastErr) {
return lastErr
}
}
return nil
return lastErr
}

// hardResetCreateWorkspaceFromRepo clone a GIT repository, triggeres from the --hardreset flag
Expand All @@ -105,6 +139,12 @@ func hardResetCreateWorkspaceFromRepo(t *terminal.Terminal, recreateStore recrea
orgID = activeorg.ID
clusterID := config.GlobalConfig.GetDefaultClusterID()
options := store.NewCreateWorkspacesOptions(clusterID, workspace.Name).WithGitRepo(workspace.GitRepo)
if workspace.WorkspaceGroupID != "" {
options = options.WithWorkspaceGroupID(workspace.WorkspaceGroupID)
}
if workspace.InstanceType != "" {
options = options.WithInstanceType(workspace.InstanceType)
}

user, err := recreateStore.GetCurrentUser()
if err != nil {
Expand Down Expand Up @@ -154,6 +194,12 @@ func hardResetCreateEmptyWorkspace(t *terminal.Terminal, recreateStore recreateS
orgID = activeorg.ID
clusterID := config.GlobalConfig.GetDefaultClusterID()
options := store.NewCreateWorkspacesOptions(clusterID, workspace.Name)
if workspace.WorkspaceGroupID != "" {
options = options.WithWorkspaceGroupID(workspace.WorkspaceGroupID)
}
if workspace.InstanceType != "" {
options = options.WithInstanceType(workspace.InstanceType)
}

user, err := recreateStore.GetCurrentUser()
if err != nil {
Expand Down
Loading