Skip to content

Commit 19c8a80

Browse files
committed
Merge remote-tracking branch 'origin/main' into cj/coder-stat
2 parents 9a82882 + f61001d commit 19c8a80

File tree

263 files changed

+7213
-5546
lines changed

Some content is hidden

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

263 files changed

+7213
-5546
lines changed

.vscode/settings.json

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,5 @@
212212
// We often use a version of TypeScript that's ahead of the version shipped
213213
// with VS Code.
214214
"typescript.tsdk": "./site/node_modules/typescript/lib",
215-
"grammarly.selectors": [
216-
{
217-
"language": "markdown",
218-
"scheme": "file",
219-
"pattern": "docs/contributing/frontend.md"
220-
}
221-
]
215+
"prettier.prettierPath": "./node_modules/prettier"
222216
}

Makefile

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,9 @@ endif
5252
FIND_EXCLUSIONS= \
5353
-not \( \( -path '*/.git/*' -o -path './build/*' -o -path './vendor/*' -o -path './.coderv2/*' -o -path '*/node_modules/*' -o -path './site/out/*' -o -path './coderd/apidoc/*' \) -prune \)
5454
# Source files used for make targets, evaluated on use.
55-
GO_SRC_FILES = $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.go')
55+
GO_SRC_FILES := $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.go')
5656
# All the shell files in the repo, excluding ignored files.
57-
SHELL_SRC_FILES = $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.sh')
57+
SHELL_SRC_FILES := $(shell find . $(FIND_EXCLUSIONS) -type f -name '*.sh')
5858

5959
# All ${OS}_${ARCH} combos we build for. Windows binaries have the .exe suffix.
6060
OS_ARCHES := \
@@ -431,7 +431,7 @@ lint/helm:
431431
gen: \
432432
coderd/database/dump.sql \
433433
coderd/database/querier.go \
434-
coderd/database/dbmock/store.go \
434+
coderd/database/dbmock/dbmock.go \
435435
provisionersdk/proto/provisioner.pb.go \
436436
provisionerd/proto/provisionerd.pb.go \
437437
site/src/api/typesGenerated.ts \
@@ -453,7 +453,7 @@ gen/mark-fresh:
453453
files="\
454454
coderd/database/dump.sql \
455455
coderd/database/querier.go \
456-
coderd/database/dbmock/store.go \
456+
coderd/database/dbmock/dbmock.go \
457457
provisionersdk/proto/provisioner.pb.go \
458458
provisionerd/proto/provisionerd.pb.go \
459459
site/src/api/typesGenerated.ts \
@@ -490,7 +490,7 @@ coderd/database/querier.go: coderd/database/sqlc.yaml coderd/database/dump.sql $
490490
./coderd/database/generate.sh
491491

492492

493-
coderd/database/dbmock/store.go: coderd/database/db.go coderd/database/querier.go
493+
coderd/database/dbmock/dbmock.go: coderd/database/db.go coderd/database/querier.go
494494
go generate ./coderd/database/dbmock/
495495

496496
provisionersdk/proto/provisioner.pb.go: provisionersdk/proto/provisioner.proto

agent/agentssh/agentssh.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,9 +648,11 @@ func (s *Server) trackSession(ss ssh.Session, add bool) (ok bool) {
648648
// Server closed.
649649
return false
650650
}
651+
s.wg.Add(1)
651652
s.sessions[ss] = struct{}{}
652653
return true
653654
}
655+
s.wg.Done()
654656
delete(s.sessions, ss)
655657
return true
656658
}

