Skip to content

Commit 1550884

Browse files
authored
Merge branch 'main' into matifali/dogfood-filerowser
2 parents ca96deb + 7d92537 commit 1550884

File tree

30 files changed

+268
-326
lines changed

30 files changed

+268
-326
lines changed

.github/workflows/ci.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ jobs:
126126
127127
# Check for any typos
128128
- name: Check for typos
129-
uses: crate-ci/typos@v1.16.0
129+
uses: crate-ci/typos@v1.16.1
130130
with:
131131
config: .github/workflows/typos.toml
132132

.github/workflows/dogfood.yaml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,22 +51,30 @@ jobs:
5151
tags: "codercom/oss-dogfood:${{ steps.docker-tag-name.outputs.tag }},codercom/oss-dogfood:latest"
5252
cache-from: type=registry,ref=codercom/oss-dogfood:latest
5353
cache-to: type=inline
54+
5455
deploy_template:
5556
needs: deploy_image
5657
runs-on: ubuntu-latest
5758
steps:
5859
- name: Checkout
5960
uses: actions/checkout@v3
61+
6062
- name: Get short commit SHA
6163
id: vars
6264
run: echo "sha_short=$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT
65+
66+
- name: Get latest commit title
67+
id: message
68+
run: echo "pr_title=$(git log --format=%s -n 1 ${{ github.sha }})" >> $GITHUB_OUTPUT
69+
6370
- name: "Get latest Coder binary from the server"
6471
run: |
6572
curl -fsSL "https://dev.coder.com/bin/coder-linux-amd64" -o "./coder"
6673
chmod +x "./coder"
74+
6775
- name: "Push template"
6876
run: |
69-
./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION
77+
./coder templates push $CODER_TEMPLATE_NAME --directory $CODER_TEMPLATE_DIR --yes --name=$CODER_TEMPLATE_VERSION --message="$CODER_TEMPLATE_MESSAGE"
7078
env:
7179
# Consumed by Coder CLI
7280
CODER_URL: https://dev.coder.com
@@ -75,3 +83,4 @@ jobs:
7583
CODER_TEMPLATE_NAME: ${{ secrets.CODER_TEMPLATE_NAME }}
7684
CODER_TEMPLATE_VERSION: ${{ steps.vars.outputs.sha_short }}
7785
CODER_TEMPLATE_DIR: ./dogfood
86+
CODER_TEMPLATE_MESSAGE: ${{ steps.message.outputs.pr_title }}

.github/workflows/pr-deploy.yaml

Lines changed: 2 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ permissions:
1717
pull-requests: write
1818

1919
concurrency:
20-
group: ${{ github.workflow }}-${{ github.ref }}
21-
cancel-in-progress: true
20+
group: ${{ github.workflow }}-${{ github.event.issue.number || github.run_id }}
21+
cancel-in-progress: false
2222

2323
jobs:
2424
pr_commented:
@@ -58,23 +58,6 @@ jobs:
5858
CODER_BASE_IMAGE_TAG: ghcr.io/coder/coder-preview-base:pr${{ steps.pr_number.outputs.PR_NUMBER }}
5959
CODER_IMAGE_TAG: ghcr.io/coder/coder-preview:pr${{ steps.pr_number.outputs.PR_NUMBER }}
6060

61-
- name: Find Deploy Comment
62-
if: github.event_name == 'issue_comment'
63-
uses: peter-evans/find-comment@v2
64-
id: fco
65-
with:
66-
issue-number: ${{ steps.pr_number.outputs.PR_NUMBER }}
67-
comment-author: "github-actions[bot]"
68-
body-includes: /deploy-pr
69-
70-
- name: React with Rocket
71-
if: github.event_name == 'issue_comment'
72-
id: comment_ido
73-
uses: peter-evans/create-or-update-comment@v3
74-
with:
75-
comment-id: ${{ steps.fco.outputs.comment-id }}
76-
reactions: rocket
77-
7861
- name: Find Comment
7962
uses: peter-evans/find-comment@v2
8063
id: fc

