- Notifications
You must be signed in to change notification settings - Fork928
feat: autostop workspaces owned by suspended users#13790
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.
Already on GitHub?Sign in to your account
Uh oh!
There was an error while loading.Please reload this page.
Changes fromall commits
c422f34
63ddb62
627f68a
1bb5f92
7c35a55
9e95207
b9908cf
File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading.Please reload this page.
Jump to
Uh oh!
There was an error while loading.Please reload this page.
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -316,7 +316,7 @@ func getNextTransition( | ||
error, | ||
) { | ||
switch { | ||
case isEligibleForAutostop(user,ws, latestBuild, latestJob, currentTick): | ||
return database.WorkspaceTransitionStop, database.BuildReasonAutostop, nil | ||
case isEligibleForAutostart(user, ws, latestBuild, latestJob, templateSchedule, currentTick): | ||
return database.WorkspaceTransitionStart, database.BuildReasonAutostart, nil | ||
@@ -376,8 +376,8 @@ func isEligibleForAutostart(user database.User, ws database.Workspace, build dat | ||
return !currentTick.Before(nextTransition) | ||
} | ||
//isEligibleForAutostop returns true if the workspace should be autostopped. | ||
func isEligibleForAutostop(user database.User,ws database.Workspace, build database.WorkspaceBuild, job database.ProvisionerJob, currentTick time.Time) bool { | ||
if job.JobStatus == database.ProvisionerJobStatusFailed { | ||
return false | ||
} | ||
@@ -387,6 +387,10 @@ func isEligibleForAutostop(ws database.Workspace, build database.WorkspaceBuild, | ||
return false | ||
} | ||
if build.Transition == database.WorkspaceTransitionStart && user.Status == database.UserStatusSuspended { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Do we care about any other user statuses? MemberAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. No, I don't want to mess with others - just suspended. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I was going to mention There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. IIRC on the first interaction with API the dormant user will be switched to active, so yes. Member There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. By definition... they shouldn't be able to...? Once they log in, they're active. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. Ok, what is your preference - should I extend the logic to dormant users too? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others.Learn more. I think it could be a follow-up PR since there may be additional considerations. | ||
return true | ||
} | ||
// A workspace must be started in order for it to be auto-stopped. | ||
return build.Transition == database.WorkspaceTransitionStart && | ||
!build.Deadline.IsZero() && | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -563,6 +563,52 @@ func TestExecutorWorkspaceAutostopBeforeDeadline(t *testing.T) { | ||
assert.Len(t, stats.Transitions, 0) | ||
} | ||
func TestExecuteAutostopSuspendedUser(t *testing.T) { | ||
t.Parallel() | ||
var ( | ||
ctx = testutil.Context(t, testutil.WaitShort) | ||
tickCh = make(chan time.Time) | ||
statsCh = make(chan autobuild.Stats) | ||
client = coderdtest.New(t, &coderdtest.Options{ | ||
AutobuildTicker: tickCh, | ||
IncludeProvisionerDaemon: true, | ||
AutobuildStats: statsCh, | ||
}) | ||
) | ||
admin := coderdtest.CreateFirstUser(t, client) | ||
version := coderdtest.CreateTemplateVersion(t, client, admin.OrganizationID, nil) | ||
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version.ID) | ||
template := coderdtest.CreateTemplate(t, client, admin.OrganizationID, version.ID) | ||
userClient, user := coderdtest.CreateAnotherUser(t, client, admin.OrganizationID) | ||
workspace := coderdtest.CreateWorkspace(t, userClient, admin.OrganizationID, template.ID) | ||
coderdtest.AwaitWorkspaceBuildJobCompleted(t, userClient, workspace.LatestBuild.ID) | ||
// Given: workspace is running, and the user is suspended. | ||
workspace = coderdtest.MustWorkspace(t, userClient, workspace.ID) | ||
mtojek marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
require.Equal(t, codersdk.WorkspaceStatusRunning, workspace.LatestBuild.Status) | ||
_, err := client.UpdateUserStatus(ctx, user.ID.String(), codersdk.UserStatusSuspended) | ||
require.NoError(t, err, "update user status") | ||
// When: the autobuild executor ticks after the scheduled time | ||
go func() { | ||
tickCh <- time.Unix(0, 0) // the exact time is not important | ||
close(tickCh) | ||
}() | ||
// Then: the workspace should be stopped | ||
stats := <-statsCh | ||
assert.Len(t, stats.Errors, 0) | ||
assert.Len(t, stats.Transitions, 1) | ||
assert.Equal(t, stats.Transitions[workspace.ID], database.WorkspaceTransitionStop) | ||
// Wait for stop to complete | ||
workspace = coderdtest.MustWorkspace(t, client, workspace.ID) | ||
workspaceBuild := coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID) | ||
assert.Equal(t, codersdk.WorkspaceStatusStopped, workspaceBuild.Status) | ||
} | ||
func TestExecutorWorkspaceAutostopNoWaitChangedMyMind(t *testing.T) { | ||
t.Parallel() | ||
Some generated files are not rendered by default. Learn more abouthow customized files appear on GitHub.
Uh oh!
There was an error while loading.Please reload this page.
Uh oh!
There was an error while loading.Please reload this page.