mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
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:
@@ -538,7 +538,7 @@ func TestWorkspaceUpdateAutostart(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestWorkspaceUpdateAutostop(t *testing.T) {
|
||||
func TestWorkspaceUpdateTTL(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
testCases := []struct {
|
||||
@@ -615,6 +615,56 @@ func TestWorkspaceUpdateAutostop(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestWorkspaceExtend(t *testing.T) {
|
||||
t.Parallel()
|
||||
var (
|
||||
ctx = context.Background()
|
||||
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
||||
user = coderdtest.CreateFirstUser(t, client)
|
||||
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
|
||||
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
|
||||
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
|
||||
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
|
||||
extend = 90 * time.Minute
|
||||
_ = coderdtest.AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID)
|
||||
oldDeadline = time.Now().Add(*workspace.TTL).UTC()
|
||||
newDeadline = time.Now().Add(*workspace.TTL + extend).UTC()
|
||||
)
|
||||
|
||||
workspace, err := client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err, "fetch provisioned workspace")
|
||||
require.InDelta(t, oldDeadline.Unix(), workspace.LatestBuild.Deadline.Unix(), 60)
|
||||
|
||||
// Updating the deadline should succeed
|
||||
req := codersdk.PutExtendWorkspaceRequest{
|
||||
Deadline: newDeadline,
|
||||
}
|
||||
err = client.PutExtendWorkspace(ctx, workspace.ID, req)
|
||||
require.NoError(t, err, "failed to extend workspace")
|
||||
|
||||
// Ensure deadline set correctly
|
||||
updated, err := client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err, "failed to fetch updated workspace")
|
||||
require.InDelta(t, newDeadline.Unix(), updated.LatestBuild.Deadline.Unix(), 60)
|
||||
|
||||
// Zero time should fail
|
||||
err = client.PutExtendWorkspace(ctx, workspace.ID, codersdk.PutExtendWorkspaceRequest{
|
||||
Deadline: time.Time{},
|
||||
})
|
||||
require.ErrorContains(t, err, "deadline: required", "setting an empty deadline on a workspace should fail")
|
||||
|
||||
// Updating with an earlier time should also fail
|
||||
err = client.PutExtendWorkspace(ctx, workspace.ID, codersdk.PutExtendWorkspaceRequest{
|
||||
Deadline: oldDeadline,
|
||||
})
|
||||
require.ErrorContains(t, err, "must be after existing deadline", "setting an earlier deadline should fail")
|
||||
|
||||
// Ensure deadline still set correctly
|
||||
updated, err = client.Workspace(ctx, workspace.ID)
|
||||
require.NoError(t, err, "failed to fetch updated workspace")
|
||||
require.InDelta(t, newDeadline.Unix(), updated.LatestBuild.Deadline.Unix(), 60)
|
||||
}
|
||||
|
||||
func TestWorkspaceWatcher(t *testing.T) {
|
||||
t.Parallel()
|
||||
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
|
||||
|
||||
Reference in New Issue
Block a user