Skip to content

Commit 446b7bd

Browse files
committed
Merge branch 'main' of github.com:coder/coder into bq/update-resources-table
2 parents e721eec + d2ee18c commit 446b7bd

File tree

239 files changed

+7275
-1469
lines changed

Some content is hidden

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

239 files changed

+7275
-1469
lines changed

.github/workflows/dogfood.yaml

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ on:
1212
workflow_dispatch:
1313

1414
jobs:
15-
deploy:
15+
deploy_image:
1616
runs-on: ubuntu-latest
1717
steps:
1818
- name: Get branch name
@@ -47,3 +47,27 @@ jobs:
4747
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:latest"
4848
cache-from: type=registry,ref=codercom/oss-dogfood:latest
4949
cache-to: type=inline
50+
deploy_template:
51+
runs-on: ubuntu-latest
52+
steps:
53+
- name: Checkout
54+
uses: actions/checkout@v3
55+
- name: Get short commit SHA
56+
id: vars
57+
run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"
58+
- name: "Install latest Coder"
59+
run: |
60+
curl -L https://coder.com/install.sh | sh
61+
# env:
62+
# VERSION: 0.x
63+
- name: "Push template"
64+
run: |
65+
coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION
66+
env:
67+
# Consumed by Coder CLI
68+
CODER_URL: https://dev.coder.com
69+
CODER_SESSION_TOKEN: ${{ secrets.CODER_SESSION_TOKEN }}
70+
# Template source & details
71+
CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }}
72+
CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }}
73+
CODER_TEMPLATE_DIR: ./dogfood

.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",

agent/agent.go

Lines changed: 1 addition & 0 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

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,

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_ADDRESS",
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/login.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -248,9 +248,9 @@ func login() *cobra.Command {
248248
return nil
249249
},
250250
}
251-
cliflag.StringVarP(cmd.Flags(), &email, "email", "e", "CODER_EMAIL", "", "Specifies an email address to authenticate with.")
252-
cliflag.StringVarP(cmd.Flags(), &username, "username", "u", "CODER_USERNAME", "", "Specifies a username to authenticate with.")
253-
cliflag.StringVarP(cmd.Flags(), &password, "password", "p", "CODER_PASSWORD", "", "Specifies a password to authenticate with.")
251+
cliflag.StringVarP(cmd.Flags(), &email, "first-user-email", "", "CODER_FIRST_USER_EMAIL", "", "Specifies an email address to use if creating the first user for the deployment.")
252+
cliflag.StringVarP(cmd.Flags(), &username, "first-user-username", "", "CODER_FIRST_USER_USERNAME", "", "Specifies a username to use if creating the first user for the deployment.")
253+
cliflag.StringVarP(cmd.Flags(), &password, "first-user-password", "", "CODER_FIRST_USER_PASSWORD", "", "Specifies a password to use if creating the first user for the deployment.")
254254
return cmd
255255
}
256256

cli/login_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func TestLogin(t *testing.T) {
7474
// accurately detect Windows ptys when they are not attached to a process:
7575
// https://github.com/mattn/go-isatty/issues/59
7676
doneChan := make(chan struct{})
77-
root, _ := clitest.New(t, "login", client.URL.String(), "--username", "testuser", "--email", "user@coder.com", "--password", "password")
77+
root, _ := clitest.New(t, "login", client.URL.String(), "--first-user-username", "testuser", "--first-user-email", "user@coder.com", "--first-user-password", "password")
7878
pty := ptytest.New(t)
7979
root.SetIn(pty.Input())
8080
root.SetOut(pty.Output())

cli/portforward.go

Lines changed: 2 additions & 3 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
}
@@ -156,7 +155,7 @@ func portForward() *cobra.Command {
156155
case <-ticker.C:
157156
}
158157

159-
_, err = conn.Ping()
158+
_, err = conn.Ping(ctx)
160159
if err != nil {
161160
continue
162161
}

cli/root.go

Lines changed: 4 additions & 2 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
}

