Skip to content

Commit 7ec20e0

Browse files
committed
Add some missing workspace updates
There are some failure cases where we do not set the type as a workspace build which causes the workspace update to never be published.
1 parent 686a4aa commit 7ec20e0

File tree

4 files changed

+54
-21
lines changed

4 files changed

+54
-21
lines changed

coderd/coderdtest/coderdtest.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -584,10 +584,14 @@ func CreateWorkspaceBuild(
584584
client *codersdk.Client,
585585
workspace codersdk.Workspace,
586586
transition database.WorkspaceTransition,
587+
mutators ...func(*codersdk.CreateWorkspaceBuildRequest),
587588
) codersdk.WorkspaceBuild {
588589
req := codersdk.CreateWorkspaceBuildRequest{
589590
Transition: codersdk.WorkspaceTransition(transition),
590591
}
592+
for _, mut := range mutators {
593+
mut(&req)
594+
}
591595
build, err := client.CreateWorkspaceBuild(context.Background(), workspace.ID, req)
592596
require.NoError(t, err)
593597
return build

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -757,31 +757,30 @@ func (server *Server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*p
757757

758758
switch jobType := failJob.Type.(type) {
759759
case *proto.FailedJob_WorkspaceBuild_:
760-
if jobType.WorkspaceBuild.State == nil {
761-
break
762-
}
763760
var input WorkspaceProvisionJob
764761
err = json.Unmarshal(job.Input, &input)
765762
if err != nil {
766763
return nil, xerrors.Errorf("unmarshal workspace provision input: %w", err)
767764
}
768765

769766
var build database.WorkspaceBuild
770-
err := server.Database.InTx(func(db database.Store) error {
771-
workspaceBuild, err := db.GetWorkspaceBuildByID(ctx, input.WorkspaceBuildID)
767+
err = server.Database.InTx(func(db database.Store) error {
768+
build, err = db.GetWorkspaceBuildByID(ctx, input.WorkspaceBuildID)
772769
if err != nil {
773770
return xerrors.Errorf("get workspace build: %w", err)
774771
}
775772

776-
build, err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{
777-
ID: input.WorkspaceBuildID,
778-
UpdatedAt: database.Now(),
779-
ProvisionerState: jobType.WorkspaceBuild.State,
780-
Deadline: workspaceBuild.Deadline,
781-
MaxDeadline: workspaceBuild.MaxDeadline,
782-
})
783-
if err != nil {
784-
return xerrors.Errorf("update workspace build state: %w", err)
773+
if jobType.WorkspaceBuild.State != nil {
774+
_, err = db.UpdateWorkspaceBuildByID(ctx, database.UpdateWorkspaceBuildByIDParams{
775+
ID: input.WorkspaceBuildID,
776+
UpdatedAt: database.Now(),
777+
ProvisionerState: jobType.WorkspaceBuild.State,
778+
Deadline: build.Deadline,
779+
MaxDeadline: build.MaxDeadline,
780+
})
781+
if err != nil {
782+
return xerrors.Errorf("update workspace build state: %w", err)
783+
}
785784
}
786785

787786
return nil

coderd/workspaces_test.go

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1637,6 +1637,7 @@ func TestWorkspaceExtend(t *testing.T) {
16371637
func TestWorkspaceWatcher(t *testing.T) {
16381638
t.Parallel()
16391639
client, closeFunc := coderdtest.NewWithProvisionerCloser(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
1640+
defer closeFunc.Close()
16401641
user := coderdtest.CreateFirstUser(t, client)
16411642
authToken := uuid.NewString()
16421643
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
@@ -1720,7 +1721,6 @@ func TestWorkspaceWatcher(t *testing.T) {
17201721
return w.LatestBuild.Resources[0].Agents[0].Status == codersdk.WorkspaceAgentDisconnected
17211722
})
17221723

1723-
closeFunc.Close()
17241724
build := coderdtest.CreateWorkspaceBuild(t, client, workspace, database.WorkspaceTransitionStart)
17251725
wait("first is for the workspace build itself", nil)
17261726
err = client.CancelWorkspaceBuild(ctx, build.ID)
@@ -1733,13 +1733,37 @@ func TestWorkspaceWatcher(t *testing.T) {
17331733
require.NoError(t, err)
17341734
wait("update workspace name", nil)
17351735

1736+
// Add a new version that will fail.
1737+
updatedVersion := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, &echo.Responses{
1738+
Parse: echo.ParseComplete,
1739+
ProvisionPlan: echo.ProvisionComplete,
1740+
ProvisionApply: []*proto.Provision_Response{{
1741+
Type: &proto.Provision_Response_Complete{
1742+
Complete: &proto.Provision_Complete{
1743+
Error: "test error",
1744+
},
1745+
},
1746+
}},
1747+
}, func(req *codersdk.CreateTemplateVersionRequest) {
1748+
req.TemplateID = template.ID
1749+
})
1750+
coderdtest.AwaitTemplateVersionJob(t, client, updatedVersion.ID)
17361751
err = client.UpdateActiveTemplateVersion(ctx, template.ID, codersdk.UpdateActiveTemplateVersion{
1737-
ID: template.ActiveVersionID,
1752+
ID: updatedVersion.ID,
17381753
})
17391754
require.NoError(t, err)
17401755
wait("update active template version", nil)
17411756

1742-
cancel()
1757+
// Build with the new template; should end up with a failure state.
1758+
_ = coderdtest.CreateWorkspaceBuild(t, client, workspace, database.WorkspaceTransitionStart, func(req *codersdk.CreateWorkspaceBuildRequest) {
1759+
req.TemplateVersionID = updatedVersion.ID
1760+
})
1761+
wait("workspace build pending", func(w codersdk.Workspace) bool {
1762+
return w.LatestBuild.Status == codersdk.WorkspaceStatusPending
1763+
})
1764+
wait("workspace build failed", func(w codersdk.Workspace) bool {
1765+
return w.LatestBuild.Status == codersdk.WorkspaceStatusFailed
1766+
})
17431767
}
17441768

17451769
func mustLocation(t *testing.T, location string) *time.Location {

provisionerd/runner/runner.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -900,7 +900,7 @@ func (r *Runner) buildWorkspace(ctx context.Context, stage string, req *sdkproto
900900
// will still be available for us to send the cancel to the provisioner
901901
stream, err := r.provisioner.Provision(ctx)
902902
if err != nil {
903-
return nil, r.failedJobf("provision: %s", err)
903+
return nil, r.failedWorkspaceBuildf("provision: %s", err)
904904
}
905905
defer stream.Close()
906906
go func() {
@@ -918,13 +918,13 @@ func (r *Runner) buildWorkspace(ctx context.Context, stage string, req *sdkproto
918918

919919
err = stream.Send(req)
920920
if err != nil {
921-
return nil, r.failedJobf("start provision: %s", err)
921+
return nil, r.failedWorkspaceBuildf("start provision: %s", err)
922922
}
923923

924924
for {
925925
msg, err := stream.Recv()
926926
if err != nil {
927-
return nil, r.failedJobf("recv workspace provision: %s", err)
927+
return nil, r.failedWorkspaceBuildf("recv workspace provision: %s", err)
928928
}
929929
switch msgType := msg.Type.(type) {
930930
case *sdkproto.Provision_Response_Log:
@@ -967,7 +967,7 @@ func (r *Runner) buildWorkspace(ctx context.Context, stage string, req *sdkproto
967967
// Stop looping!
968968
return msgType.Complete, nil
969969
default:
970-
return nil, r.failedJobf("invalid message type %T received from provisioner", msg.Type)
970+
return nil, r.failedWorkspaceBuildf("invalid message type %T received from provisioner", msg.Type)
971971
}
972972
}
973973
}
@@ -1102,6 +1102,12 @@ func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *p
11021102
}, nil
11031103
}
11041104

1105+
func (r *Runner) failedWorkspaceBuildf(format string, args ...interface{}) *proto.FailedJob {
1106+
failedJob := r.failedJobf(format, args...)
1107+
failedJob.Type = &proto.FailedJob_WorkspaceBuild_{}
1108+
return failedJob
1109+
}
1110+
11051111
func (r *Runner) failedJobf(format string, args ...interface{}) *proto.FailedJob {
11061112
message := fmt.Sprintf(format, args...)
11071113
var code string

0 commit comments

Comments
 (0)