4
4
"archive/tar"
5
5
"bytes"
6
6
"database/sql"
7
+ "encoding/json"
7
8
"errors"
8
9
"fmt"
9
10
"net/http"
@@ -12,6 +13,7 @@ import (
12
13
"github.com/go-chi/render"
13
14
"github.com/google/uuid"
14
15
"github.com/moby/moby/pkg/namesgenerator"
16
+ "golang.org/x/xerrors"
15
17
16
18
"github.com/coder/coder/database"
17
19
"github.com/coder/coder/httpapi"
@@ -26,6 +28,7 @@ type ProjectHistory struct {
26
28
UpdatedAt time.Time `json:"updated_at"`
27
29
Name string `json:"name"`
28
30
StorageMethod database.ProjectStorageMethod `json:"storage_method"`
31
+ Import ProvisionerJob `json:"import"`
29
32
}
30
33
31
34
// CreateProjectHistoryRequest enables callers to create a new Project Version.
@@ -50,12 +53,33 @@ func (api *api) projectHistoryByOrganization(rw http.ResponseWriter, r *http.Req
50
53
}
51
54
apiHistory := make ([]ProjectHistory , 0 )
52
55
for _ , version := range history {
53
- apiHistory = append (apiHistory , convertProjectHistory (version ))
56
+ job , err := api .Database .GetProvisionerJobByID (r .Context (), version .ImportJobID )
57
+ if err != 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 ))
54
64
}
55
65
render .Status (r , http .StatusOK )
56
66
render .JSON (rw , r , apiHistory )
57
67
}
58
68
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
+ if err != 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
+
59
83
// Creates a new version of the project. An import job is queued to parse
60
84
// the storage method provided. Once completed, the import job will specify
61
85
// the version as latest.
@@ -82,37 +106,71 @@ func (api *api) postProjectHistoryByOrganization(rw http.ResponseWriter, r *http
82
106
return
83
107
}
84
108
109
+ apiKey := httpmw .APIKey (r )
85
110
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
+ var provisionerJob database.ProvisionerJob
113
+ var projectHistory 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
+ if err != nil {
120
+ return xerrors .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
+ if err != nil {
134
+ return xerrors .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
+ if err != nil {
148
+ return xerrors .Errorf ("insert project history: %s" , err )
149
+ }
150
+ return nil
96
151
})
97
152
if err != nil {
98
153
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
99
- Message : fmt . Sprintf ( "insert project history: %s" , err ),
154
+ Message : err . Error ( ),
100
155
})
101
156
return
102
157
}
103
158
104
- // TODO: A job to process the new version should occur here.
105
-
106
159
render .Status (r , http .StatusCreated )
107
- render .JSON (rw , r , convertProjectHistory (history ))
160
+ render .JSON (rw , r , convertProjectHistory (projectHistory , provisionerJob ))
108
161
}
109
162
110
- func convertProjectHistory (history database.ProjectHistory ) ProjectHistory {
163
+ func convertProjectHistory (history database.ProjectHistory , job database. ProvisionerJob ) ProjectHistory {
111
164
return ProjectHistory {
112
165
ID : history .ID ,
113
166
ProjectID : history .ProjectID ,
114
167
CreatedAt : history .CreatedAt ,
115
168
UpdatedAt : history .UpdatedAt ,
116
169
Name : history .Name ,
170
+ Import : convertProvisionerJob (job ),
117
171
}
118
172
}
173
+
174
+ func projectHistoryLogsChannel (projectHistoryID uuid.UUID ) string {
175
+ return fmt .Sprintf ("project-history-logs:%s" , projectHistoryID )
176
+ }
0 commit comments