Skip to content

Commit e091841

Browse files
committed
Merge branch 'main' into paginate-ws/presleyp
2 parents 296281d + 0a5e554 commit e091841

File tree

252 files changed

+9013
-1796
lines changed

Some content is hidden

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

252 files changed

+9013
-1796
lines changed

.github/workflows/typos.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ IST = "IST"
55
MacOS = "macOS"
66

77
[default.extend-words]
8+
# do as sudo replacement
9+
doas = "doas"
810

911
[files]
1012
extend-exclude = [

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,14 @@
1919
"derphttp",
2020
"derpmap",
2121
"devel",
22+
"dflags",
2223
"drpc",
2324
"drpcconn",
2425
"drpcmux",
2526
"drpcserver",
2627
"Dsts",
2728
"enablements",
29+
"eventsourcemock",
2830
"fatih",
2931
"Formik",
3032
"gitsshkey",
@@ -85,8 +87,10 @@
8587
"ptytest",
8688
"quickstart",
8789
"reconfig",
90+
"replicasync",
8891
"retrier",
8992
"rpty",
93+
"SCIM",
9094
"sdkproto",
9195
"sdktrace",
9296
"Signup",

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ Once installed, you can start a production deployment<sup>1</sup> with a single
6060
# Automatically sets up an external access URL on *.try.coder.app
6161
coder server
6262

63-
# Requires a PostgreSQL instance and external access URL
63+
# Requires a PostgreSQL instance (version 13 or higher) and external access URL
6464
coder server --postgres-url <url> --access-url <url>
6565
```
6666

@@ -95,7 +95,7 @@ Join our community on [Discord](https://coder.com/chat?utm_source=github.com/cod
9595

9696
## Contributing
9797

98-
If you're using Coder in your organization, please try to add your company name to the [ADOPTERS.md](./ADOPTERS.md). It really helps the project to gain momentum and credibility. It's a small contribution back to the project with a big impact.
98+
If you're using Coder in your organization, please try to add your company name to the [ADOPTERS.md](./ADOPTERS.md). It really helps the project to gain momentum and credibility. It's a small contribution back to the project with a big impact.
9999

100100
Read the [contributing docs](https://coder.com/docs/coder-oss/latest/CONTRIBUTING).
101101

agent/agent.go

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ func (a *agent) runTailnet(ctx context.Context, derpMap *tailcfg.DERPMap) {
170170
if a.isClosed() {
171171
return
172172
}
173+
a.logger.Debug(ctx, "running tailnet with derpmap", slog.F("derpmap", derpMap))
173174
if a.network != nil {
174175
a.network.SetDERPMap(derpMap)
175176
return
@@ -878,12 +879,22 @@ func (r *reconnectingPTY) Close() {
878879
// after one or both of them are done writing. If the context is canceled, both
879880
// of the connections will be closed.
880881
func Bicopy(ctx context.Context, c1, c2 io.ReadWriteCloser) {
881-
defer c1.Close()
882-
defer c2.Close()
882+
ctx, cancel := context.WithCancel(ctx)
883+
defer cancel()
884+
885+
defer func() {
886+
_ = c1.Close()
887+
_ = c2.Close()
888+
}()
883889

884890
var wg sync.WaitGroup
885891
copyFunc := func(dst io.WriteCloser, src io.Reader) {
886-
defer wg.Done()
892+
defer func() {
893+
wg.Done()
894+
// If one side of the copy fails, ensure the other one exits as
895+
// well.
896+
cancel()
897+
}()
887898
_, _ = io.Copy(dst, src)
888899
}
889900

agent/agent_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -465,7 +465,7 @@ func TestAgent(t *testing.T) {
465465

466466
conn, _ := setupAgent(t, codersdk.WorkspaceAgentMetadata{}, 0)
467467
require.Eventually(t, func() bool {
468-
_, err := conn.Ping()
468+
_, err := conn.Ping(context.Background())
469469
return err == nil
470470
}, testutil.WaitMedium, testutil.IntervalFast)
471471
conn1, err := conn.DialContext(context.Background(), l.Addr().Network(), l.Addr().String())
@@ -483,9 +483,7 @@ func TestAgent(t *testing.T) {
483483

484484
t.Run("Speedtest", func(t *testing.T) {
485485
t.Parallel()
486-
if testing.Short() {
487-
t.Skip("The minimum duration for a speedtest is hardcoded in Tailscale to 5s!")
488-
}
486+
t.Skip("This test is relatively flakey because of Tailscale's speedtest code...")
489487
derpMap := tailnettest.RunDERPAndSTUN(t)
490488
conn, _ := setupAgent(t, codersdk.WorkspaceAgentMetadata{
491489
DERPMap: derpMap,

agent/apphealth.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,10 @@ func NewWorkspaceAppHealthReporter(logger slog.Logger, workspaceAgentApps Worksp
6060
continue
6161
}
6262
app := nextApp
63-
t := time.NewTicker(time.Duration(app.Healthcheck.Interval) * time.Second)
6463
go func() {
64+
t := time.NewTicker(time.Duration(app.Healthcheck.Interval) * time.Second)
65+
defer t.Stop()
66+
6567
for {
6668
select {
6769
case <-ctx.Done():
@@ -118,6 +120,7 @@ func NewWorkspaceAppHealthReporter(logger slog.Logger, workspaceAgentApps Worksp
118120
lastHealth := copyHealth(health)
119121
mu.Unlock()
120122
reportTicker := time.NewTicker(time.Second)
123+
defer reportTicker.Stop()
121124
// every second we check if the health values of the apps have changed
122125
// and if there is a change we will report the new values.
123126
for {

cli/agent_test.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ import (
77
"github.com/stretchr/testify/assert"
88
"github.com/stretchr/testify/require"
99

10-
"cdr.dev/slog"
11-
1210
"github.com/coder/coder/cli/clitest"
1311
"github.com/coder/coder/coderd/coderdtest"
1412
"github.com/coder/coder/provisioner/echo"
@@ -67,11 +65,11 @@ func TestWorkspaceAgent(t *testing.T) {
6765
if assert.NotEmpty(t, workspace.LatestBuild.Resources) && assert.NotEmpty(t, resources[0].Agents) {
6866
assert.NotEmpty(t, resources[0].Agents[0].Version)
6967
}
70-
dialer, err := client.DialWorkspaceAgentTailnet(ctx, slog.Logger{}, resources[0].Agents[0].ID)
68+
dialer, err := client.DialWorkspaceAgent(ctx, resources[0].Agents[0].ID, nil)
7169
require.NoError(t, err)
7270
defer dialer.Close()
7371
require.Eventually(t, func() bool {
74-
_, err := dialer.Ping()
72+
_, err := dialer.Ping(ctx)
7573
return err == nil
7674
}, testutil.WaitMedium, testutil.IntervalFast)
7775
cancelFunc()
@@ -128,11 +126,11 @@ func TestWorkspaceAgent(t *testing.T) {
128126
if assert.NotEmpty(t, resources) && assert.NotEmpty(t, resources[0].Agents) {
129127
assert.NotEmpty(t, resources[0].Agents[0].Version)
130128
}
131-
dialer, err := client.DialWorkspaceAgentTailnet(ctx, slog.Logger{}, resources[0].Agents[0].ID)
129+
dialer, err := client.DialWorkspaceAgent(ctx, resources[0].Agents[0].ID, nil)
132130
require.NoError(t, err)
133131
defer dialer.Close()
134132
require.Eventually(t, func() bool {
135-
_, err := dialer.Ping()
133+
_, err := dialer.Ping(ctx)
136134
return err == nil
137135
}, testutil.WaitMedium, testutil.IntervalFast)
138136
cancelFunc()
@@ -189,11 +187,11 @@ func TestWorkspaceAgent(t *testing.T) {
189187
if assert.NotEmpty(t, resources) && assert.NotEmpty(t, resources[0].Agents) {
190188
assert.NotEmpty(t, resources[0].Agents[0].Version)
191189
}
192-
dialer, err := client.DialWorkspaceAgentTailnet(ctx, slog.Logger{}, resources[0].Agents[0].ID)
190+
dialer, err := client.DialWorkspaceAgent(ctx, resources[0].Agents[0].ID, nil)
193191
require.NoError(t, err)
194192
defer dialer.Close()
195193
require.Eventually(t, func() bool {
196-
_, err := dialer.Ping()
194+
_, err := dialer.Ping(ctx)
197195
return err == nil
198196
}, testutil.WaitMedium, testutil.IntervalFast)
199197
cancelFunc()

cli/config/file.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ func (r Root) Session() File {
1313
return File(filepath.Join(string(r), "session"))
1414
}
1515

16+
// ReplicaID is a unique identifier for the Coder server.
17+
func (r Root) ReplicaID() File {
18+
return File(filepath.Join(string(r), "replica_id"))
19+
}
20+
1621
func (r Root) URL() File {
1722
return File(filepath.Join(string(r), "url"))
1823
}

cli/configssh_test.go

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/stretchr/testify/assert"
2020
"github.com/stretchr/testify/require"
2121

22-
"cdr.dev/slog"
2322
"cdr.dev/slog/sloggers/slogtest"
2423

2524
"github.com/coder/coder/agent"
@@ -115,7 +114,7 @@ func TestConfigSSH(t *testing.T) {
115114
_ = agentCloser.Close()
116115
}()
117116
resources := coderdtest.AwaitWorkspaceAgents(t, client, workspace.ID)
118-
agentConn, err := client.DialWorkspaceAgentTailnet(context.Background(), slog.Logger{}, resources[0].Agents[0].ID)
117+
agentConn, err := client.DialWorkspaceAgent(context.Background(), resources[0].Agents[0].ID, nil)
119118
require.NoError(t, err)
120119
defer agentConn.Close()
121120

cli/deployment/flags.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ func Flags() *codersdk.DeploymentFlags {
3232
Name: "Wildcard Address URL",
3333
Flag: "wildcard-access-url",
3434
EnvVar: "CODER_WILDCARD_ACCESS_URL",
35-
Description: `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".`,
35+
Description: `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com" or "*-suffix.example.com". Ports or schemes should not be included. The scheme will be copied from the access URL.`,
3636
},
3737
Address: &codersdk.StringFlag{
3838
Name: "Bind Address",
@@ -85,6 +85,13 @@ func Flags() *codersdk.DeploymentFlags {
8585
Description: "Addresses for STUN servers to establish P2P connections. Set empty to disable P2P connections.",
8686
Default: []string{"stun.l.google.com:19302"},
8787
},
88+
DerpServerRelayAddress: &codersdk.StringFlag{
89+
Name: "DERP Server Relay Address",
90+
Flag: "derp-server-relay-address",
91+
EnvVar: "CODER_DERP_SERVER_RELAY_URL",
92+
Description: "An HTTP address that is accessible by other replicas to relay DERP traffic. Required for high availability.",
93+
Enterprise: true,
94+
},
8895
DerpConfigURL: &codersdk.StringFlag{
8996
Name: "DERP Config URL",
9097
Flag: "derp-config-url",

cli/portforward.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import (
1616
"github.com/spf13/cobra"
1717
"golang.org/x/xerrors"
1818

19-
"cdr.dev/slog"
2019
"github.com/coder/coder/agent"
2120
"github.com/coder/coder/cli/cliflag"
2221
"github.com/coder/coder/cli/cliui"
@@ -96,7 +95,7 @@ func portForward() *cobra.Command {
9695
return xerrors.Errorf("await agent: %w", err)
9796
}
9897

99-
conn, err := client.DialWorkspaceAgentTailnet(ctx, slog.Logger{}, workspaceAgent.ID)
98+
conn, err := client.DialWorkspaceAgent(ctx, workspaceAgent.ID, nil)
10099
if err != nil {
101100
return err
102101
}
@@ -139,8 +138,7 @@ func portForward() *cobra.Command {
139138
case <-ctx.Done():
140139
closeErr = ctx.Err()
141140
case <-sigs:
142-
_, _ = fmt.Fprintln(cmd.OutOrStderr(), "Received signal, closing all listeners and active connections")
143-
closeErr = xerrors.New("signal received")
141+
_, _ = fmt.Fprintln(cmd.OutOrStderr(), "\nReceived signal, closing all listeners and active connections")
144142
}
145143

146144
cancel()
@@ -156,7 +154,7 @@ func portForward() *cobra.Command {
156154
case <-ticker.C:
157155
}
158156

159-
_, err = conn.Ping()
157+
_, err = conn.Ping(ctx)
160158
if err != nil {
161159
continue
162160
}
@@ -214,7 +212,11 @@ func listenAndPortForward(ctx context.Context, cmd *cobra.Command, conn *codersd
214212
for {
215213
netConn, err := l.Accept()
216214
if err != nil {
217-
_, _ = fmt.Fprintf(cmd.OutOrStderr(), "Error accepting connection from '%v://%v': %+v\n", spec.listenNetwork, spec.listenAddress, err)
215+
// Silently ignore net.ErrClosed errors.
216+
if xerrors.Is(err, net.ErrClosed) {
217+
return
218+
}
219+
_, _ = fmt.Fprintf(cmd.OutOrStderr(), "Error accepting connection from '%v://%v': %v\n", spec.listenNetwork, spec.listenAddress, err)
218220
_, _ = fmt.Fprintln(cmd.OutOrStderr(), "Killing listener")
219221
return
220222
}

cli/root.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"context"
55
"flag"
66
"fmt"
7+
"io"
78
"net/http"
89
"net/url"
910
"os"
@@ -100,8 +101,9 @@ func Core() []*cobra.Command {
100101
}
101102

102103
func AGPL() []*cobra.Command {
103-
all := append(Core(), Server(deployment.Flags(), func(_ context.Context, o *coderd.Options) (*coderd.API, error) {
104-
return coderd.New(o), nil
104+
all := append(Core(), Server(deployment.Flags(), func(_ context.Context, o *coderd.Options) (*coderd.API, io.Closer, error) {
105+
api := coderd.New(o)
106+
return api, api, nil
105107
}))
106108
return all
107109
}
@@ -607,7 +609,8 @@ func (h *headerTransport) RoundTrip(req *http.Request) (*http.Response, error) {
607609

608610
// ExperimentalEnabled returns if the experimental feature flag is enabled.
609611
func ExperimentalEnabled(cmd *cobra.Command) bool {
610-
return cliflag.IsSetBool(cmd, varExperimental)
612+
enabled, _ := cmd.Flags().GetBool(varExperimental)
613+
return enabled
611614
}
612615

613616
// EnsureExperimental will ensure that the experimental feature flag is set if the given flag is set.

0 commit comments

Comments
 (0)