Skip to content

Commit c7dff0e

Browse files
committed
add initial deadline field to workspace_build
1 parent c04d045 commit c7dff0e

File tree

5 files changed

+81
-1
lines changed

5 files changed

+81
-1
lines changed

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,7 @@ func New(options *Options) *API {
315315
r.Put("/", api.putWorkspaceTTL)
316316
})
317317
r.Get("/watch", api.watchWorkspace)
318+
r.Put("/deadline", api.putWorkspaceDeadline)
318319
})
319320
})
320321
r.Route("/workspacebuilds/{workspacebuild}", func(r chi.Router) {

coderd/workspaces.go

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,35 @@ func (api *API) putWorkspaceTTL(rw http.ResponseWriter, r *http.Request) {
570570
}
571571
}
572572

573+
func (api *API) putWorkspaceDeadline(rw http.ResponseWriter, r *http.Request) {
574+
workspace := httpmw.WorkspaceParam(r)
575+
576+
if !api.Authorize(rw, r, rbac.ActionUpdate, rbac.ResourceWorkspace.
577+
InOrg(workspace.OrganizationID).WithOwner(workspace.OwnerID.String()).WithID(workspace.ID.String())) {
578+
return
579+
}
580+
581+
var req codersdk.PutExtendWorkspaceRequest
582+
if !httpapi.Read(rw, r, &req) {
583+
return
584+
}
585+
586+
build, err := api.Database.GetLatestWorkspaceBuildByWorkspaceID(r.Context(), workspace.ID)
587+
if err != nil {
588+
httpapi.Write(rw, http.StatusInternalServerError, httpapi.Response{
589+
Message: fmt.Sprintf("get latest workspace build: %s", err),
590+
})
591+
return
592+
}
593+
594+
if build.Transition != database.WorkspaceTransitionStart {
595+
httpapi.Write(rw, http.StatusBadRequest, httpapi.Response{
596+
Message: fmt.Sprintf("workspace must be started, current status: %s", build.Transition),
597+
})
598+
return
599+
}
600+
}
601+
573602
func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) {
574603
workspace := httpmw.WorkspaceParam(r)
575604

coderd/workspaces_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,31 @@ func TestWorkspaceUpdateAutostop(t *testing.T) {
615615
})
616616
}
617617

618+
func TestWorkspaceExtendAutostop(t *testing.T) {
619+
t.Parallel()
620+
var (
621+
ctx = context.Background()
622+
client = coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})
623+
user = coderdtest.CreateFirstUser(t, client)
624+
version = coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
625+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
626+
project = coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
627+
workspace = coderdtest.CreateWorkspace(t, client, user.OrganizationID, project.ID)
628+
extend = 90 * time.Minute
629+
)
630+
631+
initTTL := time.Now()
632+
req := codersdk.PutExtendWorkspaceRequest{
633+
Deadline: initTTL.Add(extend),
634+
}
635+
err := client.PutExtendWorkspace(ctx, workspace.ID, req)
636+
require.NoError(t, err, "failed to update workspace ttl")
637+
638+
updated, err := client.Workspace(ctx, workspace.ID)
639+
require.NoError(t, err, "failed to fetch updated workspace")
640+
require.Equal(t, workspace.LatestBuild.Deadline.Add(extend), updated.LatestBuild.Deadline)
641+
}
642+
618643
func TestWorkspaceWatcher(t *testing.T) {
619644
t.Parallel()
620645
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerD: true})

codersdk/workspaces.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,26 @@ func (c *Client) UpdateWorkspaceTTL(ctx context.Context, id uuid.UUID, req Updat
177177
return nil
178178
}
179179

180+
// PutExtendWorkspaceRequest is a request to extend the deadline of
181+
// the active workspace build.
182+
type PutExtendWorkspaceRequest struct {
183+
Deadline time.Time `json:"deadline" validate:"required, datetime=RFC3339"`
184+
}
185+
186+
// PutExtendWorkspace updates the deadline for resources of the latest workspace build.
187+
func (c *Client) PutExtendWorkspace(ctx context.Context, id uuid.UUID, req PutExtendWorkspaceRequest) error {
188+
path := fmt.Sprintf("/api/v2/workspaces/%s/extend", id.String())
189+
res, err := c.Request(ctx, http.MethodPut, path, req)
190+
if err != nil {
191+
return xerrors.Errorf("extend workspace ttl: %w", err)
192+
}
193+
defer res.Body.Close()
194+
if res.StatusCode != http.StatusOK {
195+
return readBodyAsError(res)
196+
}
197+
return nil
198+
}
199+
180200
type WorkspaceFilter struct {
181201
OrganizationID uuid.UUID
182202
// Owner can be a user_id (uuid), "me", or a username

site/src/api/typesGenerated.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,11 @@ export interface ProvisionerJobLog {
216216
readonly output: string
217217
}
218218

219+
// From codersdk/workspaces.go:182:6
220+
export interface PutWorkspaceDeadlineRequest {
221+
readonly stop_at: string
222+
}
223+
219224
// From codersdk/roles.go:12:6
220225
export interface Role {
221226
readonly name: string
@@ -430,7 +435,7 @@ export interface WorkspaceBuildsRequest extends Pagination {
430435
readonly WorkspaceID: string
431436
}
432437

433-
// From codersdk/workspaces.go:180:6
438+
// From codersdk/workspaces.go:200:6
434439
export interface WorkspaceFilter {
435440
readonly OrganizationID: string
436441
readonly Owner: string

0 commit comments

Comments
 (0)