Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7d3d47f

Browse files
committed
Merge branch 'main' into 6818-reverse-port-fwd
2 parents 7506df9 + ab54008 commit 7d3d47f

Some content is hidden

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

63 files changed

+700
-623
lines changed

.github/workflows/ci.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
127127
# Check for any typos
128128
- name: Check for typos
129-
uses: crate-ci/[email protected].0
129+
uses: crate-ci/[email protected].1
130130
with:
131131
config: .github/workflows/typos.toml
132132

@@ -165,7 +165,7 @@ jobs:
165165
- name: Setup sqlc
166166
uses: sqlc-dev/setup-sqlc@v3
167167
with:
168-
sqlc-version: "1.18.0"
168+
sqlc-version: "1.19.1"
169169

170170
- name: go install tools
171171
run: |

.github/workflows/dogfood.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,30 @@ jobs:
5151
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:latest"
5252
cache-from: type=registry,ref=codercom/oss-dogfood:latest
5353
cache-to: type=inline
54+
5455
deploy_template:
5556
needs: deploy_image
5657
runs-on: ubuntu-latest
5758
steps:
5859
- name: Checkout
5960
uses: actions/checkout@v3
61+
6062
- name: Get short commit SHA
6163
id: vars
6264
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
65+
66+
- name: Get latest commit title
67+
id: message
68+
run: echo "pr_title=$(git log --format=%s -n 1 ${{ github.sha }})" >> $GITHUB_OUTPUT
69+
6370
- name: "Get latest Coder binary from the server"
6471
run: |
6572
curl -fsSL "https://dev.coder.com/bin/coder-linux-amd64" -o "./coder"
6673
chmod +x "./coder"
74+
6775
- name: "Push template"
6876
run: |
69-
./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION
77+
./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION --message="$CODER_TEMPLATE_MESSAGE"
7078
env:
7179
# Consumed by Coder CLI
7280
CODER_URL: https://dev.coder.com
@@ -75,3 +83,4 @@ jobs:
7583
CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }}
7684
CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }}
7785
CODER_TEMPLATE_DIR: ./dogfood
86+
CODER_TEMPLATE_MESSAGE: ${{ steps.message.outputs.pr_title }}

.github/workflows/pr-deploy.yaml

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ permissions:
1717
pull-requests: write
1818

1919
concurrency:
20-
group: ${{ github.workflow }}-${{ github.ref }}
21-
cancel-in-progress: true
20+
group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}
21+
cancel-in-progress: false
2222

2323
jobs:
2424
pr_commented:
@@ -58,23 +58,6 @@ 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-
7861
- name: Find Comment
7962
uses: peter-evans/find-comment@v2
8063
id: fc
@@ -116,7 +99,7 @@ jobs:
11699
- name: Setup sqlc
117100
uses: sqlc-dev/setup-sqlc@v3
118101
with:
119-
sqlc-version: "1.18.0"
102+
sqlc-version: "1.19.1"
120103

121104
- name: GHCR Login
122105
uses: docker/login-action@v2

.github/workflows/security.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
- name: Setup sqlc
8484
uses: sqlc-dev/setup-sqlc@v3
8585
with:
86-
sqlc-version: "1.18.0"
86+
sqlc-version: "1.19.1"
8787

8888
- name: Install yq
8989
run: go run github.com/mikefarah/yq/[email protected]

.github/workflows/stale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
with:
1818
stale-issue-label: "stale"
1919
stale-pr-label: "stale"
20-
days-before-stale: 90
20+
days-before-stale: 180
2121
# Pull Requests become stale more quickly due to merge conflicts.
2222
# Also, we promote minimizing WIP.
2323
days-before-pr-stale: 7

agent/agent.go

