fix: adjust workspace claims to be initiated by users (#20179)

The prebuilds user never initiates a workspace claim autonomously. A
claim can only happen when a user attempts to create a workspace. When
listing prebuild provisioner jobs, it would not make sense to see jobs
related to users who are creating workspaces and have gotten a prebuilt
workspace. When cleaning up an overwhelmed provisioner queue, we should
not delete claims as they have humans waiting for them and are not part
of the thundering herd.

Therefore, this PR ensures that provisioner jobs that claim workspaces
are considered to be initiated by the user, not the prebuilds system.
This commit is contained in:
Sas Swart
2025-10-08 10:40:54 +02:00
committed by GitHub
parent 037e6f06f5
commit 544f15523c
5 changed files with 9 additions and 16 deletions
-1
View File
@@ -66,5 +66,4 @@ type Claimer interface {
nextStartAt sql.NullTime,
ttl sql.NullInt64,
) (*uuid.UUID, error)
Initiator() uuid.UUID
}
-4
View File
@@ -35,8 +35,4 @@ func (NoopClaimer) Claim(context.Context, time.Time, uuid.UUID, string, uuid.UUI
return nil, ErrAGPLDoesNotSupportPrebuiltWorkspaces
}
func (NoopClaimer) Initiator() uuid.UUID {
return uuid.Nil
}
var DefaultClaimer Claimer = NoopClaimer{}
-1
View File
@@ -719,7 +719,6 @@ func createWorkspace(
} else {
// Prebuild found!
workspaceID = claimedWorkspace.ID
initiatorID = prebuildsClaimer.Initiator()
}
// We have to refetch the workspace for the joined in fields.
-4
View File
@@ -55,8 +55,4 @@ func (c EnterpriseClaimer) Claim(
return &result.ID, nil
}
func (EnterpriseClaimer) Initiator() uuid.UUID {
return database.PrebuildsSystemUserID
}
var _ prebuilds.Claimer = &EnterpriseClaimer{}
+9 -6
View File
@@ -86,10 +86,6 @@ func (m *storeSpy) ClaimPrebuiltWorkspace(ctx context.Context, arg database.Clai
func TestClaimPrebuild(t *testing.T) {
t.Parallel()
if !dbtestutil.WillUsePostgres() {
t.Skip("This test requires postgres")
}
const (
desiredInstances = 1
presetCount = 2
@@ -260,13 +256,15 @@ func TestClaimPrebuild(t *testing.T) {
switch {
case tc.claimingErr != nil && (isNoPrebuiltWorkspaces || isUnsupported):
require.NoError(t, err)
build := coderdtest.AwaitWorkspaceBuildJobCompleted(t, userClient, userWorkspace.LatestBuild.ID)
_ = build
coderdtest.AwaitWorkspaceBuildJobCompleted(t, userClient, userWorkspace.LatestBuild.ID)
// Then: the number of running prebuilds hasn't changed because claiming prebuild is failed and we fallback to creating new workspace.
currentPrebuilds, err := spy.GetRunningPrebuiltWorkspaces(ctx)
require.NoError(t, err)
require.Equal(t, expectedPrebuildsCount, len(currentPrebuilds))
// If there are no prebuilt workspaces to claim, a new workspace is created from scratch
// and the initiator is set as usual.
require.Equal(t, user.ID, userWorkspace.LatestBuild.Job.InitiatorID)
return
case tc.claimingErr != nil && errors.Is(tc.claimingErr, unexpectedClaimingError):
@@ -278,6 +276,9 @@ func TestClaimPrebuild(t *testing.T) {
currentPrebuilds, err := spy.GetRunningPrebuiltWorkspaces(ctx)
require.NoError(t, err)
require.Equal(t, expectedPrebuildsCount, len(currentPrebuilds))
// If a prebuilt workspace claim fails for an unanticipated, erroneous reason,
// no workspace is created and therefore the initiator is not set.
require.Equal(t, uuid.Nil, userWorkspace.LatestBuild.Job.InitiatorID)
return
default:
@@ -285,6 +286,8 @@ func TestClaimPrebuild(t *testing.T) {
require.NoError(t, err)
build := coderdtest.AwaitWorkspaceBuildJobCompleted(t, userClient, userWorkspace.LatestBuild.ID)
require.Equal(t, build.Job.Status, codersdk.ProvisionerJobSucceeded)
// Prebuild claims are initiated by the user who requested to create a workspace.
require.Equal(t, user.ID, userWorkspace.LatestBuild.Job.InitiatorID)
}
// at this point we know that tc.claimingErr is nil