@@ -15,6 +15,7 @@ import (
15
15
"nhooyr.io/websocket"
16
16
17
17
"cdr.dev/slog"
18
+ "github.com/coder/coder/agent"
18
19
"github.com/coder/coder/coderd/database"
19
20
"github.com/coder/coder/coderd/httpapi"
20
21
"github.com/coder/coder/coderd/httpmw"
@@ -25,8 +26,8 @@ import (
25
26
)
26
27
27
28
func (api * api ) workspaceAgent (rw http.ResponseWriter , r * http.Request ) {
28
- agent := httpmw .WorkspaceAgentParam (r )
29
- apiAgent , err := convertWorkspaceAgent (agent , api .AgentConnectionUpdateFrequency )
29
+ workspaceAgent := httpmw .WorkspaceAgentParam (r )
30
+ apiAgent , err := convertWorkspaceAgent (workspaceAgent , api .AgentConnectionUpdateFrequency )
30
31
if err != nil {
31
32
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
32
33
Message : fmt .Sprintf ("convert workspace agent: %s" , err ),
@@ -43,8 +44,8 @@ func (api *api) workspaceAgentDial(rw http.ResponseWriter, r *http.Request) {
43
44
api .websocketWaitMutex .Unlock ()
44
45
defer api .websocketWaitGroup .Done ()
45
46
46
- agent := httpmw .WorkspaceAgentParam (r )
47
- apiAgent , err := convertWorkspaceAgent (agent , api .AgentConnectionUpdateFrequency )
47
+ workspaceAgent := httpmw .WorkspaceAgentParam (r )
48
+ apiAgent , err := convertWorkspaceAgent (workspaceAgent , api .AgentConnectionUpdateFrequency )
48
49
if err != nil {
49
50
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
50
51
Message : fmt .Sprintf ("convert workspace agent: %s" , err ),
@@ -78,7 +79,7 @@ func (api *api) workspaceAgentDial(rw http.ResponseWriter, r *http.Request) {
78
79
return
79
80
}
80
81
err = peerbroker .ProxyListen (r .Context (), session , peerbroker.ProxyOptions {
81
- ChannelID : agent .ID .String (),
82
+ ChannelID : workspaceAgent .ID .String (),
82
83
Logger : api .Logger .Named ("peerbroker-proxy-dial" ),
83
84
Pubsub : api .Pubsub ,
84
85
})
@@ -88,16 +89,49 @@ func (api *api) workspaceAgentDial(rw http.ResponseWriter, r *http.Request) {
88
89
}
89
90
}
90
91
91
- func (api * api ) workspaceAgentMe (rw http.ResponseWriter , r * http.Request ) {
92
- agent := httpmw .WorkspaceAgent (r )
93
- apiAgent , err := convertWorkspaceAgent (agent , api .AgentConnectionUpdateFrequency )
92
+ func (api * api ) workspaceAgentMetadata (rw http.ResponseWriter , r * http.Request ) {
93
+ workspaceAgent := httpmw .WorkspaceAgent (r )
94
+ apiAgent , err := convertWorkspaceAgent (workspaceAgent , api .AgentConnectionUpdateFrequency )
94
95
if err != nil {
95
96
httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
96
97
Message : fmt .Sprintf ("convert workspace agent: %s" , err ),
97
98
})
98
99
return
99
100
}
100
- httpapi .Write (rw , http .StatusOK , apiAgent )
101
+ resource , err := api .Database .GetWorkspaceResourceByID (r .Context (), workspaceAgent .ResourceID )
102
+ if err != nil {
103
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
104
+ Message : fmt .Sprintf ("get workspace resource: %s" , err ),
105
+ })
106
+ return
107
+ }
108
+ build , err := api .Database .GetWorkspaceBuildByJobID (r .Context (), resource .JobID )
109
+ if err != nil {
110
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
111
+ Message : fmt .Sprintf ("get workspace build: %s" , err ),
112
+ })
113
+ return
114
+ }
115
+ workspace , err := api .Database .GetWorkspaceByID (r .Context (), build .WorkspaceID )
116
+ if err != nil {
117
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
118
+ Message : fmt .Sprintf ("get workspace build: %s" , err ),
119
+ })
120
+ return
121
+ }
122
+ owner , err := api .Database .GetUserByID (r .Context (), workspace .OwnerID )
123
+ if err != nil {
124
+ httpapi .Write (rw , http .StatusInternalServerError , httpapi.Response {
125
+ Message : fmt .Sprintf ("get workspace build: %s" , err ),
126
+ })
127
+ return
128
+ }
129
+ httpapi .Write (rw , http .StatusOK , agent.Metadata {
130
+ OwnerEmail : owner .Email ,
131
+ OwnerUsername : owner .Username ,
132
+ EnvironmentVariables : apiAgent .EnvironmentVariables ,
133
+ StartupScript : apiAgent .StartupScript ,
134
+ })
101
135
}
102
136
103
137
func (api * api ) workspaceAgentListen (rw http.ResponseWriter , r * http.Request ) {
@@ -106,7 +140,7 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
106
140
api .websocketWaitMutex .Unlock ()
107
141
defer api .websocketWaitGroup .Done ()
108
142
109
- agent := httpmw .WorkspaceAgent (r )
143
+ workspaceAgent := httpmw .WorkspaceAgent (r )
110
144
conn , err := websocket .Accept (rw , r , & websocket.AcceptOptions {
111
145
CompressionMode : websocket .CompressionDisabled ,
112
146
})
@@ -116,7 +150,7 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
116
150
})
117
151
return
118
152
}
119
- resource , err := api .Database .GetWorkspaceResourceByID (r .Context (), agent .ResourceID )
153
+ resource , err := api .Database .GetWorkspaceResourceByID (r .Context (), workspaceAgent .ResourceID )
120
154
if err != nil {
121
155
httpapi .Write (rw , http .StatusBadRequest , httpapi.Response {
122
156
Message : fmt .Sprintf ("accept websocket: %s" , err ),
@@ -135,7 +169,7 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
135
169
return
136
170
}
137
171
closer , err := peerbroker .ProxyDial (proto .NewDRPCPeerBrokerClient (provisionersdk .Conn (session )), peerbroker.ProxyOptions {
138
- ChannelID : agent .ID .String (),
172
+ ChannelID : workspaceAgent .ID .String (),
139
173
Pubsub : api .Pubsub ,
140
174
Logger : api .Logger .Named ("peerbroker-proxy-listen" ),
141
175
})
@@ -144,7 +178,7 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
144
178
return
145
179
}
146
180
defer closer .Close ()
147
- firstConnectedAt := agent .FirstConnectedAt
181
+ firstConnectedAt := workspaceAgent .FirstConnectedAt
148
182
if ! firstConnectedAt .Valid {
149
183
firstConnectedAt = sql.NullTime {
150
184
Time : database .Now (),
@@ -155,10 +189,10 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
155
189
Time : database .Now (),
156
190
Valid : true ,
157
191
}
158
- disconnectedAt := agent .DisconnectedAt
192
+ disconnectedAt := workspaceAgent .DisconnectedAt
159
193
updateConnectionTimes := func () error {
160
194
err = api .Database .UpdateWorkspaceAgentConnectionByID (r .Context (), database.UpdateWorkspaceAgentConnectionByIDParams {
161
- ID : agent .ID ,
195
+ ID : workspaceAgent .ID ,
162
196
FirstConnectedAt : firstConnectedAt ,
163
197
LastConnectedAt : lastConnectedAt ,
164
198
DisconnectedAt : disconnectedAt ,
@@ -205,7 +239,7 @@ func (api *api) workspaceAgentListen(rw http.ResponseWriter, r *http.Request) {
205
239
return
206
240
}
207
241
208
- api .Logger .Info (r .Context (), "accepting agent" , slog .F ("resource" , resource ), slog .F ("agent" , agent ))
242
+ api .Logger .Info (r .Context (), "accepting agent" , slog .F ("resource" , resource ), slog .F ("agent" , workspaceAgent ))
209
243
210
244
ticker := time .NewTicker (api .AgentConnectionUpdateFrequency )
211
245
defer ticker .Stop ()
@@ -294,7 +328,7 @@ func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, agentUpdateFrequency
294
328
return codersdk.WorkspaceAgent {}, xerrors .Errorf ("unmarshal: %w" , err )
295
329
}
296
330
}
297
- agent := codersdk.WorkspaceAgent {
331
+ workspaceAgent := codersdk.WorkspaceAgent {
298
332
ID : dbAgent .ID ,
299
333
CreatedAt : dbAgent .CreatedAt ,
300
334
UpdatedAt : dbAgent .UpdatedAt ,
@@ -307,31 +341,31 @@ func convertWorkspaceAgent(dbAgent database.WorkspaceAgent, agentUpdateFrequency
307
341
EnvironmentVariables : envs ,
308
342
}
309
343
if dbAgent .FirstConnectedAt .Valid {
310
- agent .FirstConnectedAt = & dbAgent .FirstConnectedAt .Time
344
+ workspaceAgent .FirstConnectedAt = & dbAgent .FirstConnectedAt .Time
311
345
}
312
346
if dbAgent .LastConnectedAt .Valid {
313
- agent .LastConnectedAt = & dbAgent .LastConnectedAt .Time
347
+ workspaceAgent .LastConnectedAt = & dbAgent .LastConnectedAt .Time
314
348
}
315
349
if dbAgent .DisconnectedAt .Valid {
316
- agent .DisconnectedAt = & dbAgent .DisconnectedAt .Time
350
+ workspaceAgent .DisconnectedAt = & dbAgent .DisconnectedAt .Time
317
351
}
318
352
switch {
319
353
case ! dbAgent .FirstConnectedAt .Valid :
320
354
// If the agent never connected, it's waiting for the compute
321
355
// to start up.
322
- agent .Status = codersdk .WorkspaceAgentConnecting
356
+ workspaceAgent .Status = codersdk .WorkspaceAgentConnecting
323
357
case dbAgent .DisconnectedAt .Time .After (dbAgent .LastConnectedAt .Time ):
324
358
// If we've disconnected after our last connection, we know the
325
359
// agent is no longer connected.
326
- agent .Status = codersdk .WorkspaceAgentDisconnected
360
+ workspaceAgent .Status = codersdk .WorkspaceAgentDisconnected
327
361
case agentUpdateFrequency * 2 >= database .Now ().Sub (dbAgent .LastConnectedAt .Time ):
328
362
// The connection updated it's timestamp within the update frequency.
329
363
// We multiply by two to allow for some lag.
330
- agent .Status = codersdk .WorkspaceAgentConnected
364
+ workspaceAgent .Status = codersdk .WorkspaceAgentConnected
331
365
case database .Now ().Sub (dbAgent .LastConnectedAt .Time ) > agentUpdateFrequency * 2 :
332
366
// The connection died without updating the last connected.
333
- agent .Status = codersdk .WorkspaceAgentDisconnected
367
+ workspaceAgent .Status = codersdk .WorkspaceAgentDisconnected
334
368
}
335
369
336
- return agent , nil
370
+ return workspaceAgent , nil
337
371
}
0 commit comments