Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 71d8fa9

Browse files
authored
Merge branch 'main' into jaaydenh/dynamic-params-websocket
2 parents 1777ca9 + 669e790 commit 71d8fa9

File tree

21 files changed

+796
-100
lines changed

21 files changed

+796
-100
lines changed

agent/reconnectingpty/screen.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -307,9 +307,9 @@ func (rpty *screenReconnectingPTY) doAttach(ctx context.Context, conn net.Conn,
307307
if closeErr != nil {
308308
logger.Debug(ctx, "closed ptty with error", slog.Error(closeErr))
309309
}
310-
closeErr = process.Kill()
311-
if closeErr != nil {
312-
logger.Debug(ctx, "killed process with error", slog.Error(closeErr))
310+
killErr := process.Kill()
311+
if killErr != nil {
312+
logger.Debug(ctx, "killed process with error", slog.Error(killErr))
313313
}
314314
rpty.metrics.WithLabelValues("screen_wait").Add(1)
315315
return nil, nil, err

cli/configssh_test.go

+8-8
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
435435
"# :hostname-suffix=coder-suffix",
436436
"# :header=X-Test-Header=foo",
437437
"# :header=X-Test-Header2=bar",
438-
"# :header-command=printf h1=v1 h2=\"v2\" h3='v3'",
438+
"# :header-command=echo h1=v1 h2=\"v2\" h3='v3'",
439439
"#",
440440
}, "\n"),
441441
strings.Join([]string{
@@ -451,7 +451,7 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
451451
"--hostname-suffix", "coder-suffix",
452452
"--header", "X-Test-Header=foo",
453453
"--header", "X-Test-Header2=bar",
454-
"--header-command", "printf h1=v1 h2=\"v2\" h3='v3'",
454+
"--header-command", "echo h1=v1 h2=\"v2\" h3='v3'",
455455
},
456456
},
457457
{
@@ -566,36 +566,36 @@ func TestConfigSSH_FileWriteAndOptionsFlow(t *testing.T) {
566566
name: "Header command",
567567
args: []string{
568568
"--yes",
569-
"--header-command", "printf h1=v1",
569+
"--header-command", "echo h1=v1",
570570
},
571571
wantErr: false,
572572
hasAgent: true,
573573
wantConfig: wantConfig{
574-
regexMatch: `ProxyCommand .* --header-command "printf h1=v1" ssh .* --ssh-host-prefix coder. %h`,
574+
regexMatch: `ProxyCommand .* --header-command "echo h1=v1" ssh .* --ssh-host-prefix coder. %h`,
575575
},
576576
},
577577
{
578578
name: "Header command with double quotes",
579579
args: []string{
580580
"--yes",
581-
"--header-command", "printf h1=v1 h2=\"v2\"",
581+
"--header-command", "echo h1=v1 h2=\"v2\"",
582582
},
583583
wantErr: false,
584584
hasAgent: true,
585585
wantConfig: wantConfig{
586-
regexMatch: `ProxyCommand .* --header-command "printf h1=v1 h2=\\\"v2\\\"" ssh .* --ssh-host-prefix coder. %h`,
586+
regexMatch: `ProxyCommand .* --header-command "echo h1=v1 h2=\\\"v2\\\"" ssh .* --ssh-host-prefix coder. %h`,
587587
},
588588
},
589589
{
590590
name: "Header command with single quotes",
591591
args: []string{
592592
"--yes",
593-
"--header-command", "printf h1=v1 h2='v2'",
593+
"--header-command", "echo h1=v1 h2='v2'",
594594
},
595595
wantErr: false,
596596
hasAgent: true,
597597
wantConfig: wantConfig{
598-
regexMatch: `ProxyCommand .* --header-command "printf h1=v1 h2='v2'" ssh .* --ssh-host-prefix coder. %h`,
598+
regexMatch: `ProxyCommand .* --header-command "echo h1=v1 h2='v2'" ssh .* --ssh-host-prefix coder. %h`,
599599
},
600600
},
601601
{

coderd/database/dbauthz/dbauthz_test.go

+2-3
Original file line numberDiff line numberDiff line change
@@ -886,7 +886,7 @@ func (s *MethodTestSuite) TestOrganization() {
886886
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{UserID: u.ID, OrganizationID: a.ID})
887887
b := dbgen.Organization(s.T(), db, database.Organization{})
888888
_ = dbgen.OrganizationMember(s.T(), db, database.OrganizationMember{UserID: u.ID, OrganizationID: b.ID})
889-
check.Args(database.GetOrganizationsByUserIDParams{UserID: u.ID, Deleted: false}).Asserts(a, policy.ActionRead, b, policy.ActionRead).Returns(slice.New(a, b))
889+
check.Args(database.GetOrganizationsByUserIDParams{UserID: u.ID, Deleted: sql.NullBool{Valid: true, Bool: false}}).Asserts(a, policy.ActionRead, b, policy.ActionRead).Returns(slice.New(a, b))
890890
}))
891891
s.Run("InsertOrganization", s.Subtest(func(db database.Store, check *expects) {
892892
check.Args(database.InsertOrganizationParams{
@@ -994,8 +994,7 @@ func (s *MethodTestSuite) TestOrganization() {
994994
member, policy.ActionRead,
995995
member, policy.ActionDelete).
996996
WithNotAuthorized("no rows").
997-
WithCancelled(cancelledErr).
998-
ErrorsWithInMemDB(sql.ErrNoRows)
997+
WithCancelled(cancelledErr)
999998
}))
1000999
s.Run("UpdateOrganization", s.Subtest(func(db database.Store, check *expects) {
10011000
o := dbgen.Organization(s.T(), db, database.Organization{

coderd/database/dbfake/builder.go

+18
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ type OrganizationBuilder struct {
1717
t *testing.T
1818
db database.Store
1919
seed database.Organization
20+
delete bool
2021
allUsersAllowance int32
2122
members []uuid.UUID
2223
groups map[database.Group][]uuid.UUID
@@ -45,6 +46,12 @@ func (b OrganizationBuilder) EveryoneAllowance(allowance int) OrganizationBuilde
4546
return b
4647
}
4748

49+
func (b OrganizationBuilder) Deleted(deleted bool) OrganizationBuilder {
50+
//nolint: revive // returns modified struct
51+
b.delete = deleted
52+
return b
53+
}
54+
4855
func (b OrganizationBuilder) Seed(seed database.Organization) OrganizationBuilder {
4956
//nolint: revive // returns modified struct
5057
b.seed = seed
@@ -119,6 +126,17 @@ func (b OrganizationBuilder) Do() OrganizationResponse {
119126
}
120127
}
121128

129+
if b.delete {
130+
now := dbtime.Now()
131+
err = b.db.UpdateOrganizationDeletedByID(ctx, database.UpdateOrganizationDeletedByIDParams{
132+
UpdatedAt: now,
133+
ID: org.ID,
134+
})
135+
require.NoError(b.t, err)
136+
org.Deleted = true
137+
org.UpdatedAt = now
138+
}
139+
122140
return OrganizationResponse{
123141
Org: org,
124142
AllUsersGroup: everyone,

coderd/database/dbmem/dbmem.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -2357,10 +2357,13 @@ func (q *FakeQuerier) DeleteOrganizationMember(ctx context.Context, arg database
23572357
q.mutex.Lock()
23582358
defer q.mutex.Unlock()
23592359

2360-
deleted := slices.DeleteFunc(q.data.organizationMembers, func(member database.OrganizationMember) bool {
2361-
return member.OrganizationID == arg.OrganizationID && member.UserID == arg.UserID
2360+
deleted := false
2361+
q.data.organizationMembers = slices.DeleteFunc(q.data.organizationMembers, func(member database.OrganizationMember) bool {
2362+
match := member.OrganizationID == arg.OrganizationID && member.UserID == arg.UserID
2363+
deleted = deleted || match
2364+
return match
23622365
})
2363-
if len(deleted) == 0 {
2366+
if !deleted {
23642367
return sql.ErrNoRows
23652368
}
23662369

@@ -4156,6 +4159,9 @@ func (q *FakeQuerier) GetOrganizations(_ context.Context, args database.GetOrgan
41564159
if args.Name != "" && !strings.EqualFold(org.Name, args.Name) {
41574160
continue
41584161
}
4162+
if args.Deleted != org.Deleted {
4163+
continue
4164+
}
41594165
tmp = append(tmp, org)
41604166
}
41614167

@@ -4172,7 +4178,11 @@ func (q *FakeQuerier) GetOrganizationsByUserID(_ context.Context, arg database.G
41724178
continue
41734179
}
41744180
for _, organization := range q.organizations {
4175-
if organization.ID != organizationMember.OrganizationID || organization.Deleted != arg.Deleted {
4181+
if organization.ID != organizationMember.OrganizationID {
4182+
continue
4183+
}
4184+
4185+
if arg.Deleted.Valid && organization.Deleted != arg.Deleted.Bool {
41764186
continue
41774187
}
41784188
organizations = append(organizations, organization)

coderd/database/queries.sql.go

+9-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/organizations.sql

+7-2
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,13 @@ SELECT
5555
FROM
5656
organizations
5757
WHERE
58-
-- Optionally include deleted organizations
59-
deleted = @deleted AND
58+
-- Optionally provide a filter for deleted organizations.
59+
CASE WHEN
60+
sqlc.narg('deleted') :: boolean IS NULL THEN
61+
true
62+
ELSE
63+
deleted = sqlc.narg('deleted')
64+
END AND
6065
id = ANY(
6166
SELECT
6267
organization_id

coderd/httpmw/prometheus.go

+42-10
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package httpmw
33
import (
44
"net/http"
55
"strconv"
6+
"strings"
67
"time"
78

89
"github.com/go-chi/chi/v5"
@@ -22,18 +23,18 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
2223
Name: "requests_processed_total",
2324
Help: "The total number of processed API requests",
2425
}, []string{"code", "method", "path"})
25-
requestsConcurrent := factory.NewGauge(prometheus.GaugeOpts{
26+
requestsConcurrent := factory.NewGaugeVec(prometheus.GaugeOpts{
2627
Namespace: "coderd",
2728
Subsystem: "api",
2829
Name: "concurrent_requests",
2930
Help: "The number of concurrent API requests.",
30-
})
31-
websocketsConcurrent := factory.NewGauge(prometheus.GaugeOpts{
31+
}, []string{"method", "path"})
32+
websocketsConcurrent := factory.NewGaugeVec(prometheus.GaugeOpts{
3233
Namespace: "coderd",
3334
Subsystem: "api",
3435
Name: "concurrent_websockets",
3536
Help: "The total number of concurrent API websockets.",
36-
})
37+
}, []string{"path"})
3738
websocketsDist := factory.NewHistogramVec(prometheus.HistogramOpts{
3839
Namespace: "coderd",
3940
Subsystem: "api",
@@ -61,7 +62,6 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
6162
var (
6263
start = time.Now()
6364
method = r.Method
64-
rctx = chi.RouteContext(r.Context())
6565
)
6666

6767
sw, ok := w.(*tracing.StatusWriter)
@@ -72,24 +72,25 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
7272
var (
7373
dist *prometheus.HistogramVec
7474
distOpts []string
75+
path = getRoutePattern(r)
7576
)
77+
7678
// We want to count WebSockets separately.
7779
if httpapi.IsWebsocketUpgrade(r) {
78-
websocketsConcurrent.Inc()
79-
defer websocketsConcurrent.Dec()
80+
websocketsConcurrent.WithLabelValues(path).Inc()
81+
defer websocketsConcurrent.WithLabelValues(path).Dec()
8082

8183
dist = websocketsDist
8284
} else {
83-
requestsConcurrent.Inc()
84-
defer requestsConcurrent.Dec()
85+
requestsConcurrent.WithLabelValues(method, path).Inc()
86+
defer requestsConcurrent.WithLabelValues(method, path).Dec()
8587

8688
dist = requestsDist
8789
distOpts = []string{method}
8890
}
8991

9092
next.ServeHTTP(w, r)
9193

92-
path := rctx.RoutePattern()
9394
distOpts = append(distOpts, path)
9495
statusStr := strconv.Itoa(sw.Status)
9596

@@ -98,3 +99,34 @@ func Prometheus(register prometheus.Registerer) func(http.Handler) http.Handler
9899
})
99100
}
100101
}
102+
103+
func getRoutePattern(r *http.Request) string {
104+
rctx := chi.RouteContext(r.Context())
105+
if rctx == nil {
106+
return ""
107+
}
108+
109+
if pattern := rctx.RoutePattern(); pattern != "" {
110+
// Pattern is already available
111+
return pattern
112+
}
113+
114+
routePath := r.URL.Path
115+
if r.URL.RawPath != "" {
116+
routePath = r.URL.RawPath
117+
}
118+
119+
tctx := chi.NewRouteContext()
120+
routes := rctx.Routes
121+
if routes != nil && !routes.Match(tctx, r.Method, routePath) {
122+
// No matching pattern. /api/* requests will be matched as "UNKNOWN"
123+
// All other ones will be matched as "STATIC".
124+
if strings.HasPrefix(routePath, "/api/") {
125+
return "UNKNOWN"
126+
}
127+
return "STATIC"
128+
}
129+
130+
// tctx has the updated pattern, since Match mutates it
131+
return tctx.RoutePattern()
132+
}

0 commit comments

Comments
 (0)