Skip to content

Commit a62c6ae

Browse files
authored
Merge branch 'main' into mafredri/feat-add-workspace-and-agent-health
2 parents 9774488 + 647fd76 commit a62c6ae

File tree

117 files changed

+8478
-1014
lines changed

Some content is hidden

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

117 files changed

+8478
-1014
lines changed

.github/workflows/ci.yaml

+2-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ jobs:
8989
- "scripts/Dockerfile.base"
9090
- "scripts/helm.sh"
9191
ci:
92-
- ".github/**"
92+
- ".github/actions/**"
93+
- ".github/workflows/ci.yaml"
9394
- id: debug
9495
run: |
9596
echo "${{ toJSON(steps.filter )}}"

.github/workflows/pr-deploy.yaml

+17
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,23 @@ jobs:
5858
CODER_BASE_IMAGE_TAG: ghcr.io/coder/coder-preview-base:pr${{ steps.pr_number.outputs.PR_NUMBER }}
5959
CODER_IMAGE_TAG: ghcr.io/coder/coder-preview:pr${{ steps.pr_number.outputs.PR_NUMBER }}
6060

61+
- name: Find Deploy Comment
62+
if: github.event_name == 'issue_comment'
63+
uses: peter-evans/find-comment@v2
64+
id: fco
65+
with:
66+
issue-number: ${{ steps.pr_number.outputs.PR_NUMBER }}
67+
comment-author: "github-actions[bot]"
68+
body-includes: /deploy-pr
69+
70+
- name: React with Rocket
71+
if: github.event_name == 'issue_comment'
72+
id: comment_ido
73+
uses: peter-evans/create-or-update-comment@v3
74+
with:
75+
comment-id: ${{ steps.fco.outputs.comment-id }}
76+
reactions: rocket
77+
6178
- name: Find Comment
6279
uses: peter-evans/find-comment@v2
6380
id: fc

agent/agent.go

+45-7
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ type Client interface {
7777
PostStartup(ctx context.Context, req agentsdk.PostStartupRequest) error
7878
PostMetadata(ctx context.Context, key string, req agentsdk.PostMetadataRequest) error
7979
PatchStartupLogs(ctx context.Context, req agentsdk.PatchStartupLogs) error
80+
GetServiceBanner(ctx context.Context) (codersdk.ServiceBannerConfig, error)
8081
}
8182

8283
type Agent interface {
@@ -163,7 +164,9 @@ type agent struct {
163164

164165
envVars map[string]string
165166
// manifest is atomic because values can change after reconnection.
166-
manifest atomic.Pointer[agentsdk.Manifest]
167+
manifest atomic.Pointer[agentsdk.Manifest]
168+
// serviceBanner is atomic because it can change.
169+
serviceBanner atomic.Pointer[codersdk.ServiceBannerConfig]
167170
sessionToken atomic.Pointer[string]
168171
sshServer *agentssh.Server
169172
sshMaxTimeout time.Duration
@@ -191,6 +194,7 @@ func (a *agent) init(ctx context.Context) {
191194
sshSrv.Env = a.envVars
192195
sshSrv.AgentToken = func() string { return *a.sessionToken.Load() }
193196
sshSrv.Manifest = &a.manifest
197+
sshSrv.ServiceBanner = &a.serviceBanner
194198
a.sshServer = sshSrv
195199

196200
go a.runLoop(ctx)
@@ -203,6 +207,7 @@ func (a *agent) init(ctx context.Context) {
203207
func (a *agent) runLoop(ctx context.Context) {
204208
go a.reportLifecycleLoop(ctx)
205209
go a.reportMetadataLoop(ctx)
210+
go a.fetchServiceBannerLoop(ctx)
206211

207212
for retrier := retry.New(100*time.Millisecond, 10*time.Second); retrier.Wait(ctx); {
208213
a.logger.Info(ctx, "connecting to coderd")
@@ -275,14 +280,15 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
275280
return result
276281
}
277282

278-
func adjustIntervalForTests(i int64) time.Duration {
283+
// adjustIntervalForTests returns a duration of testInterval milliseconds long
284+
// for tests and interval seconds long otherwise.
285+
func adjustIntervalForTests(interval time.Duration, testInterval time.Duration) time.Duration {
279286
// In tests we want to set shorter intervals because engineers are
280287
// impatient.
281-
base := time.Second
282288
if flag.Lookup("test.v") != nil {
283-
base = time.Millisecond * 100
289+
return testInterval
284290
}
285-
return time.Duration(i) * base
291+
return interval
286292
}
287293

288294
type metadataResultAndKey struct {
@@ -306,7 +312,7 @@ func (t *trySingleflight) Do(key string, fn func()) {
306312
}
307313

308314
func (a *agent) reportMetadataLoop(ctx context.Context) {
309-
baseInterval := adjustIntervalForTests(1)
315+
baseInterval := adjustIntervalForTests(time.Second, time.Millisecond*100)
310316

311317
const metadataLimit = 128
312318

@@ -383,7 +389,9 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
383389
}
384390
// The last collected value isn't quite stale yet, so we skip it.
385391
if collectedAt.Add(
386-
adjustIntervalForTests(md.Interval),
392+
adjustIntervalForTests(
393+
time.Duration(md.Interval)*time.Second,
394+
time.Duration(md.Interval)*time.Millisecond*100),
387395
).After(time.Now()) {
388396
continue
389397
}
@@ -491,6 +499,30 @@ func (a *agent) setLifecycle(ctx context.Context, state codersdk.WorkspaceAgentL
491499
}
492500
}
493501

502+
// fetchServiceBannerLoop fetches the service banner on an interval. It will
503+
// not be fetched immediately; the expectation is that it is primed elsewhere
504+
// (and must be done before the session actually starts).
505+
func (a *agent) fetchServiceBannerLoop(ctx context.Context) {
506+
ticker := time.NewTicker(adjustIntervalForTests(2*time.Minute, time.Millisecond*100))
507+
defer ticker.Stop()
508+
for {
509+
select {
510+
case <-ctx.Done():
511+
return
512+
case <-ticker.C:
513+
serviceBanner, err := a.client.GetServiceBanner(ctx)
514+
if err != nil {
515+
if ctx.Err() != nil {
516+
return
517+
}
518+
a.logger.Error(ctx, "failed to update service banner", slog.Error(err))
519+
continue
520+
}
521+
a.serviceBanner.Store(&serviceBanner)
522+
}
523+
}
524+
}
525+
494526
func (a *agent) run(ctx context.Context) error {
495527
// This allows the agent to refresh it's token if necessary.
496528
// For instance identity this is required, since the instance
@@ -501,6 +533,12 @@ func (a *agent) run(ctx context.Context) error {
501533
}
502534
a.sessionToken.Store(&sessionToken)
503535

536+
serviceBanner, err := a.client.GetServiceBanner(ctx)
537+
if err != nil {
538+
return xerrors.Errorf("fetch service banner: %w", err)
539+
}
540+
a.serviceBanner.Store(&serviceBanner)
541+
504542
manifest, err := a.client.Manifest(ctx)
505543
if err != nil {
506544
return xerrors.Errorf("fetch metadata: %w", err)

0 commit comments

Comments
 (0)