workspace

package
v0.48.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 6, 2024 License: Apache-2.0 Imports: 47 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var CodeCmd = &cobra.Command{
	Use:     "code [WORKSPACE] [PROJECT]",
	Short:   "Open a workspace in your preferred IDE",
	Args:    cobra.RangeArgs(0, 2),
	Aliases: []string{"open"},
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		ctx := context.Background()
		var workspaceId string
		var projectName string
		var providerConfigId *string
		var ideId string
		var workspace *apiclient.WorkspaceDTO

		activeProfile, err := c.GetActiveProfile()
		if err != nil {
			return err
		}

		ideId = c.DefaultIdeId

		apiClient, err := apiclient_util.GetApiClient(&activeProfile)
		if err != nil {
			return err
		}

		if len(args) == 0 {
			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(true)
				return nil
			}

			workspace = selection.GetWorkspaceFromPrompt(workspaceList, "Open")
			if workspace == nil {
				return nil
			}
			workspaceId = workspace.Id
		} else {
			workspace, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]), true)
			if err != nil {
				if strings.Contains(err.Error(), workspaces.ErrWorkspaceNotFound.Error()) {
					log.Debug(err)
					return errors.New("workspace not found. You can see all workspace names by running the command `daytona list`")
				}
				return err
			}
			workspaceId = workspace.Id
		}

		if len(args) == 0 || len(args) == 1 {
			selectedProject, err := selectWorkspaceProject(workspaceId, &activeProfile)
			if err != nil {
				return err
			}
			if selectedProject == nil {
				return nil
			}

			projectName = selectedProject.Name
			providerConfigId = selectedProject.GitProviderConfigId
		}

		if len(args) == 2 {
			projectName = args[1]
			for _, project := range workspace.Projects {
				if project.Name == projectName {
					providerConfigId = project.GitProviderConfigId
					break
				}
			}
		}

		if ideFlag != "" {
			ideId = ideFlag
		}

		if !workspace_util.IsProjectRunning(workspace, projectName) {
			wsRunningStatus, err := AutoStartWorkspace(workspace.Name, projectName)
			if err != nil {
				return err
			}
			if !wsRunningStatus {
				return nil
			}
		}

		providerMetadata := ""
		if ideId != "ssh" {
			providerMetadata, err = workspace_util.GetProjectProviderMetadata(workspace, projectName)
			if err != nil {
				return err
			}
		}

		gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId)
		if err != nil {
			log.Warn(err)
		}

		yesFlag, _ := cmd.Flags().GetBool("yes")
		ideList := config.GetIdeList()
		ide_views.RenderIdeOpeningMessage(workspace.Name, projectName, ideId, ideList)
		return openIDE(ideId, activeProfile, workspaceId, projectName, providerMetadata, yesFlag, gpgKey)
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) == 1 {
			return getProjectNameCompletions(cmd, args, toComplete)
		}

		return getWorkspaceNameCompletions()
	},
}
View Source
var CreateCmd = &cobra.Command{
	Use:     "create [REPOSITORY_URL | PROJECT_CONFIG_NAME]...",
	Short:   "Create a workspace",
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := context.Background()
		var projects []apiclient.CreateProjectDTO
		var workspaceName string
		var existingWorkspaceNames []string
		var existingProjectConfigNames []string
		promptUsingTUI := len(args) == 0

		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		activeProfile, err := c.GetActiveProfile()
		if err != nil {
			return err
		}

		profileData, res, err := apiClient.ProfileAPI.GetProfileData(ctx).Execute()
		if err != nil {
			return apiclient_util.HandleErrorResponse(res, err)
		}

		if nameFlag != "" {
			workspaceName = nameFlag
		}

		workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute()
		if err != nil {
			return apiclient_util.HandleErrorResponse(res, err)
		}
		for _, workspaceInfo := range workspaceList {
			existingWorkspaceNames = append(existingWorkspaceNames, workspaceInfo.Name)
		}

		if promptUsingTUI {
			err = processPrompting(ctx, apiClient, &workspaceName, &projects, existingWorkspaceNames)
			if err != nil {
				if common.IsCtrlCAbort(err) {
					return nil
				} else {
					return err
				}
			}
		} else {
			existingProjectConfigNames, err = processCmdArguments(ctx, args, apiClient, &projects)
			if err != nil {
				return err
			}

			initialSuggestion := projects[0].Name

			if workspaceName == "" {
				workspaceName = workspace_util.GetSuggestedName(initialSuggestion, existingWorkspaceNames)
			}
		}

		if workspaceName == "" || len(projects) == 0 {
			return errors.New("workspace name and repository urls are required")
		}

		projectNames := []string{}
		for i := range projects {
			if profileData != nil && profileData.EnvVars != nil {
				projects[i].EnvVars = util.MergeEnvVars(profileData.EnvVars, projects[i].EnvVars)
			} else {
				projects[i].EnvVars = util.MergeEnvVars(projects[i].EnvVars)
			}
			projectNames = append(projectNames, projects[i].Name)
		}

		for i, projectConfigName := range existingProjectConfigNames {
			if projectConfigName == "" {
				continue
			}
			logs_view.DisplayLogEntry(logs.LogEntry{
				ProjectName: &projects[i].Name,
				Msg:         fmt.Sprintf("Using detected project config '%s'\n", projectConfigName),
			}, i)
		}

		targetList, res, err := apiClient.TargetAPI.ListTargets(ctx).Execute()
		if err != nil {
			return apiclient_util.HandleErrorResponse(res, err)
		}

		target, err := workspace_util.GetTarget(workspace_util.GetTargetConfig{
			Ctx:               ctx,
			ApiClient:         apiClient,
			TargetList:        targetList,
			ActiveProfileName: activeProfile.Name,
			TargetNameFlag:    targetNameFlag,
			PromptUsingTUI:    promptUsingTUI,
		})
		if err != nil {
			if common.IsCtrlCAbort(err) {
				return nil
			}
			return err
		}

		logs_view.CalculateLongestPrefixLength(projectNames)

		logs_view.DisplayLogEntry(logs.LogEntry{
			Msg: "Request submitted\n",
		}, logs_view.STATIC_INDEX)

		activeProfile, err = c.GetActiveProfile()
		if err != nil {
			return err
		}

		var tsConn *tsnet.Server
		if target.Name != "local" || activeProfile.Id != "default" {
			tsConn, err = tailscale.GetConnection(&activeProfile)
			if err != nil {
				return err
			}
		}

		id := stringid.GenerateRandomID()
		id = stringid.TruncateID(id)

		logsContext, stopLogs := context.WithCancel(context.Background())
		go apiclient_util.ReadWorkspaceLogs(logsContext, activeProfile, id, projectNames, true, true, nil)

		createdWorkspace, res, err := apiClient.WorkspaceAPI.CreateWorkspace(ctx).Workspace(apiclient.CreateWorkspaceDTO{
			Id:       id,
			Name:     workspaceName,
			Target:   target.Name,
			Projects: projects,
		}).Execute()
		if err != nil {
			stopLogs()
			return apiclient_util.HandleErrorResponse(res, err)
		}
		gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, projects[0].GitProviderConfigId)
		if err != nil {
			log.Warn(err)
		}

		err = waitForDial(createdWorkspace, &activeProfile, tsConn, gpgKey)
		if err != nil {
			stopLogs()
			return err
		}

		stopLogs()

		fmt.Print("\033[?25h")

		wsInfo, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceName).Verbose(true).Execute()
		if err != nil {
			return apiclient_util.HandleErrorResponse(res, err)
		}

		chosenIdeId := c.DefaultIdeId
		if ideFlag != "" {
			chosenIdeId = ideFlag
		}

		ideList := config.GetIdeList()
		var chosenIde config.Ide

		for _, ide := range ideList {
			if ide.Id == chosenIdeId {
				chosenIde = ide
			}
		}

		fmt.Println()
		info.Render(wsInfo, chosenIde.Name, false)

		if noIdeFlag {
			views.RenderCreationInfoMessage("Run 'daytona code' when you're ready to start developing")
			return nil
		}

		views.RenderCreationInfoMessage(fmt.Sprintf("Opening the workspace in %s ...", chosenIde.Name))

		projectName := wsInfo.Projects[0].Name
		providerMetadata, err := workspace_util.GetProjectProviderMetadata(wsInfo, projectName)
		if err != nil {
			return err
		}

		return openIDE(chosenIdeId, activeProfile, createdWorkspace.Id, wsInfo.Projects[0].Name, providerMetadata, yesFlag, gpgKey)
	},
}
View Source
var DeleteCmd = &cobra.Command{
	Use:     "delete [WORKSPACE]",
	Short:   "Delete a workspace",
	GroupID: util.WORKSPACE_GROUP,
	Aliases: []string{"remove", "rm"},
	RunE: func(cmd *cobra.Command, args []string) error {
		if allFlag {
			if yesFlag {
				fmt.Println("Deleting all workspaces.")
				err := DeleteAllWorkspaces(forceFlag)
				if err != nil {
					return err
				}
			} else {
				form := huh.NewForm(
					huh.NewGroup(
						huh.NewConfirm().
							Title("Delete all workspaces?").
							Description("Are you sure you want to delete all workspaces?").
							Value(&yesFlag),
					),
				).WithTheme(views.GetCustomTheme())

				err := form.Run()
				if err != nil {
					return err
				}

				if yesFlag {
					err := DeleteAllWorkspaces(forceFlag)
					if err != nil {
						return err
					}
				} else {
					fmt.Println("Operation canceled.")
				}
			}
			return nil
		}

		ctx := context.Background()

		var workspaceDeleteList = []*apiclient.WorkspaceDTO{}
		var workspaceDeleteListNames = []string{}
		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		if len(args) == 0 {
			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(false)
				return nil
			}

			workspaceDeleteList = selection.GetWorkspacesFromPrompt(workspaceList, "Delete")
			for _, workspace := range workspaceDeleteList {
				workspaceDeleteListNames = append(workspaceDeleteListNames, workspace.Name)
			}
		} else {
			for _, arg := range args {
				workspace, err := apiclient_util.GetWorkspace(arg, false)
				if err != nil {
					log.Error(fmt.Sprintf("[ %s ] : %v", arg, err))
					continue
				}
				workspaceDeleteList = append(workspaceDeleteList, workspace)
				workspaceDeleteListNames = append(workspaceDeleteListNames, workspace.Name)
			}
		}

		if len(workspaceDeleteList) == 0 {
			return nil
		}

		if !yesFlag {
			form := huh.NewForm(
				huh.NewGroup(
					huh.NewConfirm().
						Title(fmt.Sprintf("Delete workspace(s): [%s]?", strings.Join(workspaceDeleteListNames, ", "))).
						Description(fmt.Sprintf("Are you sure you want to delete the workspace(s): [%s]?", strings.Join(workspaceDeleteListNames, ", "))).
						Value(&yesFlag),
				),
			).WithTheme(views.GetCustomTheme())

			err := form.Run()
			if err != nil {
				return err
			}
		}

		if !yesFlag {
			fmt.Println("Operation canceled.")
		} else {
			for _, workspace := range workspaceDeleteList {
				err := RemoveWorkspace(ctx, apiClient, workspace, forceFlag)
				if err != nil {
					log.Error(fmt.Sprintf("[ %s ] : %v", workspace.Name, err))
				}
				views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully deleted", workspace.Name))
			}
		}
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return getWorkspaceNameCompletions()
	},
}
View Source
var InfoCmd = &cobra.Command{
	Use:     "info [WORKSPACE]",
	Short:   "Show workspace info",
	Aliases: []string{"view", "inspect"},
	Args:    cobra.RangeArgs(0, 1),
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := context.Background()

		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		var workspace *apiclient.WorkspaceDTO

		if len(args) == 0 {
			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(true).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(true)
				return nil
			}

			if format.FormatFlag != "" {
				format.UnblockStdOut()
			}

			workspace = selection.GetWorkspaceFromPrompt(workspaceList, "View")
			if format.FormatFlag != "" {
				format.BlockStdOut()
			}

		} else {
			workspace, err = apiclient_util.GetWorkspace(args[0], true)
			if err != nil {
				return err
			}
		}

		if workspace == nil {
			return nil
		}

		if format.FormatFlag != "" {
			formattedData := format.NewFormatter(workspace)
			formattedData.Print()
			return nil
		}

		info.Render(workspace, "", false)
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return getWorkspaceNameCompletions()
	},
}
View Source
var ListCmd = &cobra.Command{
	Use:     "list",
	Short:   "List workspaces",
	Args:    cobra.ExactArgs(0),
	Aliases: []string{"ls"},
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := context.Background()
		var specifyGitProviders bool

		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Verbose(verbose).Execute()

		if err != nil {
			return apiclient.HandleErrorResponse(res, err)
		}

		gitProviders, res, err := apiClient.GitProviderAPI.ListGitProviders(ctx).Execute()
		if err != nil {
			return apiclient.HandleErrorResponse(res, err)
		}

		if len(gitProviders) > 1 {
			specifyGitProviders = true
		}

		if format.FormatFlag != "" {
			formattedData := format.NewFormatter(workspaceList)
			formattedData.Print()
			return nil
		}

		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		activeProfile, err := c.GetActiveProfile()
		if err != nil {
			return err
		}

		list_view.ListWorkspaces(workspaceList, specifyGitProviders, verbose, activeProfile.Name)

		return nil
	},
}
View Source
var RestartCmd = &cobra.Command{
	Use:     "restart [WORKSPACE]",
	Short:   "Restart a workspace",
	Args:    cobra.RangeArgs(0, 1),
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		var workspaceId string

		ctx := context.Background()

		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		if len(args) == 0 {
			if restartProjectFlag != "" {
				err := cmd.Help()
				if err != nil {
					return err
				}
				return nil
			}

			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(true)
				return nil
			}

			workspace := selection.GetWorkspaceFromPrompt(workspaceList, "Restart")
			if workspace == nil {
				return nil
			}
			workspaceId = workspace.Name
		} else {
			workspaceId = args[0]
		}

		err = RestartWorkspace(apiClient, workspaceId, restartProjectFlag)
		if err != nil {
			return err
		}
		if restartProjectFlag != "" {
			views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' successfully restarted", restartProjectFlag, workspaceId))
		} else {
			views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully restarted", workspaceId))
		}
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return getAllWorkspacesByState(WORKSPACE_STATUS_RUNNING)
	},
}
View Source
var SshCmd = &cobra.Command{
	Use:     "ssh [WORKSPACE] [PROJECT] [CMD...]",
	Short:   "SSH into a project using the terminal",
	Args:    cobra.ArbitraryArgs,
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		activeProfile, err := c.GetActiveProfile()
		if err != nil {
			return err
		}

		ctx := context.Background()
		var workspace *apiclient.WorkspaceDTO
		var projectName string
		var providerConfigId *string

		apiClient, err := apiclient_util.GetApiClient(&activeProfile)
		if err != nil {
			return err
		}

		if len(args) == 0 {
			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(true)
				return nil
			}

			workspace = selection.GetWorkspaceFromPrompt(workspaceList, "SSH Into")
			if workspace == nil {
				return nil
			}
		} else {
			workspace, err = apiclient_util.GetWorkspace(args[0], true)
			if err != nil {
				return err
			}
		}

		if len(args) == 0 || len(args) == 1 {
			selectedProject, err := selectWorkspaceProject(workspace.Id, &activeProfile)
			if err != nil {
				return err
			}
			if selectedProject == nil {
				return nil
			}
			projectName = selectedProject.Name
			providerConfigId = selectedProject.GitProviderConfigId
		}

		if len(args) >= 2 {
			projectName = args[1]
			for _, project := range workspace.Projects {
				if project.Name == projectName {
					providerConfigId = project.GitProviderConfigId
					break
				}
			}
		}

		if edit {
			err := editSSHConfig(activeProfile, workspace, projectName)
			if err != nil {
				return err
			}
			return nil
		}

		if !workspace_util.IsProjectRunning(workspace, projectName) {
			wsRunningStatus, err := AutoStartWorkspace(workspace.Name, projectName)
			if err != nil {
				return err
			}
			if !wsRunningStatus {
				return nil
			}
		}

		sshArgs := []string{}
		if len(args) > 2 {
			sshArgs = append(sshArgs, args[2:]...)
		}

		gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId)
		if err != nil {
			log.Warn(err)
		}

		return ide.OpenTerminalSsh(activeProfile, workspace.Id, projectName, gpgKey, sshOptions, sshArgs...)
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		if len(args) >= 2 {
			return nil, cobra.ShellCompDirectiveNoFileComp
		}
		if len(args) == 1 {
			return getProjectNameCompletions(cmd, args, toComplete)
		}

		return getWorkspaceNameCompletions()
	},
}
View Source
var SshProxyCmd = &cobra.Command{
	Use:    "ssh-proxy [PROFILE_ID] [WORKSPACE_ID] [PROJECT]",
	Args:   cobra.RangeArgs(2, 3),
	Hidden: true,
	RunE: func(cmd *cobra.Command, args []string) error {
		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		profileId := args[0]
		workspaceId := args[1]
		projectName := ""

		profile, err := c.GetProfile(profileId)
		if err != nil {
			return err
		}

		if len(args) == 3 {
			projectName = args[2]
		} else {
			projectName, err = apiclient.GetFirstWorkspaceProjectName(workspaceId, projectName, &profile)
			if err != nil {
				return err
			}
		}

		workspace, err := apiclient.GetWorkspace(workspaceId, true)
		if err != nil {
			return err
		}

		if workspace.Target == "local" && profile.Id == "default" {

			project := workspace.Projects[0]

			if project.Name != projectName {
				for _, p := range workspace.Projects {
					if p.Name == projectName {
						project = p
						break
					}
				}
			}

			cli, err := client.NewClientWithOpts(client.FromEnv, client.WithAPIVersionNegotiation())
			if err != nil {
				return err
			}

			dockerClient := docker.NewDockerClient(docker.DockerClientConfig{
				ApiClient: cli,
			})

			containerName := dockerClient.GetProjectContainerName(conversion.ToProject(&project))

			ctx := context.Background()

			config := container.ExecOptions{
				AttachStdin:  true,
				AttachStderr: true,
				AttachStdout: true,
				Cmd:          []string{"daytona", "expose", fmt.Sprint(ssh_config.SSH_PORT)},
			}

			response, err := cli.ContainerExecCreate(ctx, containerName, config)
			if err != nil {
				return err
			}

			resp, err := cli.ContainerExecAttach(ctx, response.ID, container.ExecStartOptions{
				Tty: config.Tty,
			})

			if err != nil {
				return err
			}

			go func() {
				_, err = stdcopy.StdCopy(os.Stdout, os.Stderr, resp.Reader)
				if err != nil {
					log.Fatal(err)
				}
			}()

			go func() {
				_, err := io.Copy(resp.Conn, os.Stdin)
				if err != nil {
					log.Fatal(err)
				}
			}()

			for {
				res, err := cli.ContainerExecInspect(ctx, response.ID)
				if err != nil {
					return err
				}

				if !res.Running {
					os.Exit(res.ExitCode)
				}

				time.Sleep(100 * time.Millisecond)
			}
		}

		tsConn, err := tailscale.GetConnection(&profile)
		if err != nil {
			return err
		}

		errChan := make(chan error)

		dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", project.GetProjectHostname(workspaceId, projectName), ssh_config.SSH_PORT))
		if err != nil {
			return err
		}

		go func() {
			_, err := io.Copy(os.Stdout, dialConn)
			if err != nil {
				errChan <- err
			}
			errChan <- nil
		}()

		go func() {
			_, err := io.Copy(dialConn, os.Stdin)
			if err != nil {
				errChan <- err
			}
			errChan <- nil
		}()

		return <-errChan
	},
}
View Source
var StartCmd = &cobra.Command{
	Use:     "start [WORKSPACE]",
	Short:   "Start a workspace",
	Args:    cobra.RangeArgs(0, 1),
	GroupID: util.WORKSPACE_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		var selectedWorkspacesNames []string
		var activeProfile config.Profile
		var ideId string
		var ideList []config.Ide
		var providerConfigId *string
		projectProviderMetadata := ""

		ctx := context.Background()

		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		if allFlag {
			return startAllWorkspaces()
		}

		if len(args) == 0 {
			if startProjectFlag != "" {
				return cmd.Help()
			}
			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(true)
				return nil
			}

			selectedWorkspaces := selection.GetWorkspacesFromPrompt(workspaceList, "Start")
			for _, workspaces := range selectedWorkspaces {
				selectedWorkspacesNames = append(selectedWorkspacesNames, workspaces.Name)
			}
		} else {
			selectedWorkspacesNames = append(selectedWorkspacesNames, args[0])
		}

		if len(selectedWorkspacesNames) == 1 {
			workspaceName := selectedWorkspacesNames[0]
			var workspaceId string
			if codeFlag {
				c, err := config.GetConfig()
				if err != nil {
					return err
				}

				activeProfile, err = c.GetActiveProfile()
				if err != nil {
					return err
				}

				ideList = config.GetIdeList()
				ideId = c.DefaultIdeId

				wsInfo, res, err := apiClient.WorkspaceAPI.GetWorkspace(ctx, workspaceName).Execute()
				if err != nil {
					return apiclient_util.HandleErrorResponse(res, err)
				}
				workspaceId = wsInfo.Id
				if startProjectFlag == "" {
					startProjectFlag = wsInfo.Projects[0].Name
					providerConfigId = wsInfo.Projects[0].GitProviderConfigId
				} else {
					for _, project := range wsInfo.Projects {
						if project.Name == startProjectFlag {
							providerConfigId = project.GitProviderConfigId
							break
						}
					}
				}

				if ideId != "ssh" {
					projectProviderMetadata, err = workspace_util.GetProjectProviderMetadata(wsInfo, wsInfo.Projects[0].Name)
					if err != nil {
						return err
					}
				}
			}

			err = StartWorkspace(apiClient, workspaceName, startProjectFlag)
			if err != nil {
				return err
			}
			gpgKey, err := GetGitProviderGpgKey(apiClient, ctx, providerConfigId)
			if err != nil {
				log.Warn(err)
			}

			if startProjectFlag == "" {
				views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' started successfully", workspaceName))
			} else {
				views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' started successfully", startProjectFlag, workspaceName))

				if codeFlag {
					ide_views.RenderIdeOpeningMessage(workspaceName, startProjectFlag, ideId, ideList)
					err = openIDE(ideId, activeProfile, workspaceId, startProjectFlag, projectProviderMetadata, yesFlag, gpgKey)
					if err != nil {
						return err
					}
				}
			}
		} else {
			for _, workspace := range selectedWorkspacesNames {
				err := StartWorkspace(apiClient, workspace, "")
				if err != nil {
					log.Errorf("Failed to start workspace %s: %v\n\n", workspace, err)
					continue
				}
				views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", workspace))
			}
		}
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return getAllWorkspacesByState(WORKSPACE_STATUS_STOPPED)
	},
}
View Source
var StopCmd = &cobra.Command{
	Use:     "stop [WORKSPACE]",
	Short:   "Stop a workspace",
	GroupID: util.WORKSPACE_GROUP,
	Args:    cobra.RangeArgs(0, 1),
	RunE: func(cmd *cobra.Command, args []string) error {
		timeFormat := time.Now().Format("2006-01-02 15:04:05")
		from, err := time.Parse("2006-01-02 15:04:05", timeFormat)
		if err != nil {
			return err
		}

		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		activeProfile, err := c.GetActiveProfile()
		if err != nil {
			return err
		}

		if allFlag {
			return stopAllWorkspaces(activeProfile, from)
		}

		ctx := context.Background()

		apiClient, err := apiclient_util.GetApiClient(nil)
		if err != nil {
			return err
		}

		if len(args) == 0 {
			if stopProjectFlag != "" {
				return cmd.Help()
			}
			workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				views_util.NotifyEmptyWorkspaceList(true)
				return nil
			}

			selectedWorkspaces := selection.GetWorkspacesFromPrompt(workspaceList, "Stop")

			for _, workspace := range selectedWorkspaces {
				err := StopWorkspace(apiClient, workspace.Name, "")
				if err != nil {
					log.Errorf("Failed to stop workspace %s: %v\n\n", workspace.Name, err)
					continue
				}

				projectNames := util.ArrayMap(workspace.Projects, func(p apiclient.Project) string {
					return p.Name
				})
				apiclient_util.ReadWorkspaceLogs(ctx, activeProfile, workspace.Id, projectNames, false, true, &from)
				views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' successfully stopped", workspace.Name))
			}
		} else {
			workspaceId := args[0]
			var projectNames []string

			err = StopWorkspace(apiClient, workspaceId, stopProjectFlag)
			if err != nil {
				return err
			}

			workspace, err := apiclient_util.GetWorkspace(workspaceId, false)
			if err != nil {
				return err
			}

			if startProjectFlag != "" {
				projectNames = append(projectNames, stopProjectFlag)
			} else {
				projectNames = util.ArrayMap(workspace.Projects, func(p apiclient.Project) string {
					return p.Name
				})
			}

			apiclient_util.ReadWorkspaceLogs(ctx, activeProfile, workspace.Id, projectNames, false, true, &from)

			if stopProjectFlag != "" {
				views.RenderInfoMessage(fmt.Sprintf("Project '%s' from workspace '%s' successfully stopped", stopProjectFlag, workspaceId))
			} else {
				views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' successfully stopped", workspaceId))
			}
		}
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return getAllWorkspacesByState(WORKSPACE_STATUS_RUNNING)
	},
}

Functions

func AutoStartWorkspace added in v0.29.0

func AutoStartWorkspace(workspaceId string, projectName string) (bool, error)

func DeleteAllWorkspaces added in v0.7.0

func DeleteAllWorkspaces(force bool) error

func GetGitProviderGpgKey added in v0.40.0

func GetGitProviderGpgKey(apiClient *apiclient.APIClient, ctx context.Context, providerConfigId *string) (string, error)

func RemoveWorkspace added in v0.31.0

func RemoveWorkspace(ctx context.Context, apiClient *apiclient.APIClient, workspace *apiclient.WorkspaceDTO, force bool) error

func RestartWorkspace added in v0.35.0

func RestartWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName string) error

func StartWorkspace added in v0.31.0

func StartWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName string) error

func StopWorkspace added in v0.31.0

func StopWorkspace(apiClient *apiclient.APIClient, workspaceId, projectName string) error

Types

type WorkspaceState added in v0.4.0

type WorkspaceState string
const (
	WORKSPACE_STATUS_RUNNING WorkspaceState = "Running"
	WORKSPACE_STATUS_STOPPED WorkspaceState = "Unavailable"
)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL