feat: add API/SDK support for autostop extension (#1778)

* Adds deadline column to workspace_builds, associated DB/API plumbing
* database: Upon inserting a row into workspace_builds, deadline will 
  initially be zero.
* autobuild: Executor now checks the Deadline field of the workspace_build
  for the purpose of autostop logic.
* coderd: Adds a new route /api/v2/workspaces/:workspace/extend which allows
  updating the deadline of the currently active workspace build. The new
  deadline must be after the existing deadline, and not the zero time.
* provisionerd: updates workspace_build.deadline upon successful workspace 
  build completion (equal to now plus workspace TTL, if it exists).
This commit is contained in:
Cian Johnston
2022-05-26 18:08:11 +01:00
committed by GitHub
parent c04d045279
commit 8f0a5a81f1
18 changed files with 306 additions and 34 deletions

View File

@ -2745,7 +2745,7 @@ func (q *sqlQuerier) UpdateWorkspaceAgentConnectionByID(ctx context.Context, arg
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
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
@ -2771,12 +2771,13 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildByWorkspaceID(ctx context.Context, w
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
)
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
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
FROM (
SELECT
workspace_id, MAX(build_number) as max_build_number
@ -2813,6 +2814,7 @@ func (q *sqlQuerier) GetLatestWorkspaceBuildsByWorkspaceIDs(ctx context.Context,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
); err != nil {
return nil, err
}
@ -2829,7 +2831,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
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
@ -2853,13 +2855,14 @@ func (q *sqlQuerier) GetWorkspaceBuildByID(ctx context.Context, id uuid.UUID) (W
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
)
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
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
@ -2883,13 +2886,14 @@ func (q *sqlQuerier) GetWorkspaceBuildByJobID(ctx context.Context, jobID uuid.UU
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
)
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
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
@ -2953,6 +2957,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg Get
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
); err != nil {
return nil, err
}
@ -2969,7 +2974,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceID(ctx context.Context, arg Get
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
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
@ -2997,6 +3002,7 @@ func (q *sqlQuerier) GetWorkspaceBuildByWorkspaceIDAndName(ctx context.Context,
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
)
return i, err
}
@ -3014,10 +3020,11 @@ INSERT INTO
transition,
initiator_id,
job_id,
provisioner_state
provisioner_state,
deadline
)
VALUES
($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11) RETURNING id, created_at, updated_at, workspace_id, template_version_id, name, build_number, transition, initiator_id, provisioner_state, job_id
($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
`
type InsertWorkspaceBuildParams struct {
@ -3032,6 +3039,7 @@ type InsertWorkspaceBuildParams struct {
InitiatorID uuid.UUID `db:"initiator_id" json:"initiator_id"`
JobID uuid.UUID `db:"job_id" json:"job_id"`
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
Deadline time.Time `db:"deadline" json:"deadline"`
}
func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspaceBuildParams) (WorkspaceBuild, error) {
@ -3047,6 +3055,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa
arg.InitiatorID,
arg.JobID,
arg.ProvisionerState,
arg.Deadline,
)
var i WorkspaceBuild
err := row.Scan(
@ -3061,6 +3070,7 @@ func (q *sqlQuerier) InsertWorkspaceBuild(ctx context.Context, arg InsertWorkspa
&i.InitiatorID,
&i.ProvisionerState,
&i.JobID,
&i.Deadline,
)
return i, err
}
@ -3070,7 +3080,8 @@ UPDATE
workspace_builds
SET
updated_at = $2,
provisioner_state = $3
provisioner_state = $3,
deadline = $4
WHERE
id = $1
`
@ -3079,10 +3090,16 @@ type UpdateWorkspaceBuildByIDParams struct {
ID uuid.UUID `db:"id" json:"id"`
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
ProvisionerState []byte `db:"provisioner_state" json:"provisioner_state"`
Deadline time.Time `db:"deadline" json:"deadline"`
}
func (q *sqlQuerier) UpdateWorkspaceBuildByID(ctx context.Context, arg UpdateWorkspaceBuildByIDParams) error {
_, err := q.db.ExecContext(ctx, updateWorkspaceBuildByID, arg.ID, arg.UpdatedAt, arg.ProvisionerState)
_, err := q.db.ExecContext(ctx, updateWorkspaceBuildByID,
arg.ID,
arg.UpdatedAt,
arg.ProvisionerState,
arg.Deadline,
)
return err
}