cli/cliui/resources.go

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
5050
row := table.Row{"Resource"}
5151
if !options.HideAgentState {
5252
row = append(row, "Status")
53+
row = append(row, "Health")
5354
row = append(row, "Version")
5455
}
5556
if !options.HideAccess {
@@ -81,6 +82,7 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
8182
DefaultStyles.Bold.Render(resourceAddress),
8283
"",
8384
"",
85+
"",
8486
})
8587
// Display all agents associated with the resource.
8688
for index, agent := range resource.Agents {
@@ -93,13 +95,13 @@ func WorkspaceResources(writer io.Writer, resources []codersdk.WorkspaceResource
9395
fmt.Sprintf("%s─ %s (%s, %s)", pipe, agent.Name, agent.OperatingSystem, agent.Architecture),
9496
}
9597
if !options.HideAgentState {
96-
var agentStatus string
97-
var agentVersion string
98+
var agentStatus, agentHealth, agentVersion string
9899
if !options.HideAgentState {
99100
agentStatus = renderAgentStatus(agent)
101+
agentHealth = renderAgentHealth(agent)
100102
agentVersion = renderAgentVersion(agent.Version, options.ServerVersion)
101103
}
102-
row = append(row, agentStatus, agentVersion)
104+
row = append(row, agentStatus, agentHealth, agentVersion)
103105
}
104106
if !options.HideAccess {
105107
sshCommand := "coder ssh " + options.WorkspaceName
@@ -141,6 +143,13 @@ func renderAgentStatus(agent codersdk.WorkspaceAgent) string {
141143
}
142144
}
143145

146+
func renderAgentHealth(agent codersdk.WorkspaceAgent) string {
147+
if agent.Health.Healthy {
148+
return DefaultStyles.Keyword.Render("✔ healthy")
149+
}
150+
return DefaultStyles.Error.Render("✘ " + agent.Health.Reason)
151+
}
152+
144153
func renderAgentVersion(agentVersion, serverVersion string) string {
145154
if agentVersion == "" {
146155
agentVersion = "(unknown)"

cli/cliui/resources_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ func TestWorkspaceResources(t *testing.T) {
2929
LifecycleState: codersdk.WorkspaceAgentLifecycleCreated,
3030
Architecture: "amd64",
3131
OperatingSystem: "linux",
32+
Health: codersdk.WorkspaceAgentHealth{Healthy: true},
3233
}},
3334
}}, cliui.WorkspaceResourcesOptions{
3435
WorkspaceName: "example",
@@ -65,6 +66,7 @@ func TestWorkspaceResources(t *testing.T) {
6566
Name: "dev",
6667
OperatingSystem: "linux",
6768
Architecture: "amd64",
69+
Health: codersdk.WorkspaceAgentHealth{Healthy: true},
6870
}},
6971
}, {
7072
Transition: codersdk.WorkspaceTransitionStart,
@@ -76,13 +78,18 @@ func TestWorkspaceResources(t *testing.T) {
7678
Name: "go",
7779
Architecture: "amd64",
7880
OperatingSystem: "linux",
81+
Health: codersdk.WorkspaceAgentHealth{Healthy: true},
7982
}, {
8083
DisconnectedAt: &disconnected,
8184
Status: codersdk.WorkspaceAgentDisconnected,
8285
LifecycleState: codersdk.WorkspaceAgentLifecycleReady,
8386
Name: "postgres",
8487
Architecture: "amd64",
8588
OperatingSystem: "linux",
89+
Health: codersdk.WorkspaceAgentHealth{
90+
Healthy: false,
91+
Reason: "agent has lost connection",
92+
},
8693
}},
8794
}}, cliui.WorkspaceResourcesOptions{
8895
WorkspaceName: "dev",
@@ -94,6 +101,12 @@ func TestWorkspaceResources(t *testing.T) {
94101
}()
95102
ptty.ExpectMatch("google_compute_disk.root")
96103
ptty.ExpectMatch("google_compute_instance.dev")
104+
ptty.ExpectMatch("healthy")
105+
ptty.ExpectMatch("coder ssh dev.dev")
106+
ptty.ExpectMatch("kubernetes_pod.dev")
107+
ptty.ExpectMatch("healthy")
108+
ptty.ExpectMatch("coder ssh dev.go")
109+
ptty.ExpectMatch("agent has lost connection")
97110
ptty.ExpectMatch("coder ssh dev.postgres")
98111
<-done
99112
})

cli/list.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package cli
22

