Skip to content

Commit abc7415

Browse files
committed
Merge remote-tracking branch 'origin/main' into dreamteam/external_proxy_cli_cmd
2 parents 27d1476 + dc5e16a commit abc7415

File tree

108 files changed

+1624
-1238
lines changed

Some content is hidden

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

108 files changed

+1624
-1238
lines changed

.github/workflows/cron-weekly.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ jobs:
2121
use-verbose-mode: "yes"
2222
config-file: ".github/workflows/mlc_config.json"
2323
folder-path: "docs/"
24+
file-path: "./README.md"
2425

2526
- name: Send Slack notification
2627
if: failure()

.github/workflows/mlc_config.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,6 @@
1818
{
1919
"pattern": "tailscale.com"
2020
}
21-
]
21+
],
22+
"aliveStatusCodes": [200, 0]
2223
}

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ coder server --postgres-url <url> --access-url <url>
8484

8585
> <sup>1</sup> For production deployments, set up an external PostgreSQL instance for reliability.
8686
87-
Use `coder --help` to get a list of flags and environment variables. Use our [install guides](https://coder.com/docs/v2/latest/guides) for a full walkthrough.
87+
Use `coder --help` to get a list of flags and environment variables. Use our [install guides](https://coder.com/docs/v2/latest/install) for a full walkthrough.
8888

8989
## Documentation
9090

agent/agent.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1407,5 +1407,14 @@ func expandDirectory(dir string) (string, error) {
14071407
}
14081408
dir = filepath.Join(home, dir[1:])
14091409
}
1410-
return os.ExpandEnv(dir), nil
1410+
dir = os.ExpandEnv(dir)
1411+
1412+
if !filepath.IsAbs(dir) {
1413+
home, err := userHomeDir()
1414+
if err != nil {
1415+
return "", err
1416+
}
1417+
dir = filepath.Join(home, dir)
1418+
}
1419+
return dir, nil
14111420
}

agent/agent_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1391,6 +1391,22 @@ func TestAgent_Startup(t *testing.T) {
13911391
require.Equal(t, homeDir, client.getStartup().ExpandedDirectory)
13921392
})
13931393