Lines changed: 54 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import (
66
"encoding/binary"
77
"encoding/json"
88
"errors"
9-
"flag"
109
"fmt"
1110
"io"
1211
"net"
@@ -52,21 +51,22 @@ const (
5251
)
5352

5453
type Options struct {
55-
Filesystem afero.Fs
56-
LogDir string
57-
TempDir string
58-
ExchangeToken func(ctx context.Context) (string, error)
59-
Client Client
60-
ReconnectingPTYTimeout time.Duration
61-
EnvironmentVariables map[string]string
62-
Logger slog.Logger
63-
IgnorePorts map[int]string
64-
SSHMaxTimeout time.Duration
65-
TailnetListenPort uint16
66-
Subsystem codersdk.AgentSubsystem
67-
Addresses []netip.Prefix
68-
69-
PrometheusRegistry *prometheus.Registry
54+
Filesystem afero.Fs
55+
LogDir string
56+
TempDir string
57+
ExchangeToken func(ctx context.Context) (string, error)
58+
Client Client
59+
ReconnectingPTYTimeout time.Duration
60+
EnvironmentVariables map[string]string
61+
Logger slog.Logger
62+
IgnorePorts map[int]string
63+
SSHMaxTimeout time.Duration
64+
TailnetListenPort uint16
65+
Subsystem codersdk.AgentSubsystem
66+
Addresses []netip.Prefix
67+
PrometheusRegistry *prometheus.Registry
68+
ReportMetadataInterval time.Duration
69+
ServiceBannerRefreshInterval time.Duration
7070
}
7171

7272
type Client interface {
@@ -107,6 +107,12 @@ func New(options Options) Agent {
107107
return "", nil
108108
}
109109
}
110+
if options.ReportMetadataInterval == 0 {
111+
options.ReportMetadataInterval = 1 * time.Minute
112+
}
113+
if options.ServiceBannerRefreshInterval == 0 {
114+
options.ServiceBannerRefreshInterval = 2 * time.Minute
115+
}
110116

111117
prometheusRegistry := options.PrometheusRegistry
112118
if prometheusRegistry == nil {
@@ -115,25 +121,27 @@ func New(options Options) Agent {
115121

116122
ctx, cancelFunc := context.WithCancel(context.Background())
117123
a := &agent{
118-
tailnetListenPort: options.TailnetListenPort,
119-
reconnectingPTYTimeout: options.ReconnectingPTYTimeout,
120-
logger: options.Logger,
121-
closeCancel: cancelFunc,
122-
closed: make(chan struct{}),
123-
envVars: options.EnvironmentVariables,
124-
client: options.Client,
125-
exchangeToken: options.ExchangeToken,
126-
filesystem: options.Filesystem,
127-
logDir: options.LogDir,
128-
tempDir: options.TempDir,
129-
lifecycleUpdate: make(chan struct{}, 1),
130-
lifecycleReported: make(chan codersdk.WorkspaceAgentLifecycle, 1),
131-
lifecycleStates: []agentsdk.PostLifecycleRequest{{State: codersdk.WorkspaceAgentLifecycleCreated}},
132-
ignorePorts: options.IgnorePorts,
133-
connStatsChan: make(chan *agentsdk.Stats, 1),
134-
sshMaxTimeout: options.SSHMaxTimeout,
135-
subsystem: options.Subsystem,
136-
addresses: options.Addresses,
124+
tailnetListenPort: options.TailnetListenPort,
125+
reconnectingPTYTimeout: options.ReconnectingPTYTimeout,
126+
logger: options.Logger,
127+
closeCancel: cancelFunc,
128+
closed: make(chan struct{}),
129+
envVars: options.EnvironmentVariables,
130+
client: options.Client,
131+
exchangeToken: options.ExchangeToken,
132+
filesystem: options.Filesystem,
133+
logDir: options.LogDir,
134+
tempDir: options.TempDir,
135+
lifecycleUpdate: make(chan struct{}, 1),
136+
lifecycleReported: make(chan codersdk.WorkspaceAgentLifecycle, 1),
137+
lifecycleStates: []agentsdk.PostLifecycleRequest{{State: codersdk.WorkspaceAgentLifecycleCreated}},
138+
ignorePorts: options.IgnorePorts,
139+
connStatsChan: make(chan *agentsdk.Stats, 1),
140+
reportMetadataInterval: options.ReportMetadataInterval,
141+
serviceBannerRefreshInterval: options.ServiceBannerRefreshInterval,
142+
sshMaxTimeout: options.SSHMaxTimeout,
143+
subsystem: options.Subsystem,
144+
addresses: options.Addresses,
137145

138146
prometheusRegistry: prometheusRegistry,
139147
metrics: newAgentMetrics(prometheusRegistry),
@@ -165,13 +173,14 @@ type agent struct {
165173
closed chan struct{}
166174

167175
envVars map[string]string
168-
// manifest is atomic because values can change after reconnection.
169-
manifest atomic.Pointer[agentsdk.Manifest]
170-
// serviceBanner is atomic because it can change.
171-
serviceBanner atomic.Pointer[codersdk.ServiceBannerConfig]
172-
sessionToken atomic.Pointer[string]
173-
sshServer *agentssh.Server
174-
sshMaxTimeout time.Duration
176+
177+
manifest atomic.Pointer[agentsdk.Manifest] // manifest is atomic because values can change after reconnection.
178+
reportMetadataInterval time.Duration
179+
serviceBanner atomic.Pointer[codersdk.ServiceBannerConfig] // serviceBanner is atomic because it is periodically updated.
180+
serviceBannerRefreshInterval time.Duration
181+
sessionToken atomic.Pointer[string]
182+
sshServer *agentssh.Server
183+
sshMaxTimeout time.Duration
175184

176185
lifecycleUpdate chan struct{}
177186
lifecycleReported chan codersdk.WorkspaceAgentLifecycle
@@ -283,17 +292,6 @@ func (a *agent) collectMetadata(ctx context.Context, md codersdk.WorkspaceAgentM
283292
return result
284293
}
285294

286-
// adjustIntervalForTests returns a duration of testInterval milliseconds long
287-
// for tests and interval seconds long otherwise.
288-
func adjustIntervalForTests(interval time.Duration, testInterval time.Duration) time.Duration {
289-
// In tests we want to set shorter intervals because engineers are
290-
// impatient.
291-
if flag.Lookup("test.v") != nil {
292-
return testInterval
293-
}
294-
return interval
295-
}
296-
297295
type metadataResultAndKey struct {
298296
result *codersdk.WorkspaceAgentMetadataResult
299297
key string
@@ -315,12 +313,10 @@ func (t *trySingleflight) Do(key string, fn func()) {
315313
}
316314

317315
func (a *agent) reportMetadataLoop(ctx context.Context) {
318-
baseInterval := adjustIntervalForTests(time.Second, time.Millisecond*100)
319-
320316
const metadataLimit = 128
321317

322318
var (
323-
baseTicker = time.NewTicker(baseInterval)
319+
baseTicker = time.NewTicker(a.reportMetadataInterval)
324320
lastCollectedAts = make(map[string]time.Time)
325321
metadataResults = make(chan metadataResultAndKey, metadataLimit)
326322
)
@@ -391,11 +387,7 @@ func (a *agent) reportMetadataLoop(ctx context.Context) {
391387
continue
392388
}
393389
// The last collected value isn't quite stale yet, so we skip it.
394-
if collectedAt.Add(
395-
adjustIntervalForTests(
396-
time.Duration(md.Interval)*time.Second,
397-
time.Duration(md.Interval)*time.Millisecond*100),
398-
).After(time.Now()) {
390+
if collectedAt.Add(a.reportMetadataInterval).After(time.Now()) {
399391
continue
400392
}
401393
}
@@ -506,7 +498,7 @@ func (a *agent) setLifecycle(ctx context.Context, state codersdk.WorkspaceAgentL
506498
// not be fetched immediately; the expectation is that it is primed elsewhere
507499
// (and must be done before the session actually starts).
508500
func (a *agent) fetchServiceBannerLoop(ctx context.Context) {
509-
ticker := time.NewTicker(adjustIntervalForTests(2*time.Minute, time.Millisecond*5))
501+
ticker := time.NewTicker(a.serviceBannerRefreshInterval)
510502
defer ticker.Stop()
511503
for {
512504
select {

agent/agent_test.go

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -424,8 +424,12 @@ func TestAgent_Session_TTY_MOTD_Update(t *testing.T) {
424424

425425
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
426426
defer cancel()
427+
428+
setSBInterval := func(_ *agenttest.Client, opts *agent.Options) {
429+
opts.ServiceBannerRefreshInterval = 5 * time.Millisecond
430+
}
427431
//nolint:dogsled // Allow the blank identifiers.
428-
conn, client, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0)
432+
conn, client, _, _, _ := setupAgent(t, agentsdk.Manifest{}, 0, setSBInterval)
429433
for _, test := range tests {
430434
test := test
431435
// Set new banner func and wait for the agent to call it to update the
@@ -1143,7 +1147,9 @@ func TestAgent_Metadata(t *testing.T) {
11431147
Script: echoHello,
11441148
},
11451149
},
1146-
}, 0)
1150+
}, 0, func(_ *agenttest.Client, opts *agent.Options) {
1151+
opts.ReportMetadataInterval = 100 * time.Millisecond
1152+
})
11471153

11481154
var gotMd map[string]agentsdk.PostMetadataRequest
11491155
require.Eventually(t, func() bool {
@@ -1174,23 +1180,23 @@ func TestAgent_Metadata(t *testing.T) {
11741180
Script: echoHello,
11751181
},
11761182
},
1177-
}, 0)
1183+
}, 0, func(_ *agenttest.Client, opts *agent.Options) {
1184+
opts.ReportMetadataInterval = testutil.IntervalFast
1185+
})
11781186

11791187
var gotMd map[string]agentsdk.PostMetadataRequest
11801188
require.Eventually(t, func() bool {
11811189
gotMd = client.GetMetadata()
11821190
return len(gotMd) == 1
1183-
}, testutil.WaitShort, testutil.IntervalMedium)
1191+
}, testutil.WaitShort, testutil.IntervalFast/2)
11841192

11851193
collectedAt1 := gotMd["greeting"].CollectedAt
1186-
if !assert.Equal(t, "hello", strings.TrimSpace(gotMd["greeting"].Value)) {
1187-
t.Errorf("got: %+v", gotMd)
1188-
}
1194+
require.Equal(t, "hello", strings.TrimSpace(gotMd["greeting"].Value))
11891195

11901196
if !assert.Eventually(t, func() bool {
11911197
gotMd = client.GetMetadata()
11921198
return gotMd["greeting"].CollectedAt.After(collectedAt1)
1193-
}, testutil.WaitShort, testutil.IntervalMedium) {
1199+
}, testutil.WaitShort, testutil.IntervalFast/2) {
11941200
t.Fatalf("expected metadata to be collected again")
11951201
}
11961202
})
@@ -1227,7 +1233,9 @@ func TestAgentMetadata_Timing(t *testing.T) {
12271233
Script: "exit 1",
12281234
},
12291235
},
1230-
}, 0)
1236+
}, 0, func(_ *agenttest.Client, opts *agent.Options) {
1237+
opts.ReportMetadataInterval = intervalUnit
1238+
})
12311239

12321240
require.Eventually(t, func() bool {
12331241
return len(client.GetMetadata()) == 2
@@ -1844,14 +1852,14 @@ func setupSSHCommand(t *testing.T, beforeArgs []string, afterArgs []string) (*pt
18441852

18451853
func setupSSHSession(
18461854
t *testing.T,
1847-
options agentsdk.Manifest,
1855+
manifest agentsdk.Manifest,
18481856
serviceBanner codersdk.ServiceBannerConfig,
18491857
prepareFS func(fs afero.Fs),
18501858
) *ssh.Session {
18511859
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
18521860
defer cancel()
18531861
//nolint:dogsled
1854-
conn, _, _, fs, _ := setupAgent(t, options, 0, func(c *agenttest.Client, _ *agent.Options) {
1862+
conn, _, _, fs, _ := setupAgent(t, manifest, 0, func(c *agenttest.Client, _ *agent.Options) {
18551863
c.SetServiceBannerFunc(func() (codersdk.ServiceBannerConfig, error) {
18561864
return serviceBanner, nil
18571865
})

0 commit comments

Comments
 (0)