Skip to content
Merged
Show file tree
Hide file tree
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
3 changes: 0 additions & 3 deletions pkg/cmd/ls/ls.go
Original file line number Diff line number Diff line change
Expand Up @@ -424,9 +424,6 @@ func displayLsResetBreadCrumb(t *terminal.Terminal, workspaces []entity.Workspac
foundAResettableWorkspace = true
}
}
if foundAResettableWorkspace {
t.Vprintf("%s", t.Yellow("If this problem persists, run the command again with the --hard flag (warning: the --hard flag will not preserve uncommitted files!) \n\n"))
}
}

// buildGPULookup builds a map of instance type name to GPU name.
Expand Down
8 changes: 4 additions & 4 deletions pkg/cmd/recreate/doc.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ with a fresh copy of the remote source and run the workspace setupscript.
recreate a workspace with the name `naive-pubsub`

```
$ brev recreate payments-frontend
Starting hard reset 🤙 This can take a couple of minutes.
$ brev recreate naive-pubsub
recreating 🤙 This can take a couple of minutes.

Deleting workspace - naive-pubsub.
Workspace is starting. This can take up to 2 minutes the first time.
Deleting instance - naive-pubsub.
Instance is starting. This can take up to 2 minutes the first time.
name naive-pubsub
template v7nd45zsc Admin
resource class 4x16
Expand Down
18 changes: 9 additions & 9 deletions pkg/cmd/recreate/recreate.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ func NewCmdRecreate(t *terminal.Terminal, store recreateStore) *cobra.Command {

func RunRecreate(t *terminal.Terminal, args []string, recreateStore recreateStore) error {
for _, arg := range args {
err := hardResetProcess(arg, t, recreateStore)
err := recreateProcess(arg, t, recreateStore)
if err != nil {
return breverrors.WrapAndTrace(err)
}
}
return nil
}

// hardResetProcess deletes an existing workspace and creates a new one
func hardResetProcess(workspaceName string, t *terminal.Terminal, recreateStore recreateStore) error {
// recreateProcess deletes an existing workspace and creates a new one
func recreateProcess(workspaceName string, t *terminal.Terminal, recreateStore recreateStore) error {
t.Vprint(t.Green("recreating 🤙 " + t.Yellow("This can take a couple of minutes.\n")))
workspace, err := util.GetUserWorkspaceByNameOrIDErr(recreateStore, workspaceName)
if err != nil {
Expand All @@ -78,21 +78,21 @@ func hardResetProcess(workspaceName string, t *terminal.Terminal, recreateStore
time.Sleep(10 * time.Second)

if len(deletedWorkspace.GitRepo) != 0 {
err := hardResetCreateWorkspaceFromRepo(t, recreateStore, deletedWorkspace)
err := createWorkspaceFromRepo(t, recreateStore, deletedWorkspace)
if err != nil {
return breverrors.WrapAndTrace(err)
}
} else {
err := hardResetCreateEmptyWorkspace(t, recreateStore, deletedWorkspace)
err := createEmptyWorkspace(t, recreateStore, deletedWorkspace)
if err != nil {
return breverrors.WrapAndTrace(err)
}
}
return nil
}

// hardResetCreateWorkspaceFromRepo clone a GIT repository, triggeres from the --hardreset flag
func hardResetCreateWorkspaceFromRepo(t *terminal.Terminal, recreateStore recreateStore, workspace *entity.Workspace) error {
// createWorkspaceFromRepo recreates a workspace from its git repo source.
func createWorkspaceFromRepo(t *terminal.Terminal, recreateStore recreateStore, workspace *entity.Workspace) error {
t.Vprint(t.Green("Instance is starting. ") + t.Yellow("This can take up to 2 minutes the first time."))
var orgID string
activeorg, err := recreateStore.GetActiveOrganizationOrDefault()
Expand Down Expand Up @@ -133,8 +133,8 @@ func hardResetCreateWorkspaceFromRepo(t *terminal.Terminal, recreateStore recrea
return nil
}

// hardResetCreateEmptyWorkspace creates a new empty worksapce, triggered from the --hardreset flag
func hardResetCreateEmptyWorkspace(t *terminal.Terminal, recreateStore recreateStore, workspace *entity.Workspace) error {
// createEmptyWorkspace recreates an empty workspace (no git repo).
func createEmptyWorkspace(t *terminal.Terminal, recreateStore recreateStore, workspace *entity.Workspace) error {
t.Vprint(t.Green("Instance is starting. ") + t.Yellow("This can take up to 2 minutes the first time.\n"))

// ensure name
Expand Down
193 changes: 3 additions & 190 deletions pkg/cmd/reset/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@ package reset

import (
_ "embed"
"strings"
"time"

"github.com/brevdev/brev-cli/pkg/cmd/completions"
"github.com/brevdev/brev-cli/pkg/cmd/util"
"github.com/brevdev/brev-cli/pkg/config"
"github.com/brevdev/brev-cli/pkg/entity"
"github.com/brevdev/brev-cli/pkg/featureflag"
"github.com/brevdev/brev-cli/pkg/store"
"github.com/brevdev/brev-cli/pkg/terminal"

breverrors "github.com/brevdev/brev-cli/pkg/errors"
Expand All @@ -28,16 +23,9 @@ type ResetStore interface {
completions.CompletionStore
util.GetWorkspaceByNameOrIDErrStore
ResetWorkspace(workspaceID string) (*entity.Workspace, error)
GetActiveOrganizationOrDefault() (*entity.Organization, error)
GetCurrentUser() (*entity.User, error)
CreateWorkspace(organizationID string, options *store.CreateWorkspacesOptions) (*entity.Workspace, error)
GetWorkspace(id string) (*entity.Workspace, error)
DeleteWorkspace(workspaceID string) (*entity.Workspace, error)
}

func NewCmdReset(t *terminal.Terminal, loginResetStore ResetStore, noLoginResetStore ResetStore) *cobra.Command {
var hardreset bool

cmd := &cobra.Command{
Annotations: map[string]string{"provider-dependent": ""},
Use: "reset",
Expand All @@ -48,192 +36,17 @@ func NewCmdReset(t *terminal.Terminal, loginResetStore ResetStore, noLoginResetS
ValidArgsFunction: completions.GetAllWorkspaceNameCompletionHandler(noLoginResetStore, t),
RunE: func(cmd *cobra.Command, args []string) error {
for _, arg := range args {
if hardreset {
err := hardResetProcess(arg, t, loginResetStore)
if err != nil {
return breverrors.WrapAndTrace(err)
}
} else {
err := resetWorkspace(arg, t, loginResetStore)
if err != nil {
return breverrors.WrapAndTrace(err)
}
err := resetWorkspace(arg, t, loginResetStore)
if err != nil {
return breverrors.WrapAndTrace(err)
}
}
return nil
},
}

cmd.Flags().BoolVarP(&hardreset, "hard", "", false, "DEPRECATED: use brev recreate")
return cmd
}

// hardResetProcess deletes an existing workspace and creates a new one
func hardResetProcess(workspaceName string, t *terminal.Terminal, resetStore ResetStore) error {
t.Vprint(t.Green("Starting hard reset 🤙 " + t.Yellow("This can take a couple of minutes.\n")))
workspace, err := util.GetUserWorkspaceByNameOrIDErr(resetStore, workspaceName)
if err != nil {
return breverrors.WrapAndTrace(err)
}

deletedWorkspace, err := resetStore.DeleteWorkspace(workspace.ID)
if err != nil {
return breverrors.WrapAndTrace(err)
}

t.Vprint(t.Yellow("Deleting instance - %s.", deletedWorkspace.Name))
time.Sleep(10 * time.Second)

if len(deletedWorkspace.GitRepo) != 0 {
err := hardResetCreateWorkspaceFromRepo(t, resetStore, deletedWorkspace)
if err != nil {
return breverrors.WrapAndTrace(err)
}
} else {
err := hardResetCreateEmptyWorkspace(t, resetStore, deletedWorkspace)
if err != nil {
return breverrors.WrapAndTrace(err)
}
}
t.Vprint(t.Red("NOTE: THIS COMMAND IS DEPRECATED"))
t.Vprint(t.Red("It still worked, but use brev recreate " + workspaceName + " next time"))
return nil
}

// hardResetCreateWorkspaceFromRepo clone a GIT repository, triggeres from the --hardreset flag
func hardResetCreateWorkspaceFromRepo(t *terminal.Terminal, resetStore ResetStore, workspace *entity.Workspace) error {
t.Vprint(t.Green("Instance is starting. ") + t.Yellow("This can take up to 2 minutes the first time."))
var orgID string
activeorg, err := resetStore.GetActiveOrganizationOrDefault()
if err != nil {
return breverrors.WrapAndTrace(err)
}
if activeorg == nil {
return breverrors.NewValidationError("no org exist")
}
orgID = activeorg.ID
clusterID := config.GlobalConfig.GetDefaultClusterID()
options := store.NewCreateWorkspacesOptions(clusterID, workspace.Name).WithGitRepo(workspace.GitRepo)

user, err := resetStore.GetCurrentUser()
if err != nil {
return breverrors.WrapAndTrace(err)
}

options = resolveWorkspaceUserOptions(options, user)

options.StartupScriptPath = workspace.StartupScriptPath
options.Execs = workspace.ExecsV0
options.Repos = workspace.ReposV0
options.IDEConfig = &workspace.IDEConfig

w, err := resetStore.CreateWorkspace(orgID, options)
if err != nil {
return breverrors.WrapAndTrace(err)
}

err = pollUntil(t, w.ID, entity.Running, resetStore, true)
if err != nil {
return breverrors.WrapAndTrace(err)
}

t.Vprint(t.Green("\nYour instance is ready!"))
t.Vprintf("%s", t.Green("\nSSH into your machine:\n\tssh %s\n", w.GetLocalIdentifier()))
return nil
}

// hardResetCreateEmptyWorkspace creates a new empty worksapce, triggered from the --hardreset flag
func hardResetCreateEmptyWorkspace(t *terminal.Terminal, resetStore ResetStore, workspace *entity.Workspace) error {
t.Vprint(t.Green("Instance is starting. ") + t.Yellow("This can take up to 2 minutes the first time.\n"))

// ensure name
if len(workspace.Name) == 0 {
return breverrors.NewValidationError("name field is required for empty instances")
}

// ensure org
var orgID string
activeorg, err := resetStore.GetActiveOrganizationOrDefault()
if err != nil {
return breverrors.WrapAndTrace(err)
}
if activeorg == nil {
return breverrors.NewValidationError("no org exist")
}
orgID = activeorg.ID
clusterID := config.GlobalConfig.GetDefaultClusterID()
options := store.NewCreateWorkspacesOptions(clusterID, workspace.Name)

user, err := resetStore.GetCurrentUser()
if err != nil {
return breverrors.WrapAndTrace(err)
}

options = resolveWorkspaceUserOptions(options, user)

options.StartupScriptPath = workspace.StartupScriptPath
options.Execs = workspace.ExecsV0
options.Repos = workspace.ReposV0
options.IDEConfig = &workspace.IDEConfig

w, err := resetStore.CreateWorkspace(orgID, options)
if err != nil {
return breverrors.WrapAndTrace(err)
}

err = pollUntil(t, w.ID, entity.Running, resetStore, true)
if err != nil {
return breverrors.WrapAndTrace(err)
}

t.Vprint(t.Green("\nYour instance is ready!"))
t.Vprintf("%s", t.Green("\nSSH into your machine:\n\tssh %s\n", w.GetLocalIdentifier()))

return nil
}

func pollUntil(t *terminal.Terminal, wsid string, state string, resetStore ResetStore, canSafelyExit bool) error {
s := t.NewSpinner()
isReady := false
if canSafelyExit {
t.Vprintf("You can safely ctrl+c to exit\n")
}
s.Suffix = " hang tight 🤙"
s.Start()
for !isReady {
time.Sleep(5 * time.Second)
ws, err := resetStore.GetWorkspace(wsid)
if err != nil {
return breverrors.WrapAndTrace(err)
}
s.Suffix = " instance is " + strings.ToLower(ws.Status)
if ws.Status == state {
s.Suffix = "Instance is ready!"
s.Stop()
isReady = true
}
}
return nil
}

func resolveWorkspaceUserOptions(options *store.CreateWorkspacesOptions, user *entity.User) *store.CreateWorkspacesOptions {
if options.WorkspaceTemplateID == "" {
if featureflag.IsAdmin(user.GlobalUserType) {
options.WorkspaceTemplateID = store.DevWorkspaceTemplateID
} else {
options.WorkspaceTemplateID = store.UserWorkspaceTemplateID
}
}
if options.WorkspaceClassID == "" {
if featureflag.IsAdmin(user.GlobalUserType) {
options.WorkspaceClassID = store.DevWorkspaceClassID
} else {
options.WorkspaceClassID = store.UserWorkspaceClassID
}
}
return options
}

func resetWorkspace(workspaceName string, t *terminal.Terminal, resetStore ResetStore) error {
workspace, err := util.GetUserWorkspaceByNameOrIDErr(resetStore, workspaceName)
if err != nil {
Expand Down
Loading