cli/root.go

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,13 @@ import (
2121
"text/tabwriter"
2222
"time"
2323

24-
"golang.org/x/exp/slices"
25-
"golang.org/x/xerrors"
26-
27-
"cdr.dev/slog"
28-
2924
"github.com/charmbracelet/lipgloss"
30-
"github.com/gobwas/httphead"
3125
"github.com/mattn/go-isatty"
3226
"github.com/mitchellh/go-wordwrap"
27+
"golang.org/x/exp/slices"
28+
"golang.org/x/xerrors"
3329

30+
"cdr.dev/slog"
3431
"github.com/coder/coder/buildinfo"
3532
"github.com/coder/coder/cli/clibase"
3633
"github.com/coder/coder/cli/cliui"
@@ -431,6 +428,15 @@ type RootCmd struct {
431428
}
432429

433430
func addTelemetryHeader(client *codersdk.Client, inv *clibase.Invocation) {
431+
transport, ok := client.HTTPClient.Transport.(*headerTransport)
432+
if !ok {
433+
transport = &headerTransport{
434+
transport: client.HTTPClient.Transport,
435+
header: http.Header{},
436+
}
437+
client.HTTPClient.Transport = transport
438+
}
439+
434440
var topts []telemetry.CLIOption
435441
for _, opt := range inv.Command.FullOptions() {
436442
if opt.ValueSource == clibase.ValueSourceNone || opt.ValueSource == clibase.ValueSourceDefault {
@@ -460,10 +466,7 @@ func addTelemetryHeader(client *codersdk.Client, inv *clibase.Invocation) {
460466
return
461467
}
462468

463-
client.ExtraHeaders.Set(
464-
codersdk.CLITelemetryHeader,
465-
s,
466-
)
469+
transport.header.Add(codersdk.CLITelemetryHeader, s)
467470
}
468471

469472
// InitClient sets client to a new client.
@@ -561,18 +564,17 @@ func (r *RootCmd) setClient(client *codersdk.Client, serverURL *url.URL) error {
561564
transport: http.DefaultTransport,
562565
header: http.Header{},
563566
}
567+
for _, header := range r.header {
568+
parts := strings.SplitN(header, "=", 2)
569+
if len(parts) < 2 {
570+
return xerrors.Errorf("split header %q had less than two parts", header)
571+
}
572+
transport.header.Add(parts[0], parts[1])
573+
}
564574
client.URL = serverURL
565575
client.HTTPClient = &http.Client{
566576
Transport: transport,
567577
}
568-
client.ExtraHeaders = make(http.Header)
569-
for _, hd := range r.header {
570-
k, v, ok := httphead.ParseHeaderLine([]byte(hd))
571-
if !ok {
572-
return xerrors.Errorf("invalid header: %s", hd)
573-
}
574-
client.ExtraHeaders.Add(string(k), string(v))
575-
}
576578
return nil
577579
}
578580

cli/root_test.go

Lines changed: 108 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ package cli_test
22

33
import (
44
"bytes"
5+
"fmt"
56
"net/http"
67
"net/http/httptest"
8+
"strings"
9+
"sync/atomic"
710
"testing"
811

912
"github.com/coder/coder/cli/clibase"
13+
"github.com/coder/coder/coderd"
14+
"github.com/coder/coder/coderd/coderdtest"
15+
"github.com/coder/coder/codersdk"
16+
"github.com/coder/coder/pty/ptytest"
17+
"github.com/coder/coder/testutil"
1018

1119
"github.com/stretchr/testify/assert"
1220
"github.com/stretchr/testify/require"
@@ -64,21 +72,112 @@ func TestRoot(t *testing.T) {
6472
t.Run("Header", func(t *testing.T) {
6573
t.Parallel()
6674

67-
done := make(chan struct{})
75+
var called int64
6876
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
77+
atomic.AddInt64(&called, 1)
6978
assert.Equal(t, "wow", r.Header.Get("X-Testing"))
79+
assert.Equal(t, "Dean was Here!", r.Header.Get("Cool-Header"))
7080
w.WriteHeader(http.StatusGone)
71-
select {
72-
case <-done:
73-
close(done)
74-
default:
75-
}
7681
}))
7782
defer srv.Close()
7883
buf := new(bytes.Buffer)
79-
inv, _ := clitest.New(t, "--header", "X-Testing=wow", "login", srv.URL)
84+
inv, _ := clitest.New(t,
85+
"--no-feature-warning",
86+
"--no-version-warning",
87+
"--header", "X-Testing=wow",
88+
"--header", "Cool-Header=Dean was Here!",
89+
"login", srv.URL,
90+
)
8091
inv.Stdout = buf
81-
// This won't succeed, because we're using the login cmd to assert requests.
82-
_ = inv.Run()
92+
93+
err := inv.Run()
94+
require.Error(t, err)
95+
require.ErrorContains(t, err, "unexpected status code 410")
96+
require.EqualValues(t, 1, atomic.LoadInt64(&called), "called exactly once")
97+
})
98+
}
99+
100+
// TestDERPHeaders ensures that the client sends the global `--header`s to the
101+
// DERP server when connecting.
102+
func TestDERPHeaders(t *testing.T) {
103+
t.Parallel()
104+
105+
// Create a coderd API instance the hard way since we need to change the
106+
// handler to inject our custom /derp handler.
107+
setHandler, cancelFunc, serverURL, newOptions := coderdtest.NewOptions(t, nil)
108+
109+
// We set the handler after server creation for the access URL.
110+
coderAPI := coderd.New(newOptions)
111+
setHandler(coderAPI.RootHandler)
112+
provisionerCloser := coderdtest.NewProvisionerDaemon(t, coderAPI)
113+
t.Cleanup(func() {
114+
_ = provisionerCloser.Close()
115+
})
116+
client := codersdk.New(serverURL)
117+
t.Cleanup(func() {
118+
cancelFunc()
119+
_ = provisionerCloser.Close()
120+
_ = coderAPI.Close()
121+
client.HTTPClient.CloseIdleConnections()
122+
})
123+
124+
var (
125+
user = coderdtest.CreateFirstUser(t, client)
126+
workspace = runAgent(t, client, user.UserID)
127+
)
128+
129+
// Inject custom /derp handler so we can inspect the headers.
130+
var (
131+
expectedHeaders = map[string]string{
132+
"X-Test-Header": "test-value",
133+
"Cool-Header": "Dean was Here!",
134+
}
135+
derpCalled int64
136+
)
137+
setHandler(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
138+
if strings.HasPrefix(r.URL.Path, "/derp") {
139+
ok := true
140+
for k, v := range expectedHeaders {
141+
if r.Header.Get(k) != v {
142+
ok = false
143+
break
144+
}
145+
}
146+
if ok {
147+
// Only increment if all the headers are set, because the agent
148+
// calls derp also.
149+
atomic.AddInt64(&derpCalled, 1)
150+
}
151+
}
152+
153+
coderAPI.RootHandler.ServeHTTP(w, r)
154+
}))
155+
156+
// Connect with the headers set as args.
157+
args := []string{
158+
"--no-feature-warning",
159+
"--no-version-warning",
160+
"ping", workspace.Name,
161+
"-n", "1",
162+
}
163+
for k, v := range expectedHeaders {
164+
args = append(args, "--header", fmt.Sprintf("%s=%s", k, v))
165+
}
166+
inv, root := clitest.New(t, args...)
167+
clitest.SetupConfig(t, client, root)
168+
pty := ptytest.New(t)
169+
inv.Stdin = pty.Input()
170+
inv.Stderr = pty.Output()
171+
inv.Stdout = pty.Output()
172+
173+
ctx := testutil.Context(t, testutil.WaitLong)
174+
cmdDone := tGo(t, func() {
175+
err := inv.WithContext(ctx).Run()
176+
assert.NoError(t, err)
83177
})
178+
179+
pty.ExpectMatch("pong from " + workspace.Name)
180+
<-cmdDone
181+
182+
require.Greater(t, atomic.LoadInt64(&derpCalled), int64(0), "expected /derp to be called at least once")
84183
}

