Skip to content

Commit bf418dc

Browse files
committed
Merge branch 'main' into colin/healthcheck
2 parents 7ef0217 + 47afafa commit bf418dc

23 files changed

+238
-182
lines changed

.github/workflows/ci.yaml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,13 @@ jobs:
3535
uses: actions/checkout@v3
3636

3737
# Install Go!
38-
- uses: actions/setup-go@v3
38+
- uses: actions/setup-go@v4
3939
with:
4040
go-version: "~1.20"
4141

4242
# Check for any typos!
4343
- name: Check for typos
44-
uses: crate-ci/typos@v1.13.14
44+
uses: crate-ci/typos@v1.14.3
4545
with:
4646
config: .github/workflows/typos.toml
4747
- name: Fix the typos
@@ -150,7 +150,7 @@ jobs:
150150
- name: Install node_modules
151151
run: ./scripts/yarn_install.sh
152152

153-
- uses: actions/setup-go@v3
153+
- uses: actions/setup-go@v4
154154
with:
155155
go-version: "~1.20"
156156

@@ -250,7 +250,7 @@ jobs:
250250
steps:
251251
- uses: actions/checkout@v3
252252

253-
- uses: actions/setup-go@v3
253+
- uses: actions/setup-go@v4
254254
with:
255255
go-version: "~1.20"
256256

@@ -273,7 +273,7 @@ jobs:
273273
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
274274

275275
- name: Install gotestsum
276-
uses: jaxxstorm/action-install-gh-release@v1.9.0
276+
uses: jaxxstorm/action-install-gh-release@v1.10.0
277277
env:
278278
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
279279
with:
@@ -330,7 +330,7 @@ jobs:
330330
steps:
331331
- uses: actions/checkout@v3
332332

333-
- uses: actions/setup-go@v3
333+
- uses: actions/setup-go@v4
334334
with:
335335
go-version: "~1.20"
336336

@@ -353,7 +353,7 @@ jobs:
353353
key: ${{ runner.os }}-go-mod-${{ hashFiles('**/go.sum') }}
354354

355355
- name: Install gotestsum
356-
uses: jaxxstorm/action-install-gh-release@v1.9.0
356+
uses: jaxxstorm/action-install-gh-release@v1.10.0
357357
env:
358358
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
359359
with:
@@ -413,7 +413,7 @@ jobs:
413413
- name: Set up Google Cloud SDK
414414
uses: google-github-actions/setup-gcloud@v1
415415

416-
- uses: actions/setup-go@v3
416+
- uses: actions/setup-go@v4
417417
with:
418418
go-version: "~1.20"
419419

@@ -542,7 +542,7 @@ jobs:
542542
.eslintcache
543543
key: js-${{ runner.os }}-e2e-${{ hashFiles('**/yarn.lock') }}
544544

545-
- uses: actions/setup-go@v3
545+
- uses: actions/setup-go@v4
546546
with:
547547
go-version: "~1.20"
548548

.github/workflows/release.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ jobs:
9090
username: ${{ github.actor }}
9191
password: ${{ secrets.GITHUB_TOKEN }}
9292

93-
- uses: actions/setup-go@v3
93+
- uses: actions/setup-go@v4
9494
with:
9595
go-version: "~1.20"
9696

.github/workflows/security.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ jobs:
3030
languages: go, javascript
3131

3232
- name: Setup Go
33-
uses: actions/setup-go@v3
33+
uses: actions/setup-go@v4
3434
with:
3535
go-version: "~1.20"
3636

@@ -71,7 +71,7 @@ jobs:
7171
with:
7272
fetch-depth: 0
7373

74-
- uses: actions/setup-go@v3
74+
- uses: actions/setup-go@v4
7575
with:
7676
go-version: "~1.20"
7777

