8000 Merge remote-tracking branch 'origin/main' into prebuilds-db · coder/coder@1b29686 · GitHub
[go: up one dir, main page]

Skip to content
8000

Commit 1b29686

Browse files
Merge remote-tracking branch 'origin/main' into prebuilds-db
2 parents e489e1b + 5c8cac9 commit 1b29686

Some content is hidden

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

41 files changed

+1130
-792
lines changed

agent/proto/agent.pb.go

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

agent/proto/agent.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ message WorkspaceAgentDevcontainer {
102102
bytes id = 1;
103103
string workspace_folder = 2;
104104
string config_path = 3;
105+
string name = 4;
105106
}
106107

107108
message GetManifestRequest {}

cli/server.go

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -920,34 +920,30 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
920920
notificationsManager *notifications.Manager
921921
)
922922

923-
if notificationsCfg.Enabled() {
924-
metrics := notifications.NewMetrics(options.PrometheusRegistry)
925-
helpers := templateHelpers(options)
923+
metrics := notifications.NewMetrics(options.PrometheusRegistry)
924+
helpers := templateHelpers(options)
926925

927-
// The enqueuer is responsible for enqueueing notifications to the given store.
928-
enqueuer, err := notifications.NewStoreEnqueuer(notificationsCfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
929-
if err != nil {
930-
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
931-
}
932-
options.NotificationsEnqueuer = enqueuer
926+
// The enqueuer is responsible for enqueueing notifications to the given store.
927+
enqueuer, err := notifications.NewStoreEnqueuer(notificationsCfg, options.Database, helpers, logger.Named("notifications.enqueuer"), quartz.NewReal())
928+
if err != nil {
929+
return xerrors.Errorf("failed to instantiate notification store enqueuer: %w", err)
930+
}
931+
options.NotificationsEnqueuer = enqueuer
933932

934-
// The notification manager is responsible for:
935-
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
936-
// - keeping the store updated with status updates
937-
notificationsManager, err = notifications.NewManager(notificationsCfg, options.Database, options.Pubsub, helpers, metrics, logger.Named("notifications.manager"))
938-
if err != nil {
939-
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
940-
}
933+
// The notification manager is responsible for:
934+
// - creating notifiers and managing their lifecycles (notifiers are responsible for dequeueing/sending notifications)
935+
// - keeping the store updated with status updates
936+
notificationsManager, err = notifications.NewManager(notificationsCfg, options.Database, options.Pubsub, helpers, metrics, logger.Named("notifications.manager"))
937+
if err != nil {
938+
return xerrors.Errorf("failed to instantiate notification manager: %w", err)
939+
}
941940

942-
// nolint:gocritic // We need to run the manager in a notifier context.
943-
notificationsManager.Run(dbauthz.AsNotifier(ctx))
941+
// nolint:gocritic // We need to run the manager in a notifier context.
942+
notificationsManager.Run(dbauthz.AsNotifier(ctx))
944943

945-
// Run report generator to distribute periodic reports.
946-
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
947-
defer notificationReportGenerator.Close()
948-
} else {
949-
logger.Debug(ctx, "notifications are currently disabled as there are no configured delivery methods. See https://coder.com/docs/admin/monitoring/notifications#delivery-methods for more details")
950-
}
944+
// Run report generator to distribute periodic reports.
945+
notificationReportGenerator := reports.NewReportGenerator(ctx, logger.Named("notifications.report_generator"), options.Database, options.NotificationsEnqueuer, quartz.NewReal())
946+
defer notificationReportGenerator.Close()
951947

952948
// Since errCh only has one buffered slot, all routines
953949
// sending on it must be wrapped in a select/default to

cli/server_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -298,7 +298,7 @@ func TestServer(t *testing.T) {
298298
out := pty.ReadAll()
299299
numLines := countLines(string(out))
300300
t.Logf("numLines: %d", numLines)
301-
require.Less(t, numLines, 12, "expected less than 12 lines of output (terminal width 80), got %d", numLines)
301+
require.Less(t, numLines, 20, "expected less than 20 lines of output (terminal width 80), got %d", numLines)
302302
})
303303

