mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat!: add ability to cancel pending workspace build (#18713)
Closes #17791 This PR adds ability to cancel workspace builds that are in "pending" status. Breaking changes: - CancelWorkspaceBuild method in codersdk now accepts an optional request parameter API: - Added `expect_status` query parameter to the cancel workspace build endpoint - This parameter ensures the job hasn't changed state before canceling - API returns `412 Precondition Failed` if the job is not in the expected status - Valid values: `running` or `pending` - Wrapped the entire cancel method in a database transaction UI: - Added confirmation dialog to the `Cancel` button, since it's a destructive operation   - Enabled cancel action for pending workspaces (`expect_status=pending` is sent if workspace is in pending status)  --------- Co-authored-by: Dean Sheather <dean@deansheather.com>
This commit is contained in:
co-authored by
Dean Sheather
parent
2f42b64182
commit
8202514ce0
@@ -164,7 +164,7 @@ func TestTools(t *testing.T) {
|
||||
|
||||
// Important: cancel the build. We don't run any provisioners, so this
|
||||
// will remain in the 'pending' state indefinitely.
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, result.ID))
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, result.ID, codersdk.CancelWorkspaceBuildParams{}))
|
||||
})
|
||||
|
||||
t.Run("Start", func(t *testing.T) {
|
||||
@@ -184,7 +184,7 @@ func TestTools(t *testing.T) {
|
||||
|
||||
// Important: cancel the build. We don't run any provisioners, so this
|
||||
// will remain in the 'pending' state indefinitely.
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, result.ID))
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, result.ID, codersdk.CancelWorkspaceBuildParams{}))
|
||||
})
|
||||
|
||||
t.Run("TemplateVersionChange", func(t *testing.T) {
|
||||
@@ -216,7 +216,7 @@ func TestTools(t *testing.T) {
|
||||
require.Equal(t, r.Workspace.ID.String(), updateBuild.WorkspaceID.String())
|
||||
require.Equal(t, newVersion.TemplateVersion.ID.String(), updateBuild.TemplateVersionID.String())
|
||||
// Cancel the build so it doesn't remain in the 'pending' state indefinitely.
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, updateBuild.ID))
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, updateBuild.ID, codersdk.CancelWorkspaceBuildParams{}))
|
||||
|
||||
// Roll back to the original version
|
||||
rollbackBuild, err := testTool(t, toolsdk.CreateWorkspaceBuild, tb, toolsdk.CreateWorkspaceBuildArgs{
|
||||
@@ -229,7 +229,7 @@ func TestTools(t *testing.T) {
|
||||
require.Equal(t, r.Workspace.ID.String(), rollbackBuild.WorkspaceID.String())
|
||||
require.Equal(t, originalVersionID.String(), rollbackBuild.TemplateVersionID.String())
|
||||
// Cancel the build so it doesn't remain in the 'pending' state indefinitely.
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, rollbackBuild.ID))
|
||||
require.NoError(t, client.CancelWorkspaceBuild(ctx, rollbackBuild.ID, codersdk.CancelWorkspaceBuildParams{}))
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
@@ -123,9 +123,29 @@ func (c *Client) WorkspaceBuild(ctx context.Context, id uuid.UUID) (WorkspaceBui
|
||||
return workspaceBuild, json.NewDecoder(res.Body).Decode(&workspaceBuild)
|
||||
}
|
||||
|
||||
type CancelWorkspaceBuildStatus string
|
||||
|
||||
const (
|
||||
CancelWorkspaceBuildStatusRunning CancelWorkspaceBuildStatus = "running"
|
||||
CancelWorkspaceBuildStatusPending CancelWorkspaceBuildStatus = "pending"
|
||||
)
|
||||
|
||||
type CancelWorkspaceBuildParams struct {
|
||||
// ExpectStatus ensures the build is in the expected status before canceling.
|
||||
ExpectStatus CancelWorkspaceBuildStatus `json:"expect_status,omitempty"`
|
||||
}
|
||||
|
||||
func (c *CancelWorkspaceBuildParams) asRequestOption() RequestOption {
|
||||
return func(r *http.Request) {
|
||||
q := r.URL.Query()
|
||||
q.Set("expect_status", string(c.ExpectStatus))
|
||||
r.URL.RawQuery = q.Encode()
|
||||
}
|
||||
}
|
||||
|
||||
// CancelWorkspaceBuild marks a workspace build job as canceled.
|
||||
func (c *Client) CancelWorkspaceBuild(ctx context.Context, id uuid.UUID) error {
|
||||
res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/workspacebuilds/%s/cancel", id), nil)
|
||||
func (c *Client) CancelWorkspaceBuild(ctx context.Context, id uuid.UUID, req CancelWorkspaceBuildParams) error {
|
||||
res, err := c.Request(ctx, http.MethodPatch, fmt.Sprintf("/api/v2/workspacebuilds/%s/cancel", id), nil, req.asRequestOption())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user