@@ -137,7 +137,7 @@ jobs:
137137
echo "image=$(cat "$image_job")" >> $GITHUB_OUTPUT
138138
139139
- name: Run Trivy vulnerability scanner
140-
uses: aquasecurity/trivy-action@8bd2f9fbda2109502356ff8a6a89da55b1ead252
140+
uses: aquasecurity/trivy-action@1f0aa582c8c8f5f7639610d6d38baddfea4fdcee
141141
with:
142142
image-ref: ${{ steps.build.outputs.image }}
143143
format: sarif

.github/workflows/stale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ jobs:
1111
issues: write
1212
pull-requests: write
1313
steps:
14-
- uses: actions/stale@v7.0.0
14+
- uses: actions/stale@v8.0.0
1515
with:
1616
stale-issue-label: "stale"
1717
stale-pr-label: "stale"

agent/agent.go

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"go.uber.org/atomic"
3636
gossh "golang.org/x/crypto/ssh"
3737
"golang.org/x/exp/slices"
38-
"golang.org/x/sync/singleflight"
3938
"golang.org/x/xerrors"
4039
"tailscale.com/net/speedtest"
4140
"tailscale.com/tailcfg"
@@ -264,6 +263,21 @@ type metadataResultAndKey struct {
264263
key string
265264
}
266265

266+
type trySingleflight struct {
267+
m sync.Map
268+
}
269+
270+
func (t *trySingleflight) Do(key string, fn func()) {
271+
_, loaded := t.m.LoadOrStore(key, struct{}{})
272+
if !loaded {
273+
// There is already a goroutine running for this key.
274+
return
275+
}
276+
277+
defer t.m.Delete(key)
278+
fn()
279+
}
280+
267281
func (a *agent) reportMetadataLoop(ctx context.Context) {
268282
baseInterval := adjustIntervalForTests(1)
269283

@@ -276,7 +290,11 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
276290
)
277291
defer baseTicker.Stop()
278292

279-
var flight singleflight.Group
293+
// We use a custom singleflight that immediately returns if there is already
294+
// a goroutine running for a given key. This is to prevent a build-up of
295+
// goroutines waiting on Do when the script takes many multiples of
296+
// baseInterval to run.
297+
var flight trySingleflight
280298

