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

Skip to content

Commit 169bd5e

Browse files
committed
Merge remote-tracking branch 'origin/main' into stevenmasley/old_version
2 parents 0351ce5 + 74934e1 commit 169bd5e

File tree

139 files changed

+4873
-2003
lines changed

Some content is hidden

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

139 files changed

+4873
-2003
lines changed

agent/agent.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,11 @@ func (a *agent) runLoop() {
368368
if ctx.Err() != nil {
369369
// Context canceled errors may come from websocket pings, so we
370370
// don't want to use `errors.Is(err, context.Canceled)` here.
371+
a.logger.Warn(ctx, "runLoop exited with error", slog.Error(ctx.Err()))
371372
return
372373
}
373374
if a.isClosed() {
375+
a.logger.Warn(ctx, "runLoop exited because agent is closed")
374376
return
375377
}
376378
if errors.Is(err, io.EOF) {
@@ -1051,7 +1053,11 @@ func (a *agent) run() (retErr error) {
10511053
return a.statsReporter.reportLoop(ctx, aAPI)
10521054
})
10531055

1054-
return connMan.wait()
1056+
err = connMan.wait()
1057+
if err != nil {
1058+
a.logger.Info(context.Background(), "connection manager errored", slog.Error(err))
1059+
}
1060+
return err
10551061
}
10561062

10571063
// handleManifest returns a function that fetches and processes the manifest

cli/agent.go

