Skip to content

Commit 8cf12e9

Browse files
committed
Merge remote-tracking branch 'origin/main' into groups
2 parents 7f2de03 + 6b365f4 commit 8cf12e9

File tree

174 files changed

+4901
-2234
lines changed

Some content is hidden

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

174 files changed

+4901
-2234
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -410,7 +410,7 @@ gen/mark-fresh:
410410
# Runs migrations to output a dump of the database schema after migrations are
411411
# applied.
412412
coderd/database/dump.sql: coderd/database/gen/dump/main.go $(wildcard coderd/database/migrations/*.sql)
413-
go run coderd/database/gen/dump/main.go
413+
go run ./coderd/database/gen/dump/main.go
414414

415415
# Generates Go code for querying the database.
416416
coderd/database/querier.go: coderd/database/sqlc.yaml coderd/database/dump.sql $(wildcard coderd/database/queries/*.sql) coderd/database/gen/enum/main.go

agent/agent.go

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,15 @@ func (a *agent) runTailnet(ctx context.Context, derpMap *tailcfg.DERPMap) {
272272

273273
// runCoordinator listens for nodes and updates the self-node as it changes.
274274
func (a *agent) runCoordinator(ctx context.Context) {
275+
for {
276+
reconnect := a.runCoordinatorWithRetry(ctx)
277+
if !reconnect {
278+
return
279+
}
280+
}
281+
}
282+
283+
func (a *agent) runCoordinatorWithRetry(ctx context.Context) (reconnect bool) {
275284
var coordinator net.Conn
276285
var err error
277286
// An exponential back-off occurs when the connection is failing to dial.
@@ -280,38 +289,38 @@ func (a *agent) runCoordinator(ctx context.Context) {
280289
coordinator, err = a.coordinatorDialer(ctx)
281290
if err != nil {
282291
if errors.Is(err, context.Canceled) {
283-
return
292+
return false
284293
}
285294
if a.isClosed() {
286-
return
295+
return false
287296
}
288297
a.logger.Warn(context.Background(), "failed to dial", slog.Error(err))
289298
continue
290299
}
300+
//nolint:revive // Defer is ok because we're exiting this loop.
301+
defer coordinator.Close()
291302
a.logger.Info(context.Background(), "connected to coordination server")
292303
break
293304
}
294305
select {
295306
case <-ctx.Done():
296-
return
307+
return false
297308
default:
298309
}
299-
defer coordinator.Close()
300310
sendNodes, errChan := tailnet.ServeCoordinator(coordinator, a.network.UpdateNodes)
301311
a.network.SetNodeCallback(sendNodes)
302312
select {
303313
case <-ctx.Done():
304-
return
314+
return false
305315
case err := <-errChan:
306316
if a.isClosed() {
307-
return
317+
return false
308318
}
309319
if errors.Is(err, context.Canceled) {
310-
return
320+
return false
311321
}
312322
a.logger.Debug(ctx, "node broker accept exited; restarting connection", slog.Error(err))
313-
a.runCoordinator(ctx)
314-
return
323+
return true
315324
}
316325
}
317326

agent/agent_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,7 @@ func TestAgent(t *testing.T) {
490490
require.Eventually(t, func() bool {
491491
_, err := conn.Ping()
492492
return err == nil
493-
}, testutil.WaitMedium, testutil.IntervalFast)
493+
}, testutil.WaitLong, testutil.IntervalFast)
494494
})
495495

496496
t.Run("Speedtest", func(t *testing.T) {

cli/cliui/provisionerjob.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ func WorkspaceBuild(ctx context.Context, writer io.Writer, client *codersdk.Clie
2222
build, err := client.WorkspaceBuild(ctx, build)
2323
return build.Job, err
2424
},
25-
Logs: func() (<-chan codersdk.ProvisionerJobLog, error) {
25+
Logs: func() (<-chan codersdk.ProvisionerJobLog, io.Closer, error) {
2626
return client.WorkspaceBuildLogsAfter(ctx, build, before)
2727
},
2828
})
@@ -31,7 +31,7 @@ func WorkspaceBuild(ctx context.Context, writer io.Writer, client *codersdk.Clie
3131
type ProvisionerJobOptions struct {
3232
Fetch func() (codersdk.ProvisionerJob, error)
3333
Cancel func() error
34-
Logs func() (<-chan codersdk.ProvisionerJobLog, error)
34+
Logs func() (<-chan codersdk.ProvisionerJobLog, io.Closer, error)
3535

3636
FetchInterval time.Duration
3737
// Verbose determines whether debug and trace logs will be shown.
@@ -132,10 +132,11 @@ func ProvisionerJob(ctx context.Context, writer io.Writer, opts ProvisionerJobOp
132132
// The initial stage needs to print after the signal handler has been registered.
133133
printStage()
134134

135-
logs, err := opts.Logs()
135+
logs, closer, err := opts.Logs()
136136
if err != nil {
137137
return xerrors.Errorf("logs: %w", err)
138138
}
139+
defer closer.Close()
139140

140141
var (
141142
// logOutput is where log output is written

cli/cliui/provisionerjob_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cliui_test
22

33
import (
44
"context"
5+
"io"
56
"os"
67
"runtime"
78
"sync"
@@ -136,8 +137,10 @@ func newProvisionerJob(t *testing.T) provisionerJobTest {
136137
Cancel: func() error {
137138
return nil
138139
},
139-
Logs: func() (<-chan codersdk.ProvisionerJobLog, error) {
140-
return logs, nil
140+
Logs: func() (<-chan codersdk.ProvisionerJobLog, io.Closer, error) {
141+
return logs, closeFunc(func() error {
142+
return nil
143+
}), nil
141144
},
142145
})
143146
},
@@ -164,3 +167,9 @@ func newProvisionerJob(t *testing.T) provisionerJobTest {
164167
PTY: ptty,
165168
}
166169
}
170+
171+
type closeFunc func() error
172+
173+
func (c closeFunc) Close() error {
174+
return c()
175+
}

cli/create.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"io"
56
"time"
67

78
"github.com/spf13/cobra"
@@ -253,7 +254,7 @@ PromptParamLoop:
253254
Cancel: func() error {
254255
return client.CancelTemplateVersionDryRun(cmd.Context(), templateVersion.ID, dryRun.ID)
255256
},
256-
Logs: func() (<-chan codersdk.ProvisionerJobLog, error) {
257+
Logs: func() (<-chan codersdk.ProvisionerJobLog, io.Closer, error) {
257258
return client.TemplateVersionDryRunLogsAfter(cmd.Context(), templateVersion.ID, dryRun.ID, after)
258259
},
259260
// Don't show log output for the dry-run unless there's an error.

cli/resetpassword_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func TestResetPassword(t *testing.T) {
4747
go func() {
4848
defer close(serverDone)
4949
err = serverCmd.ExecuteContext(ctx)
50-
assert.ErrorIs(t, err, context.Canceled)
50+
assert.NoError(t, err)
5151
}()
5252
var rawURL string
5353
require.Eventually(t, func() bool {

cli/root.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,7 @@ func Root(subcommands []*cobra.Command) *cobra.Command {
165165
}
166166

167167
cmd.AddCommand(subcommands...)
168+
fixUnknownSubcommandError(cmd.Commands())
168169

169170
cmd.SetUsageTemplate(usageTemplate())
170171

@@ -187,6 +188,35 @@ func Root(subcommands []*cobra.Command) *cobra.Command {
187188
return cmd
188189
}
189190

191+
// fixUnknownSubcommandError modifies the provided commands so that the
192+
// ones with subcommands output the correct error message when an
193+
// unknown subcommand is invoked.
194+
//
195+
// Example:
196+
//
197+
// unknown command "bad" for "coder templates"
198+
func fixUnknownSubcommandError(commands []*cobra.Command) {
199+
for _, sc := range commands {
200+
if sc.HasSubCommands() {
201+
if sc.Run == nil && sc.RunE == nil {
202+
if sc.Args != nil {
203+
// In case the developer does not know about this
204+
// behavior in Cobra they must verify correct
205+
// behavior. For instance, settings Args to
206+
// `cobra.ExactArgs(0)` will not give the same
207+
// message as `cobra.NoArgs`. Likewise, omitting the
208+
// run function will not give the wanted error.
209+
panic("developer error: subcommand has subcommands and Args but no Run or RunE")
210+
}
211+
sc.Args = cobra.NoArgs
212+
sc.Run = func(*cobra.Command, []string) {}
213+
}
214+
215+
fixUnknownSubcommandError(sc.Commands())
216+
}
217+
}
218+
}
219+
190220
// versionCmd prints the coder version
191221
func versionCmd() *cobra.Command {
192222
return &cobra.Command{

cli/server.go

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
7272
var (
7373
accessURL string
7474
address string
75+
wildcardAccessURL string
7576
autobuildPollInterval time.Duration
7677
derpServerEnabled bool
7778
derpServerRegionID int
@@ -103,6 +104,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
103104
oidcScopes []string
104105
tailscaleEnable bool
105106
telemetryEnable bool
107+
telemetryTraceEnable bool
106108
telemetryURL string
107109
tlsCertFile string
108110
tlsClientCAFile string
@@ -160,17 +162,26 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
160162
sqlDriver = "postgres"
161163
)
162164

163-
if traceEnable || telemetryEnable {
164-
sdkTracerProvider, err := tracing.TracerProvider(ctx, "coderd", tracing.TracerOpts{
165+
// Coder tracing should be disabled if telemetry is disabled unless
166+
// --telemetry-trace was explicitly provided.
167+
shouldCoderTrace := telemetryEnable && !isTest()
168+
// Only override if telemetryTraceEnable was specifically set.
169+
// By default we want it to be controlled by telemetryEnable.
170+
if cmd.Flags().Changed("telemetry-trace") {
171+
shouldCoderTrace = telemetryTraceEnable
172+
}
173+
174+
if traceEnable || shouldCoderTrace {
175+
sdkTracerProvider, closeTracing, err := tracing.TracerProvider(ctx, "coderd", tracing.TracerOpts{
165176
Default: traceEnable,
166-
Coder: telemetryEnable && !isTest(),
177+
Coder: shouldCoderTrace,
167178
})
168179
if err != nil {
169180
logger.Warn(ctx, "start telemetry exporter", slog.Error(err))
170181
} else {
171182
// allow time for traces to flush even if command context is canceled
172183
defer func() {
173-
_ = shutdownWithTimeout(sdkTracerProvider, 5*time.Second)
184+
_ = shutdownWithTimeout(closeTracing, 5*time.Second)
174185
}()
175186

176187
d, err := tracing.PostgresDriver(sdkTracerProvider, "coderd.database")
@@ -337,8 +348,13 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
337348
return xerrors.Errorf("create derp map: %w", err)
338349
}
339350

351+
appHostname := strings.TrimPrefix(wildcardAccessURL, "http://")
352+
appHostname = strings.TrimPrefix(appHostname, "https://")
353+
appHostname = strings.TrimPrefix(appHostname, "*.")
354+
340355
options := &coderd.Options{
341356
AccessURL: accessURLParsed,
357+
AppHostname: appHostname,
342358
Logger: logger.Named("coderd"),
343359
Database: databasefake.New(),
344360
DERPMap: derpMap,
@@ -545,7 +561,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
545561
},
546562
}
547563
defer func() {
548-
_ = shutdownWithTimeout(server, 5*time.Second)
564+
_ = shutdownWithTimeout(server.Shutdown, 5*time.Second)
549565
}()
550566

551567
eg := errgroup.Group{}
@@ -633,7 +649,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
633649
// in-flight requests, give in-flight requests 5 seconds to
634650
// complete.
635651
cmd.Println("Shutting down API server...")
636-
err = shutdownWithTimeout(server, 5*time.Second)
652+
err = shutdownWithTimeout(server.Shutdown, 5*time.Second)
637653
if err != nil {
638654
cmd.Printf("API server shutdown took longer than 5s: %s", err)
639655
} else {
@@ -655,7 +671,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
655671
if verbose {
656672
cmd.Printf("Shutting down provisioner daemon %d...\n", id)
657673
}
658-
err := shutdownWithTimeout(provisionerDaemon, 5*time.Second)
674+
err := shutdownWithTimeout(provisionerDaemon.Shutdown, 5*time.Second)
659675
if err != nil {
660676
cmd.PrintErrf("Failed to shutdown provisioner daemon %d: %s\n", id, err)
661677
return
@@ -690,6 +706,9 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
690706
// Trigger context cancellation for any remaining services.
691707
cancel()
692708

709+
if xerrors.Is(exitErr, context.Canceled) {
710+
return nil
711+
}
693712
return exitErr
694713
},
695714
}
@@ -742,6 +761,7 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
742761
"External URL to access your deployment. This must be accessible by all provisioned workspaces.")
743762
cliflag.StringVarP(root.Flags(), &address, "address", "a", "CODER_ADDRESS", "127.0.0.1:3000",
744763
"Bind address of the server.")
764+
cliflag.StringVarP(root.Flags(), &wildcardAccessURL, "wildcard-access-url", "", "CODER_WILDCARD_ACCESS_URL", "", `Specifies the wildcard hostname to use for workspace applications in the form "*.example.com".`)
745765
cliflag.StringVarP(root.Flags(), &derpConfigURL, "derp-config-url", "", "CODER_DERP_CONFIG_URL", "",
746766
"URL to fetch a DERP mapping on startup. See: https://tailscale.com/kb/1118/custom-derp-servers/")
747767
cliflag.StringVarP(root.Flags(), &derpConfigPath, "derp-config-path", "", "CODER_DERP_CONFIG_PATH", "",
@@ -809,6 +829,8 @@ func Server(newAPI func(context.Context, *coderd.Options) (*coderd.API, error))
809829
enableTelemetryByDefault := !isTest()
810830
cliflag.BoolVarP(root.Flags(), &telemetryEnable, "telemetry", "", "CODER_TELEMETRY", enableTelemetryByDefault,
811831
"Whether telemetry is enabled or not. Coder collects anonymized usage data to help improve our product.")
832+
cliflag.BoolVarP(root.Flags(), &telemetryTraceEnable, "telemetry-trace", "", "CODER_TELEMETRY_TRACE", enableTelemetryByDefault,
833+
"Whether Opentelemetry traces are sent to Coder. Coder collects anonymized application tracing to help improve our product. Disabling telemetry also disables this option.")
812834
cliflag.StringVarP(root.Flags(), &telemetryURL, "telemetry-url", "", "CODER_TELEMETRY_URL", "https://telemetry.coder.com",
813835
"URL to send telemetry.")
814836
_ = root.Flags().MarkHidden("telemetry-url")
@@ -903,10 +925,10 @@ func isLocalURL(ctx context.Context, u *url.URL) (bool, error) {
903925
return false, nil
904926
}
905927

906-
func shutdownWithTimeout(s interface{ Shutdown(context.Context) error }, timeout time.Duration) error {
928+
func shutdownWithTimeout(shutdown func(context.Context) error, timeout time.Duration) error {
907929
ctx, cancel := context.WithTimeout(context.Background(), timeout)
908930
defer cancel()
909-
return s.Shutdown(ctx)
931+
return shutdown(ctx)
910932
}
911933

912934
// nolint:revive

0 commit comments

Comments
 (0)