Skip to content

Commit b959fb1

Browse files
committed
feat: Add vscodeipc subcommand for VS Code Extension
This enables the VS Code extension to communicate with a Coder client. The extension will download the slim binary from `/bin/*` for the respective client architecture and OS, then execute `coder vscodeipc` for the connecting workspace.
1 parent eae77d7 commit b959fb1

File tree

11 files changed

+523
-73
lines changed

11 files changed

+523
-73
lines changed

cli/extension.go

-7
This file was deleted.

cli/root.go

+1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ func Core() []*cobra.Command {
9797
users(),
9898
versionCmd(),
9999
workspaceAgent(),
100+
vscodeipcCmd(),
100101
}
101102
}
102103

cli/speedtest.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ func speedtest() *cobra.Command {
7171
return ctx.Err()
7272
case <-ticker.C:
7373
}
74-
dur, err := conn.Ping(ctx)
74+
dur, p2p, err := conn.Ping(ctx)
7575
if err != nil {
7676
continue
7777
}
@@ -80,7 +80,7 @@ func speedtest() *cobra.Command {
8080
continue
8181
}
8282
peer := status.Peer[status.Peers()[0]]
83-
if peer.CurAddr == "" && direct {
83+
if !p2p && direct {
8484
cmd.Printf("Waiting for a direct connection... (%dms via %s)\n", dur.Milliseconds(), peer.Relay)
8585
continue
8686
}

cli/vscodeipc.go

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"net/http"
7+
"net/url"
8+
"os"
9+
10+
"github.com/google/uuid"
11+
"github.com/spf13/cobra"
12+
"golang.org/x/xerrors"
13+
14+
"github.com/coder/coder/cli/vscodeipc"
15+
"github.com/coder/coder/codersdk"
16+
)
17+
18+
// vscodeipcCmd spawns a local HTTP server on the provided port that listens to messages.
19+
// It's made for use by the Coder VS Code extension. See: https://github.com/coder/vscode-coder
20+
func vscodeipcCmd() *cobra.Command {
21+
var port uint16
22+
cmd := &cobra.Command{
23+
Use: "vscodeipc <workspace-agent>",
24+
Args: cobra.ExactArgs(1),
25+
Hidden: true,
26+
RunE: func(cmd *cobra.Command, args []string) error {
27+
rawURL := os.Getenv("CODER_URL")
28+
if rawURL == "" {
29+
return xerrors.New("CODER_URL must be set!")
30+
}
31+
token := os.Getenv("CODER_TOKEN")
32+
if token == "" {
33+
return xerrors.New("CODER_TOKEN must be set!")
34+
}
35+
if port == 0 {
36+
return xerrors.Errorf("port must be specified!")
37+
}
38+
listener, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port))
39+
if err != nil {
40+
return xerrors.Errorf("listen: %w", err)
41+
}
42+
defer listener.Close()
43+
url, err := url.Parse(rawURL)
44+
if err != nil {
45+
return err
46+
}
47+
agentID, err := uuid.Parse(args[0])
48+
if err != nil {
49+
return err
50+
}
51+
client := codersdk.New(url)
52+
client.SetSessionToken(token)
53+
54+
handler, closer, err := vscodeipc.New(cmd.Context(), client, agentID, nil)
55+
if err != nil {
56+
return err
57+
}
58+
defer closer.Close()
59+
server := http.Server{
60+
Handler: handler,
61+
}
62+
cmd.Printf("Ready\n")
63+
return server.Serve(listener)
64+
},
65+
}
66+
cmd.Flags().Uint16VarP(&port, "port", "p", 0, "The port to listen on!")
67+
return cmd
68+
}

0 commit comments

Comments
 (0)