MCPcopy Index your code
hub / github.com/coder/coder / chatStartWorkspace

Method chatStartWorkspace

coderd/exp_chats.go:3857–3928  ·  view source on GitHub ↗

chatStartWorkspace starts a stopped workspace by creating a new build with the "start" transition. It mirrors chatCreateWorkspace but for the start path. Aliased as ChatStartWorkspace in coderd/export_test.go so external tests in the coderd_test package can drive the auto-update path end-to-end. Th

(
	ctx context.Context,
	ownerID uuid.UUID,
	workspaceID uuid.UUID,
	req codersdk.CreateWorkspaceBuildRequest,
)

Source from the content-addressed store, hash-verified

3855// end-to-end. The proper fix is to extract the request building into
3856// a pure function; tracked in CODAGT-292.
3857func (api *API) chatStartWorkspace(
3858 ctx context.Context,
3859 ownerID uuid.UUID,
3860 workspaceID uuid.UUID,
3861 req codersdk.CreateWorkspaceBuildRequest,
3862) (codersdk.WorkspaceBuild, error) {
3863 actor, _, err := httpmw.UserRBACSubject(ctx, api.Database, ownerID, rbac.ScopeAll)
3864 if err != nil {
3865 return codersdk.WorkspaceBuild{}, xerrors.Errorf("load user authorization: %w", err)
3866 }
3867 ctx = dbauthz.As(ctx, actor)
3868
3869 workspace, err := api.Database.GetWorkspaceByID(ctx, workspaceID)
3870 if err != nil {
3871 return codersdk.WorkspaceBuild{}, xerrors.Errorf("get workspace: %w", err)
3872 }
3873
3874 updatedToActiveVersion := false
3875 if req.Transition == codersdk.WorkspaceTransitionStart {
3876 template, err := api.Database.GetTemplateByID(ctx, workspace.TemplateID)
3877 if err != nil {
3878 return codersdk.WorkspaceBuild{}, xerrors.Errorf("get template: %w", err)
3879 }
3880
3881 templateAccessControl := (*(api.AccessControlStore.Load())).GetTemplateAccessControl(template)
3882 if templateAccessControl.RequireActiveVersion {
3883 latestBuild, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(ctx, workspace.ID)
3884 if err != nil {
3885 return codersdk.WorkspaceBuild{}, xerrors.Errorf("get latest workspace build: %w", err)
3886 }
3887
3888 updatedToActiveVersion = latestBuild.TemplateVersionID != template.ActiveVersionID
3889 req.TemplateVersionID = template.ActiveVersionID
3890 }
3891 }
3892
3893 // Build a synthetic API key so postWorkspaceBuildsInternal can
3894 // record the correct initiator.
3895 syntheticKey := database.APIKey{
3896 UserID: ownerID,
3897 }
3898
3899 apiBuild, err := api.postWorkspaceBuildsInternal(
3900 ctx,
3901 syntheticKey,
3902 workspace,
3903 req,
3904 func(action policy.Action, object rbac.Objecter) bool {
3905 // Authorization is handled by dbauthz on the context.
3906 authErr := api.HTTPAuth.Authorizer.Authorize(ctx, actor, action, object.RBACObject())
3907 return authErr == nil
3908 },
3909 audit.WorkspaceBuildBaggage{},
3910 )
3911 if err != nil {
3912 if updatedToActiveVersion && isChatStartWorkspaceManualUpdateRequiredError(err) {
3913 const retryInstructions = "The workspace needs the template's active version before it can start. Use read_template with this workspace's template_id to inspect the active version's required parameters, then retry start_workspace with a parameters object that supplies any missing or changed values. If the correct value for a parameter is not obvious from its description or defaults, ask the user rather than guessing."
3914 if responder, ok := httperror.IsResponder(err); ok {

Callers

nothing calls this directly

Calls 15

UserRBACSubjectFunction · 0.92
AsFunction · 0.92
IsResponderFunction · 0.92
NewResponseErrorFunction · 0.92
GetWorkspaceByIDMethod · 0.65
GetTemplateByIDMethod · 0.65
AuthorizeMethod · 0.65

Tested by

no test coverage detected