cli/scaletest.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -902,10 +902,10 @@ func (r *RootCmd) scaletestWorkspaceTraffic() *clibase.Cmd {
902902
_, _ = fmt.Fprintln(inv.Stderr, "\nUploading traces...")
903903
if err := closeTracing(ctx); err != nil {
904904
_, _ = fmt.Fprintf(inv.Stderr, "\nError uploading traces: %+v\n", err)
905-
// Wait for prometheus metrics to be scraped
906-
_, _ = fmt.Fprintf(inv.Stderr, "Waiting %s for prometheus metrics to be scraped\n", scaletestPrometheusWait)
907-
<-time.After(scaletestPrometheusWait)
908905
}
906+
// Wait for prometheus metrics to be scraped
907+
_, _ = fmt.Fprintf(inv.Stderr, "Waiting %s for prometheus metrics to be scraped\n", scaletestPrometheusWait)
908+
<-time.After(scaletestPrometheusWait)
909909
}()
910910
tracer := tracerProvider.Tracer(scaletestTracerName)
911911

cli/server.go

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ import (
6868
"github.com/coder/coder/coderd/database/dbmetrics"
6969
"github.com/coder/coder/coderd/database/dbpurge"
7070
"github.com/coder/coder/coderd/database/migrations"
71+
"github.com/coder/coder/coderd/database/pubsub"
7172
"github.com/coder/coder/coderd/devtunnel"
7273
"github.com/coder/coder/coderd/gitauth"
7374
"github.com/coder/coder/coderd/gitsshkey"
@@ -463,7 +464,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
463464
Logger: logger.Named("coderd"),
464465
Database: dbfake.New(),
465466
DERPMap: derpMap,
466-
Pubsub: database.NewPubsubInMemory(),
467+
Pubsub: pubsub.NewInMemory(),
467468
CacheDir: cacheDir,
468469
GoogleTokenValidator: googleTokenValidator,
469470
GitAuthConfigs: gitAuthConfigs,
@@ -588,8 +589,8 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
588589

589590
if cfg.InMemoryDatabase {
590591
// This is only used for testing.
591-
options.Database = dbmetrics.New(dbfake.New(), options.PrometheusRegistry)
592-
options.Pubsub = database.NewPubsubInMemory()
592+
options.Database = dbfake.New()
593+
options.Pubsub = pubsub.NewInMemory()
593594
} else {
594595
sqlDB, err := connectToPostgres(ctx, logger, sqlDriver, cfg.PostgresURL.String())
595596
if err != nil {
@@ -599,14 +600,18 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
599600
_ = sqlDB.Close()
600601
}()
601602

602-
options.Database = dbmetrics.New(database.New(sqlDB), options.PrometheusRegistry)
603-
options.Pubsub, err = database.NewPubsub(ctx, sqlDB, cfg.PostgresURL.String())
603+
options.Database = database.New(sqlDB)
604+
options.Pubsub, err = pubsub.New(ctx, sqlDB, cfg.PostgresURL.String())
604605
if err != nil {
605606
return xerrors.Errorf("create pubsub: %w", err)
606607
}
607608
defer options.Pubsub.Close()
608609
}
609610

611+
if options.DeploymentValues.Prometheus.Enable && options.DeploymentValues.Prometheus.CollectDBMetrics {
612+
options.Database = dbmetrics.New(options.Database, options.PrometheusRegistry)
613+
}
614+
610615
var deploymentID string
611616
err = options.Database.InTx(func(tx database.Store) error {
612617
// This will block until the lock is acquired, and will be

0 commit comments

Comments
 (0)