Skip to content

Commit 1219cf7

Browse files
committed
Merge branch 'main' of github.com:/coder/coder into dk/llm-proxy
Signed-off-by: Danny Kopping <dannykopping@gmail.com>
2 parents f5b4f49 + afb54f6 commit 1219cf7

Some content is hidden

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

68 files changed

+2466
-454
lines changed

.github/actions/setup-go/action.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ description: |
44
inputs:
55
version:
66
description: "The Go version to use."
7-
default: "1.24.4"
7+
default: "1.24.6"
88
use-preinstalled-go:
99
description: "Whether to use preinstalled Go."
1010
default: "false"

agent/agentssh/x11_test.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@ func TestServer_X11_EvictionLRU(t *testing.T) {
135135
t.Skip("X11 forwarding is only supported on Linux")
136136
}
137137

138-
ctx := testutil.Context(t, testutil.WaitLong)
138+
ctx := testutil.Context(t, testutil.WaitSuperLong)
139139
logger := testutil.Logger(t)
140140
fs := afero.NewMemMapFs()
141141

@@ -238,7 +238,9 @@ func TestServer_X11_EvictionLRU(t *testing.T) {
238238
payload := "hello world"
239239
go func() {
240240
conn, err := inproc.Dial(ctx, testutil.NewAddr("tcp", fmt.Sprintf("localhost:%d", agentssh.X11StartPort+agentssh.X11DefaultDisplayOffset)))
241-
assert.NoError(t, err)
241+
if !assert.NoError(t, err) {
242+
return
243+
}
242244
_, err = conn.Write([]byte(payload))
243245
assert.NoError(t, err)
244246
_ = conn.Close()

cli/cliui/select.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -349,7 +349,11 @@ func RichMultiSelect(inv *serpent.Invocation, richOptions RichMultiSelectOptions
349349
}
350350

351351
// Check selected option, convert descriptions (line) to values
352-
var results []string
352+
//
353+
// The function must return an initialized empty array, since it is later marshaled
354+
// into JSON. Otherwise, `var results []string` would be marshaled to "null".
355+
// See: https://github.com/golang/go/issues/27589
356+
results := []string{}
353357
for _, sel := range selected {
354358
custom := true
355359
for i, option := range richOptions.Options {

cli/cliui/select_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,17 @@ func TestRichMultiSelect(t *testing.T) {
111111
allowCustom: true,
112112
want: []string{"aaa", "bbb"},
113113
},
114+
{
115+
name: "NoOptionSelected",
116+
options: []codersdk.TemplateVersionParameterOption{
117+
{Name: "AAA", Description: "This is AAA", Value: "aaa"},
118+
{Name: "BBB", Description: "This is BBB", Value: "bbb"},
119+
{Name: "CCC", Description: "This is CCC", Value: "ccc"},
120+
},
121+
defaults: []string{},
122+
allowCustom: false,
123+
want: []string{},
124+
},
114125
}
115126

116127
for _, tt := range tests {

cli/server.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ import (
5656

5757
"cdr.dev/slog"
5858
"cdr.dev/slog/sloggers/sloghuman"
59+
"github.com/coder/coder/v2/coderd/pproflabel"
5960
"github.com/coder/pretty"
6061
"github.com/coder/quartz"
6162
"github.com/coder/retry"
@@ -1523,14 +1524,14 @@ func newProvisionerDaemon(
15231524
tracer := coderAPI.TracerProvider.Tracer(tracing.TracerName)
15241525
terraformClient, terraformServer := drpcsdk.MemTransportPipe()
15251526
wg.Add(1)
1526-
go func() {
1527+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceTerraformProvisioner), func(ctx context.Context) {
15271528
defer wg.Done()
15281529
<-ctx.Done()
15291530
_ = terraformClient.Close()
15301531
_ = terraformServer.Close()
1531-
}()
1532+
})
15321533
wg.Add(1)
1533-
go func() {
1534+
pproflabel.Go(ctx, pproflabel.Service(pproflabel.ServiceTerraformProvisioner), func(ctx context.Context) {
15341535
defer wg.Done()
15351536
defer cancel()
15361537

@@ -1549,7 +1550,7 @@ func newProvisionerDaemon(
15491550
default:
15501551
}
15511552
}
1552-
}()
1553+
})
15531554

15541555
connector[string(database.ProvisionerTypeTerraform)] = sdkproto.NewDRPCProvisionerClient(terraformClient)
15551556
default:

coderd/apidoc/docs.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/apidoc/swagger.json

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/autobuild/lifecycle_executor.go

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020

2121
"cdr.dev/slog"
2222
"github.com/coder/coder/v2/coderd/files"
23+
"github.com/coder/coder/v2/coderd/pproflabel"
2324

2425
"github.com/coder/coder/v2/coderd/audit"
2526
"github.com/coder/coder/v2/coderd/database"
@@ -107,10 +108,10 @@ func (e *Executor) WithStatsChannel(ch chan<- Stats) *Executor {
107108
// tick from its channel. It will stop when its context is Done, or when
108109
// its channel is closed.
109110
func (e *Executor) Run() {
110-
go func() {
111+
pproflabel.Go(e.ctx, pproflabel.Service(pproflabel.ServiceLifecycles), func(ctx context.Context) {
111112
for {
112113
select {
113-
case <-e.ctx.Done():
114+
case <-ctx.Done():
114115
return
115116
case t, ok := <-e.tick:
116117
if !ok {
@@ -120,15 +121,15 @@ func (e *Executor) Run() {
120121
e.metrics.autobuildExecutionDuration.Observe(stats.Elapsed.Seconds())
121122
if e.statsCh != nil {
122123
select {
123-
case <-e.ctx.Done():
124+
case <-ctx.Done():
124125
return
125126
case e.statsCh <- stats:
126127
}
127128
}
128-
e.log.Debug(e.ctx, "run stats", slog.F("elapsed", stats.Elapsed), slog.F("transitions", stats.Transitions))
129+
e.log.Debug(ctx, "run stats", slog.F("elapsed", stats.Elapsed), slog.F("transitions", stats.Transitions))
129130
}
130131
}
131-
}()
132+
})
132133
}
133134

134135
func (e *Executor) runOnce(t time.Time) Stats {

coderd/coderd.go

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import (
1414
"net/url"
1515
"path/filepath"
1616
"regexp"
17+
"runtime/pprof"
1718
"strings"
1819
"sync"
1920
"sync/atomic"
@@ -22,6 +23,7 @@ import (
2223
"github.com/ammario/tlru"
2324

2425
"github.com/coder/coder/v2/coderd/oauth2provider"
26+
"github.com/coder/coder/v2/coderd/pproflabel"
2527
"github.com/coder/coder/v2/coderd/prebuilds"
2628
"github.com/coder/coder/v2/coderd/wsbuilder"
2729

@@ -860,6 +862,7 @@ func New(options *Options) *API {
860862

861863
r.Use(
862864
httpmw.Recover(api.Logger),
865+
httpmw.WithProfilingLabels,
863866
tracing.StatusWriterMiddleware,
864867
tracing.Middleware(api.TracerProvider),
865868
httpmw.AttachRequestID,
@@ -1347,7 +1350,13 @@ func New(options *Options) *API {
13471350
).Get("/connection", api.workspaceAgentConnectionGeneric)
13481351
r.Route("/me", func(r chi.Router) {
13491352
r.Use(workspaceAgentInfo)
1350-
r.Get("/rpc", api.workspaceAgentRPC)
1353+
r.Group(func(r chi.Router) {
1354+
r.Use(
1355+
// Override the request_type for agent rpc traffic.
1356+
httpmw.WithStaticProfilingLabels(pprof.Labels(pproflabel.RequestTypeTag, "agent-rpc")),
1357+
)
1358+
r.Get("/rpc", api.workspaceAgentRPC)
1359+
})
13511360
r.Patch("/logs", api.patchWorkspaceAgentLogs)
13521361
r.Patch("/app-status", api.patchWorkspaceAgentAppStatus)
13531362
// Deprecated: Required to support legacy agents
@@ -1423,7 +1432,8 @@ func New(options *Options) *API {
14231432
r.Get("/timings", api.workspaceTimings)
14241433
r.Route("/acl", func(r chi.Router) {
14251434
r.Use(
1426-
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentWorkspaceSharing))
1435+
httpmw.RequireExperiment(api.Experiments, codersdk.ExperimentWorkspaceSharing),
1436+
)
14271437

14281438
r.Patch("/", api.patchWorkspaceACL)
14291439
})

coderd/database/dbauthz/dbauthz.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1387,6 +1387,14 @@ func (q *querier) CountUnreadInboxNotificationsByUserID(ctx context.Context, use
13871387
return q.db.CountUnreadInboxNotificationsByUserID(ctx, userID)
13881388
}
13891389

1390+
func (q *querier) CreateUserSecret(ctx context.Context, arg database.CreateUserSecretParams) (database.UserSecret, error) {
1391+
obj := rbac.ResourceUserSecret.WithOwner(arg.UserID.String())
1392+
if err := q.authorizeContext(ctx, policy.ActionCreate, obj); err != nil {
1393+
return database.UserSecret{}, err
1394+
}
1395+
return q.db.CreateUserSecret(ctx, arg)
1396+
}
1397+
13901398
// TODO: Handle org scoped lookups
13911399
func (q *querier) CustomRoles(ctx context.Context, arg database.CustomRolesParams) ([]database.CustomRole, error) {
13921400
roleObject := rbac.ResourceAssignRole
@@ -1657,6 +1665,19 @@ func (q *querier) DeleteTailnetTunnel(ctx context.Context, arg database.DeleteTa
16571665
return q.db.DeleteTailnetTunnel(ctx, arg)
16581666
}
16591667

1668+
func (q *querier) DeleteUserSecret(ctx context.Context, id uuid.UUID) error {
1669+
// First get the secret to check ownership
1670+
secret, err := q.GetUserSecret(ctx, id)
1671+
if err != nil {
1672+
return err
1673+
}
1674+
1675+
if err := q.authorizeContext(ctx, policy.ActionDelete, secret); err != nil {
1676+
return err
1677+
}
1678+
return q.db.DeleteUserSecret(ctx, id)
1679+
}
1680+
16601681
func (q *querier) DeleteWebpushSubscriptionByUserIDAndEndpoint(ctx context.Context, arg database.DeleteWebpushSubscriptionByUserIDAndEndpointParams) error {
16611682
if err := q.authorizeContext(ctx, policy.ActionDelete, rbac.ResourceWebpushSubscription.WithOwner(arg.UserID.String())); err != nil {
16621683
return err
@@ -3075,6 +3096,28 @@ func (q *querier) GetUserNotificationPreferences(ctx context.Context, userID uui
30753096
return q.db.GetUserNotificationPreferences(ctx, userID)
30763097
}
30773098

3099+
func (q *querier) GetUserSecret(ctx context.Context, id uuid.UUID) (database.UserSecret, error) {
3100+
// First get the secret to check ownership
3101+
secret, err := q.db.GetUserSecret(ctx, id)
3102+
if err != nil {
3103+
return database.UserSecret{}, err
3104+
}
3105+
3106+
if err := q.authorizeContext(ctx, policy.ActionRead, secret); err != nil {
3107+
return database.UserSecret{}, err
3108+
}
3109+
return secret, nil
3110+
}
3111+
3112+
func (q *querier) GetUserSecretByUserIDAndName(ctx context.Context, arg database.GetUserSecretByUserIDAndNameParams) (database.UserSecret, error) {
3113+
obj := rbac.ResourceUserSecret.WithOwner(arg.UserID.String())
3114+
if err := q.authorizeContext(ctx, policy.ActionRead, obj); err != nil {
3115+
return database.UserSecret{}, err
3116+
}
3117+
3118+
return q.db.GetUserSecretByUserIDAndName(ctx, arg)
3119+
}
3120+
30783121
func (q *querier) GetUserStatusCounts(ctx context.Context, arg database.GetUserStatusCountsParams) ([]database.GetUserStatusCountsRow, error) {
30793122
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceUser); err != nil {
30803123
return nil, err
@@ -4173,6 +4216,14 @@ func (q *querier) ListProvisionerKeysByOrganizationExcludeReserved(ctx context.C
41734216
return fetchWithPostFilter(q.auth, policy.ActionRead, q.db.ListProvisionerKeysByOrganizationExcludeReserved)(ctx, organizationID)
41744217
}
41754218

4219+
func (q *querier) ListUserSecrets(ctx context.Context, userID uuid.UUID) ([]database.UserSecret, error) {
4220+
obj := rbac.ResourceUserSecret.WithOwner(userID.String())
4221+
if err := q.authorizeContext(ctx, policy.ActionRead, obj); err != nil {
4222+
return nil, err
4223+
}
4224+
return q.db.ListUserSecrets(ctx, userID)
4225+
}
4226+
41764227
func (q *querier) ListWorkspaceAgentPortShares(ctx context.Context, workspaceID uuid.UUID) ([]database.WorkspaceAgentPortShare, error) {
41774228
workspace, err := q.db.GetWorkspaceByID(ctx, workspaceID)
41784229
if err != nil {
@@ -4886,6 +4937,19 @@ func (q *querier) UpdateUserRoles(ctx context.Context, arg database.UpdateUserRo
48864937
return q.db.UpdateUserRoles(ctx, arg)
48874938
}
48884939

4940+
func (q *querier) UpdateUserSecret(ctx context.Context, arg database.UpdateUserSecretParams) (database.UserSecret, error) {
4941+
// First get the secret to check ownership
4942+
secret, err := q.db.GetUserSecret(ctx, arg.ID)
4943+
if err != nil {
4944+
return database.UserSecret{}, err
4945+
}
4946+
4947+
if err := q.authorizeContext(ctx, policy.ActionUpdate, secret); err != nil {
4948+
return database.UserSecret{}, err
4949+
}
4950+
return q.db.UpdateUserSecret(ctx, arg)
4951+
}
4952+
48894953
func (q *querier) UpdateUserStatus(ctx context.Context, arg database.UpdateUserStatusParams) (database.User, error) {
48904954
fetch := func(ctx context.Context, arg database.UpdateUserStatusParams) (database.User, error) {
48914955
return q.db.GetUserByID(ctx, arg.ID)
@@ -5396,6 +5460,26 @@ func (q *querier) UpsertWorkspaceAppAuditSession(ctx context.Context, arg databa
53965460
return q.db.UpsertWorkspaceAppAuditSession(ctx, arg)
53975461
}
53985462

5463+
func (q *querier) ValidateGroupIDs(ctx context.Context, groupIDs []uuid.UUID) (database.ValidateGroupIDsRow, error) {
5464+
// This check is probably overly restrictive, but the "correct" check isn't
5465+
// necessarily obvious. It's only used as a verification check for ACLs right
5466+
// now, which are performed as system.
5467+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
5468+
return database.ValidateGroupIDsRow{}, err
5469+
}
5470+
return q.db.ValidateGroupIDs(ctx, groupIDs)
5471+
}
5472+
5473+
func (q *querier) ValidateUserIDs(ctx context.Context, userIDs []uuid.UUID) (database.ValidateUserIDsRow, error) {
5474+
// This check is probably overly restrictive, but the "correct" check isn't
5475+
// necessarily obvious. It's only used as a verification check for ACLs right
5476+
// now, which are performed as system.
5477+
if err := q.authorizeContext(ctx, policy.ActionRead, rbac.ResourceSystem); err != nil {
5478+
return database.ValidateUserIDsRow{}, err
5479+
}
5480+
return q.db.ValidateUserIDs(ctx, userIDs)
5481+
}
5482+
53995483
func (q *querier) GetAuthorizedTemplates(ctx context.Context, arg database.GetTemplatesWithFilterParams, _ rbac.PreparedAuthorized) ([]database.Template, error) {
54005484
// TODO Delete this function, all GetTemplates should be authorized. For now just call getTemplates on the authz querier.
54015485
return q.GetTemplatesWithFilter(ctx, arg)

0 commit comments

Comments
 (0)