Lines changed: 70 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ import (
2525
"cdr.dev/slog/sloggers/sloghuman"
2626
"cdr.dev/slog/sloggers/slogjson"
2727
"cdr.dev/slog/sloggers/slogstackdriver"
28+
"github.com/coder/serpent"
29+
2830
"github.com/coder/coder/v2/agent"
2931
"github.com/coder/coder/v2/agent/agentexec"
3032
"github.com/coder/coder/v2/agent/agentssh"
@@ -33,7 +35,6 @@ import (
3335
"github.com/coder/coder/v2/cli/clilog"
3436
"github.com/coder/coder/v2/codersdk"
3537
"github.com/coder/coder/v2/codersdk/agentsdk"
36-
"github.com/coder/serpent"
3738
)
3839

3940
func (r *RootCmd) workspaceAgent() *serpent.Command {
@@ -63,8 +64,10 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
6364
// This command isn't useful to manually execute.
6465
Hidden: true,
6566
Handler: func(inv *serpent.Invocation) error {
66-
ctx, cancel := context.WithCancel(inv.Context())
67-
defer cancel()
67+
ctx, cancel := context.WithCancelCause(inv.Context())
68+
defer func() {
69+
cancel(xerrors.New("agent exited"))
70+
}()
6871

6972
var (
7073
ignorePorts = map[int]string{}
@@ -281,7 +284,6 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
281284
return xerrors.Errorf("add executable to $PATH: %w", err)
282285
}
283286

284-
prometheusRegistry := prometheus.NewRegistry()
285287
subsystemsRaw := inv.Environ.Get(agent.EnvAgentSubsystem)
286288
subsystems := []codersdk.AgentSubsystem{}
287289
for _, s := range strings.Split(subsystemsRaw, ",") {
@@ -325,46 +327,70 @@ func (r *RootCmd) workspaceAgent() *serpent.Command {
325327
logger.Info(ctx, "agent devcontainer detection not enabled")
326328
}
327329

328-
agnt := agent.New(agent.Options{
329-
Client: client,
330-
Logger: logger,
331-
LogDir: logDir,
332-
ScriptDataDir: scriptDataDir,
333-
// #nosec G115 - Safe conversion as tailnet listen port is within uint16 range (0-65535)
334-
TailnetListenPort: uint16(tailnetListenPort),
335-
ExchangeToken: func(ctx context.Context) (string, error) {
336-
if exchangeToken == nil {
337-
return client.SDK.SessionToken(), nil
338-
}
339-
resp, err := exchangeToken(ctx)
340-
if err != nil {
341-
return "", err
342-
}
343-
client.SetSessionToken(resp.SessionToken)
344-
return resp.SessionToken, nil
345-
},
346-
EnvironmentVariables: environmentVariables,
347-
IgnorePorts: ignorePorts,
348-
SSHMaxTimeout: sshMaxTimeout,
349-
Subsystems: subsystems,
350-
351-
PrometheusRegistry: prometheusRegistry,
352-
BlockFileTransfer: blockFileTransfer,
353-
Execer: execer,
354-
SubAgent: subAgent,
355-
356-
ExperimentalDevcontainersEnabled: experimentalDevcontainersEnabled,
357-
})
358-
359-
promHandler := agent.PrometheusMetricsHandler(prometheusRegistry, logger)
360-
prometheusSrvClose := ServeHandler(ctx, logger, promHandler, prometheusAddress, "prometheus")
361-
defer prometheusSrvClose()
362-
363-
debugSrvClose := ServeHandler(ctx, logger, agnt.HTTPDebug(), debugAddress, "debug")
364-
defer debugSrvClose()
365-
366-
<-ctx.Done()
367-
return agnt.Close()
330+
reinitEvents := agentsdk.WaitForReinitLoop(ctx, logger, client)
331+
332+
var (
333+
lastErr error
334+
mustExit bool
335+
)
336+
for {
337+
prometheusRegistry := prometheus.NewRegistry()
338+
339+
agnt := agent.New(agent.Options{
340+
Client: client,
341+
Logger: logger,
342+
LogDir: logDir,
343+
ScriptDataDir: scriptDataDir,
344+
// #nosec G115 - Safe conversion as tailnet listen port is within uint16 range (0-65535)
345+
TailnetListenPort: uint16(tailnetListenPort),
346+
ExchangeToken: func(ctx context.Context) (string, error) {
347+
if exchangeToken == nil {
348+
return client.SDK.SessionToken(), nil
349+
}
350+
resp, err := exchangeToken(ctx)
351+
if err != nil {
352+
return "", err
353+
}
354+
client.SetSessionToken(resp.SessionToken)
355+
return resp.SessionToken, nil
356+
},
357+
EnvironmentVariables: environmentVariables,
358+
IgnorePorts: ignorePorts,
359+
SSHMaxTimeout: sshMaxTimeout,
360+
Subsystems: subsystems,
361+
362+
PrometheusRegistry: prometheusRegistry,
363+
BlockFileTransfer: blockFileTransfer,
364+
Execer: execer,
365+
SubAgent: subAgent,
366+
ExperimentalDevcontainersEnabled: experimentalDevcontainersEnabled,
367+
})
368+
369+
promHandler := agent.PrometheusMetricsHandler(prometheusRegistry, logger)
370+
prometheusSrvClose := ServeHandler(ctx, logger, promHandler, prometheusAddress, "prometheus")
371+
372+
debugSrvClose := ServeHandler(ctx, logger, agnt.HTTPDebug(), debugAddress, "debug")
373+
374+
select {
375+
case <-ctx.Done():
376+
logger.Info(ctx, "agent shutting down", slog.Error(context.Cause(ctx)))
377+
mustExit = true
378+
case event := <-reinitEvents:
379+
logger.Info(ctx, "agent received instruction to reinitialize",
380+
slog.F("workspace_id", event.WorkspaceID), slog.F("reason", event.Reason))
381+
}
382+
383+
lastErr = agnt.Close()
384+
debugSrvClose()
385+
prometheusSrvClose()
386+
387+
if mustExit {
388+
break
389+
}
390+
391+
logger.Info(ctx, "agent reinitializing")
392+
}
393+
return lastErr
368394
},
369395
}
370396

cli/server.go

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -928,6 +928,37 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
928928
options.StatsBatcher = batcher
929929
defer closeBatcher()
930930

931+
// Manage notifications.
932+
var (
933+
notificationsCfg = options.DeploymentValues.Notifications
934+
notificationsManager *notifications.Manager
935+
)
936+
937+
metrics := notifications.NewMetrics(options.PrometheusRegistry)
938+
helpers := templateHelpers(options)
939+
940+
// The enqueuer is responsible for enqueueing notifications to the given store.
941+
enqueuer, err := notifications.NewStoreEnqueuer(notificationsCfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
942+
if err != nil {
943+
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
944+
}
945+
options.NotificationsEnqueuer = enqueuer
946+
947+
// The notification manager is responsible for:
948+
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
949+
// - keeping the store updated with status updates
950+
notificationsManager, err = notifications.NewManager(notificationsCfg, options.Database, options.Pubsub, helpers, metrics, logger.Named("notifications.manager"))
951+
if err != nil {
952+
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
953+
}
954+
955+
// nolint:gocritic // We need to run the manager in a notifier context.
956+
notificationsManager.Run(dbauthz.AsNotifier(ctx))
957+
958+
// Run report generator to distribute periodic reports.
959+
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
960+
defer notificationReportGenerator.Close()
961+
931962
// We use a separate coderAPICloser so the Enterprise API
932963
// can have its own close functions. This is cleaner
933964
// than abstracting the Coder API itself.
@@ -975,37 +1006,6 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
9751006
return xerrors.Errorf("write config url: %w", err)
9761007
}
9771008

978-
// Manage notifications.
979-
var (
980-
notificationsCfg = options.DeploymentValues.Notifications
981-
notificationsManager *notifications.Manager
982-
)
983-
984-
metrics := notifications.NewMetrics(options.PrometheusRegistry)
985-
helpers := templateHelpers(options)
986-
987-
// The enqueuer is responsible for enqueueing notifications to the given store.
988-
enqueuer, err := notifications.NewStoreEnqueuer(notificationsCfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
989-
if err != nil {
990-
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
991-
}
992-
options.NotificationsEnqueuer = enqueuer
993-
994-
// The notification manager is responsible for:
995-
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
996-
// - keeping the store updated with status updates
997-
notificationsManager, err = notifications.NewManager(notificationsCfg, options.Database, options.Pubsub, helpers, metrics, logger.Named("notifications.manager"))
998-
if err != nil {
999-
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
1000-
}
1001-
1002-
// nolint:gocritic // We need to run the manager in a notifier context.
1003-
notificationsManager.Run(dbauthz.AsNotifier(ctx))
1004-
1005-
// Run report generator to distribute periodic reports.
1006-
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
1007-
defer notificationReportGenerator.Close()
1008-
10091009
// Since errCh only has one buffered slot, all routines
10101010
// sending on it must be wrapped in a select/default to
10111011
// avoid leaving dangling goroutines waiting for the

coderd/apidoc/docs.go

Lines changed: 45 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 37 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)