Skip to content

Commit 81ceae6

Browse files
committed
Fix race where provisioner job is inserted before project version
1 parent 49799a0 commit 81ceae6

File tree

2 files changed

+36
-38
lines changed

2 files changed

+36
-38
lines changed

coderd/projectversion.go

Lines changed: 17 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -125,16 +125,29 @@ func (api *api) postProjectVersionByOrganization(rw http.ResponseWriter, r *http
125125
var provisionerJob database.ProvisionerJob
126126
var projectVersion database.ProjectVersion
127127
err = api.Database.InTx(func(db database.Store) error {
128-
projectVersionID := uuid.New()
128+
provisionerJobID := uuid.New()
129+
projectVersion, err = api.Database.InsertProjectVersion(r.Context(), database.InsertProjectVersionParams{
130+
ID: uuid.New(),
131+
ProjectID: project.ID,
132+
CreatedAt: database.Now(),
133+
UpdatedAt: database.Now(),
134+
Name: namesgenerator.GetRandomName(1),
135+
StorageMethod: createProjectVersion.StorageMethod,
136+
StorageSource: createProjectVersion.StorageSource,
137+
ImportJobID: provisionerJobID,
138+
})
139+
if err != nil {
140+
return xerrors.Errorf("insert project version: %s", err)
141+
}
142+
129143
input, err := json.Marshal(projectImportJob{
130-
ProjectVersionID: projectVersionID,
144+
ProjectVersionID: projectVersion.ID,
131145
})
132146
if err != nil {
133147
return xerrors.Errorf("marshal import job: %w", err)
134148
}
135-
136149
provisionerJob, err = db.InsertProvisionerJob(r.Context(), database.InsertProvisionerJobParams{
137-
ID: uuid.New(),
150+
ID: provisionerJobID,
138151
CreatedAt: database.Now(),
139152
UpdatedAt: database.Now(),
140153
InitiatorID: apiKey.UserID,
@@ -146,20 +159,6 @@ func (api *api) postProjectVersionByOrganization(rw http.ResponseWriter, r *http
146159
if err != nil {
147160
return xerrors.Errorf("insert provisioner job: %w", err)
148161
}
149-
150-
projectVersion, err = api.Database.InsertProjectVersion(r.Context(), database.InsertProjectVersionParams{
151-
ID: projectVersionID,
152-
ProjectID: project.ID,
153-
CreatedAt: database.Now(),
154-
UpdatedAt: database.Now(),
155-
Name: namesgenerator.GetRandomName(1),
156-
StorageMethod: createProjectVersion.StorageMethod,
157-
StorageSource: createProjectVersion.StorageSource,
158-
ImportJobID: provisionerJob.ID,
159-
})
160-
if err != nil {
161-
return xerrors.Errorf("insert project version: %s", err)
162-
}
163162
return nil
164163
})
165164
if err != nil {

coderd/workspacehistory.go

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -126,17 +126,32 @@ func (api *api) postWorkspaceHistoryByUser(rw http.ResponseWriter, r *http.Reque
126126
// This must happen in a transaction to ensure history can be inserted, and
127127
// the prior history can update it's "after" column to point at the new.
128128
err = api.Database.InTx(func(db database.Store) error {
129-
// Generate the ID before-hand so the provisioner job is aware of it!
130-
workspaceHistoryID := uuid.New()
129+
provisionerJobID := uuid.New()
130+
workspaceHistory, err = db.InsertWorkspaceHistory(r.Context(), database.InsertWorkspaceHistoryParams{
131+
ID: uuid.New(),
132+
CreatedAt: database.Now(),
133+
UpdatedAt: database.Now(),
134+
WorkspaceID: workspace.ID,
135+
ProjectVersionID: projectVersion.ID,
136+
BeforeID: priorHistoryID,
137+
Name: namesgenerator.GetRandomName(1),
138+
Initiator: user.ID,
139+
Transition: createBuild.Transition,
140+
ProvisionJobID: provisionerJobID,
141+
})
142+
if err != nil {
143+
return xerrors.Errorf("insert workspace history: %w", err)
144+
}
145+
131146
input, err := json.Marshal(workspaceProvisionJob{
132-
WorkspaceHistoryID: workspaceHistoryID,
147+
WorkspaceHistoryID: workspaceHistory.ID,
133148
})
134149
if err != nil {
135150
return xerrors.Errorf("marshal provision job: %w", err)
136151
}
137152

138153
provisionerJob, err = db.InsertProvisionerJob(r.Context(), database.InsertProvisionerJobParams{
139-
ID: uuid.New(),
154+
ID: provisionerJobID,
140155
CreatedAt: database.Now(),
141156
UpdatedAt: database.Now(),
142157
InitiatorID: user.ID,
@@ -149,22 +164,6 @@ func (api *api) postWorkspaceHistoryByUser(rw http.ResponseWriter, r *http.Reque
149164
return xerrors.Errorf("insert provisioner job: %w", err)
150165
}
151166

152-
workspaceHistory, err = db.InsertWorkspaceHistory(r.Context(), database.InsertWorkspaceHistoryParams{
153-
ID: workspaceHistoryID,
154-
CreatedAt: database.Now(),
155-
UpdatedAt: database.Now(),
156-
WorkspaceID: workspace.ID,
157-
ProjectVersionID: projectVersion.ID,
158-
BeforeID: priorHistoryID,
159-
Name: namesgenerator.GetRandomName(1),
160-
Initiator: user.ID,
161-
Transition: createBuild.Transition,
162-
ProvisionJobID: provisionerJob.ID,
163-
})
164-
if err != nil {
165-
return xerrors.Errorf("insert workspace history: %w", err)
166-
}
167-
168167
if priorHistoryID.Valid {
169168
// Update the prior history entries "after" column.
170169
err = db.UpdateWorkspaceHistoryByID(r.Context(), database.UpdateWorkspaceHistoryByIDParams{

0 commit comments

Comments
 (0)