Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
revert non-test files
  • Loading branch information
aslilac committed Jun 20, 2025
commit 835331352bc641e0dc05a571b469129131b0b5d7
2 changes: 2 additions & 0 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ func (a *agent) reportMetadata(ctx context.Context, aAPI proto.DRPCAgentClient26
// channel to synchronize the results and avoid both messy
// mutex logic and overloading the API.
for _, md := range manifest.Metadata {
md := md
// We send the result to the channel in the goroutine to avoid
// sending the same result multiple times. So, we don't care about
// the return values.
Expand Down Expand Up @@ -1296,6 +1297,7 @@ func (a *agent) updateCommandEnv(current []string) (updated []string, err error)
"CODER": "true",
"CODER_WORKSPACE_NAME": manifest.WorkspaceName,
"CODER_WORKSPACE_AGENT_NAME": manifest.AgentName,
"CODER_WORKSPACE_OWNER_NAME": manifest.OwnerName,

// Specific Coder subcommands require the agent token exposed!
"CODER_AGENT_TOKEN": *a.sessionToken.Load(),
Expand Down
2 changes: 2 additions & 0 deletions agent/agentscripts/agentscripts.go
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ func (r *Runner) Init(scripts []codersdk.WorkspaceAgentScript, scriptCompleted S
if script.Cron == "" {
continue
}
script := script
_, err := r.cron.AddFunc(script.Cron, func() {
err := r.trackRun(r.cronCtx, script.WorkspaceAgentScript, ExecuteCronScripts)
if err != nil {
Expand Down Expand Up @@ -253,6 +254,7 @@ func (r *Runner) Execute(ctx context.Context, option ExecuteOption) error {
continue
}

script := script
eg.Go(func() error {
err := r.trackRun(ctx, script.WorkspaceAgentScript, option)
if err != nil {
Expand Down
1 change: 1 addition & 0 deletions cli/organizationroles.go
Original file line number Diff line number Diff line change
Expand Up @@ -435,6 +435,7 @@ func applyOrgResourceActions(role *codersdk.Role, resource string, actions []str
// Construct new site perms with only new perms for the resource
keep := make([]codersdk.Permission, 0)
for _, perm := range role.OrganizationPermissions {
perm := perm
if string(perm.ResourceType) != resource {
keep = append(keep, perm)
}
Expand Down
2 changes: 2 additions & 0 deletions cli/organizationsettings.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func (r *RootCmd) setOrganizationSettings(orgContext *OrganizationContext, setti
}

for _, set := range settings {
set := set
patch := set.Patch
cmd.Children = append(cmd.Children, &serpent.Command{
Use: set.Name,
Expand Down Expand Up @@ -191,6 +192,7 @@ func (r *RootCmd) printOrganizationSetting(orgContext *OrganizationContext, sett
}

for _, set := range settings {
set := set
fetch := set.Fetch
cmd.Children = append(cmd.Children, &serpent.Command{
Use: set.Name,
Expand Down
13 changes: 7 additions & 6 deletions cli/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -1202,6 +1202,7 @@ func (r *RootCmd) Server(newAPI func(context.Context, *coderd.Options) (*coderd.
var wg sync.WaitGroup
for i, provisionerDaemon := range provisionerDaemons {
id := i + 1
provisionerDaemon := provisionerDaemon
wg.Add(1)
go func() {
defer wg.Done()
Expand Down Expand Up @@ -1679,6 +1680,7 @@ func configureServerTLS(ctx context.Context, logger slog.Logger, tlsMinVersion,

// Expensively check which certificate matches the client hello.
for _, cert := range certs {
cert := cert
if err := hi.SupportsCertificate(&cert); err == nil {
return &cert, nil
}
Expand Down Expand Up @@ -2310,19 +2312,20 @@ func ConnectToPostgres(ctx context.Context, logger slog.Logger, driver string, d

var err error
var sqlDB *sql.DB
dbNeedsClosing := true
// Try to connect for 30 seconds.
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
defer cancel()

defer func() {
if err == nil {
if !dbNeedsClosing {
return
}
if sqlDB != nil {
_ = sqlDB.Close()
sqlDB = nil
logger.Debug(ctx, "closed db before returning from ConnectToPostgres")
}
logger.Error(ctx, "connect to postgres failed", slog.Error(err))
}()

var tries int
Expand Down Expand Up @@ -2358,11 +2361,8 @@ func ConnectToPostgres(ctx context.Context, logger slog.Logger, driver string, d
return nil, xerrors.Errorf("get postgres version: %w", err)
}
defer version.Close()
if version.Err() != nil {
return nil, xerrors.Errorf("version select: %w", version.Err())
}
if !version.Next() {
return nil, xerrors.Errorf("no rows returned for version select")
return nil, xerrors.Errorf("no rows returned for version select: %w", version.Err())
}
var versionNum int
err = version.Scan(&versionNum)
Expand Down Expand Up @@ -2404,6 +2404,7 @@ func ConnectToPostgres(ctx context.Context, logger slog.Logger, driver string, d
// of connection churn.
sqlDB.SetMaxIdleConns(3)

dbNeedsClosing = false
return sqlDB, nil
}

Expand Down
1 change: 1 addition & 0 deletions coderd/database/pubsub/pubsub_memory.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ func (m *MemoryPubsub) Publish(event string, message []byte) error {
var wg sync.WaitGroup
for _, listener := range listeners {
wg.Add(1)
listener := listener
go func() {
defer wg.Done()
listener.send(context.Background(), message)
Expand Down
2 changes: 2 additions & 0 deletions coderd/externalauth/externalauth.go
Original file line number Diff line number Diff line change
Expand Up @@ -505,6 +505,8 @@ func ConvertConfig(instrument *promoauth.Factory, entries []codersdk.ExternalAut
ids := map[string]struct{}{}
configs := []*Config{}
for _, entry := range entries {
entry := entry

// Applies defaults to the config entry.
// This allows users to very simply state that they type is "GitHub",
// apply their client secret and ID, and have the UI appear nicely.
Expand Down
4 changes: 4 additions & 0 deletions coderd/idpsync/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ func (s AGPLIDPSync) SyncGroups(ctx context.Context, db database.Store, user dat
// membership via the groups the user is in.
userOrgs := make(map[uuid.UUID][]database.GetGroupsRow)
for _, g := range userGroups {
g := g
userOrgs[g.Group.OrganizationID] = append(userOrgs[g.Group.OrganizationID], g)
}

Expand Down Expand Up @@ -336,6 +337,8 @@ func (s GroupSyncSettings) ParseClaims(orgID uuid.UUID, mergedClaims jwt.MapClai

groups := make([]ExpectedGroup, 0)
for _, group := range parsedGroups {
group := group

// Legacy group mappings happen before the regex filter.
mappedGroupName, ok := s.LegacyNameMapping[group]
if ok {
Expand All @@ -352,6 +355,7 @@ func (s GroupSyncSettings) ParseClaims(orgID uuid.UUID, mergedClaims jwt.MapClai
mappedGroupIDs, ok := s.Mapping[group]
if ok {
for _, gid := range mappedGroupIDs {
gid := gid
groups = append(groups, ExpectedGroup{OrganizationID: orgID, GroupID: &gid})
}
continue
Expand Down
1 change: 1 addition & 0 deletions coderd/rbac/authz.go
Original file line number Diff line number Diff line change
Expand Up @@ -760,6 +760,7 @@ func rbacTraceAttributes(actor Subject, action policy.Action, objectType string,
uniqueRoleNames := actor.SafeRoleNames()
roleStrings := make([]string, 0, len(uniqueRoleNames))
for _, roleName := range uniqueRoleNames {
roleName := roleName
roleStrings = append(roleStrings, roleName.String())
}
return trace.WithAttributes(
Expand Down
27 changes: 19 additions & 8 deletions coderd/rbac/roles.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,11 +270,15 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
Site: append(
// Workspace dormancy and workspace are omitted.
// Workspace is specifically handled based on the opts.NoOwnerWorkspaceExec
allPermsExcept(ResourceWorkspaceDormant, ResourceWorkspace),
allPermsExcept(ResourceWorkspaceDormant, ResourcePrebuiltWorkspace, ResourceWorkspace),
// This adds back in the Workspace permissions.
Permissions(map[string][]policy.Action{
ResourceWorkspace.Type: ownerWorkspaceActions,
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent},
// PrebuiltWorkspaces are a subset of Workspaces.
// Explicitly setting PrebuiltWorkspace permissions for clarity.
// Note: even without PrebuiltWorkspace permissions, access is still granted via Workspace permissions.
ResourcePrebuiltWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete},
})...),
Org: map[string][]Permission{},
User: []Permission{},
Expand All @@ -290,7 +294,7 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
ResourceWorkspaceProxy.Type: {policy.ActionRead},
}),
Org: map[string][]Permission{},
User: append(allPermsExcept(ResourceWorkspaceDormant, ResourceUser, ResourceOrganizationMember),
User: append(allPermsExcept(ResourceWorkspaceDormant, ResourcePrebuiltWorkspace, ResourceUser, ResourceOrganizationMember),
Permissions(map[string][]policy.Action{
// Reduced permission set on dormant workspaces. No build, ssh, or exec
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent},
Expand Down Expand Up @@ -335,8 +339,9 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
ResourceAssignOrgRole.Type: {policy.ActionRead},
ResourceTemplate.Type: ResourceTemplate.AvailableActions(),
// CRUD all files, even those they did not upload.
ResourceFile.Type: {policy.ActionCreate, policy.ActionRead},
ResourceWorkspace.Type: {policy.ActionRead},
ResourceFile.Type: {policy.ActionCreate, policy.ActionRead},
ResourceWorkspace.Type: {policy.ActionRead},
ResourcePrebuiltWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete},
// CRUD to provisioner daemons for now.
ResourceProvisionerDaemon.Type: {policy.ActionCreate, policy.ActionRead, policy.ActionUpdate, policy.ActionDelete},
// Needs to read all organizations since
Expand Down Expand Up @@ -413,9 +418,13 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
}),
Org: map[string][]Permission{
// Org admins should not have workspace exec perms.
organizationID.String(): append(allPermsExcept(ResourceWorkspace, ResourceWorkspaceDormant, ResourceAssignRole), Permissions(map[string][]policy.Action{
organizationID.String(): append(allPermsExcept(ResourceWorkspace, ResourceWorkspaceDormant, ResourcePrebuiltWorkspace, ResourceAssignRole), Permissions(map[string][]policy.Action{
ResourceWorkspaceDormant.Type: {policy.ActionRead, policy.ActionDelete, policy.ActionCreate, policy.ActionUpdate, policy.ActionWorkspaceStop, policy.ActionCreateAgent, policy.ActionDeleteAgent},
ResourceWorkspace.Type: slice.Omit(ResourceWorkspace.AvailableActions(), policy.ActionApplicationConnect, policy.ActionSSH),
// PrebuiltWorkspaces are a subset of Workspaces.
// Explicitly setting PrebuiltWorkspace permissions for clarity.
// Note: even without PrebuiltWorkspace permissions, access is still granted via Workspace permissions.
ResourcePrebuiltWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete},
})...),
},
User: []Permission{},
Expand Down Expand Up @@ -493,9 +502,10 @@ func ReloadBuiltinRoles(opts *RoleOptions) {
Site: []Permission{},
Org: map[string][]Permission{
organizationID.String(): Permissions(map[string][]policy.Action{
ResourceTemplate.Type: ResourceTemplate.AvailableActions(),
ResourceFile.Type: {policy.ActionCreate, policy.ActionRead},
ResourceWorkspace.Type: {policy.ActionRead},
ResourceTemplate.Type: ResourceTemplate.AvailableActions(),
ResourceFile.Type: {policy.ActionCreate, policy.ActionRead},
ResourceWorkspace.Type: {policy.ActionRead},
ResourcePrebuiltWorkspace.Type: {policy.ActionUpdate, policy.ActionDelete},
// Assigning template perms requires this permission.
ResourceOrganization.Type: {policy.ActionRead},
ResourceOrganizationMember.Type: {policy.ActionRead},
Expand Down Expand Up @@ -837,6 +847,7 @@ func Permissions(perms map[string][]policy.Action) []Permission {
list := make([]Permission, 0, len(perms))
for k, actions := range perms {
for _, act := range actions {
act := act
list = append(list, Permission{
Negate: false,
ResourceType: k,
Expand Down
1 change: 1 addition & 0 deletions coderd/webpush/webpush.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ func (n *Webpusher) Dispatch(ctx context.Context, userID uuid.UUID, msg codersdk
var mu sync.Mutex
var eg errgroup.Group
for _, subscription := range subscriptions {
subscription := subscription
eg.Go(func() error {
// TODO: Implement some retry logic here. For now, this is just a
// best-effort attempt.
Expand Down
1 change: 1 addition & 0 deletions enterprise/coderd/proxyhealth/proxyhealth.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,7 @@ func (p *ProxyHealth) runOnce(ctx context.Context, now time.Time) (map[uuid.UUID
}
// Each proxy needs to have a status set. Make a local copy for the
// call to be run async.
proxy := proxy
status := ProxyStatus{
Proxy: proxy,
CheckedAt: now,
Expand Down
3 changes: 3 additions & 0 deletions enterprise/replicasync/replicasync.go
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,9 @@ func (m *Manager) AllPrimary() []database.Replica {
continue
}

// When we assign the non-pointer to a
// variable it loses the reference.
replica := replica
replicas = append(replicas, replica)
}
return replicas
Expand Down
28 changes: 28 additions & 0 deletions site/site.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ type Options struct {
Entitlements *entitlements.Set
Telemetry telemetry.Reporter
Logger slog.Logger
HideAITasks bool
}

func New(opts *Options) *Handler {
Expand Down Expand Up @@ -316,6 +317,8 @@ type htmlState struct {
Experiments string
Regions string
DocsURL string

TasksTabVisible string
}

type csrfState struct {
Expand Down Expand Up @@ -445,6 +448,7 @@ func (h *Handler) renderHTMLWithState(r *http.Request, filePath string, state ht
var user database.User
var themePreference string
var terminalFont string
var tasksTabVisible bool
orgIDs := []uuid.UUID{}
eg.Go(func() error {
var err error
Expand Down Expand Up @@ -480,6 +484,20 @@ func (h *Handler) renderHTMLWithState(r *http.Request, filePath string, state ht
orgIDs = memberIDs[0].OrganizationIDs
return err
})
eg.Go(func() error {
// If HideAITasks is true, force hide the tasks tab
if h.opts.HideAITasks {
tasksTabVisible = false
return nil
}

hasAITask, err := h.opts.Database.HasTemplateVersionsWithAITask(ctx)
if err != nil {
return err
}
tasksTabVisible = hasAITask
return nil
})
err := eg.Wait()
if err == nil {
var wg sync.WaitGroup
Expand Down Expand Up @@ -550,6 +568,14 @@ func (h *Handler) renderHTMLWithState(r *http.Request, filePath string, state ht
}
}()
}
wg.Add(1)
go func() {
defer wg.Done()
tasksTabVisible, err := json.Marshal(tasksTabVisible)
if err == nil {
state.TasksTabVisible = html.EscapeString(string(tasksTabVisible))
}
}()
wg.Wait()
}

Expand Down Expand Up @@ -823,6 +849,8 @@ func verifyBinSha1IsCurrent(dest string, siteFS fs.FS, shaFiles map[string]strin

// Verify the hash of each on-disk binary.
for file, hash1 := range shaFiles {
file := file
hash1 := hash1
eg.Go(func() error {
hash2, err := sha1HashFile(filepath.Join(dest, file))
if err != nil {
Expand Down