MCPcopy Index your code
hub / github.com/coder/coder / workspaceAgentRPC

Method workspaceAgentRPC

coderd/workspaceagentsrpc.go:42–198  ·  view source on GitHub ↗

@Summary Workspace agent RPC API @ID workspace-agent-rpc-api @Security CoderSessionToken @Tags Agents @Success 101 @Router /api/v2/workspaceagents/me/rpc [get] @x-apidocgen {"skip": true}

(rw http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

40// @Router /api/v2/workspaceagents/me/rpc [get]
41// @x-apidocgen {"skip": true}
42func (api *API) workspaceAgentRPC(rw http.ResponseWriter, r *http.Request) {
43 ctx := r.Context()
44 logger := api.Logger.Named("agentrpc")
45
46 version := r.URL.Query().Get("version")
47 if version == "" {
48 // The initial version on this HTTP endpoint was 2.0, so assume this version if unspecified.
49 // Coder v2.7.1 (not to be confused with the Agent API version) calls this endpoint without
50 // a version parameter and wants Agent API version 2.0.
51 version = "2.0"
52 }
53 if err := proto.CurrentVersion.Validate(version); err != nil {
54 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
55 Message: "Unknown or unsupported API version",
56 Validations: []codersdk.ValidationError{
57 {Field: "version", Detail: err.Error()},
58 },
59 })
60 return
61 }
62
63 // The role parameter distinguishes the real workspace agent from
64 // other clients using the same agent token (e.g. coder-logstream-kube).
65 // Only connections with the "agent" role trigger connection monitoring
66 // that updates first_connected_at/last_connected_at/disconnected_at.
67 // For backward compatibility, we default to monitoring when the role
68 // is omitted, since older agents don't send this parameter. In a
69 // future release, once all agents include role=agent, we can change
70 // this default to skip monitoring for unspecified roles.
71 role := r.URL.Query().Get("role")
72 monitorConnection := role == "" || role == "agent"
73
74 api.WebsocketWaitMutex.Lock()
75 api.WebsocketWaitGroup.Add(1)
76 api.WebsocketWaitMutex.Unlock()
77 defer api.WebsocketWaitGroup.Done()
78 workspaceAgent := httpmw.WorkspaceAgent(r)
79 build := httpmw.LatestBuild(r)
80
81 workspace, err := api.Database.GetWorkspaceByID(ctx, build.WorkspaceID)
82 if err != nil {
83 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
84 Message: "Internal error fetching workspace.",
85 Detail: err.Error(),
86 })
87 return
88 }
89
90 logger = logger.With(
91 slog.F("owner", workspace.OwnerUsername),
92 slog.F("workspace_name", workspace.Name),
93 slog.F("agent_name", workspaceAgent.Name),
94 )
95
96 conn, err := websocket.Accept(rw, r, nil)
97 if err != nil {
98 httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{
99 Message: "Failed to accept websocket.",

Callers

nothing calls this directly

Calls 15

WriteFunction · 0.92
WorkspaceAgentFunction · 0.92
LatestBuildFunction · 0.92
WebsocketNetConnFunction · 0.92
NewFunction · 0.92
WithStreamIDFunction · 0.92
WithAPIVersionFunction · 0.92
NamedMethod · 0.80
ContextMethod · 0.65
GetMethod · 0.65
ValidateMethod · 0.65

Tested by

no test coverage detected