From ee908412b78cf68313959a6164d5f75dad4b48d0 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 20:44:28 +0000 Subject: [PATCH 01/12] add reason field for workspace build --- .../autobuild/executor/lifecycle_executor.go | 9 ++++++ coderd/database/databasefake/databasefake.go | 1 + coderd/database/dump.sql | 9 +++++- .../000024_workspace_build_reason.down.sql | 4 +++ .../000024_workspace_build_reason.up.sql | 4 +++ coderd/database/models.go | 21 ++++++++++++++ coderd/database/queries.sql.go | 29 +++++++++++++------ coderd/database/queries/workspacebuilds.sql | 5 ++-- coderd/workspacebuilds.go | 1 + coderd/workspaces.go | 1 + 10 files changed, 72 insertions(+), 12 deletions(-) create mode 100644 coderd/database/migrations/000024_workspace_build_reason.down.sql create mode 100644 coderd/database/migrations/000024_workspace_build_reason.up.sql diff --git a/coderd/autobuild/executor/lifecycle_executor.go b/coderd/autobuild/executor/lifecycle_executor.go index 161b85cf0f53f..0295d4cb47efd 100644 --- a/coderd/autobuild/executor/lifecycle_executor.go +++ b/coderd/autobuild/executor/lifecycle_executor.go @@ -224,6 +224,14 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa if err != nil { return xerrors.Errorf("insert provisioner job: %w", err) } + + var buildReason database.BuildReason + switch trans { + case database.WorkspaceTransitionStart: + buildReason = database.BuildReasonAutostart + case database.WorkspaceTransitionStop: + buildReason = database.BuildReasonAutostop + } _, err = store.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ ID: workspaceBuildID, CreatedAt: now, @@ -236,6 +244,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) diff --git a/coderd/database/databasefake/databasefake.go b/coderd/database/databasefake/databasefake.go index e41c70b874ed8..7a9e3ed23ed6a 100644 --- a/coderd/database/databasefake/databasefake.go +++ b/coderd/database/databasefake/databasefake.go @@ -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 diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index b479dc2315a99..9e3a048d9d052 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -6,6 +6,12 @@ CREATE TYPE audit_action AS ENUM ( 'delete' ); +CREATE TYPE build_reason AS ENUM ( + 'member', + 'autostart', + 'autostop' +); + CREATE TYPE log_level AS ENUM ( 'trace', 'debug', @@ -311,7 +317,8 @@ CREATE TABLE workspace_builds ( initiator_id uuid NOT NULL, provisioner_state bytea, job_id uuid NOT NULL, - deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL + deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL, + reason build_reason DEFAULT 'member'::public.build_reason NOT NULL ); CREATE TABLE workspace_resources ( diff --git a/coderd/database/migrations/000024_workspace_build_reason.down.sql b/coderd/database/migrations/000024_workspace_build_reason.down.sql new file mode 100644 index 0000000000000..84d8975996e5c --- /dev/null +++ b/coderd/database/migrations/000024_workspace_build_reason.down.sql @@ -0,0 +1,4 @@ +ALTER TABLE ONLY workspace_builds + DROP COLUMN IF EXISTS reason; + +DROP TYPE build_reason; diff --git a/coderd/database/migrations/000024_workspace_build_reason.up.sql b/coderd/database/migrations/000024_workspace_build_reason.up.sql new file mode 100644 index 0000000000000..c78240d473260 --- /dev/null +++ b/coderd/database/migrations/000024_workspace_build_reason.up.sql @@ -0,0 +1,4 @@ +CREATE TYPE build_reason AS ENUM ('member', 'autostart', 'autostop'); + +ALTER TABLE ONLY workspace_builds + ADD COLUMN IF NOT EXISTS reason build_reason NOT NULL DEFAULT 'member'; diff --git a/coderd/database/models.go b/coderd/database/models.go index 3dbbf5da05be3..f5ade198be336 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -34,6 +34,26 @@ func (e *AuditAction) Scan(src interface{}) error { return nil } +type BuildReason string + +const ( + BuildReasonMember BuildReason = "member" + BuildReasonAutostart BuildReason = "autostart" + BuildReasonAutostop BuildReason = "autostop" +) + +func (e *BuildReason) Scan(src interface{}) error { + switch s := src.(type) { + case []byte: + *e = BuildReason(s) + case string: + *e = BuildReason(s) + default: + return fmt.Errorf("unsupported scan type for BuildReason: %T", src) + } + return nil +} + type LogLevel string const ( @@ -525,6 +545,7 @@ type WorkspaceBuild struct { ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"` JobID uuid.UUID `db:"job_id" json:"job_id"` Deadline time.Time `db:"deadline" json:"deadline"` + Reason BuildReason `db:"reason" json:"reason"` } type WorkspaceResource struct { diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index b91a784a2fc84..0596f24246ccf 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -3278,7 +3278,7 @@ func (q *sqlQuerier) InsertWorkspaceApp(ctx context.Context, arg InsertWorkspace const getLatestWorkspaceBuildByWorkspaceID = `-- name: GetLatestWorkspaceBuildByWorkspaceID :one SELECT - id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE @@ -3305,12 +3305,13 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ) return i, err } const getLatestWorkspaceBuildsByWorkspaceIDs = `-- name: GetLatestWorkspaceBuildsByWorkspaceIDs :many -SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.name, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline +SELECT wb.id, wb.created_at, wb.updated_at, wb.workspace_id, wb.template_version_id, wb.name, wb.build_number, wb.transition, wb.initiator_id, wb.provisioner_state, wb.job_id, wb.deadline, wb.reason FROM ( SELECT workspace_id, MAX(build_number) as max_build_number @@ -3348,6 +3349,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ); err != nil { return nil, err } @@ -3364,7 +3366,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context, const getWorkspaceBuildByID = `-- name: GetWorkspaceBuildByID :one SELECT - id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE @@ -3389,13 +3391,14 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ) return i, err } const getWorkspaceBuildByJobID = `-- name: GetWorkspaceBuildByJobID :one SELECT - id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE @@ -3420,13 +3423,14 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ) return i, err } const getWorkspaceBuildByWorkspaceID = `-- name: GetWorkspaceBuildByWorkspaceID :many SELECT - id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE @@ -3491,6 +3495,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg Get &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ); err != nil { return nil, err } @@ -3507,7 +3512,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg Get const getWorkspaceBuildByWorkspaceIDAndBuildNumber = `-- name: GetWorkspaceBuildByWorkspaceIDAndBuildNumber :one SELECT - id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE @@ -3536,13 +3541,14 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx context.Co &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ) return i, err } const getWorkspaceBuildByWorkspaceIDAndName = `-- name: GetWorkspaceBuildByWorkspaceIDAndName :one SELECT - id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE @@ -3571,6 +3577,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context, &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ) return i, err } @@ -3629,10 +3636,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 id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13) RETURNING id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason ` type InsertWorkspaceBuildParams struct { @@ -3648,6 +3656,7 @@ type InsertWorkspaceBuildParams struct { JobID uuid.UUID `db:"job_id" json:"job_id"` ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"` Deadline time.Time `db:"deadline" json:"deadline"` + Reason BuildReason `db:"reason" json:"reason"` } func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error) { @@ -3664,6 +3673,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa arg.JobID, arg.ProvisionerState, arg.Deadline, + arg.Reason, ) var i WorkspaceBuild err := row.Scan( @@ -3679,6 +3689,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ) return i, err } diff --git a/coderd/database/queries/workspacebuilds.sql b/coderd/database/queries/workspacebuilds.sql index df2ce44c94f1e..2e84616e99a33 100644 --- a/coderd/database/queries/workspacebuilds.sql +++ b/coderd/database/queries/workspacebuilds.sql @@ -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 diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index d0db01e4a1722..9016732e26851 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -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.BuildReasonMember, }) if err != nil { return xerrors.Errorf("insert workspace build: %w", err) diff --git a/coderd/workspaces.go b/coderd/workspaces.go index 188a61242c03f..154536071c595 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -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.BuildReasonMember, }) if err != nil { return xerrors.Errorf("insert workspace build: %w", err) From d4606174b581a91eb72b39d92b3f8d592db0f96b Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 20:59:36 +0000 Subject: [PATCH 02/12] add the reason field to FE via API --- codersdk/workspacebuilds.go | 9 +++++++++ site/src/api/typesGenerated.ts | 6 +++++- site/src/testHelpers/entities.ts | 5 +++-- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go index 79dae16d8f12c..166058a2bab99 100644 --- a/codersdk/workspacebuilds.go +++ b/codersdk/workspacebuilds.go @@ -19,6 +19,14 @@ const ( WorkspaceTransitionDelete WorkspaceTransition = "delete" ) +type BuildReason string + +const ( + BuildReasonMember BuildReason = "member" + BuildReasonAutostart BuildReason = "autostart" + 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 { @@ -37,6 +45,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. diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 0f2521ad79d87..35f32f64b13ff 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -443,7 +443,7 @@ export interface WorkspaceApp { readonly icon?: string } -// From codersdk/workspacebuilds.go:24:6 +// From codersdk/workspacebuilds.go:32:6 export interface WorkspaceBuild { readonly id: string readonly created_at: string @@ -460,6 +460,7 @@ export interface WorkspaceBuild { readonly initiator_name: string readonly job: ProvisionerJob readonly deadline: string + readonly reason: BuildReason } // From codersdk/workspaces.go:84:6 @@ -488,6 +489,9 @@ export interface WorkspaceResource { readonly agents?: WorkspaceAgent[] } +// From codersdk/workspacebuilds.go:22:6 +export type BuildReason = "autostart" | "autostop" | "member" + // From codersdk/provisionerdaemons.go:23:6 export type LogLevel = "debug" | "error" | "info" | "trace" | "warn" diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index dfc5dbbbbb83a..f94838a5d8d31 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -144,8 +144,8 @@ export const MockWorkspaceBuild: TypesGen.WorkspaceBuild = { build_number: 1, created_at: "2022-05-17T17:39:01.382927298Z", id: "1", - initiator_id: "", - initiator_name: "", + initiator_id: MockUser.id, + initiator_name: MockUser.username, job: MockProvisionerJob, name: "a-workspace-build", template_version_id: "", @@ -156,6 +156,7 @@ export const MockWorkspaceBuild: TypesGen.WorkspaceBuild = { workspace_owner_name: MockUser.username, workspace_id: "759f1d46-3174-453d-aa60-980a9c1442f3", deadline: "2022-05-17T23:39:00.00Z", + reason: "member", } export const MockWorkspaceBuildStop: TypesGen.WorkspaceBuild = { From 105ccfa0330cd3634324fdd8e2fe58ff21eaa706 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 21:13:10 +0000 Subject: [PATCH 03/12] update BuildReasonMember to BuildReasonInitiator --- coderd/database/dump.sql | 4 ++-- .../database/migrations/000024_workspace_build_reason.up.sql | 4 ++-- coderd/database/models.go | 2 +- coderd/workspacebuilds.go | 2 +- coderd/workspaces.go | 2 +- codersdk/workspacebuilds.go | 2 +- site/src/api/typesGenerated.ts | 2 +- site/src/testHelpers/entities.ts | 2 +- 8 files changed, 10 insertions(+), 10 deletions(-) diff --git a/coderd/database/dump.sql b/coderd/database/dump.sql index 9e3a048d9d052..dee75904e13e7 100644 --- a/coderd/database/dump.sql +++ b/coderd/database/dump.sql @@ -7,7 +7,7 @@ CREATE TYPE audit_action AS ENUM ( ); CREATE TYPE build_reason AS ENUM ( - 'member', + 'initiator', 'autostart', 'autostop' ); @@ -318,7 +318,7 @@ CREATE TABLE workspace_builds ( provisioner_state bytea, job_id uuid NOT NULL, deadline timestamp with time zone DEFAULT '0001-01-01 00:00:00+00'::timestamp with time zone NOT NULL, - reason build_reason DEFAULT 'member'::public.build_reason NOT NULL + reason build_reason DEFAULT 'initiator'::public.build_reason NOT NULL ); CREATE TABLE workspace_resources ( diff --git a/coderd/database/migrations/000024_workspace_build_reason.up.sql b/coderd/database/migrations/000024_workspace_build_reason.up.sql index c78240d473260..a4cfb3a49c676 100644 --- a/coderd/database/migrations/000024_workspace_build_reason.up.sql +++ b/coderd/database/migrations/000024_workspace_build_reason.up.sql @@ -1,4 +1,4 @@ -CREATE TYPE build_reason AS ENUM ('member', 'autostart', 'autostop'); +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 'member'; + ADD COLUMN IF NOT EXISTS reason build_reason NOT NULL DEFAULT 'initiator'; diff --git a/coderd/database/models.go b/coderd/database/models.go index f5ade198be336..7b4ac76016671 100644 --- a/coderd/database/models.go +++ b/coderd/database/models.go @@ -37,7 +37,7 @@ func (e *AuditAction) Scan(src interface{}) error { type BuildReason string const ( - BuildReasonMember BuildReason = "member" + BuildReasonInitiator BuildReason = "initiator" BuildReasonAutostart BuildReason = "autostart" BuildReasonAutostop BuildReason = "autostop" ) diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index 9016732e26851..1ac70f27f501d 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -439,7 +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.BuildReasonMember, + Reason: database.BuildReasonInitiator, }) if err != nil { return xerrors.Errorf("insert workspace build: %w", err) diff --git a/coderd/workspaces.go b/coderd/workspaces.go index 154536071c595..ff41ab7c52abe 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -436,7 +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.BuildReasonMember, + Reason: database.BuildReasonInitiator, }) if err != nil { return xerrors.Errorf("insert workspace build: %w", err) diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go index 166058a2bab99..3995f3b21bd66 100644 --- a/codersdk/workspacebuilds.go +++ b/codersdk/workspacebuilds.go @@ -22,7 +22,7 @@ const ( type BuildReason string const ( - BuildReasonMember BuildReason = "member" + BuildReasonInitiator BuildReason = "initiator" BuildReasonAutostart BuildReason = "autostart" BuildReasonAutostop BuildReason = "autostop" ) diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 35f32f64b13ff..20bcd0533f6a0 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -490,7 +490,7 @@ export interface WorkspaceResource { } // From codersdk/workspacebuilds.go:22:6 -export type BuildReason = "autostart" | "autostop" | "member" +export type BuildReason = "autostart" | "autostop" | "initiator" // From codersdk/provisionerdaemons.go:23:6 export type LogLevel = "debug" | "error" | "info" | "trace" | "warn" diff --git a/site/src/testHelpers/entities.ts b/site/src/testHelpers/entities.ts index f94838a5d8d31..bcfe21a9286ca 100644 --- a/site/src/testHelpers/entities.ts +++ b/site/src/testHelpers/entities.ts @@ -156,7 +156,7 @@ export const MockWorkspaceBuild: TypesGen.WorkspaceBuild = { workspace_owner_name: MockUser.username, workspace_id: "759f1d46-3174-453d-aa60-980a9c1442f3", deadline: "2022-05-17T23:39:00.00Z", - reason: "member", + reason: "initiator", } export const MockWorkspaceBuildStop: TypesGen.WorkspaceBuild = { From 90e0d1756fab86146ac33ae2a5fd443960d83112 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 21:27:32 +0000 Subject: [PATCH 04/12] add unit tests --- coderd/autobuild/executor/lifecycle_executor_test.go | 8 ++++++++ coderd/workspacebuilds.go | 1 + 2 files changed, 9 insertions(+) diff --git a/coderd/autobuild/executor/lifecycle_executor_test.go b/coderd/autobuild/executor/lifecycle_executor_test.go index 1680fe0368e12..988327f53ce59 100644 --- a/coderd/autobuild/executor/lifecycle_executor_test.go +++ b/coderd/autobuild/executor/lifecycle_executor_test.go @@ -51,6 +51,10 @@ 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, err := client.Workspace(context.Background(), workspace.ID) + assert.NoError(t, err) + assert.Equal(t, codersdk.BuildReasonAutostart, workspace.LatestBuild.Reason) } func TestExecutorAutostartTemplateUpdated(t *testing.T) { @@ -200,6 +204,10 @@ 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, err := client.Workspace(context.Background(), workspace.ID) + assert.NoError(t, err) + assert.Equal(t, codersdk.BuildReasonAutostop, workspace.LatestBuild.Reason) } func TestExecutorAutostopExtend(t *testing.T) { diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index 1ac70f27f501d..f6cac24ade77e 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -640,6 +640,7 @@ func convertWorkspaceBuild( InitiatorUsername: initiatorName, Job: convertProvisionerJob(job), Deadline: workspaceBuild.Deadline, + Reason: codersdk.BuildReason(workspaceBuild.Reason), } } From d103f69ba7d6a29612e69789b7f2c5bd06deee14 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 21:32:23 +0000 Subject: [PATCH 05/12] add more unit tests --- coderd/workspaces_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index c7021685b0a3c..017fde1b0ac50 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -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) { From fa38b8f7157967c092cda45bf58acef52bf17d64 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 21:39:22 +0000 Subject: [PATCH 06/12] add error for unknown transition --- .../autobuild/executor/lifecycle_executor.go | 67 +++++++++++-------- 1 file changed, 38 insertions(+), 29 deletions(-) diff --git a/coderd/autobuild/executor/lifecycle_executor.go b/coderd/autobuild/executor/lifecycle_executor.go index 0295d4cb47efd..26d66cbfbc4df 100644 --- a/coderd/autobuild/executor/lifecycle_executor.go +++ b/coderd/autobuild/executor/lifecycle_executor.go @@ -209,21 +209,6 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa } provisionerJobID := uuid.New() now := database.Now() - newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ - ID: provisionerJobID, - CreatedAt: now, - UpdatedAt: now, - InitiatorID: workspace.OwnerID, - OrganizationID: template.OrganizationID, - Provisioner: template.Provisioner, - Type: database.ProvisionerJobTypeWorkspaceBuild, - StorageMethod: priorJob.StorageMethod, - StorageSource: priorJob.StorageSource, - Input: input, - }) - if err != nil { - return xerrors.Errorf("insert provisioner job: %w", err) - } var buildReason database.BuildReason switch trans { @@ -231,23 +216,47 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa buildReason = database.BuildReasonAutostart case database.WorkspaceTransitionStop: buildReason = database.BuildReasonAutostop + default: + return xerrors.Errorf("Unsupported transition: %q", trans) } - _, err = store.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ - ID: workspaceBuildID, - CreatedAt: now, - UpdatedAt: now, - WorkspaceID: workspace.ID, - TemplateVersionID: priorHistory.TemplateVersionID, - BuildNumber: priorBuildNumber + 1, - Name: namesgenerator.GetRandomName(1), - ProvisionerState: priorHistory.ProvisionerState, - InitiatorID: workspace.OwnerID, - Transition: trans, - JobID: newProvisionerJob.ID, - Reason: buildReason, + + err = store.InTx(func(store database.Store) error { + newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ + ID: provisionerJobID, + CreatedAt: now, + UpdatedAt: now, + InitiatorID: workspace.OwnerID, + OrganizationID: template.OrganizationID, + Provisioner: template.Provisioner, + Type: database.ProvisionerJobTypeWorkspaceBuild, + StorageMethod: priorJob.StorageMethod, + StorageSource: priorJob.StorageSource, + Input: input, + }) + if err != nil { + return xerrors.Errorf("insert provisioner job: %w", err) + } + _, err = store.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ + ID: workspaceBuildID, + CreatedAt: now, + UpdatedAt: now, + WorkspaceID: workspace.ID, + TemplateVersionID: priorHistory.TemplateVersionID, + BuildNumber: priorBuildNumber + 1, + Name: namesgenerator.GetRandomName(1), + ProvisionerState: priorHistory.ProvisionerState, + InitiatorID: workspace.OwnerID, + Transition: trans, + JobID: newProvisionerJob.ID, + Reason: buildReason, + }) + if err != nil { + return xerrors.Errorf("insert workspace build: %w", err) + } + return nil }) if err != nil { - return xerrors.Errorf("insert workspace build: %w", err) + return err } return nil } From 2e8c46260a830edad8d8a63a68416d3fcbb7ee71 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 22:04:20 +0000 Subject: [PATCH 07/12] fix lint --- coderd/autobuild/executor/lifecycle_executor.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/coderd/autobuild/executor/lifecycle_executor.go b/coderd/autobuild/executor/lifecycle_executor.go index 26d66cbfbc4df..99783b7b4744f 100644 --- a/coderd/autobuild/executor/lifecycle_executor.go +++ b/coderd/autobuild/executor/lifecycle_executor.go @@ -220,8 +220,8 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa return xerrors.Errorf("Unsupported transition: %q", trans) } - err = store.InTx(func(store database.Store) error { - newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ + err = store.InTx(func(db database.Store) error { + newProvisionerJob, err := db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ ID: provisionerJobID, CreatedAt: now, UpdatedAt: now, @@ -236,7 +236,7 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa if err != nil { return xerrors.Errorf("insert provisioner job: %w", err) } - _, err = store.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ + _, err = db.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ ID: workspaceBuildID, CreatedAt: now, UpdatedAt: now, From 6fb655f88061ff36e6a62d5306d2685007b9e1ca Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 22:09:33 +0000 Subject: [PATCH 08/12] add documentation --- codersdk/workspacebuilds.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/codersdk/workspacebuilds.go b/codersdk/workspacebuilds.go index 3995f3b21bd66..5657747cf326c 100644 --- a/codersdk/workspacebuilds.go +++ b/codersdk/workspacebuilds.go @@ -22,9 +22,15 @@ const ( 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" - BuildReasonAutostop BuildReason = "autostop" + // "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. From eacd6a08c3e5676b89b21a22d59d2c1dcbb24718 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 22:25:08 +0000 Subject: [PATCH 09/12] fix unit tests --- coderd/workspaces.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coderd/workspaces.go b/coderd/workspaces.go index ff41ab7c52abe..c043be1694764 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -807,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{} From b7288b11967632e7d9b0d89640b2521f04eff021 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Thu, 16 Jun 2022 22:47:17 +0000 Subject: [PATCH 10/12] fix generated types --- site/src/api/typesGenerated.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 20bcd0533f6a0..45b8a766adb70 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -443,7 +443,7 @@ export interface WorkspaceApp { readonly icon?: string } -// From codersdk/workspacebuilds.go:32:6 +// From codersdk/workspacebuilds.go:38:6 export interface WorkspaceBuild { readonly id: string readonly created_at: string From ae7e9081f3ee9b166342d5beb5d7683315c0d264 Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 17 Jun 2022 16:08:31 +0000 Subject: [PATCH 11/12] remove nested transaction --- .../autobuild/executor/lifecycle_executor.go | 64 +++++++++---------- .../executor/lifecycle_executor_test.go | 6 +- 2 files changed, 31 insertions(+), 39 deletions(-) diff --git a/coderd/autobuild/executor/lifecycle_executor.go b/coderd/autobuild/executor/lifecycle_executor.go index 99783b7b4744f..88e14033e055a 100644 --- a/coderd/autobuild/executor/lifecycle_executor.go +++ b/coderd/autobuild/executor/lifecycle_executor.go @@ -220,43 +220,37 @@ func build(ctx context.Context, store database.Store, workspace database.Workspa return xerrors.Errorf("Unsupported transition: %q", trans) } - err = store.InTx(func(db database.Store) error { - newProvisionerJob, err := db.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ - ID: provisionerJobID, - CreatedAt: now, - UpdatedAt: now, - InitiatorID: workspace.OwnerID, - OrganizationID: template.OrganizationID, - Provisioner: template.Provisioner, - Type: database.ProvisionerJobTypeWorkspaceBuild, - StorageMethod: priorJob.StorageMethod, - StorageSource: priorJob.StorageSource, - Input: input, - }) - if err != nil { - return xerrors.Errorf("insert provisioner job: %w", err) - } - _, err = db.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ - ID: workspaceBuildID, - CreatedAt: now, - UpdatedAt: now, - WorkspaceID: workspace.ID, - TemplateVersionID: priorHistory.TemplateVersionID, - BuildNumber: priorBuildNumber + 1, - Name: namesgenerator.GetRandomName(1), - ProvisionerState: priorHistory.ProvisionerState, - InitiatorID: workspace.OwnerID, - Transition: trans, - JobID: newProvisionerJob.ID, - Reason: buildReason, - }) - if err != nil { - return xerrors.Errorf("insert workspace build: %w", err) - } - return nil + newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{ + ID: provisionerJobID, + CreatedAt: now, + UpdatedAt: now, + InitiatorID: workspace.OwnerID, + OrganizationID: template.OrganizationID, + Provisioner: template.Provisioner, + Type: database.ProvisionerJobTypeWorkspaceBuild, + StorageMethod: priorJob.StorageMethod, + StorageSource: priorJob.StorageSource, + Input: input, + }) + if err != nil { + return xerrors.Errorf("insert provisioner job: %w", err) + } + _, err = store.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{ + ID: workspaceBuildID, + CreatedAt: now, + UpdatedAt: now, + WorkspaceID: workspace.ID, + TemplateVersionID: priorHistory.TemplateVersionID, + BuildNumber: priorBuildNumber + 1, + Name: namesgenerator.GetRandomName(1), + ProvisionerState: priorHistory.ProvisionerState, + InitiatorID: workspace.OwnerID, + Transition: trans, + JobID: newProvisionerJob.ID, + Reason: buildReason, }) if err != nil { - return err + return xerrors.Errorf("insert workspace build: %w", err) } return nil } diff --git a/coderd/autobuild/executor/lifecycle_executor_test.go b/coderd/autobuild/executor/lifecycle_executor_test.go index 988327f53ce59..913445998e843 100644 --- a/coderd/autobuild/executor/lifecycle_executor_test.go +++ b/coderd/autobuild/executor/lifecycle_executor_test.go @@ -52,8 +52,7 @@ func TestExecutorAutostartOK(t *testing.T) { assert.Contains(t, stats.Transitions, workspace.ID) assert.Equal(t, database.WorkspaceTransitionStart, stats.Transitions[workspace.ID]) - workspace, err := client.Workspace(context.Background(), workspace.ID) - assert.NoError(t, err) + workspace = coderdtest.MustWorkspace(t, client, workspace.ID) assert.Equal(t, codersdk.BuildReasonAutostart, workspace.LatestBuild.Reason) } @@ -205,8 +204,7 @@ func TestExecutorAutostopOK(t *testing.T) { assert.Contains(t, stats.Transitions, workspace.ID) assert.Equal(t, database.WorkspaceTransitionStop, stats.Transitions[workspace.ID]) - workspace, err := client.Workspace(context.Background(), workspace.ID) - assert.NoError(t, err) + workspace = coderdtest.MustWorkspace(t, client, workspace.ID) assert.Equal(t, codersdk.BuildReasonAutostop, workspace.LatestBuild.Reason) } From c5b9aac6720ca9d5dc8a105b62fcafc1eb607fdf Mon Sep 17 00:00:00 2001 From: Abhineet Jain Date: Fri, 17 Jun 2022 16:14:36 +0000 Subject: [PATCH 12/12] rename migration file --- ..._reason.down.sql => 000025_workspace_build_reason.down.sql} | 0 ...uild_reason.up.sql => 000025_workspace_build_reason.up.sql} | 0 coderd/database/queries.sql.go | 3 ++- 3 files changed, 2 insertions(+), 1 deletion(-) rename coderd/database/migrations/{000024_workspace_build_reason.down.sql => 000025_workspace_build_reason.down.sql} (100%) rename coderd/database/migrations/{000024_workspace_build_reason.up.sql => 000025_workspace_build_reason.up.sql} (100%) diff --git a/coderd/database/migrations/000024_workspace_build_reason.down.sql b/coderd/database/migrations/000025_workspace_build_reason.down.sql similarity index 100% rename from coderd/database/migrations/000024_workspace_build_reason.down.sql rename to coderd/database/migrations/000025_workspace_build_reason.down.sql diff --git a/coderd/database/migrations/000024_workspace_build_reason.up.sql b/coderd/database/migrations/000025_workspace_build_reason.up.sql similarity index 100% rename from coderd/database/migrations/000024_workspace_build_reason.up.sql rename to coderd/database/migrations/000025_workspace_build_reason.up.sql diff --git a/coderd/database/queries.sql.go b/coderd/database/queries.sql.go index 0596f24246ccf..06c3012548651 100644 --- a/coderd/database/queries.sql.go +++ b/coderd/database/queries.sql.go @@ -3583,7 +3583,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context, } const getWorkspaceBuildsCreatedAfter = `-- name: GetWorkspaceBuildsCreatedAfter :many -SELECT id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline FROM workspace_builds WHERE created_at > $1 +SELECT id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id, deadline, reason FROM workspace_builds WHERE created_at > $1 ` func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, createdAt time.Time) ([]WorkspaceBuild, error) { @@ -3608,6 +3608,7 @@ func (q *sqlQuerier) GetWorkspaceBuildsCreatedAfter(ctx context.Context, created &i.ProvisionerState, &i.JobID, &i.Deadline, + &i.Reason, ); err != nil { return nil, err }