- Notifications
You must be signed in to change notification settings - Fork1.1k
feat: reinitialize agents when a prebuilt workspace is claimed#17475
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 from1 commit
c09c9b9476fe718c8bca67ce4eea52ac64e362db7cdcc7379ff66b3fefff5d9cebd5db26791389feebefb117b5ca22b4149bbd2c758042017e8dcee725f97ba9b156721ee970e54d7e727998581d93003763fc120f879c761784c9604eb27bf4d2cf38b4f0d20df5384bb3b6883972db146b1585eb16cd730d803150adc0b4ecf103fa3edf7e45919a63250872125ecb65eea7e1339f3c1a8ba65363dcc7ad9b6d394571d890747bb3870dbFile 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
- Loading branch information
Uh oh!
There was an error while loading.Please reload this page.
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1105,14 +1105,24 @@ func (w WorkspaceAgentWaiter) MatchResources(m func([]codersdk.WorkspaceResource | ||
| return w | ||
| } | ||
| // WaitForCriterium represents a boolean assertion to be made against each agent | ||
| // that a given WorkspaceAgentWaited knows about. Each WaitForCriterium should apply | ||
| // the check to a single agent, but it should be named for plural, because `func (w WorkspaceAgentWaiter) WaitFor` | ||
| // applies the check to all agents that it is aware of. This ensures that the public API of the waiter | ||
| // reads correctly. For example: | ||
| // | ||
| // waiter := coderdtest.NewWorkspaceAgentWaiter(t, client, r.Workspace.ID) | ||
| // waiter.WaitFor(coderdtest.AgentsReady) | ||
| type WaitForCriterium func(agent codersdk.WorkspaceAgent) bool | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| // AgentsReady checks that the latest lifecycle state of an agent is "Ready". | ||
| func AgentsReady(agent codersdk.WorkspaceAgent) bool { | ||
| return agent.LifecycleState == codersdk.WorkspaceAgentLifecycleReady | ||
| } | ||
| // AgentsReady checks that the latest lifecycle state of an agent is anything except "Ready". | ||
| func AgentsNotReady(agent codersdk.WorkspaceAgent) bool { | ||
| return !AgentsReady(agent) | ||
| } | ||
| func (w WorkspaceAgentWaiter) WaitFor(criteria ...WaitForCriterium) { | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1771,20 +1771,21 @@ func TestCompleteJob(t *testing.T) { | ||
| t.Run(tc.name, func(t *testing.T) { | ||
dannykopping marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| t.Parallel() | ||
| //GIVEN an enqueued provisioner job and its dependencies: | ||
| userID := uuid.New() | ||
| srv, db, ps, pd := setup(t, false, &overrides{}) | ||
| buildID := uuid.New() | ||
| jobInput := provisionerdserver.WorkspaceProvisionJob{ | ||
| WorkspaceBuildID: buildID, | ||
| } | ||
| if tc.shouldReinitializeAgent { // This is the key lever in the test | ||
| // GIVEN the enqueued provisioner job is for a workspace being claimed by a user: | ||
| jobInput.PrebuildClaimedByUser = userID | ||
| } | ||
| input, err := json.Marshal(jobInput) | ||
| require.NoError(t, err) | ||
| ctx := testutil.Context(t, testutil.WaitShort) | ||
| @@ -1821,19 +1822,17 @@ func TestCompleteJob(t *testing.T) { | ||
| }) | ||
| require.NoError(t, err) | ||
| //GIVEN something is listening to process workspace reinitialization: | ||
| eventName := agentsdk.PrebuildClaimedChannel(workspace.ID) | ||
| reinitChan := make(chan []byte, 1) | ||
| cancel, err := ps.Subscribe(eventName, func(inner context.Context, userIDMessage []byte) { | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| reinitChan <- userIDMessage | ||
| }) | ||
| require.NoError(t, err) | ||
| defer cancel() | ||
| //WHEN thejop is completed | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| completedJob := proto.CompletedJob{ | ||
| JobId: job.ID.String(), | ||
| @@ -1845,12 +1844,14 @@ func TestCompleteJob(t *testing.T) { | ||
| require.NoError(t, err) | ||
| select { | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| case userIDMessage := <-reinitChan: | ||
| // THEN workspace agent reinitialization instruction was received: | ||
| gotUserID, err := uuid.ParseBytes(userIDMessage) | ||
| require.NoError(t, err) | ||
| require.True(t, tc.shouldReinitializeAgent) | ||
| require.Equal(t, userID, gotUserID) | ||
| case <-ctx.Done(): | ||
| // THEN workspace agent reinitialization instruction was not received. | ||
| require.False(t, tc.shouldReinitializeAgent) | ||
| } | ||
| }) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -692,10 +692,6 @@ func createWorkspace( | ||
| if len(agents) > 1 { | ||
| return xerrors.Errorf("multiple agents are not yet supported in prebuilt workspaces") | ||
| ||
| } | ||
| } | ||
| // We have to refetch the workspace for the joined in fields. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -694,7 +694,7 @@ const ( | ||
| ReinitializeReasonPrebuildClaimed ReinitializationReason = "prebuild_claimed" | ||
| ) | ||
| typeReinitializationEvent struct { | ||
| Message string `json:"message"` | ||
| Reason ReinitializationReason `json:"reason"` | ||
| } | ||
| @@ -707,7 +707,7 @@ func PrebuildClaimedChannel(id uuid.UUID) string { | ||
| // - ping: ignored, keepalive | ||
| // - prebuild claimed: a prebuilt workspace is claimed, so the agent must reinitialize. | ||
| // NOTE: the caller is responsible for closing the events chan. | ||
| func (c *Client) WaitForReinit(ctx context.Context, events chan<-ReinitializationEvent) error { | ||
| // TODO: allow configuring httpclient | ||
| c.SDK.HTTPClient.Timeout = time.Hour * 24 | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page.
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| @@ -737,19 +737,19 @@ func (c *Client) WaitForReinit(ctx context.Context, events chan<- Reinitializati | ||
| if sse.Type != codersdk.ServerSentEventTypeData { | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| continue | ||
| } | ||
| varreinitEvent ReinitializationEvent | ||
| b, ok := sse.Data.([]byte) | ||
| if !ok { | ||
| return xerrors.Errorf("expected data as []byte, got %T", sse.Data) | ||
| } | ||
| err = json.Unmarshal(b, &reinitEvent) | ||
| if err != nil { | ||
| return xerrors.Errorf("unmarshal reinit response: %w", err) | ||
| } | ||
| select { | ||
SasSwart marked this conversation as resolved. OutdatedShow resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| case <-ctx.Done(): | ||
| return ctx.Err() | ||
| case events <-reinitEvent: | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -277,6 +277,7 @@ func provisionEnv( | ||
| if len(tokens) == 1 { | ||
| env = append(env, provider.RunningAgentTokenEnvironmentVariable("")+"="+tokens[0].Token) | ||
| } else { | ||
| // Not currently supported, but added for forward-compatibility | ||
| for _, t := range tokens { | ||
SasSwart marked this conversation as resolved. Show resolvedHide resolvedUh oh!There was an error while loading.Please reload this page. | ||
| // If there are multiple agents, provide all the tokens to terraform so that it can | ||
| // choose the correct one for each agent ID. | ||
Uh oh!
There was an error while loading.Please reload this page.