workspace

package
v0.52.0 Latest Latest
Warning

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

Go to latest
Published: Jan 24, 2025 License: Apache-2.0 Imports: 39 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

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

		ctx := context.Background()
		var providerConfigId *string
		var ideId string
		var ws *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).Execute()
			if err != nil {
				return apiclient_util.HandleErrorResponse(res, err)
			}

			if len(workspaceList) == 0 {
				return errors.New("no workspaces found")
			}

			ws = selection.GetWorkspaceFromPrompt(workspaceList, "Open")
			if ws == nil {
				return nil
			}
		} else {
			var statusCode int
			ws, statusCode, err = apiclient_util.GetWorkspace(url.PathEscape(args[0]))
			if err != nil {
				if statusCode == http.StatusNotFound {
					log.Debug(err)
					return errors.New("workspace not found. You can see all workspace names by running the command `daytona list`")
				}
				return err
			}
		}
		if create.IdeFlag != "" {
			ideId = create.IdeFlag
		}

		if ws.State.Name == apiclient.ResourceStateNameStopped {
			wsRunningStatus, err := AutoStartWorkspace(*ws)
			if err != nil {
				return err
			}
			if !wsRunningStatus {
				return nil
			}
		}

		providerMetadata := *ws.ProviderMetadata

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

		yesFlag, _ := cmd.Flags().GetBool("yes")
		ideList := config.GetIdeList()
		ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList)
		return common.OpenIDE(ideId, activeProfile, ws.Id, providerMetadata, yesFlag, gpgKey)
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetWorkspaceNameCompletions()
	},
}
View Source
var DeleteCmd = &cobra.Command{
	Use:     "delete [WORKSPACE]...",
	Short:   "Delete a workspace",
	GroupID: util.TARGET_GROUP,
	Aliases: common.GetAliases("delete"),
	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
		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, selection.DeleteActionVerb)
		} else {
			for _, arg := range args {
				workspace, _, err := apiclient_util.GetWorkspace(arg)
				if err != nil {
					log.Error(fmt.Sprintf("[ %s ] : %v", arg, err))
					continue
				}
				workspaceDeleteList = append(workspaceDeleteList, workspace)
			}
		}

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

		wsDeleteListNames := util.ArrayMap(workspaceDeleteList, func(w *apiclient.WorkspaceDTO) string {
			return w.Name
		})

		if !yesFlag {
			form := huh.NewForm(
				huh.NewGroup(
					huh.NewConfirm().
						Title(fmt.Sprintf("Delete workspace(s): [%s]?", strings.Join(wsDeleteListNames, ", "))).
						Description(fmt.Sprintf("Are you sure you want to delete the workspace(s): [%s]?", strings.Join(wsDeleteListNames, ", "))).
						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 := common.DeleteWorkspace(ctx, apiClient, workspace.Id, workspace.Name, forceFlag)
				if err != nil {
					log.Error(fmt.Sprintf("[ %s ] : %v", workspace.Name, err))
					continue
				}
				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 common.GetWorkspaceNameCompletions()
	},
}
View Source
var InfoCmd = &cobra.Command{
	Use:     "info [WORKSPACE]",
	Short:   "Show workspace info",
	Args:    cobra.RangeArgs(0, 1),
	GroupID: util.TARGET_GROUP,
	Aliases: common.GetAliases("info"),
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := context.Background()

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

		var ws *apiclient.WorkspaceDTO

		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
			}

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

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

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

		if ws == nil {
			return nil
		}

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

		info.Render(ws, "", false)
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetWorkspaceNameCompletions()
	},
}
View Source
var ListCmd = &cobra.Command{
	Use:     "list",
	Short:   "List workspaces",
	Args:    cobra.NoArgs,
	GroupID: util.TARGET_GROUP,
	Aliases: common.GetAliases("list"),
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := context.Background()
		var specifyGitProviders bool

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

		labels, err := common.MapKeyValue(labelFilters)
		if err != nil {
			return err
		}

		encoded, err := json.Marshal(labels)
		if err != nil {
			return err
		}

		workspaceList, res, err := apiClient.WorkspaceAPI.ListWorkspaces(ctx).Labels(string(encoded)).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.ListWorkspaces(workspaceList, specifyGitProviders, activeProfile.Name)
		return nil
	},
}
View Source
var LogsCmd = &cobra.Command{
	Use:     "logs [WORKSPACE]",
	Short:   "View the logs of a workspace",
	Args:    cobra.RangeArgs(0, 2),
	GroupID: util.TARGET_GROUP,
	Aliases: common.GetAliases("logs"),
	RunE: func(cmd *cobra.Command, args []string) error {
		ctx := context.Background()

		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
		}

		var ws *apiclient.WorkspaceDTO

		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
			}

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

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

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

		if ws == nil {
			return nil
		}

		common.ReadWorkspaceLogs(ctx, common.ReadLogParams{
			Id:        ws.Id,
			Label:     &ws.Name,
			ServerUrl: activeProfile.Api.Url,
			ApiKey:    activeProfile.Api.Key,
			Index:     util.Pointer(0),
			Follow:    &followFlag,
		})
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetWorkspaceNameCompletions()
	},
}
View Source
var RestartCmd = &cobra.Command{
	Use:     "restart [WORKSPACE]...",
	Short:   "Restart a workspace",
	GroupID: util.TARGET_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		var selectedWorkspaces []*apiclient.WorkspaceDTO

		ctx := context.Background()

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

		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
		}

		if len(args) == 0 {
			selectedWorkspaces = selection.GetWorkspacesFromPrompt(workspaceList, selection.RestartActionVerb)
			if selectedWorkspaces == nil {
				return nil
			}
		} else {
			for _, arg := range args {
				workspace, _, err := apiclient_util.GetWorkspace(arg)
				if err != nil {
					log.Error(fmt.Sprintf("[ %s ] : %v", arg, err))
					continue
				}
				selectedWorkspaces = append(selectedWorkspaces, workspace)
			}
		}

		if len(selectedWorkspaces) == 1 {
			workspace := selectedWorkspaces[0]

			err = StartWorkspace(apiClient, *workspace, true)
			if err != nil {
				return err
			}

			views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' restarted successfully", workspace.Name))
		} else {
			for _, ws := range selectedWorkspaces {
				err := StartWorkspace(apiClient, *ws, true)
				if err != nil {
					log.Errorf("Failed to restart workspace %s: %v\n\n", ws.Name, err)
					continue
				}
				views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' restarted successfully", ws.Name))
			}
		}

		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStarted)
	},
}
View Source
var SshCmd = &cobra.Command{
	Use:     "ssh [WORKSPACE] [CMD...]",
	Short:   "SSH into a workspace using the terminal",
	Args:    cobra.ArbitraryArgs,
	GroupID: util.TARGET_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 ws *apiclient.WorkspaceDTO

		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
			}

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

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

		if ws.State.Name == apiclient.ResourceStateNameStopped {
			wsRunningStatus, err := AutoStartWorkspace(*ws)
			if err != nil {
				return err
			}
			if !wsRunningStatus {
				return nil
			}
		}

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

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

		return ide.OpenTerminalSsh(activeProfile, ws.Id, gpgKey, sshOptions, sshArgs...)
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetWorkspaceNameCompletions()
	},
}
View Source
var SshProxyCmd = &cobra.Command{
	Use:    "ssh-proxy [PROFILE_ID] [TARGET_ID | WORKSPACE_ID]",
	Args:   cobra.ExactArgs(2),
	Hidden: true,
	RunE: func(cmd *cobra.Command, args []string) error {
		c, err := config.GetConfig()
		if err != nil {
			return err
		}

		profileId := args[0]
		resourceId := args[1]

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

		var target *apiclient.TargetDTO

		ws, statusCode, err := apiclient_util.GetWorkspace(resourceId)
		if err != nil && statusCode != http.StatusNotFound {
			return err
		}

		if ws == nil {
			target, _, err = apiclient_util.GetTarget(resourceId)
			if err != nil {
				return err
			}
		} else {
			target, _, err = apiclient_util.GetTarget(ws.TargetId)
			if err != nil {
				return err
			}
		}

		if ws != nil && common.IsLocalDockerTarget(target.TargetConfig.ProviderInfo.Name, target.TargetConfig.Options, target.TargetConfig.ProviderInfo.RunnerId) && profile.Id == "default" {

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

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

			workspace, err := conversion.Convert[apiclient.WorkspaceDTO, models.Workspace](ws)
			if err != nil {
				return err
			}

			containerName := dockerClient.GetWorkspaceContainerName(workspace)

			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)

		hostname := common.GetTailscaleHostname(target.Id)
		if ws != nil {
			hostname = common.GetTailscaleHostname(ws.Id)
		}

		dialConn, err := tsConn.Dial(context.Background(), "tcp", fmt.Sprintf("%s:%d", hostname, 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",
	GroupID: util.TARGET_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		var selectedWorkspaces []*apiclient.WorkspaceDTO
		var activeProfile config.Profile
		var ideId string
		var ideList []config.Ide
		var providerConfigId *string
		workspaceProviderMetadata := ""

		ctx := context.Background()

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

		if allFlag {
			return startAllWorkspaces()
		}

		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
			}

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

		if len(selectedWorkspaces) == 1 {
			var ws *apiclient.WorkspaceDTO
			var res *http.Response
			workspace := selectedWorkspaces[0]
			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

				ws, res, err = apiClient.WorkspaceAPI.FindWorkspace(ctx, workspace.Id).Execute()
				if err != nil {
					return apiclient_util.HandleErrorResponse(res, err)
				}
				if ideId != "ssh" {
					workspaceProviderMetadata = *ws.ProviderMetadata
				}
			}

			err = StartWorkspace(apiClient, *workspace, false)
			if err != nil {
				return err
			}
			gpgKey, err := common.GetGitProviderGpgKey(apiClient, ctx, providerConfigId)
			if err != nil {
				log.Warn(err)
			}

			views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' started successfully", workspace.Name))

			if codeFlag {
				ide_views.RenderIdeOpeningMessage(ws.TargetId, ws.Name, ideId, ideList)
				err = common.OpenIDE(ideId, activeProfile, ws.Id, workspaceProviderMetadata, yesFlag, gpgKey)
				if err != nil {
					return err
				}
			}
		} else {
			for _, ws := range selectedWorkspaces {
				err := StartWorkspace(apiClient, *ws, false)
				if err != nil {
					log.Errorf("Failed to start workspace %s: %v\n\n", ws.Name, err)
					continue
				}
				views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' started successfully", ws.Name))
			}
		}
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStopped)
	},
}
View Source
var StopCmd = &cobra.Command{
	Use:     "stop [WORKSPACE]...",
	Short:   "Stop a workspace",
	GroupID: util.TARGET_GROUP,
	RunE: func(cmd *cobra.Command, args []string) error {
		var selectedWorkspaces []*apiclient.WorkspaceDTO

		ctx := context.Background()

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

		if allFlag {
			return stopAllWorkspaces()
		}

		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
			}

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

		if len(selectedWorkspaces) == 1 {
			workspace := selectedWorkspaces[0]

			err = StopWorkspace(apiClient, *workspace)
			if err != nil {
				return err
			}

			views.RenderInfoMessage(fmt.Sprintf("Workspace '%s' stopped successfully", workspace.Name))
		} else {
			for _, ws := range selectedWorkspaces {
				err := StopWorkspace(apiClient, *ws)
				if err != nil {
					log.Errorf("Failed to stop workspace %s: %v\n\n", ws.Name, err)
					continue
				}
				views.RenderInfoMessage(fmt.Sprintf("- Workspace '%s' stopped successfully", ws.Name))
			}
		}
		return nil
	},
	ValidArgsFunction: func(cmd *cobra.Command, args []string, toComplete string) ([]string, cobra.ShellCompDirective) {
		return common.GetAllWorkspacesByState(apiclient.ResourceStateNameStarted)
	},
}

Functions

func AutoStartWorkspace added in v0.29.0

func AutoStartWorkspace(workspace apiclient.WorkspaceDTO) (bool, error)

func DeleteAllWorkspaces added in v0.7.0

func DeleteAllWorkspaces(force bool) error

func StartWorkspace added in v0.31.0

func StartWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO, restart bool) error

func StopWorkspace added in v0.31.0

func StopWorkspace(apiClient *apiclient.APIClient, workspace apiclient.WorkspaceDTO) error

Types

This section is empty.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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