Skip to content

Commit 5959a6c

Browse files
committed
feat: Add VSCODE_PROXY_URI to surface code-server ports
Fixes #4776.
1 parent 90f77a3 commit 5959a6c

File tree

4 files changed

+55
-1
lines changed

4 files changed

+55
-1
lines changed

agent/agent.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -569,7 +569,6 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
569569
// Set environment variables reliable detection of being inside a
570570
// Coder workspace.
571571
cmd.Env = append(cmd.Env, "CODER=true")
572-
573572
cmd.Env = append(cmd.Env, fmt.Sprintf("USER=%s", username))
574573
// Git on Windows resolves with UNIX-style paths.
575574
// If using backslashes, it's unable to find the executable.
@@ -585,6 +584,10 @@ func (a *agent) createCommand(ctx context.Context, rawCommand string, env []stri
585584
cmd.Env = append(cmd.Env, fmt.Sprintf("SSH_CLIENT=%s %s %s", srcAddr, srcPort, dstPort))
586585
cmd.Env = append(cmd.Env, fmt.Sprintf("SSH_CONNECTION=%s %s %s %s", srcAddr, srcPort, dstAddr, dstPort))
587586

587+
// This adds the ports dialog to code-server that enables
588+
// proxying a port dynamically.
589+
cmd.Env = append(cmd.Env, fmt.Sprintf("VSCODE_PROXY_URI=%s", metadata.VSCodePortProxyURI))
590+
588591
// Load environment variables passed via the agent.
589592
// These should override all variables we manually specify.
590593
for envKey, value := range metadata.EnvironmentVariables {

coderd/workspaceagents.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,46 @@ func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request)
8383
})
8484
return
8585
}
86+
resource, err := api.Database.GetWorkspaceResourceByID(r.Context(), workspaceAgent.ResourceID)
87+
if err != nil {
88+
httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{
89+
Message: "Internal error fetching workspace resource.",
90+
Detail: err.Error(),
91+
})
92+
return
93+
}
94+
build, err := api.Database.GetWorkspaceBuildByJobID(r.Context(), resource.JobID)
95+
if err != nil {
96+
httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{
97+
Message: "Internal error fetching workspace build.",
98+
Detail: err.Error(),
99+
})
100+
return
101+
}
102+
workspace, err := api.Database.GetWorkspaceByID(r.Context(), build.WorkspaceID)
103+
if err != nil {
104+
httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{
105+
Message: "Internal error fetching workspace.",
106+
Detail: err.Error(),
107+
})
108+
return
109+
}
110+
owner, err := api.Database.GetUserByID(r.Context(), workspace.OwnerID)
111+
if err != nil {
112+
httpapi.Write(r.Context(), rw, http.StatusInternalServerError, codersdk.Response{
113+
Message: "Internal error fetching workspace owner.",
114+
Detail: err.Error(),
115+
})
116+
return
117+
}
118+
119+
vscodeProxyURI := strings.ReplaceAll(api.AppHostname, "*",
120+
fmt.Sprintf("%s://{{port}}--%s--%s--%s",
121+
api.AccessURL.Scheme,
122+
workspaceAgent.Name,
123+
workspace.Name,
124+
owner.Username,
125+
))
86126

87127
httpapi.Write(ctx, rw, http.StatusOK, codersdk.WorkspaceAgentMetadata{
88128
Apps: convertApps(dbApps),
@@ -91,6 +131,7 @@ func (api *API) workspaceAgentMetadata(rw http.ResponseWriter, r *http.Request)
91131
EnvironmentVariables: apiAgent.EnvironmentVariables,
92132
StartupScript: apiAgent.StartupScript,
93133
Directory: apiAgent.Directory,
134+
VSCodePortProxyURI: vscodeProxyURI,
94135
})
95136
}
96137

coderd/workspaceapps_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,15 @@ func createWorkspaceWithApps(t *testing.T, client *codersdk.Client, orgID uuid.U
194194

195195
agentClient := codersdk.New(client.URL)
196196
agentClient.SessionToken = authToken
197+
metadata, err := agentClient.WorkspaceAgentMetadata(context.Background())
198+
require.NoError(t, err)
199+
require.Equal(t, fmt.Sprintf(
200+
"http://{{port}}--%s--%s--%s.%s",
201+
proxyTestAgentName,
202+
workspace.Name,
203+
"testuser",
204+
proxyTestSubdomain,
205+
), metadata.VSCodePortProxyURI)
197206
agentCloser := agent.New(agent.Options{
198207
Client: agentClient,
199208
Logger: slogtest.Make(t, nil).Named("agent"),

codersdk/workspaceagents.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ type WorkspaceAgentMetadata struct {
123123
// the Coder deployment has. If this number is >0, we
124124
// set up special configuration in the workspace.
125125
GitAuthConfigs int `json:"git_auth_configs"`
126+
VSCodePortProxyURI string `json:"vscode_port_proxy_uri"`
126127
Apps []WorkspaceApp `json:"apps"`
127128
DERPMap *tailcfg.DERPMap `json:"derpmap"`
128129
EnvironmentVariables map[string]string `json:"environment_variables"`

0 commit comments

Comments
 (0)