Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit58b810f

Browse files
fix: fix dormancy notifications (#14029)
1 parent22143d3 commit58b810f

File tree

12 files changed

+194
-128
lines changed

12 files changed

+194
-128
lines changed

‎coderd/autobuild/lifecycle_executor.go

Lines changed: 22 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import (
1919
"github.com/coder/coder/v2/coderd/database/dbtime"
2020
"github.com/coder/coder/v2/coderd/database/provisionerjobs"
2121
"github.com/coder/coder/v2/coderd/database/pubsub"
22-
"github.com/coder/coder/v2/coderd/dormancy"
2322
"github.com/coder/coder/v2/coderd/notifications"
2423
"github.com/coder/coder/v2/coderd/schedule"
2524
"github.com/coder/coder/v2/coderd/wsbuilder"
@@ -145,10 +144,11 @@ func (e *Executor) runOnce(t time.Time) Stats {
145144
var (
146145
job*database.ProvisionerJob
147146
auditLog*auditParams
148-
dormantNotification*dormancy.WorkspaceDormantNotification
147+
shouldNotifyDormancybool
149148
nextBuild*database.WorkspaceBuild
150149
activeTemplateVersion database.TemplateVersion
151150
ws database.Workspace
151+
tmpl database.Template
152152
didAutoUpdatebool
153153
)
154154
err:=e.db.InTx(func(tx database.Store)error {
@@ -182,17 +182,17 @@ func (e *Executor) runOnce(t time.Time) Stats {
182182
returnxerrors.Errorf("get template scheduling options: %w",err)
183183
}
184184

185-
template,err:=tx.GetTemplateByID(e.ctx,ws.TemplateID)
185+
tmpl,err=tx.GetTemplateByID(e.ctx,ws.TemplateID)
186186
iferr!=nil {
187187
returnxerrors.Errorf("get template by ID: %w",err)
188188
}
189189

190-
activeTemplateVersion,err=tx.GetTemplateVersionByID(e.ctx,template.ActiveVersionID)
190+
activeTemplateVersion,err=tx.GetTemplateVersionByID(e.ctx,tmpl.ActiveVersionID)
191191
iferr!=nil {
192192
returnxerrors.Errorf("get active template version by ID: %w",err)
193193
}
194194

195-
accessControl:= (*(e.accessControlStore.Load())).GetTemplateAccessControl(template)
195+
accessControl:= (*(e.accessControlStore.Load())).GetTemplateAccessControl(tmpl)
196196

197197
nextTransition,reason,err:=getNextTransition(user,ws,latestBuild,latestJob,templateSchedule,currentTick)
198198
iferr!=nil {
@@ -215,7 +215,7 @@ func (e *Executor) runOnce(t time.Time) Stats {
215215
log.Debug(e.ctx,"autostarting with active version")
216216
builder=builder.ActiveVersion()
217217

218-
iflatestBuild.TemplateVersionID!=template.ActiveVersionID {
218+
iflatestBuild.TemplateVersionID!=tmpl.ActiveVersionID {
219219
// control flag to know if the workspace was auto-updated,
220220
// so the lifecycle executor can notify the user
221221
didAutoUpdate=true
@@ -248,12 +248,7 @@ func (e *Executor) runOnce(t time.Time) Stats {
248248
returnxerrors.Errorf("update workspace dormant deleting at: %w",err)
249249
}
250250

251-
dormantNotification=&dormancy.WorkspaceDormantNotification{
252-
Workspace:ws,
253-
Initiator:"autobuild",
254-
Reason:"breached the template's threshold for inactivity",
255-
CreatedBy:"lifecycleexecutor",
256-
}
251+
shouldNotifyDormancy=true
257252

258253
log.Info(e.ctx,"dormant workspace",
259254
slog.F("last_used_at",ws.LastUsedAt),
@@ -325,14 +320,24 @@ func (e *Executor) runOnce(t time.Time) Stats {
325320
returnxerrors.Errorf("post provisioner job to pubsub: %w",err)
326321
}
327322
}
328-
ifdormantNotification!=nil {
329-
_,err=dormancy.NotifyWorkspaceDormant(
323+
ifshouldNotifyDormancy {
324+
_,err=e.notificationsEnqueuer.Enqueue(
330325
e.ctx,
331-
e.notificationsEnqueuer,
332-
*dormantNotification,
326+
ws.OwnerID,
327+
notifications.TemplateWorkspaceDormant,
328+
map[string]string{
329+
"name":ws.Name,
330+
"reason":"inactivity exceeded the dormancy threshold",
331+
"timeTilDormant":time.Duration(tmpl.TimeTilDormant).String(),
332+
},
333+
"lifecycle_executor",
334+
ws.ID,
335+
ws.OwnerID,
336+
ws.TemplateID,
337+
ws.OrganizationID,
333338
)
334339
iferr!=nil {
335-
log.Warn(e.ctx,"failed to notify of workspace marked as dormant",slog.Error(err),slog.F("workspace_id",dormantNotification.Workspace.ID))
340+
log.Warn(e.ctx,"failed to notify of workspace marked as dormant",slog.Error(err),slog.F("workspace_id",ws.ID))
336341
}
337342
}
338343
returnnil

‎coderd/autobuild/lifecycle_executor_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,6 @@ func TestNotifications(t *testing.T) {
11221122
require.Contains(t,notifyEnq.Sent[0].Targets,workspace.ID)
11231123
require.Contains(t,notifyEnq.Sent[0].Targets,workspace.OrganizationID)
11241124
require.Contains(t,notifyEnq.Sent[0].Targets,workspace.OwnerID)
1125-
require.Equal(t,notifyEnq.Sent[0].Labels["initiator"],"autobuild")
11261125
})
11271126
}
11281127

‎coderd/database/migrations/000232_update_dormancy_notification_template.down.sql

Whitespace-only changes.
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
UPDATE notification_templates
2+
SET
3+
body_template= E'Hi {{.UserName}}\n\n'||
4+
E'Your workspace **{{.Labels.name}}** has been marked as [**dormant**](https://coder.com/docs/templates/schedule#dormancy-threshold-enterprise) because of {{.Labels.reason}}.\n'||
5+
E'Dormant workspaces are [automatically deleted](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) after {{.Labels.timeTilDormant}} of inactivity.\n'||
6+
E'To prevent deletion, use your workspace with the link below.'
7+
WHERE
8+
id='0ea69165-ec14-4314-91f1-69566ac3c5a0';
9+
10+
UPDATE notification_templates
11+
SET
12+
body_template= E'Hi {{.UserName}}\n\n'||
13+
E'Your workspace **{{.Labels.name}}** has been marked for **deletion** after {{.Labels.timeTilDormant}} of [dormancy](https://coder.com/docs/templates/schedule#dormancy-auto-deletion-enterprise) because of {{.Labels.reason}}.\n'||
14+
E'To prevent deletion, use your workspace with the link below.'
15+
WHERE
16+
id='51ce2fdf-c9ca-4be1-8d70-628674f9bc42';

‎coderd/database/queries/notifications.sql

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,4 +132,3 @@ WHERE id IN
132132

133133
-- name: GetNotificationMessagesByStatus :many
134134
SELECT*FROM notification_messagesWHERE status= @statusLIMITsqlc.arg('limit')::int;
135-

‎coderd/dormancy/notifications.go

Lines changed: 0 additions & 75 deletions
This file was deleted.

‎coderd/notifications/notifications_test.go

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import (
2929
"github.com/coder/coder/v2/coderd/database/dbtestutil"
3030
"github.com/coder/coder/v2/coderd/notifications"
3131
"github.com/coder/coder/v2/coderd/notifications/dispatch"
32+
"github.com/coder/coder/v2/coderd/notifications/render"
3233
"github.com/coder/coder/v2/coderd/notifications/types"
3334
"github.com/coder/coder/v2/coderd/util/syncmap"
3435
"github.com/coder/coder/v2/codersdk"
@@ -603,6 +604,107 @@ func TestNotifierPaused(t *testing.T) {
603604
},testutil.WaitShort,testutil.IntervalFast)
604605
}
605606

607+
funcTestNotifcationTemplatesBody(t*testing.T) {
608+
t.Parallel()
609+
610+
if!dbtestutil.WillUsePostgres() {
611+
t.Skip("This test requires postgres; it relies on the notification templates added by migrations in the database")
612+
}
613+
614+
tests:= []struct {
615+
namestring
616+
id uuid.UUID
617+
payload types.MessagePayload
618+
}{
619+
{
620+
name:"TemplateWorkspaceDeleted",
621+
id:notifications.TemplateWorkspaceDeleted,
622+
payload: types.MessagePayload{
623+
UserName:"bobby",
624+
Labels:map[string]string{
625+
"name":"bobby-workspace",
626+
"reason":"autodeleted due to dormancy",
627+
"initiator":"autobuild",
628+
},
629+
},
630+
},
631+
{
632+
name:"TemplateWorkspaceAutobuildFailed",
633+
id:notifications.TemplateWorkspaceAutobuildFailed,
634+
payload: types.MessagePayload{
635+
UserName:"bobby",
636+
Labels:map[string]string{
637+
"name":"bobby-workspace",
638+
"reason":"autostart",
639+
},
640+
},
641+
},
642+
{
643+
name:"TemplateWorkspaceDormant",
644+
id:notifications.TemplateWorkspaceDormant,
645+
payload: types.MessagePayload{
646+
UserName:"bobby",
647+
Labels:map[string]string{
648+
"name":"bobby-workspace",
649+
"reason":"breached the template's threshold for inactivity",
650+
"initiator":"autobuild",
651+
"dormancyHours":"24",
652+
},
653+
},
654+
},
655+
{
656+
name:"TemplateWorkspaceAutoUpdated",
657+
id:notifications.TemplateWorkspaceAutoUpdated,
658+
payload: types.MessagePayload{
659+
UserName:"bobby",
660+
Labels:map[string]string{
661+
"name":"bobby-workspace",
662+
"template_version_name":"1.0",
663+
},
664+
},
665+
},
666+
{
667+
name:"TemplateWorkspaceMarkedForDeletion",
668+
id:notifications.TemplateWorkspaceMarkedForDeletion,
669+
payload: types.MessagePayload{
670+
UserName:"bobby",
671+
Labels:map[string]string{
672+
"name":"bobby-workspace",
673+
"reason":"template updated to new dormancy policy",
674+
"dormancyHours":"24",
675+
},
676+
},
677+
},
678+
}
679+
680+
for_,tc:=rangetests {
681+
tc:=tc
682+
683+
t.Run(tc.name,func(t*testing.T) {
684+
t.Parallel()
685+
686+
_,_,sql:=dbtestutil.NewDBWithSQLDB(t)
687+
688+
var (
689+
titleTmplstring
690+
bodyTmplstring
691+
)
692+
err:=sql.
693+
QueryRow("SELECT title_template, body_template FROM notification_templates WHERE id = $1 LIMIT 1",tc.id).
694+
Scan(&titleTmpl,&bodyTmpl)
695+
require.NoError(t,err,"failed to query body template for template:",tc.id)
696+
697+
title,err:=render.GoTemplate(titleTmpl,tc.payload,nil)
698+
require.NoError(t,err,"failed to render notification title template")
699+
require.NotEmpty(t,title,"title should not be empty")
700+
701+
body,err:=render.GoTemplate(bodyTmpl,tc.payload,nil)
702+
require.NoError(t,err,"failed to render notification body template")
703+
require.NotEmpty(t,body,"body should not be empty")
704+
})
705+
}
706+
}
707+
606708
typefakeHandlerstruct {
607709
mu sync.RWMutex
608710
succeeded,failed []string

‎coderd/provisionerdserver/provisionerdserver.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,13 +1101,11 @@ func (s *server) notifyWorkspaceBuildFailed(ctx context.Context, workspace datab
11011101
return// failed workspace build initiated by a user should not notify
11021102
}
11031103
reason=string(build.Reason)
1104-
initiator:="autobuild"
11051104

11061105
if_,err:=s.NotificationsEnqueuer.Enqueue(ctx,workspace.OwnerID,notifications.TemplateWorkspaceAutobuildFailed,
11071106
map[string]string{
1108-
"name":workspace.Name,
1109-
"initiator":initiator,
1110-
"reason":reason,
1107+
"name":workspace.Name,
1108+
"reason":reason,
11111109
},"provisionerdserver",
11121110
// Associate this notification with all the related entities.
11131111
workspace.ID,workspace.OwnerID,workspace.TemplateID,workspace.OrganizationID,

‎coderd/provisionerdserver/provisionerdserver_test.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1797,7 +1797,6 @@ func TestNotifications(t *testing.T) {
17971797
require.Contains(t,notifEnq.Sent[0].Targets,workspace.ID)
17981798
require.Contains(t,notifEnq.Sent[0].Targets,workspace.OrganizationID)
17991799
require.Contains(t,notifEnq.Sent[0].Targets,user.ID)
1800-
require.Equal(t,"autobuild",notifEnq.Sent[0].Labels["initiator"])
18011800
require.Equal(t,string(tc.buildReason),notifEnq.Sent[0].Labels["reason"])
18021801
}else {
18031802
require.Len(t,notifEnq.Sent,0)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp