Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0a83477

Browse files
committed
Add endpoints for extracting singular history
1 parentd062b5b commit0a83477

13 files changed

+240
-88
lines changed

‎coderd/coderd.go‎

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ func New(options *Options) http.Handler {
6464
r.Route("/history",func(r chi.Router) {
6565
r.Get("/",api.projectHistoryByOrganization)
6666
r.Post("/",api.postProjectHistoryByOrganization)
67+
r.Route("/{projecthistory}",func(r chi.Router) {
68+
r.Use(httpmw.ExtractProjectHistoryParam(api.Database))
69+
r.Get("/",api.projectHistoryByOrganizationAndName)
70+
})
6771
})
6872
})
6973
})
@@ -84,7 +88,10 @@ func New(options *Options) http.Handler {
8488
r.Route("/history",func(r chi.Router) {
8589
r.Post("/",api.postWorkspaceHistoryByUser)
8690
r.Get("/",api.workspaceHistoryByUser)
87-
r.Get("/latest",api.latestWorkspaceHistoryByUser)
91+
r.Route("/{workspacehistory}",func(r chi.Router) {
92+
r.Use(httpmw.ExtractWorkspaceHistoryParam(options.Database))
93+
r.Get("/",api.workspaceHistoryByName)
94+
})
8895
})
8996
})
9097
})

‎coderd/projecthistory.go‎

Lines changed: 70 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"archive/tar"
55
"bytes"
66
"database/sql"
7+
"encoding/json"
78
"errors"
89
"fmt"
910
"net/http"
@@ -12,6 +13,7 @@ import (
1213
"github.com/go-chi/render"
1314
"github.com/google/uuid"
1415
"github.com/moby/moby/pkg/namesgenerator"
16+
"golang.org/x/xerrors"
1517

1618
"github.com/coder/coder/database"
1719
"github.com/coder/coder/httpapi"
@@ -26,6 +28,7 @@ type ProjectHistory struct {
2628
UpdatedAt time.Time`json:"updated_at"`
2729
Namestring`json:"name"`
2830
StorageMethod database.ProjectStorageMethod`json:"storage_method"`
31+
ImportProvisionerJob`json:"import"`
2932
}
3033

3134
// CreateProjectHistoryRequest enables callers to create a new Project Version.
@@ -50,12 +53,33 @@ func (api *api) projectHistoryByOrganization(rw http.ResponseWriter, r *http.Req
5053
}
5154
apiHistory:=make([]ProjectHistory,0)
5255
for_,version:=rangehistory {
53-
apiHistory=append(apiHistory,convertProjectHistory(version))
56+
job,err:=api.Database.GetProvisionerJobByID(r.Context(),version.ImportJobID)
57+
iferr!=nil {
58+
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
59+
Message:fmt.Sprintf("get provisioner job: %s",err),
60+
})
61+
return
62+
}
63+
apiHistory=append(apiHistory,convertProjectHistory(version,job))
5464
}
5565
render.Status(r,http.StatusOK)
5666
render.JSON(rw,r,apiHistory)
5767
}
5868

69+
// Return a single project history by organization and name.
70+
func (api*api)projectHistoryByOrganizationAndName(rw http.ResponseWriter,r*http.Request) {
71+
projectHistory:=httpmw.ProjectHistoryParam(r)
72+
job,err:=api.Database.GetProvisionerJobByID(r.Context(),projectHistory.ImportJobID)
73+
iferr!=nil {
74+
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
75+
Message:fmt.Sprintf("get provisioner job: %s",err),
76+
})
77+
return
78+
}
79+
render.Status(r,http.StatusOK)
80+
render.JSON(rw,r,convertProjectHistory(projectHistory,job))
81+
}
82+
5983
// Creates a new version of the project. An import job is queued to parse
6084
// the storage method provided. Once completed, the import job will specify
6185
// the version as latest.
@@ -82,38 +106,68 @@ func (api *api) postProjectHistoryByOrganization(rw http.ResponseWriter, r *http
82106
return
83107
}
84108

109+
apiKey:=httpmw.APIKey(r)
85110
project:=httpmw.ProjectParam(r)
86-
history,err:=api.Database.InsertProjectHistory(r.Context(), database.InsertProjectHistoryParams{
87-
ID:uuid.New(),
88-
ProjectID:project.ID,
89-
CreatedAt:database.Now(),
90-
UpdatedAt:database.Now(),
91-
Name:namesgenerator.GetRandomName(1),
92-
StorageMethod:createProjectVersion.StorageMethod,
93-
StorageSource:createProjectVersion.StorageSource,
94-
// TODO: Make this do something!
95-
ImportJobID:uuid.New(),
111+
112+
varprovisionerJob database.ProvisionerJob
113+
varprojectHistory database.ProjectHistory
114+
err:=api.Database.InTx(func(db database.Store)error {
115+
projectHistoryID:=uuid.New()
116+
input,err:=json.Marshal(projectImportJob{
117+
ProjectHistoryID:projectHistoryID,
118+
})
119+
iferr!=nil {
120+
returnxerrors.Errorf("marshal import job: %w",err)
121+
}
122+
123+
provisionerJob,err=db.InsertProvisionerJob(r.Context(), database.InsertProvisionerJobParams{
124+
ID:uuid.New(),
125+
CreatedAt:database.Now(),
126+
UpdatedAt:database.Now(),
127+
InitiatorID:apiKey.UserID,
128+
Provisioner:project.Provisioner,
129+
Type:database.ProvisionerJobTypeProjectImport,
130+
ProjectID:project.ID,
131+
Input:input,
132+
})
133+
iferr!=nil {
134+
returnxerrors.Errorf("insert provisioner job: %w",err)
135+
}
136+
137+
projectHistory,err=api.Database.InsertProjectHistory(r.Context(), database.InsertProjectHistoryParams{
138+
ID:projectHistoryID,
139+
ProjectID:project.ID,
140+
CreatedAt:database.Now(),
141+
UpdatedAt:database.Now(),
142+
Name:namesgenerator.GetRandomName(1),
143+
StorageMethod:createProjectVersion.StorageMethod,
144+
StorageSource:createProjectVersion.StorageSource,
145+
ImportJobID:provisionerJob.ID,
146+
})
147+
iferr!=nil {
148+
returnxerrors.Errorf("insert project history: %s",err)
149+
}
150+
returnnil
96151
})
97152
iferr!=nil {
98153
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
99-
Message:fmt.Sprintf("insert project history: %s",err),
154+
Message:err.Error(),
100155
})
101156
return
102157
}
103158

104-
// TODO: A job to process the new version should occur here.
105-
106159
render.Status(r,http.StatusCreated)
107-
render.JSON(rw,r,convertProjectHistory(history))
160+
render.JSON(rw,r,convertProjectHistory(projectHistory,provisionerJob))
108161
}
109162

110-
funcconvertProjectHistory(history database.ProjectHistory)ProjectHistory {
163+
funcconvertProjectHistory(history database.ProjectHistory,job database.ProvisionerJob)ProjectHistory {
111164
returnProjectHistory{
112165
ID:history.ID,
113166
ProjectID:history.ProjectID,
114167
CreatedAt:history.CreatedAt,
115168
UpdatedAt:history.UpdatedAt,
116169
Name:history.Name,
170+
Import:convertProvisionerJob(job),
117171
}
118172
}
119173

‎coderd/projecthistory_test.go‎

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ func TestProjectHistory(t *testing.T) {
2525
Provisioner:database.ProvisionerTypeTerraform,
2626
})
2727
require.NoError(t,err)
28-
versions,err:=server.Client.ProjectHistory(context.Background(),user.Organization,project.Name)
28+
versions,err:=server.Client.ListProjectHistory(context.Background(),user.Organization,project.Name)
2929
require.NoError(t,err)
3030
require.Len(t,versions,0)
3131
})
@@ -48,14 +48,17 @@ func TestProjectHistory(t *testing.T) {
4848
require.NoError(t,err)
4949
_,err=writer.Write(make([]byte,1<<10))
5050
require.NoError(t,err)
51-
_,err=server.Client.CreateProjectHistory(context.Background(),user.Organization,project.Name, coderd.CreateProjectHistoryRequest{
51+
history,err:=server.Client.CreateProjectHistory(context.Background(),user.Organization,project.Name, coderd.CreateProjectHistoryRequest{
5252
StorageMethod:database.ProjectStorageMethodInlineArchive,
5353
StorageSource:buffer.Bytes(),
5454
})
5555
require.NoError(t,err)
56-
versions,err:=server.Client.ProjectHistory(context.Background(),user.Organization,project.Name)
56+
versions,err:=server.Client.ListProjectHistory(context.Background(),user.Organization,project.Name)
5757
require.NoError(t,err)
5858
require.Len(t,versions,1)
59+
60+
_,err=server.Client.ProjectHistory(context.Background(),user.Organization,project.Name,history.Name)
61+
require.NoError(t,err)
5962
})
6063

6164
t.Run("CreateHistoryArchiveTooBig",func(t*testing.T) {

‎coderd/provisionerdaemons.go‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,13 @@ func (server *provisionerdServer) AcquireJob(ctx context.Context, _ *proto.Empty
241241
iferr!=nil {
242242
returnnil,failJob(fmt.Sprintf("get project history: %s",err))
243243
}
244+
245+
protoJob.Type=&proto.AcquiredJob_ProjectImport_{
246+
ProjectImport:&proto.AcquiredJob_ProjectImport{
247+
ProjectHistoryId:projectHistory.ID.String(),
248+
ProjectHistoryName:projectHistory.Name,
249+
},
250+
}
244251
}
245252
switchprojectHistory.StorageMethod {
246253
casedatabase.ProjectStorageMethodInlineArchive:

‎coderd/provisioners.go‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,11 @@ import (
1010

1111
typeProvisionerJobStatusstring
1212

13+
// Completed returns whether the job is still processing.
14+
func (pProvisionerJobStatus)Completed()bool {
15+
returnp==ProvisionerJobStatusSucceeded||p==ProvisionerJobStatusFailed
16+
}
17+
1318
const (
1419
ProvisionerJobStatusPendingProvisionerJobStatus="pending"
1520
ProvisionerJobStatusRunningProvisionerJobStatus="running"

‎coderd/workspacehistory.go‎

Lines changed: 32 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ type WorkspaceHistory struct {
2929
AfterID uuid.UUID`json:"after_id"`
3030
Transition database.WorkspaceTransition`json:"transition"`
3131
Initiatorstring`json:"initiator"`
32-
JobProvisionerJob`json:"job"`
32+
ProvisionProvisionerJob`json:"provision"`
3333
}
3434

3535
// CreateWorkspaceHistoryRequest provides options to update the latest workspace history.
@@ -62,6 +62,27 @@ func (api *api) postWorkspaceHistoryByUser(rw http.ResponseWriter, r *http.Reque
6262
})
6363
return
6464
}
65+
projectHistoryJob,err:=api.Database.GetProvisionerJobByID(r.Context(),projectHistory.ImportJobID)
66+
iferr!=nil {
67+
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
68+
Message:fmt.Sprintf("get provisioner job: %s",err),
69+
})
70+
return
71+
}
72+
projectHistoryJobStatus:=convertProvisionerJob(projectHistoryJob).Status
73+
switchprojectHistoryJobStatus {
74+
caseProvisionerJobStatusPending,ProvisionerJobStatusRunning:
75+
httpapi.Write(rw,http.StatusPreconditionFailed, httpapi.Response{
76+
Message:fmt.Sprintf("The provided project history is %s. Wait for it to complete importing!",projectHistoryJobStatus),
77+
})
78+
return
79+
caseProvisionerJobStatusFailed:
80+
httpapi.Write(rw,http.StatusBadRequest, httpapi.Response{
81+
Message:fmt.Sprintf("The provided project history %q has failed to import. You cannot create workspaces using it!",projectHistory.Name),
82+
})
83+
return
84+
}
85+
6586
project,err:=api.Database.GetProjectByID(r.Context(),projectHistory.ProjectID)
6687
iferr!=nil {
6788
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
@@ -75,15 +96,11 @@ func (api *api) postWorkspaceHistoryByUser(rw http.ResponseWriter, r *http.Reque
7596
priorHistory,err:=api.Database.GetWorkspaceHistoryByWorkspaceIDWithoutAfter(r.Context(),workspace.ID)
7697
iferr==nil {
7798
priorJob,err:=api.Database.GetProvisionerJobByID(r.Context(),priorHistory.ProvisionJobID)
78-
iferr==nil {
79-
convertedJob:=convertProvisionerJob(priorJob)
80-
ifconvertedJob.Status==ProvisionerJobStatusPending||
81-
convertedJob.Status==ProvisionerJobStatusRunning {
82-
httpapi.Write(rw,http.StatusConflict, httpapi.Response{
83-
Message:"a workspace build is already active",
84-
})
85-
return
86-
}
99+
iferr==nil&&convertProvisionerJob(priorJob).Status.Completed() {
100+
httpapi.Write(rw,http.StatusConflict, httpapi.Response{
101+
Message:"a workspace build is already active",
102+
})
103+
return
87104
}
88105

89106
priorHistoryID= uuid.NullUUID{
@@ -200,24 +217,9 @@ func (api *api) workspaceHistoryByUser(rw http.ResponseWriter, r *http.Request)
200217
render.JSON(rw,r,apiHistory)
201218
}
202219

203-
// Returns the latest workspace history. This works by querying for history without "after" set.
204-
func (api*api)latestWorkspaceHistoryByUser(rw http.ResponseWriter,r*http.Request) {
205-
workspace:=httpmw.WorkspaceParam(r)
206-
207-
history,err:=api.Database.GetWorkspaceHistoryByWorkspaceIDWithoutAfter(r.Context(),workspace.ID)
208-
iferrors.Is(err,sql.ErrNoRows) {
209-
httpapi.Write(rw,http.StatusNotFound, httpapi.Response{
210-
Message:"workspace has no history",
211-
})
212-
return
213-
}
214-
iferr!=nil {
215-
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
216-
Message:fmt.Sprintf("get workspace history: %s",err),
217-
})
218-
return
219-
}
220-
job,err:=api.Database.GetProvisionerJobByID(r.Context(),history.ProvisionJobID)
220+
func (api*api)workspaceHistoryByName(rw http.ResponseWriter,r*http.Request) {
221+
workspaceHistory:=httpmw.WorkspaceHistoryParam(r)
222+
job,err:=api.Database.GetProvisionerJobByID(r.Context(),workspaceHistory.ProvisionJobID)
221223
iferr!=nil {
222224
httpapi.Write(rw,http.StatusInternalServerError, httpapi.Response{
223225
Message:fmt.Sprintf("get provisioner job: %s",err),
@@ -226,7 +228,7 @@ func (api *api) latestWorkspaceHistoryByUser(rw http.ResponseWriter, r *http.Req
226228
}
227229

228230
render.Status(r,http.StatusOK)
229-
render.JSON(rw,r,convertWorkspaceHistory(history,job))
231+
render.JSON(rw,r,convertWorkspaceHistory(workspaceHistory,job))
230232
}
231233

232234
// Converts the internal history representation to a public external-facing model.
@@ -242,7 +244,7 @@ func convertWorkspaceHistory(workspaceHistory database.WorkspaceHistory, provisi
242244
AfterID:workspaceHistory.AfterID.UUID,
243245
Transition:workspaceHistory.Transition,
244246
Initiator:workspaceHistory.Initiator,
245-
Job:convertProvisionerJob(provisionerJob),
247+
Provision:convertProvisionerJob(provisionerJob),
246248
})
247249
}
248250

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp