Skip to content
12 changes: 12 additions & 0 deletions coderd/autobuild/executor/lifecycle_executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa
}
provisionerJobID := uuid.New()
now := database.Now()

var buildReason database.BuildReason
switch trans {
case database.WorkspaceTransitionStart:
buildReason = database.BuildReasonAutostart
case database.WorkspaceTransitionStop:
buildReason = database.BuildReasonAutostop
default:
return xerrors.Errorf("Unsupported transition: %q", trans)
}

newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
ID: provisionerJobID,
CreatedAt: now,
Expand Down Expand Up @@ -236,6 +247,7 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa
InitiatorID: workspace.OwnerID,
Transition: trans,
JobID: newProvisionerJob.ID,
Reason: buildReason,
})
if err != nil {
return xerrors.Errorf("insert workspace build: %w", err)
Expand Down
6 changes: 6 additions & 0 deletions coderd/autobuild/executor/lifecycle_executor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ func TestExecutorAutostartOK(t *testing.T) {
assert.Len(t, stats.Transitions, 1)
assert.Contains(t, stats.Transitions, workspace.ID)
assert.Equal(t, database.WorkspaceTransitionStart, stats.Transitions[workspace.ID])

workspace = coderdtest.MustWorkspace(t, client, workspace.ID)
assert.Equal(t, codersdk.BuildReasonAutostart, workspace.LatestBuild.Reason)
}

func TestExecutorAutostartTemplateUpdated(t *testing.T) {
Expand Down Expand Up @@ -200,6 +203,9 @@ func TestExecutorAutostopOK(t *testing.T) {
assert.Len(t, stats.Transitions, 1)
assert.Contains(t, stats.Transitions, workspace.ID)
assert.Equal(t, database.WorkspaceTransitionStop, stats.Transitions[workspace.ID])

workspace = coderdtest.MustWorkspace(t, client, workspace.ID)
assert.Equal(t, codersdk.BuildReasonAutostop, workspace.LatestBuild.Reason)
}

func TestExecutorAutostopExtend(t *testing.T) {
Expand Down
1 change: 1 addition & 0 deletions coderd/database/databasefake/databasefake.go
Original file line number Diff line number Diff line change
Expand Up @@ -1720,6 +1720,7 @@ func (q *fakeQuerier) InsertWorkspaceBuild(_ context.Context, arg database.Inser
JobID: arg.JobID,
ProvisionerState: arg.ProvisionerState,
Deadline: arg.Deadline,
Reason: arg.Reason,
}
q.workspaceBuilds = append(q.workspaceBuilds, workspaceBuild)
return workspaceBuild, nil
Expand Down
9 changes: 8 additions & 1 deletion coderd/database/dump.sql

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
ALTER TABLE ONLY workspace_builds
DROP COLUMN IF EXISTS reason;

DROP TYPE build_reason;
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
CREATE TYPE build_reason AS ENUM ('initiator', 'autostart', 'autostop');

ALTER TABLE ONLY workspace_builds
ADD COLUMN IF NOT EXISTS reason build_reason NOT NULL DEFAULT 'initiator';
21 changes: 21 additions & 0 deletions coderd/database/models.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

32 changes: 22 additions & 10 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 3 additions & 2 deletions coderd/database/queries/workspacebuilds.sql
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,11 @@ INSERT INTO
initiator_id,
job_id,
provisioner_state,
deadline
deadline,
reason
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12) RETURNING *;
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING *;

-- name: UpdateWorkspaceBuildByID :exec
UPDATE
Expand Down
2 changes: 2 additions & 0 deletions coderd/workspacebuilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) {
InitiatorID: apiKey.UserID,
Transition: database.WorkspaceTransition(createBuild.Transition),
JobID: provisionerJob.ID,
Reason: database.BuildReasonInitiator,
})
if err != nil {
return xerrors.Errorf("insert workspace build: %w", err)
Expand Down Expand Up @@ -639,6 +640,7 @@ func convertWorkspaceBuild(
InitiatorUsername: initiatorName,
Job: convertProvisionerJob(job),
Deadline: workspaceBuild.Deadline,
Reason: codersdk.BuildReason(workspaceBuild.Reason),
}
}

Expand Down
2 changes: 2 additions & 0 deletions coderd/workspaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req
JobID: provisionerJob.ID,
BuildNumber: 1, // First build!
Deadline: time.Time{}, // provisionerd will set this upon success
Reason: database.BuildReasonInitiator,
})
if err != nil {
return xerrors.Errorf("insert workspace build: %w", err)
Expand Down Expand Up @@ -806,6 +807,7 @@ func convertWorkspaces(ctx context.Context, db database.Store, workspaces []data
ProvisionerState: workspaceBuild.ProvisionerState,
JobID: workspaceBuild.JobID,
Deadline: workspaceBuild.Deadline,
Reason: workspaceBuild.Reason,
}
}
templateByID := map[uuid.UUID]database.Template{}
Expand Down
4 changes: 3 additions & 1 deletion coderd/workspaces_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,10 @@ func TestWorkspace(t *testing.T) {
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
workspace := coderdtest.CreateWorkspace(t, client, user.OrganizationID, template.ID)

_, err := client.Workspace(context.Background(), workspace.ID)
ws, err := client.Workspace(context.Background(), workspace.ID)
require.NoError(t, err)
require.Equal(t, user.UserID, ws.LatestBuild.InitiatorID)
require.Equal(t, codersdk.BuildReasonInitiator, ws.LatestBuild.Reason)
})

t.Run("Deleted", func(t *testing.T) {
Expand Down
15 changes: 15 additions & 0 deletions codersdk/workspacebuilds.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,20 @@ const (
WorkspaceTransitionDelete WorkspaceTransition = "delete"
)

type BuildReason string

const (
// "initiator" is used when a workspace build is triggered by a user.
// Combined with the initiator id/username, it indicates which user initiated the build.
BuildReasonInitiator BuildReason = "initiator"
// "autostart" is used when a build to start a workspace is triggered by Autostart.
// The initiator id/username in this case is the workspace owner and can be ignored.
BuildReasonAutostart BuildReason = "autostart"
// "autostop" is used when a build to stop a workspace is triggered by Autostop.
// The initiator id/username in this case is the workspace owner and can be ignored.
BuildReasonAutostop BuildReason = "autostop"
)

// WorkspaceBuild is an at-point representation of a workspace state.
// BuildNumbers start at 1 and increase by 1 for each subsequent build
type WorkspaceBuild struct {
Expand All @@ -37,6 +51,7 @@ type WorkspaceBuild struct {
InitiatorUsername string `json:"initiator_name"`
Job ProvisionerJob `json:"job"`
Deadline time.Time `json:"deadline"`
Reason BuildReason `db:"reason" json:"reason"`
}

// WorkspaceBuild returns a single workspace build for a workspace.
Expand Down
Loading