cli/server.go

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717
"os/signal"
1818
"os/user"
1919
"path/filepath"
20+
"regexp"
2021
"strconv"
2122
"strings"
2223
"sync"
@@ -53,6 +54,7 @@ import (
5354
"github.com/coder/coder/coderd/database/migrations"
5455
"github.com/coder/coder/coderd/devtunnel"
5556
"github.com/coder/coder/coderd/gitsshkey"
57+
"github.com/coder/coder/coderd/httpapi"
5658
"github.com/coder/coder/coderd/prometheusmetrics"
5759
"github.com/coder/coder/coderd/telemetry"
5860
"github.com/coder/coder/coderd/tracing"
@@ -67,7 +69,7 @@ import (
6769
)
6870

6971
// nolint:gocyclo
70-
func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *coderd.Options) (*coderd.API, error)) *cobra.Command {
72+
func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *coderd.Options) (*coderd.API, io.Closer, error)) *cobra.Command {
7173
root := &cobra.Command{
7274
Use: "server",
7375
Short: "Start a Coder server",
@@ -165,9 +167,10 @@ func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *code
165167
}
166168
defer listener.Close()
167169

170+
var tlsConfig *tls.Config
168171
if dflags.TLSEnable.Value {
169-
listener, err = configureServerTLS(
170-
listener, dflags.TLSMinVersion.Value,
172+
tlsConfig, err = configureTLS(
173+
dflags.TLSMinVersion.Value,
171174
dflags.TLSClientAuth.Value,
172175
dflags.TLSCertFiles.Value,
173176
dflags.TLSKeyFiles.Value,
@@ -176,6 +179,7 @@ func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *code
176179
if err != nil {
177180
return xerrors.Errorf("configure tls: %w", err)
178181
}
182+
listener = tls.NewListener(listener, tlsConfig)
179183
}
180184

181185
tcpAddr, valid := listener.Addr().(*net.TCPAddr)
@@ -297,13 +301,19 @@ func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *code
297301
return xerrors.Errorf("create derp map: %w", err)
298302
}
299303

300-
appHostname := strings.TrimPrefix(dflags.WildcardAccessURL.Value, "http://")
301-
appHostname = strings.TrimPrefix(appHostname, "https://")
302-
appHostname = strings.TrimPrefix(appHostname, "*.")
304+
appHostname := strings.TrimSpace(dflags.WildcardAccessURL.Value)
305+
var appHostnameRegex *regexp.Regexp
306+
if appHostname != "" {
307+
appHostnameRegex, err = httpapi.CompileHostnamePattern(appHostname)
308+
if err != nil {
309+
return xerrors.Errorf("parse wildcard access URL %q: %w", appHostname, err)
310+
}
311+
}
303312

304313
options := &coderd.Options{
305314
AccessURL: accessURLParsed,
306315
AppHostname: appHostname,
316+
AppHostnameRegex: appHostnameRegex,
307317
Logger: logger.Named("coderd"),
308318
Database: databasefake.New(),
309319
DERPMap: derpMap,
@@ -320,6 +330,9 @@ func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *code
320330
Experimental: ExperimentalEnabled(cmd),
321331
DeploymentFlags: dflags,
322332
}
333+
if tlsConfig != nil {
334+
options.TLSCertificates = tlsConfig.Certificates
335+
}
323336

324337
if dflags.OAuth2GithubClientSecret.Value != "" {
325338
options.GithubOAuth2Config, err = configureGithubOAuth2(accessURLParsed,
@@ -463,11 +476,14 @@ func Server(dflags *codersdk.DeploymentFlags, newAPI func(context.Context, *code
463476
), dflags.PromAddress.Value, "prometheus")()
464477
}
465478

466-
coderAPI, err := newAPI(ctx, options)
479+
// We use a separate closer so the Enterprise API
480+
// can have it's own close functions. This is cleaner
481+
// than abstracting the Coder API itself.
482+
coderAPI, closer, err := newAPI(ctx, options)
467483
if err != nil {
468484
return err
469485
}
470-
defer coderAPI.Close()
486+
defer closer.Close()
471487

472488
client := codersdk.New(localURL)
473489
if dflags.TLSEnable.Value {
@@ -885,7 +901,7 @@ func loadCertificates(tlsCertFiles, tlsKeyFiles []string) ([]tls.Certificate, er
885901
return certs, nil
886902
}
887903

888-
func configureServerTLS(listener net.Listener, tlsMinVersion, tlsClientAuth string, tlsCertFiles, tlsKeyFiles []string, tlsClientCAFile string) (net.Listener, error) {
904+
func configureTLS(tlsMinVersion, tlsClientAuth string, tlsCertFiles, tlsKeyFiles []string, tlsClientCAFile string) (*tls.Config, error) {
889905
tlsConfig := &tls.Config{
890906
MinVersion: tls.VersionTLS12,
891907
}
@@ -921,6 +937,7 @@ func configureServerTLS(listener net.Listener, tlsMinVersion, tlsClientAuth stri
921937
if err != nil {
922938
return nil, xerrors.Errorf("load certificates: %w", err)
923939
}
940+
tlsConfig.Certificates = certs
924941
tlsConfig.GetCertificate = func(hi *tls.ClientHelloInfo) (*tls.Certificate, error) {
925942
// If there's only one certificate, return it.
926943
if len(certs) == 1 {
@@ -955,7 +972,7 @@ func configureServerTLS(listener net.Listener, tlsMinVersion, tlsClientAuth stri
955972
tlsConfig.ClientCAs = caPool
956973
}
957974

958-
return tls.NewListener(listener, tlsConfig), nil
975+
return tlsConfig, nil
959976
}
960977

961978
func configureGithubOAuth2(accessURL *url.URL, clientID, clientSecret string, allowSignups bool, allowOrgs []string, rawTeams []string, enterpriseBaseURL string) (*coderd.GithubOAuth2Config, error) {

0 commit comments

Comments
 (0)