281299
for {
282300
select {
@@ -348,7 +366,7 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
348366
// We send the result to the channel in the goroutine to avoid
349367
// sending the same result multiple times. So, we don't care about
350368
// the return values.
351-
flight.DoChan(md.Key, func() (interface{}, error) {
369+
go flight.Do(md.Key, func() {
352370
timeout := md.Timeout
353371
if timeout == 0 {
354372
timeout = md.Interval
@@ -360,13 +378,11 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
360378

361379
select {
362380
case <-ctx.Done():
363-
return 0, nil
364381
case metadataResults <- metadataResultAndKey{
365382
key: md.Key,
366383
result: a.collectMetadata(ctx, md),
367384
}:
368385
}
369-
return 0, nil
370386
})
371387
}
372388
}

coderd/tracing/exporter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import (
1212
"go.opentelemetry.io/otel/propagation"
1313
"go.opentelemetry.io/otel/sdk/resource"
1414
sdktrace "go.opentelemetry.io/otel/sdk/trace"
15-
semconv "go.opentelemetry.io/otel/semconv/v1.11.0"
15+
semconv "go.opentelemetry.io/otel/semconv/v1.14.0"
1616
"golang.org/x/xerrors"
1717
"google.golang.org/grpc/credentials"
1818
)

coderd/tracing/httpmw.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88
"github.com/go-chi/chi/v5"
99
"go.opentelemetry.io/otel"
1010
"go.opentelemetry.io/otel/propagation"
11-
semconv "go.opentelemetry.io/otel/semconv/v1.11.0"
11+
semconv "go.opentelemetry.io/otel/semconv/v1.14.0"
12+
"go.opentelemetry.io/otel/semconv/v1.14.0/httpconv"
13+
"go.opentelemetry.io/otel/semconv/v1.14.0/netconv"
1214
"go.opentelemetry.io/otel/trace"
1315

1416
"github.com/coder/coder/coderd/httpmw/patternmatcher"
@@ -78,17 +80,16 @@ func EndHTTPSpan(r *http.Request, status int, span trace.Span) {
7880
// set the resource name as we get it only once the handler is executed
7981
route := chi.RouteContext(r.Context()).RoutePattern()
8082
span.SetName(fmt.Sprintf("%s %s", r.Method, route))
81-
span.SetAttributes(semconv.NetAttributesFromHTTPRequest("tcp", r)...)
82-
span.SetAttributes(semconv.EndUserAttributesFromHTTPRequest(r)...)
83-
span.SetAttributes(semconv.HTTPServerAttributesFromHTTPRequest("", route, r)...)
83+
span.SetAttributes(netconv.Transport("tcp"))
84+
span.SetAttributes(httpconv.ServerRequest("coderd", r)...)
8485
span.SetAttributes(semconv.HTTPRouteKey.String(route))
8586

8687
// 0 status means one has not yet been sent in which case net/http library will write StatusOK
8788
if status == 0 {
8889
status = http.StatusOK
8990
}
9091
span.SetAttributes(semconv.HTTPStatusCodeKey.Int(status))
91-
span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(status, trace.SpanKindServer))
92+
span.SetStatus(httpconv.ServerStatus(status))
9293

9394
// finally end span
9495
span.End()

coderd/tracing/postgres.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"strings"
77

88
"go.nhat.io/otelsql"
9-
semconv "go.opentelemetry.io/otel/semconv/v1.11.0"
9+
semconv "go.opentelemetry.io/otel/semconv/v1.14.0"
1010
"go.opentelemetry.io/otel/trace"
1111
"golang.org/x/xerrors"
1212
)

coderd/workspaceagents.go

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"database/sql"
77
"encoding/json"
88
"errors"
9+
"flag"
910
"fmt"
1011
"net"
1112
"net/http"
@@ -18,6 +19,7 @@ import (
1819
"sync/atomic"
1920
"time"
2021

22+
"github.com/bep/debounce"
2123
"github.com/go-chi/chi/v5"
2224
"github.com/google/uuid"
2325
"go.opentelemetry.io/otel/trace"
@@ -1484,9 +1486,18 @@ func (api *API) watchWorkspaceAgentMetadata(rw http.ResponseWriter, r *http.Requ
14841486
// Send initial metadata.
14851487
sendMetadata(true)
14861488

1489+
// We debounce metadata updates to avoid overloading the frontend when
1490+
// an agent is sending a lot of updates.
1491+
pubsubDebounce := debounce.New(time.Second)
1492+
if flag.Lookup("test.v") != nil {
1493+
pubsubDebounce = debounce.New(time.Millisecond * 100)
1494+
}
1495+
14871496
// Send metadata on updates.
14881497
cancelSub, err := api.Pubsub.Subscribe(watchWorkspaceAgentMetadataChannel(workspaceAgent.ID), func(_ context.Context, _ []byte) {
1489-
sendMetadata(true)
1498+
pubsubDebounce(func() {
1499+
sendMetadata(true)
1500+
})
14901501
})
14911502
if err != nil {
14921503
httpapi.InternalServerError(rw, err)

coderd/workspaceagents_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ func TestWorkspaceAgent_Metadata(t *testing.T) {
13551355
check := func(want codersdk.WorkspaceAgentMetadataResult, got codersdk.WorkspaceAgentMetadata) {
13561356
require.WithinDuration(t, want.CollectedAt, got.Result.CollectedAt, time.Second)
13571357
require.WithinDuration(
1358-
t, time.Now(), got.Result.CollectedAt.Add(time.Duration(got.Result.Age)*time.Second), time.Millisecond*500,
1358+
t, time.Now(), got.Result.CollectedAt.Add(time.Duration(got.Result.Age)*time.Second), time.Second,
13591359
)
13601360
require.Equal(t, want.Value, got.Result.Value)
13611361
require.Equal(t, want.Error, got.Result.Error)

codersdk/client.go

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ import (
1616

1717
"go.opentelemetry.io/otel"
1818
"go.opentelemetry.io/otel/propagation"
19-
semconv "go.opentelemetry.io/otel/semconv/v1.11.0"
20-
"go.opentelemetry.io/otel/trace"
19+
"go.opentelemetry.io/otel/semconv/v1.14.0/httpconv"
2120
"golang.org/x/xerrors"
2221

2322
"github.com/coder/coder/coderd/tracing"
@@ -159,8 +158,7 @@ func (c *Client) Request(ctx context.Context, method, path string, body interfac
159158
opt(req)
160159
}
161160

162-
span.SetAttributes(semconv.NetAttributesFromHTTPRequest("tcp", req)...)
163-
span.SetAttributes(semconv.HTTPClientAttributesFromHTTPRequest(req)...)
161+
span.SetAttributes(httpconv.ClientRequest(req)...)
164162

165163
// Inject tracing headers if enabled.
166164
if c.Trace {
@@ -184,8 +182,7 @@ func (c *Client) Request(ctx context.Context, method, path string, body interfac
184182
return nil, err
185183
}
186184

187-
span.SetAttributes(semconv.HTTPStatusCodeKey.Int(resp.StatusCode))
188-
span.SetStatus(semconv.SpanStatusFromHTTPStatusCodeAndSpanKind(resp.StatusCode, trace.SpanKindClient))
185+
span.SetAttributes(httpconv.ClientResponse(resp)...)
189186

190187
// Copy the response body so we can log it if it's a loggable mime type.
191188
var respBody []byte

docs/quickstart/docker.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ Coder with Docker has the following advantages:
66
- Workspace images are easily configured
77
- Workspaces share resources for burst operations
88

9+
> Note that the below steps are only supported on a Linux distribution.
10+
> If on macOS, please [run Coder via the standalone binary](./binary.md).
11+
912
## Requirements
1013

11-
- A single macOS or Linux box
14+
- A Linux machine
1215
- A running Docker daemon
1316

1417
## Instructions

docs/templates/agent-metadata.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,17 @@ Agent metadata is in an alpha state and may break or disappear at any time.
66

77
![agent-metadata](../images/agent-metadata.png)
88

9-
With Agent Metadata, template admin can expose operational metrics from
10-
their workspaces to their users. It is a sibling of [Resource Metadata](./resource-metadata.md).
9+
With Agent Metadata, template admins can expose operational metrics from
10+
their workspaces to their users. It is the dynamic complement of [Resource Metadata](./resource-metadata.md).
1111

1212
See the [Terraform reference](https://registry.terraform.io/providers/coder/coder/latest/docs/resources/agent#metadata).
1313

1414
## Examples
1515

16-
All of these examples use [heredoc strings](https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings) for the script declaration. With heredoc strings you
16+
All of these examples use [heredoc strings](https://developer.hashicorp.com/terraform/language/expressions/strings#heredoc-strings) for the script declaration. With heredoc strings, you
1717
can script without messy escape codes, just as if you were working in your terminal.
1818

19-
Here are useful agent metadata snippets for Linux agents:
19+
Here's a standard set of metadata snippets for Linux agents:
2020

2121
```hcl
2222
resource "coder_agent" "main" {
@@ -69,7 +69,7 @@ resource "coder_agent" "main" {
6969
## Utilities
7070

7171
[vmstat](https://linux.die.net/man/8/vmstat) is available in most Linux
72-
distributions and contains virtual memory, CPU and IO statistics. Running `vmstat`
72+
distributions and provides virtual memory, CPU and IO statistics. Running `vmstat`
7373
produces output that looks like:
7474

7575
```

0 commit comments

Comments
 (0)