304304
t.Run("OAuth2GitHubDefaultProvider", func(t *testing.T) {

cli/start.go

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ func (r *RootCmd) start() *serpent.Command {
1717
var (
1818
parameterFlags workspaceParameterFlags
1919
bflags buildFlags
20+
21+
noWait bool
2022
)
2123

2224
client := new(codersdk.Client)
@@ -28,7 +30,15 @@ func (r *RootCmd) start() *serpent.Command {
2830
serpent.RequireNArgs(1),
2931
r.InitClient(client),
3032
),
31-
Options: serpent.OptionSet{cliui.SkipPromptOption()},
33+
Options: serpent.OptionSet{
34+
{
35+
Flag: "no-wait",
36+
Description: "Return immediately after starting the workspace.",
37+
Value: serpent.BoolOf(&noWait),
38+
Hidden: false,
39+
},
40+
cliui.SkipPromptOption(),
41+
},
3242
Handler: func(inv *serpent.Invocation) error {
3343
workspace, err := namedWorkspace(inv.Context(), client, inv.Args[0])
3444
if err != nil {
@@ -80,6 +90,11 @@ func (r *RootCmd) start() *serpent.Command {
8090
}
8191
}
8292

93+
if noWait {
94+
_, _ = fmt.Fprintf(inv.Stdout, "The %s workspace has been started in no-wait mode. Workspace is building in the background.\n", cliui.Keyword(workspace.Name))
95+
return nil
96+
}
97+
8398
err = cliui.WorkspaceBuild(inv.Context(), inv.Stdout, client, build.ID)
8499
if err != nil {
85100
return err

cli/start_test.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -441,3 +441,36 @@ func TestStart_Starting(t *testing.T) {
441441

442442
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
443443
}
444+
445+
func TestStart_NoWait(t *testing.T) {
446+
t.Parallel()
447+
ctx := testutil.Context(t, testutil.WaitShort)
448+
449+
// Prepare user, template, workspace
450+
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
451+
owner := coderdtest.CreateFirstUser(t, client)
452+
member, _ := coderdtest.CreateAnotherUser(t, client, owner.OrganizationID)
453+
version1 := coderdtest.CreateTemplateVersion(t, client, owner.OrganizationID, nil)
454+
coderdtest.AwaitTemplateVersionJobCompleted(t, client, version1.ID)
455+
template := coderdtest.CreateTemplate(t, client, owner.OrganizationID, version1.ID)
456+
workspace := coderdtest.CreateWorkspace(t, member, template.ID)
457+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, workspace.LatestBuild.ID)
458+
459+
// Stop the workspace
460+
build := coderdtest.CreateWorkspaceBuild(t, member, workspace, database.WorkspaceTransitionStop)
461+
coderdtest.AwaitWorkspaceBuildJobCompleted(t, client, build.ID)
462+
463+
// Start in no-wait mode
464+
inv, root := clitest.New(t, "start", workspace.Name, "--no-wait")
465+
clitest.SetupConfig(t, member, root)
466+
doneChan := make(chan struct{})
467+
pty := ptytest.New(t).Attach(inv)
468+
go func() {
469+
defer close(doneChan)
470+
err := inv.Run()
471+
assert.NoError(t, err)
472+
}()
473+
474+
pty.ExpectMatch("workspace has been started in no-wait mode")
475+
_ = testutil.RequireRecvCtx(ctx, t, doneChan)
476+
}

cli/testdata/coder_server_--help.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,10 @@ Configure TLS for your SMTP server target.
473473
Enable STARTTLS to upgrade insecure SMTP connections using TLS.
474474
DEPRECATED: Use --email-tls-starttls instead.
475475

476+
NOTIFICATIONS / INBOX OPTIONS:
477+
--notifications-inbox-enabled bool, $CODER_NOTIFICATIONS_INBOX_ENABLED (default: true)
478+
Enable Coder Inbox.
479+
476480
NOTIFICATIONS / WEBHOOK OPTIONS:
477481
--notifications-webhook-endpoint url, $CODER_NOTIFICATIONS_WEBHOOK_ENDPOINT
478482
The endpoint to which to send webhooks.

cli/testdata/coder_start_--help.golden

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ OPTIONS:
2222
Set the value of ephemeral parameters defined in the template. The
2323
format is "name=value".
2424

25+
--no-wait bool
26+
Return immediately after starting the workspace.
27+
2528
--parameter string-array, $CODER_RICH_PARAMETER
2629
Rich parameter value in the format "name=value".
2730

cli/testdata/server-config.yaml.golden

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,10 @@ notifications:
643643
# The endpoint to which to send webhooks.
644644
# (default: <unset>, type: url)
645645
endpoint:
646+
inbox:
647+
# Enable Coder Inbox.
648+
# (default: true, type: bool)
649+
enabled: true
646650
# The upper limit of attempts to send a notification.
647651
# (default: 5, type: int)
648652
maxSendAttempts: 5

coderd/agentapi/manifest.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ func dbAgentDevcontainersToProto(devcontainers []database.WorkspaceAgentDevconta
244244
for i, dc := range devcontainers {
245245
ret[i] = &agentproto.WorkspaceAgentDevcontainer{
246246
Id: dc.ID[:],
247+
Name: dc.Name,
247248
WorkspaceFolder: dc.WorkspaceFolder,
248249
ConfigPath: dc.ConfigPath,
249250
}

coderd/agentapi/manifest_test.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,13 @@ func TestGetManifest(t *testing.T) {
159159
devcontainers = []database.WorkspaceAgentDevcontainer{
160160
{
161161
ID: uuid.New(),
162+
Name: "cool",
162163
WorkspaceAgentID: agent.ID,
163164
WorkspaceFolder: "/cool/folder",
164165
},
165166
{
166167
ID: uuid.New(),
168+
Name: "another",
167169
WorkspaceAgentID: agent.ID,
168170
WorkspaceFolder: "/another/cool/folder",
169171
ConfigPath: "/another/cool/folder/.devcontainer/devcontainer.json",
@@ -283,10 +285,12 @@ func TestGetManifest(t *testing.T) {
283285
protoDevcontainers = []*agentproto.WorkspaceAgentDevcontainer{
284286
{
285287
Id: devcontainers[0].ID[:],
288+
Name: devcontainers[0].Name,
286289
WorkspaceFolder: devcontainers[0].WorkspaceFolder,
287290
},
288291
{
289292
Id: devcontainers[1].ID[:],
293+
Name: devcontainers[1].Name,
290294
WorkspaceFolder: devcontainers[1].WorkspaceFolder,
291295
ConfigPath: devcontainers[1].ConfigPath,
292296
},

coderd/apidoc/docs.go

Lines changed: 16 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: 16 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/dbgen/dbgen.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,7 @@ func WorkspaceAgentDevcontainer(t testing.TB, db database.Store, orig database.W
260260
WorkspaceAgentID: takeFirst(orig.WorkspaceAgentID, uuid.New()),
261261
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
262262
ID: []uuid.UUID{takeFirst(orig.ID, uuid.New())},
263+
Name: []string{takeFirst(orig.Name, testutil.GetRandomName(t))},
263264
WorkspaceFolder: []string{takeFirst(orig.WorkspaceFolder, "/workspace")},
264265
ConfigPath: []string{takeFirst(orig.ConfigPath, "")},
265266
})

coderd/database/dbmem/dbmem.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9199,6 +9199,7 @@ func (q *FakeQuerier) InsertWorkspaceAgentDevcontainers(_ context.Context, arg d
91999199
WorkspaceAgentID: arg.WorkspaceAgentID,
92009200
CreatedAt: arg.CreatedAt,
92019201
ID: id,
9202+
Name: arg.Name[i],
92029203
WorkspaceFolder: arg.WorkspaceFolder[i],
92039204
ConfigPath: arg.ConfigPath[i],
92049205
})

coderd/database/dump.sql

Lines changed: 4 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE workspace_agent_devcontainers DROP COLUMN name;
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
ALTER TABLE workspace_agent_devcontainers ADD COLUMN name TEXT NOT NULL DEFAULT '';
2+
ALTER TABLE workspace_agent_devcontainers ALTER COLUMN name DROP DEFAULT;
3+
4+
COMMENT ON COLUMN workspace_agent_devcontainers.name IS 'The name of the Dev Container.';

coderd/database/models.go

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

coderd/database/pubsub/pubsub.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,6 @@ func (p *PGPubsub) startListener(ctx context.Context, connectURL string) error {
492492
p.connected.Set(0)
493493
// Creates a new listener using pq.
494494
var (
495-
errCh = make(chan error)
496495
dialer = logDialer{
497496
logger: p.logger,
498497
// pq.defaultDialer uses a zero net.Dialer as well.
@@ -525,6 +524,10 @@ func (p *PGPubsub) startListener(ctx context.Context, connectURL string) error {
525524
dc.Dialer(dialer)
526525
}
527526

527+
var (
528+
errCh = make(chan error, 1)
529+
sentErrCh = false
530+
)
528531
p.pgListener = pqListenerShim{
529532
Listener: pq.NewConnectorListener(connector, connectURL, time.Second, time.Minute, func(t pq.ListenerEventType, err error) {
530533
switch t {
@@ -541,18 +544,16 @@ func (p *PGPubsub) startListener(ctx context.Context, connectURL string) error {
541544
p.logger.Error(ctx, "pubsub failed to connect to postgres", slog.Error(err))
542545
}
543546
// This callback gets events whenever the connection state changes.
544-
// Don't send if the errChannel has already been closed.
545-
select {
546-
case <-errCh:
547+
// Only send the first error.
548+
if sentErrCh {
547549
return
548-
default:
549-
errCh <- err
550-
close(errCh)
551550
}
551+
errCh <- err // won't block because we are buffered.
552+
sentErrCh = true
552553
}),
553554
}
554555
select {
555-
case err := <-errCh:
556+
case err = <-errCh:
556557
if err != nil {
557558
_ = p.pgListener.Close()
558559
return xerrors.Errorf("create pq listener: %w", err)

0 commit comments

Comments
 (0)
0