1394+
t.Run("NotAbsoluteDirectory", func(t *testing.T) {
1395+
t.Parallel()
1396+
1397+
_, client, _, _, _ := setupAgent(t, agentsdk.Manifest{
1398+
StartupScript: "true",
1399+
StartupScriptTimeout: 30 * time.Second,
1400+
Directory: "coder/coder",
1401+
}, 0)
1402+
assert.Eventually(t, func() bool {
1403+
return client.getStartup().Version != ""
1404+
}, testutil.WaitShort, testutil.IntervalFast)
1405+
homeDir, err := os.UserHomeDir()
1406+
require.NoError(t, err)
1407+
require.Equal(t, filepath.Join(homeDir, "coder/coder"), client.getStartup().ExpandedDirectory)
1408+
})
1409+
13941410
t.Run("HomeEnvironmentVariable", func(t *testing.T) {
13951411
t.Parallel()
13961412

agent/reaper/reaper_test.go

Lines changed: 30 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@ import (
1818
"github.com/coder/coder/testutil"
1919
)
2020

21-
//nolint:paralleltest // Non-parallel subtest.
21+
// TestReap checks that's the reaper is successfully reaping
22+
// exited processes and passing the PIDs through the shared
23+
// channel.
24+
//
25+
//nolint:paralleltest
2226
func TestReap(t *testing.T) {
2327
// Don't run the reaper test in CI. It does weird
2428
// things like forkexecing which may have unintended
@@ -27,45 +31,38 @@ func TestReap(t *testing.T) {
2731
t.Skip("Detected CI, skipping reaper tests")
2832
}
2933

30-
// OK checks that's the reaper is successfully reaping
31-
// exited processes and passing the PIDs through the shared
32-
// channel.
33-
34-
//nolint:paralleltest // Signal handling.
35-
t.Run("OK", func(t *testing.T) {
36-
pids := make(reap.PidCh, 1)
37-
err := reaper.ForkReap(
38-
reaper.WithPIDCallback(pids),
39-
// Provide some argument that immediately exits.
40-
reaper.WithExecArgs("/bin/sh", "-c", "exit 0"),
41-
)
42-
require.NoError(t, err)
34+
pids := make(reap.PidCh, 1)
35+
err := reaper.ForkReap(
36+
reaper.WithPIDCallback(pids),
37+
// Provide some argument that immediately exits.
38+
reaper.WithExecArgs("/bin/sh", "-c", "exit 0"),
39+
)
40+
require.NoError(t, err)
4341

44-
cmd := exec.Command("tail", "-f", "/dev/null")
45-
err = cmd.Start()
46-
require.NoError(t, err)
42+
cmd := exec.Command("tail", "-f", "/dev/null")
43+
err = cmd.Start()
44+
require.NoError(t, err)
4745

48-
cmd2 := exec.Command("tail", "-f", "/dev/null")
49-
err = cmd2.Start()
50-
require.NoError(t, err)
46+
cmd2 := exec.Command("tail", "-f", "/dev/null")
47+
err = cmd2.Start()
48+
require.NoError(t, err)
5149

52-
err = cmd.Process.Kill()
53-
require.NoError(t, err)
50+
err = cmd.Process.Kill()
51+
require.NoError(t, err)
5452

55-
err = cmd2.Process.Kill()
56-
require.NoError(t, err)
53+
err = cmd2.Process.Kill()
54+
require.NoError(t, err)
5755

58-
expectedPIDs := []int{cmd.Process.Pid, cmd2.Process.Pid}
56+
expectedPIDs := []int{cmd.Process.Pid, cmd2.Process.Pid}
5957

60-
for i := 0; i < len(expectedPIDs); i++ {
61-
select {
62-
case <-time.After(testutil.WaitShort):
63-
t.Fatalf("Timed out waiting for process")
64-
case pid := <-pids:
65-
require.Contains(t, expectedPIDs, pid)
66-
}
58+
for i := 0; i < len(expectedPIDs); i++ {
59+
select {
60+
case <-time.After(testutil.WaitShort):
61+
t.Fatalf("Timed out waiting for process")
62+
case pid := <-pids:
63+
require.Contains(t, expectedPIDs, pid)
6764
}
68-
})
65+
}
6966
}
7067

7168
//nolint:paralleltest // Signal handling.

cli/cliui/select.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,17 +70,22 @@ type RichSelectOptions struct {
7070
// RichSelect displays a list of user options including name and description.
7171
func RichSelect(inv *clibase.Invocation, richOptions RichSelectOptions) (*codersdk.TemplateVersionParameterOption, error) {
7272
opts := make([]string, len(richOptions.Options))
73+
var defaultOpt string
7374
for i, option := range richOptions.Options {
7475
line := option.Name
7576
if len(option.Description) > 0 {
7677
line += ": " + option.Description
7778
}
7879
opts[i] = line
80+
81+
if option.Value == richOptions.Default {
82+
defaultOpt = line
83+
}
7984
}
8085

8186
selected, err := Select(inv, SelectOptions{
8287
Options: opts,
83-
Default: richOptions.Default,
88+
Default: defaultOpt,
8489
Size: richOptions.Size,
8590
HideSearch: richOptions.HideSearch,
8691
})

cli/portforward_test.go

Lines changed: 88 additions & 94 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,8 @@ import (
2121
"github.com/coder/coder/testutil"
2222
)
2323

24+
//nolint:tparallel,paralleltest // Subtests require setup that must not be done in parallel.
2425
func TestPortForward(t *testing.T) {
25-
t.Parallel()
26-
t.Skip("These tests flake... a lot. It seems related to the Tailscale change, but all other tests pass...")
27-
2826
t.Run("None", func(t *testing.T) {
2927
t.Parallel()
3028

@@ -116,106 +114,102 @@ func TestPortForward(t *testing.T) {
116114
workspace = runAgent(t, client, user.UserID)
117115
)
118116

119-
for _, c := range cases { //nolint:paralleltest // the `c := c` confuses the linter
117+
for _, c := range cases {
120118
c := c
121119
// Delay parallel tests here because setupLocal reserves
122120
// a free open port which is not guaranteed to be free
123121
// between the listener closing and port-forward ready.
124-
t.Run(c.name, func(t *testing.T) {
125-
t.Run("OnePort", func(t *testing.T) {
126-
p1 := setupTestListener(t, c.setupRemote(t))
127-
128-
// Create a flag that forwards from local to listener 1.
129-
localAddress, localFlag := c.setupLocal(t)
130-
flag := fmt.Sprintf(c.flag, localFlag, p1)
131-
132-
// Launch port-forward in a goroutine so we can start dialing
133-
// the "local" listener.
134-
inv, root := clitest.New(t, "-v", "port-forward", workspace.Name, flag)
135-
clitest.SetupConfig(t, client, root)
136-
pty := ptytest.New(t)
137-
inv.Stdin = pty.Input()
138-
inv.Stdout = pty.Output()
139-
inv.Stderr = pty.Output()
140-
ctx, cancel := context.WithCancel(context.Background())
141-
defer cancel()
142-
errC := make(chan error)
143-
go func() {
144-
errC <- inv.WithContext(ctx).Run()
145-
}()
146-
pty.ExpectMatch("Ready!")
147-
148-
t.Parallel() // Port is reserved, enable parallel execution.
149-
150-
// Open two connections simultaneously and test them out of
151-
// sync.
152-
d := net.Dialer{Timeout: testutil.WaitShort}
153-
c1, err := d.DialContext(ctx, c.network, localAddress)
154-
require.NoError(t, err, "open connection 1 to 'local' listener")
155-
defer c1.Close()
156-
c2, err := d.DialContext(ctx, c.network, localAddress)
157-
require.NoError(t, err, "open connection 2 to 'local' listener")
158-
defer c2.Close()
159-
testDial(t, c2)
160-
testDial(t, c1)
161-
162-
cancel()
163-
err = <-errC
164-
require.ErrorIs(t, err, context.Canceled)
165-
})
122+
t.Run(c.name+"_OnePort", func(t *testing.T) {
123+
p1 := setupTestListener(t, c.setupRemote(t))
166124

167-
//nolint:paralleltest
168-
t.Run("TwoPorts", func(t *testing.T) {
169-
var (
170-
p1 = setupTestListener(t, c.setupRemote(t))
171-
p2 = setupTestListener(t, c.setupRemote(t))
172-
)
173-
174-
// Create a flags for listener 1 and listener 2.
175-
localAddress1, localFlag1 := c.setupLocal(t)
176-
localAddress2, localFlag2 := c.setupLocal(t)
177-
flag1 := fmt.Sprintf(c.flag, localFlag1, p1)
178-
flag2 := fmt.Sprintf(c.flag, localFlag2, p2)
179-
180-
// Launch port-forward in a goroutine so we can start dialing
181-
// the "local" listeners.
182-
inv, root := clitest.New(t, "-v", "port-forward", workspace.Name, flag1, flag2)
183-
clitest.SetupConfig(t, client, root)
184-
pty := ptytest.New(t)
185-
inv.Stdin = pty.Input()
186-
inv.Stdout = pty.Output()
187-
inv.Stderr = pty.Output()
188-
ctx, cancel := context.WithCancel(context.Background())
189-
defer cancel()
190-
errC := make(chan error)
191-
go func() {
192-
errC <- inv.WithContext(ctx).Run()
193-
}()
194-
pty.ExpectMatch("Ready!")
195-
196-
t.Parallel() // Port is reserved, enable parallel execution.
197-
198-
// Open a connection to both listener 1 and 2 simultaneously and
199-
// then test them out of order.
200-
d := net.Dialer{Timeout: testutil.WaitShort}
201-
c1, err := d.DialContext(ctx, c.network, localAddress1)
202-
require.NoError(t, err, "open connection 1 to 'local' listener 1")
203-
defer c1.Close()
204-
c2, err := d.DialContext(ctx, c.network, localAddress2)
205-
require.NoError(t, err, "open connection 2 to 'local' listener 2")
206-
defer c2.Close()
207-
testDial(t, c2)
208-
testDial(t, c1)
209-
210-
cancel()
211-
err = <-errC
212-
require.ErrorIs(t, err, context.Canceled)
213-
})
125+
// Create a flag that forwards from local to listener 1.
126+
localAddress, localFlag := c.setupLocal(t)
127+
flag := fmt.Sprintf(c.flag, localFlag, p1)
128+
129+
// Launch port-forward in a goroutine so we can start dialing
130+
// the "local" listener.
131+
inv, root := clitest.New(t, "-v", "port-forward", workspace.Name, flag)
132+
clitest.SetupConfig(t, client, root)
133+
pty := ptytest.New(t)
134+
inv.Stdin = pty.Input()
135+
inv.Stdout = pty.Output()
136+
inv.Stderr = pty.Output()
137+
ctx, cancel := context.WithCancel(context.Background())
138+
defer cancel()
139+
errC := make(chan error)
140+
go func() {
141+
errC <- inv.WithContext(ctx).Run()
142+
}()
143+
pty.ExpectMatch("Ready!")
144+
145+
t.Parallel() // Port is reserved, enable parallel execution.
146+
147+
// Open two connections simultaneously and test them out of
148+
// sync.
149+
d := net.Dialer{Timeout: testutil.WaitShort}
150+
c1, err := d.DialContext(ctx, c.network, localAddress)
151+
require.NoError(t, err, "open connection 1 to 'local' listener")
152+
defer c1.Close()
153+
c2, err := d.DialContext(ctx, c.network, localAddress)
154+
require.NoError(t, err, "open connection 2 to 'local' listener")
155+
defer c2.Close()
156+
testDial(t, c2)
157+
testDial(t, c1)
158+
159+
cancel()
160+
err = <-errC
161+
require.ErrorIs(t, err, context.Canceled)
162+
})
163+
164+
t.Run(c.name+"_TwoPorts", func(t *testing.T) {
165+
var (
166+
p1 = setupTestListener(t, c.setupRemote(t))
167+
p2 = setupTestListener(t, c.setupRemote(t))
168+
)
169+
170+
// Create a flags for listener 1 and listener 2.
171+
localAddress1, localFlag1 := c.setupLocal(t)
172+
localAddress2, localFlag2 := c.setupLocal(t)
173+
flag1 := fmt.Sprintf(c.flag, localFlag1, p1)
174+
flag2 := fmt.Sprintf(c.flag, localFlag2, p2)
175+
176+
// Launch port-forward in a goroutine so we can start dialing
177+
// the "local" listeners.
178+
inv, root := clitest.New(t, "-v", "port-forward", workspace.Name, flag1, flag2)
179+
clitest.SetupConfig(t, client, root)
180+
pty := ptytest.New(t)
181+
inv.Stdin = pty.Input()
182+
inv.Stdout = pty.Output()
183+
inv.Stderr = pty.Output()
184+
ctx, cancel := context.WithCancel(context.Background())
185+
defer cancel()
186+
errC := make(chan error)
187+
go func() {
188+
errC <- inv.WithContext(ctx).Run()
189+
}()
190+
pty.ExpectMatch("Ready!")
191+
192+
t.Parallel() // Port is reserved, enable parallel execution.
193+
194+
// Open a connection to both listener 1 and 2 simultaneously and
195+
// then test them out of order.
196+
d := net.Dialer{Timeout: testutil.WaitShort}
197+
c1, err := d.DialContext(ctx, c.network, localAddress1)
198+
require.NoError(t, err, "open connection 1 to 'local' listener 1")
199+
defer c1.Close()
200+
c2, err := d.DialContext(ctx, c.network, localAddress2)
201+
require.NoError(t, err, "open connection 2 to 'local' listener 2")
202+
defer c2.Close()
203+
testDial(t, c2)
204+
testDial(t, c1)
205+
206+
cancel()
207+
err = <-errC
208+
require.ErrorIs(t, err, context.Canceled)
214209
})
215210
}
216211

217212
// Test doing TCP and UDP at the same time.
218-
//nolint:paralleltest
219213
t.Run("All", func(t *testing.T) {
220214
var (
221215
dials = []addr{}

cli/server.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,19 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
403403
if !cfg.DERP.Server.Enable {
404404
defaultRegion = nil
405405
}
406+
407+
// HACK: see https://github.com/coder/coder/issues/6791.
408+
for _, addr := range cfg.DERP.Server.STUNAddresses {
409+
if addr != "disable" {
410+
continue
411+
}
412+
err := cfg.DERP.Server.STUNAddresses.Replace(nil)
413+
if err != nil {
414+
panic(err)
415+
}
416+
break
417+
}
418+
406419
derpMap, err := tailnet.NewDERPMap(
407420
ctx, defaultRegion, cfg.DERP.Server.STUNAddresses,
408421
cfg.DERP.Config.URL.String(), cfg.DERP.Config.Path.String(),

0 commit comments

Comments
 (0)