Skip to content

Commit 731d179

Browse files
committed
Merge branch 'main' into bq/aks-missing-parameters-on-update
2 parents 022e400 + 813b549 commit 731d179

File tree

92 files changed

+3506
-1364
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+3506
-1364
lines changed

.github/pull_request_template.md

Lines changed: 0 additions & 3 deletions
This file was deleted.

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -512,7 +512,7 @@ jobs:
512512
- name: Install node_modules
513513
run: ./scripts/yarn_install.sh
514514

515-
- run: yarn test:ci
515+
- run: yarn test:ci --max-workers ${{ steps.cpu-cores.outputs.count }}
516516
working-directory: site
517517

518518
- uses: codecov/codecov-action@v3

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,11 @@ site/test-results/*
2727
site/e2e/test-results/*
2828
site/e2e/states/*.json
2929
site/playwright-report/*
30+
site/.swc
3031

3132
# Make target for updating golden files.
3233
cli/testdata/.gen-golden
34+
helm/tests/testdata/.gen-golden
3335

3436
# Build
3537
/build/

.prettierignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ site/test-results/*
3030
site/e2e/test-results/*
3131
site/e2e/states/*.json
3232
site/playwright-report/*
33+
site/.swc
3334

3435
# Make target for updating golden files.
3536
cli/testdata/.gen-golden
37+
helm/tests/testdata/.gen-golden
3638

3739
# Build
3840
/build/

Makefile

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -516,13 +516,17 @@ coderd/apidoc/swagger.json: $(shell find ./scripts/apidocgen $(FIND_EXCLUSIONS)
516516
./scripts/apidocgen/generate.sh
517517
yarn run --cwd=site format:write:only ../docs/api ../docs/manifest.json ../coderd/apidoc/swagger.json
518518

519-
update-golden-files: cli/testdata/.gen-golden
519+
update-golden-files: cli/testdata/.gen-golden helm/tests/testdata/.gen-golden
520520
.PHONY: update-golden-files
521521

522522
cli/testdata/.gen-golden: $(wildcard cli/testdata/*.golden) $(GO_SRC_FILES)
523523
go test ./cli -run=TestCommandHelp -update
524524
touch "$@"
525525

526+
helm/tests/testdata/.gen-golden: $(wildcard helm/tests/testdata/*.golden) $(GO_SRC_FILES)
527+
go test ./helm/tests -run=TestUpdateGoldenFiles -update
528+
touch "$@"
529+
526530
# Generate a prettierrc for the site package that uses relative paths for
527531
# overrides. This allows us to share the same prettier config between the
528532
# site and the root of the repo.

agent/agent.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ type Options struct {
7777
ReconnectingPTYTimeout time.Duration
7878
EnvironmentVariables map[string]string
7979
Logger slog.Logger
80+
AgentPorts map[int]string
8081
}
8182

8283
type Client interface {
@@ -123,6 +124,7 @@ func New(options Options) io.Closer {
123124
tempDir: options.TempDir,
124125
lifecycleUpdate: make(chan struct{}, 1),
125126
lifecycleReported: make(chan codersdk.WorkspaceAgentLifecycle, 1),
127+
ignorePorts: options.AgentPorts,
126128
connStatsChan: make(chan *agentsdk.Stats, 1),
127129
}
128130
a.init(ctx)
@@ -136,6 +138,10 @@ type agent struct {
136138
filesystem afero.Fs
137139
logDir string
138140
tempDir string
141+
// ignorePorts tells the api handler which ports to ignore when
142+
// listing all listening ports. This is helpful to hide ports that
143+
// are used by the agent, that the user does not care about.
144+
ignorePorts map[int]string
139145

140146
reconnectingPTYs sync.Map
141147
reconnectingPTYTimeout time.Duration

agent/api.go

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,32 @@ import (
1111
"github.com/coder/coder/codersdk"
1212
)
1313

14-
func (*agent) apiHandler() http.Handler {
14+
func (a *agent) apiHandler() http.Handler {
1515
r := chi.NewRouter()
1616
r.Get("/", func(rw http.ResponseWriter, r *http.Request) {
1717
httpapi.Write(r.Context(), rw, http.StatusOK, codersdk.Response{
1818
Message: "Hello from the agent!",
1919
})
2020
})
2121

22-
lp := &listeningPortsHandler{}
22+
// Make a copy to ensure the map is not modified after the handler is
23+
// created.
24+
cpy := make(map[int]string)
25+
for k, b := range a.ignorePorts {
26+
cpy[k] = b
27+
}
28+
29+
lp := &listeningPortsHandler{ignorePorts: cpy}
2330
r.Get("/api/v0/listening-ports", lp.handler)
2431

2532
return r
2633
}
2734

2835
type listeningPortsHandler struct {
29-
mut sync.Mutex
30-
ports []codersdk.WorkspaceAgentListeningPort
31-
mtime time.Time
36+
mut sync.Mutex
37+
ports []codersdk.WorkspaceAgentListeningPort
38+
mtime time.Time
39+
ignorePorts map[int]string
3240
}
3341

3442
// handler returns a list of listening ports. This is tested by coderd's

agent/ports_supported.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,11 @@ func (lp *listeningPortsHandler) getListeningPorts() ([]codersdk.WorkspaceAgentL
3636
continue
3737
}
3838

39+
// Ignore ports that we've been told to ignore.
40+
if _, ok := lp.ignorePorts[int(tab.LocalAddr.Port)]; ok {
41+
continue
42+
}
43+
3944
// Don't include ports that we've already seen. This can happen on
4045
// Windows, and maybe on Linux if you're using a shared listener socket.
4146
if _, ok := seen[tab.LocalAddr.Port]; ok {

cli/agent.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"os/signal"
1212
"path/filepath"
1313
"runtime"
14+
"strconv"
1415
"sync"
1516
"time"
1617

@@ -51,6 +52,7 @@ func workspaceAgent() *cobra.Command {
5152
if err != nil {
5253
return xerrors.Errorf("parse %q: %w", rawURL, err)
5354
}
55+
agentPorts := map[int]string{}
5456

5557
isLinux := runtime.GOOS == "linux"
5658

@@ -122,6 +124,10 @@ func workspaceAgent() *cobra.Command {
122124
_ = pprof.Handler
123125
pprofSrvClose := serveHandler(ctx, logger, nil, pprofAddress, "pprof")
124126
defer pprofSrvClose()
127+
// Do a best effort here. If this fails, it's not a big deal.
128+
if port, err := urlPort(pprofAddress); err == nil {
129+
agentPorts[port] = "pprof"
130+
}
125131

126132
// exchangeToken returns a session token.
127133
// This is abstracted to allow for the same looping condition
@@ -202,6 +208,7 @@ func workspaceAgent() *cobra.Command {
202208
EnvironmentVariables: map[string]string{
203209
"GIT_ASKPASS": executablePath,
204210
},
211+
AgentPorts: agentPorts,
205212
})
206213
<-ctx.Done()
207214
return closer.Close()
@@ -264,3 +271,35 @@ func (c *closeWriter) Write(p []byte) (int, error) {
264271
}
265272
return c.w.Write(p)
266273
}
274+
275+
// extractPort handles different url strings.
276+
// - localhost:6060
277+
// - http://localhost:6060
278+
func extractPort(u string) (int, error) {
279+
port, firstError := urlPort(u)
280+
if firstError == nil {
281+
return port, nil
282+
}
283+
284+
// Try with a scheme
285+
port, err := urlPort("http://" + u)
286+
if err == nil {
287+
return port, nil
288+
}
289+
return -1, xerrors.Errorf("invalid url %q: %w", u, firstError)
290+
}
291+
292+
// urlPort extracts the port from a valid URL.
293+
func urlPort(u string) (int, error) {
294+
parsed, err := url.Parse(u)
295+
if err != nil {
296+
return -1, xerrors.Errorf("invalid url %q: %w", u, err)
297+
}
298+
if parsed.Port() != "" {
299+
port, err := strconv.ParseInt(parsed.Port(), 10, 64)
300+
if err == nil && port > 0 {
301+
return int(port), nil
302+
}
303+
}
304+
return -1, xerrors.Errorf("invalid port: %s", u)
305+
}

cli/agent_internal_test.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func Test_extractPort(t *testing.T) {
11+
t.Parallel()
12+
13+
tests := []struct {
14+
name string
15+
urlString string
16+
want int
17+
wantErr bool
18+
}{
19+
{
20+
name: "Empty",
21+
urlString: "",
22+
wantErr: true,
23+
},
24+
{
25+
name: "NoScheme",
26+
urlString: "localhost:6060",
27+
want: 6060,
28+
},
29+
{
30+
name: "WithScheme",
31+
urlString: "http://localhost:6060",
32+
want: 6060,
33+
},
34+
{
35+
name: "NoPort",
36+
urlString: "http://localhost",
37+
wantErr: true,
38+
},
39+
{
40+
name: "NoPortNoScheme",
41+
urlString: "localhost",
42+
wantErr: true,
43+
},
44+
{
45+
name: "OnlyPort",
46+
urlString: "6060",
47+
wantErr: true,
48+
},
49+
}
50+
for _, tt := range tests {
51+
tt := tt
52+
t.Run(tt.name, func(t *testing.T) {
53+
t.Parallel()
54+
got, err := extractPort(tt.urlString)
55+
if tt.wantErr {
56+
require.Error(t, err, fmt.Sprintf("extractPort(%v)", tt.urlString))
57+
} else {
58+
require.NoError(t, err, fmt.Sprintf("extractPort(%v)", tt.urlString))
59+
require.Equal(t, tt.want, got, fmt.Sprintf("extractPort(%v)", tt.urlString))
60+
}
61+
})
62+
}
63+
}

cli/clibase/clibase.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,9 @@
55
// We will extend its usage to the rest of our application, completely replacing
66
// cobra/viper. It's also a candidate to be broken out into its own open-source
77
// library, so we avoid deep coupling with Coder concepts.
8+
//
9+
// The Command interface is loosely based on the chi middleware pattern and
10+
// http.Handler/HandlerFunc.
811
package clibase
912

1013
import (

0 commit comments

Comments
 (0)