33
import (
44
"fmt"
5+
"strconv"
56
"time"
67

78
"github.com/google/uuid"
@@ -24,6 +25,7 @@ type workspaceListRow struct {
2425
WorkspaceName string `json:"-" table:"workspace,default_sort"`
2526
Template string `json:"-" table:"template"`
2627
Status string `json:"-" table:"status"`
28+
Healthy string `json:"-" table:"healthy"`
2729
LastBuilt string `json:"-" table:"last built"`
2830
Outdated bool `json:"-" table:"outdated"`
2931
StartsAt string `json:"-" table:"starts at"`
@@ -51,12 +53,17 @@ func workspaceListRowFromWorkspace(now time.Time, usersByID map[uuid.UUID]coders
5153
}
5254
}
5355

56+
healthy := ""
57+
if status == "Starting" || status == "Started" {
58+
healthy = strconv.FormatBool(workspace.Health.Healthy)
59+
}
5460
user := usersByID[workspace.OwnerID]
5561
return workspaceListRow{
5662
Workspace: workspace,
5763
WorkspaceName: user.Username + "/" + workspace.Name,
5864
Template: workspace.TemplateName,
5965
Status: status,
66+
Healthy: healthy,
6067
LastBuilt: durationDisplay(lastBuilt),
6168
Outdated: workspace.Outdated,
6269
StartsAt: autostartDisplay,

cli/stat_test.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,6 @@ func TestStatCPUCmd(t *testing.T) {
8585

8686
t.Run("JSON", func(t *testing.T) {
8787
t.Parallel()
88-
t.Skip("https://github.com/coder/coder/issues/8091")
89-
9088
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
9189
t.Cleanup(cancel)
9290
inv, _ := clitest.New(t, "stat", "cpu", "--output=json")
@@ -111,7 +109,7 @@ func TestStatMemCmd(t *testing.T) {
111109
t.Parallel()
112110
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
113111
t.Cleanup(cancel)
114-
inv, _ := clitest.New(t, "stat", "mem", "--output=text")
112+
inv, _ := clitest.New(t, "stat", "mem", "--output=text", "--host")
115113
buf := new(bytes.Buffer)
116114
inv.Stdout = buf
117115
err := inv.WithContext(ctx).Run()
@@ -124,7 +122,7 @@ func TestStatMemCmd(t *testing.T) {
124122
t.Parallel()
125123
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitShort)
126124
t.Cleanup(cancel)
127-
inv, _ := clitest.New(t, "stat", "mem", "--output=json")
125+
inv, _ := clitest.New(t, "stat", "mem", "--output=json", "--host")
128126
buf := new(bytes.Buffer)
129127
inv.Stdout = buf
130128
err := inv.WithContext(ctx).Run()

cli/testdata/coder_list_--help.golden

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ Aliases: ls
88
-a, --all bool
99
Specifies whether all workspaces will be listed or not.
1010

11-
-c, --column string-array (default: workspace,template,status,last built,outdated,starts at,stops after)
11+
-c, --column string-array (default: workspace,template,status,healthy,last built,outdated,starts at,stops after)
1212
Columns to display in table output. Available columns: workspace,
13-
template, status, last built, outdated, starts at, stops after.
13+
template, status, healthy, last built, outdated, starts at, stops
14+
after.
1415

1516
-o, --output string (default: table)
1617
Output format. Available formats: table, json.

coderd/coderd.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -727,7 +727,14 @@ func New(options *Options) *API {
727727
r.Post("/azure-instance-identity", api.postWorkspaceAuthAzureInstanceIdentity)
728728
r.Post("/aws-instance-identity", api.postWorkspaceAuthAWSInstanceIdentity)
729729
r.Post("/google-instance-identity", api.postWorkspaceAuthGoogleInstanceIdentity)
730-
r.Get("/connection", api.workspaceAgentConnectionGeneric)
730+
r.With(
731+
apiKeyMiddlewareOptional,
732+
httpmw.ExtractWorkspaceProxy(httpmw.ExtractWorkspaceProxyConfig{
733+
DB: options.Database,
734+
Optional: true,
735+
}),
736+
httpmw.RequireAPIKeyOrWorkspaceProxyAuth(),
737+
).Get("/connection", api.workspaceAgentConnectionGeneric)
731738
r.Route("/me", func(r chi.Router) {
732739
r.Use(httpmw.ExtractWorkspaceAgent(httpmw.ExtractWorkspaceAgentConfig{
733740
DB: options.Database,

coderd/database/dbauthz/dbauthz.go

Lines changed: 11 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -586,32 +586,6 @@ func (q *querier) SoftDeleteTemplateByID(ctx context.Context, id uuid.UUID) erro
586586
return deleteQ(q.log, q.auth, q.db.GetTemplateByID, deleteF)(ctx, id)
587587
}
588588

589-
func (q *querier) GetUsersWithCount(ctx context.Context, arg database.GetUsersParams) ([]database.User, int64, error) {
590-
// TODO Implement this with a SQL filter. The count is incorrect without it.
591-
rowUsers, err := q.db.GetUsers(ctx, arg)
592-
if err != nil {
593-
return nil, -1, err
594-
}
595-
596-
if len(rowUsers) == 0 {
597-
return []database.User{}, 0, nil
598-
}
599-
600-
act, ok := ActorFromContext(ctx)
601-
if !ok {
602-
return nil, -1, NoActorError
603-
}
604-
605-
// TODO: Is this correct? Should we return a restricted user?
606-
users := database.ConvertUserRows(rowUsers)
607-
users, err = rbac.Filter(ctx, q.auth, act, rbac.ActionRead, users)
608-
if err != nil {
609-
return nil, -1, err
610-
}
611-
612-
return users, rowUsers[0].Count, nil
613-
}
614-
615589
func (q *querier) SoftDeleteUserByID(ctx context.Context, id uuid.UUID) error {
616590
deleteF := func(ctx context.Context, id uuid.UUID) error {
617591
return q.db.UpdateUserDeletedByID(ctx, database.UpdateUserDeletedByIDParams{
@@ -904,15 +878,6 @@ func (q *querier) GetFileTemplates(ctx context.Context, fileID uuid.UUID) ([]dat
904878
return q.db.GetFileTemplates(ctx, fileID)
905879
}
906880

907-
func (q *querier) GetFilteredUserCount(ctx context.Context, arg database.GetFilteredUserCountParams) (int64, error) {
908-
prep, err := prepareSQLFilter(ctx, q.auth, rbac.ActionRead, rbac.ResourceUser.Type)
909-
if err != nil {
910-
return -1, xerrors.Errorf("(dev error) prepare sql filter: %w", err)
911-
}
912-
// TODO: This should be the only implementation.
913-
return q.GetAuthorizedUserCount(ctx, arg, prep)
914-
}
915-
916881
func (q *querier) GetGitAuthLink(ctx context.Context, arg database.GetGitAuthLinkParams) (database.GitAuthLink, error) {
917882
return fetch(q.log, q.auth, q.db.GetGitAuthLink)(ctx, arg)
918883
}
@@ -1389,8 +1354,12 @@ func (q *querier) GetUserLinkByUserIDLoginType(ctx context.Context, arg database
13891354
}
13901355

13911356
func (q *querier) GetUsers(ctx context.Context, arg database.GetUsersParams) ([]database.GetUsersRow, error) {
1392-
// TODO: We should use GetUsersWithCount with a better method signature.
1393-
return fetchWithPostFilter(q.auth, q.db.GetUsers)(ctx, arg)
1357+
// This does the filtering in SQL.
1358+
prep, err := prepareSQLFilter(ctx, q.auth, rbac.ActionRead, rbac.ResourceUser.Type)
1359+
if err != nil {
1360+
return nil, xerrors.Errorf("(dev error) prepare sql filter: %w", err)
1361+
}
1362+
return q.db.GetAuthorizedUsers(ctx, arg, prep)
13941363
}
13951364

13961365
// GetUsersByIDs is only used for usernames on workspace return data.
@@ -2639,6 +2608,9 @@ func (q *querier) GetAuthorizedWorkspaces(ctx context.Context, arg database.GetW
26392608
return q.GetWorkspaces(ctx, arg)
26402609
}
26412610

2642-
func (q *querier) GetAuthorizedUserCount(ctx context.Context, arg database.GetFilteredUserCountParams, prepared rbac.PreparedAuthorized) (int64, error) {
2643-
return q.db.GetAuthorizedUserCount(ctx, arg, prepared)
2611+
// GetAuthorizedUsers is not required for dbauthz since GetUsers is already
2612+
// authenticated.
2613+
func (q *querier) GetAuthorizedUsers(ctx context.Context, arg database.GetUsersParams, _ rbac.PreparedAuthorized) ([]database.GetUsersRow, error) {
2614+
// GetUsers is authenticated.
2615+
return q.GetUsers(ctx, arg)
26442616
}

0 commit comments

Comments
 (0)