Skip to content

Commit 296d821

Browse files
committed
Merge remote-tracking branch 'origin/main' into bp-scaling-coder
2 parents 26286f6 + 4f438e7 commit 296d821

File tree

68 files changed

+1100
-475
lines changed

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

+1100
-475
lines changed

.github/.linkspector.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,5 +19,6 @@ ignorePatterns:
1919
- pattern: "code.visualstudio.com"
2020
- pattern: "www.emacswiki.org"
2121
- pattern: "linux.die.net/man"
22+
- pattern: "www.gnu.org"
2223
aliveStatusCodes:
2324
- 200

Makefile

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -864,6 +864,30 @@ test-migrations: test-postgres-docker
864864
# NOTE: we set --memory to the same size as a GitHub runner.
865865
test-postgres-docker:
866866
docker rm -f test-postgres-docker-${POSTGRES_VERSION} || true
867+
868+
# Try pulling up to three times to avoid CI flakes.
869+
docker pull gcr.io/coder-dev-1/postgres:${POSTGRES_VERSION} || {
870+
retries=2
871+
for try in $(seq 1 ${retries}); do
872+
echo "Failed to pull image, retrying (${try}/${retries})..."
873+
sleep 1
874+
if docker pull gcr.io/coder-dev-1/postgres:${POSTGRES_VERSION}; then
875+
break
876+
fi
877+
done
878+
}
879+
880+
# Make sure to not overallocate work_mem and max_connections as each
881+
# connection will be allowed to use this much memory. Try adjusting
882+
# shared_buffers instead, if needed.
883+
#
884+
# - work_mem=8MB * max_connections=1000 = 8GB
885+
# - shared_buffers=2GB + effective_cache_size=1GB = 3GB
886+
#
887+
# This leaves 5GB for the rest of the system _and_ storing the
888+
# database in memory (--tmpfs).
889+
#
890+
# https://www.postgresql.org/docs/current/runtime-config-resource.html#GUC-WORK-MEM
867891
docker run \
868892
--env POSTGRES_PASSWORD=postgres \
869893
--env POSTGRES_USER=postgres \
@@ -876,9 +900,9 @@ test-postgres-docker:
876900
--detach \
877901
--memory 16GB \
878902
gcr.io/coder-dev-1/postgres:${POSTGRES_VERSION} \
879-
-c shared_buffers=1GB \
880-
-c work_mem=1GB \
903+
-c shared_buffers=2GB \
881904
-c effective_cache_size=1GB \
905+
-c work_mem=8MB \
882906
-c max_connections=1000 \
883907
-c fsync=off \
884908
-c synchronous_commit=off \

cli/exptest/exptest_scaletest_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,6 @@ import (
2020
// can influence other tests in the same package.
2121
// nolint:paralleltest
2222
func TestScaleTestWorkspaceTraffic_UseHostLogin(t *testing.T) {
23-
ctx, cancelFunc := context.WithTimeout(context.Background(), testutil.WaitMedium)
24-
defer cancelFunc()
25-
2623
log := slogtest.Make(t, &slogtest.Options{IgnoreErrors: true})
2724
client := coderdtest.New(t, &coderdtest.Options{
2825
Logger: &log,
@@ -41,6 +38,9 @@ func TestScaleTestWorkspaceTraffic_UseHostLogin(t *testing.T) {
4138
cwr.Name = "scaletest-workspace"
4239
})
4340

41+
ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong)
42+
defer cancel()
43+
4444
// Test without --use-host-login first.g
4545
inv, root := clitest.New(t, "exp", "scaletest", "workspace-traffic",
4646
"--template", tpl.Name,

cli/ssh_test.go

Lines changed: 90 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -819,102 +819,105 @@ func TestSSH(t *testing.T) {
819819

820820
tmpdir := tempDirUnixSocket(t)
821821
localSock := filepath.Join(tmpdir, "local.sock")
822-
l, err := net.Listen("unix", localSock)
823-
require.NoError(t, err)
824-
defer l.Close()
825822
remoteSock := path.Join(tmpdir, "remote.sock")
826823
for i := 0; i < 2; i++ {
827-
t.Logf("connect %d of 2", i+1)
828-
inv, root := clitest.New(t,
829-
"ssh",
830-
workspace.Name,
831-
"--remote-forward",
832-
remoteSock+":"+localSock,
833-
)
834-
fsn := clitest.NewFakeSignalNotifier(t)
835-
inv = inv.WithTestSignalNotifyContext(t, fsn.NotifyContext)
836-
inv.Stdout = io.Discard
837-
inv.Stderr = io.Discard
838-
839-
clitest.SetupConfig(t, client, root)
840-
cmdDone := tGo(t, func() {
841-
err := inv.WithContext(ctx).Run()
842-
assert.Error(t, err)
843-
})
824+
func() { // Function scope for defer.
825+
t.Logf("Connect %d/2", i+1)
826+
827+
inv, root := clitest.New(t,
828+
"ssh",
829+
workspace.Name,
830+
"--remote-forward",
831+
remoteSock+":"+localSock,
832+
)
833+
fsn := clitest.NewFakeSignalNotifier(t)
834+
inv = inv.WithTestSignalNotifyContext(t, fsn.NotifyContext)
835+
inv.Stdout = io.Discard
836+
inv.Stderr = io.Discard
844837

845-
// accept a single connection
846-
msgs := make(chan string, 1)
847-
go func() {
848-
conn, err := l.Accept()
849-
if !assert.NoError(t, err) {
850-
return
851-
}
852-
msg, err := io.ReadAll(conn)
853-
if !assert.NoError(t, err) {
854-
return
855-
}
856-
msgs <- string(msg)
857-
}()
838+
clitest.SetupConfig(t, client, root)
839+
cmdDone := tGo(t, func() {
840+
err := inv.WithContext(ctx).Run()
841+
assert.Error(t, err)
842+
})
858843

859-
// Unfortunately, there is a race in crypto/ssh where it sends the request to forward
860-
// unix sockets before it is prepared to receive the response, meaning that even after
861-
// the socket exists on the file system, the client might not be ready to accept the
862-
// channel.
863-
//
864-
// https://cs.opensource.google/go/x/crypto/+/master:ssh/streamlocal.go;drc=2fc4c88bf43f0ea5ea305eae2b7af24b2cc93287;l=33
865-
//
866-
// To work around this, we attempt to send messages in a loop until one succeeds
867-
success := make(chan struct{})
868-
done := make(chan struct{})
869-
go func() {
870-
defer close(done)
871-
var (
872-
conn net.Conn
873-
err error
874-
)
875-
for {
876-
time.Sleep(testutil.IntervalMedium)
877-
select {
878-
case <-ctx.Done():
879-
t.Error("timeout")
880-
return
881-
case <-success:
844+
// accept a single connection
845+
msgs := make(chan string, 1)
846+
l, err := net.Listen("unix", localSock)
847+
require.NoError(t, err)
848+
defer l.Close()
849+
go func() {
850+
conn, err := l.Accept()
851+
if !assert.NoError(t, err) {
882852
return
883-
default:
884-
// Ok
885853
}
886-
conn, err = net.Dial("unix", remoteSock)
887-
if err != nil {
888-
t.Logf("dial error: %s", err)
889-
continue
890-
}
891-
_, err = conn.Write([]byte("test"))
892-
if err != nil {
893-
t.Logf("write error: %s", err)
854+
msg, err := io.ReadAll(conn)
855+
if !assert.NoError(t, err) {
856+
return
894857
}
895-
err = conn.Close()
896-
if err != nil {
897-
t.Logf("close error: %s", err)
858+
msgs <- string(msg)
859+
}()
860+
861+
// Unfortunately, there is a race in crypto/ssh where it sends the request to forward
862+
// unix sockets before it is prepared to receive the response, meaning that even after
863+
// the socket exists on the file system, the client might not be ready to accept the
864+
// channel.
865+
//
866+
// https://cs.opensource.google/go/x/crypto/+/master:ssh/streamlocal.go;drc=2fc4c88bf43f0ea5ea305eae2b7af24b2cc93287;l=33
867+
//
868+
// To work around this, we attempt to send messages in a loop until one succeeds
869+
success := make(chan struct{})
870+
done := make(chan struct{})
871+
go func() {
872+
defer close(done)
873+
var (
874+
conn net.Conn
875+
err error
876+
)
877+
for {
878+
time.Sleep(testutil.IntervalMedium)
879+
select {
880+
case <-ctx.Done():
881+
t.Error("timeout")
882+
return
883+
case <-success:
884+
return
885+
default:
886+
// Ok
887+
}
888+
conn, err = net.Dial("unix", remoteSock)
889+
if err != nil {
890+
t.Logf("dial error: %s", err)
891+
continue
892+
}
893+
_, err = conn.Write([]byte("test"))
894+
if err != nil {
895+
t.Logf("write error: %s", err)
896+
}
897+
err = conn.Close()
898+
if err != nil {
899+
t.Logf("close error: %s", err)
900+
}
898901
}
899-
}
900-
}()
902+
}()
901903

902-
msg := testutil.RequireRecvCtx(ctx, t, msgs)
903-
require.Equal(t, "test", msg)
904-
close(success)
905-
fsn.Notify()
906-
<-cmdDone
907-
fsn.AssertStopped()
908-
// wait for dial goroutine to complete
909-
_ = testutil.RequireRecvCtx(ctx, t, done)
910-
911-
// wait for the remote socket to get cleaned up before retrying,
912-
// because cleaning up the socket happens asynchronously, and we
913-
// might connect to an old listener on the agent side.
914-
require.Eventually(t, func() bool {
915-
_, err = os.Stat(remoteSock)
916-
return xerrors.Is(err, os.ErrNotExist)
917-
}, testutil.WaitShort, testutil.IntervalFast)
904+
msg := testutil.RequireRecvCtx(ctx, t, msgs)
905+
require.Equal(t, "test", msg)
906+
close(success)
907+
fsn.Notify()
908+
<-cmdDone
909+
fsn.AssertStopped()
910+
// wait for dial goroutine to complete
911+
_ = testutil.RequireRecvCtx(ctx, t, done)
912+
913+
// wait for the remote socket to get cleaned up before retrying,
914+
// because cleaning up the socket happens asynchronously, and we
915+
// might connect to an old listener on the agent side.
916+
require.Eventually(t, func() bool {
917+
_, err = os.Stat(remoteSock)
918+
return xerrors.Is(err, os.ErrNotExist)
919+
}, testutil.WaitShort, testutil.IntervalFast)
920+
}()
918921
}
919922
})
920923

cli/support_test.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ func TestSupportBundle(t *testing.T) {
4545

4646
t.Run("Workspace", func(t *testing.T) {
4747
t.Parallel()
48-
ctx := testutil.Context(t, testutil.WaitShort)
48+
4949
var dc codersdk.DeploymentConfig
5050
secretValue := uuid.NewString()
5151
seedSecretDeploymentOptions(t, &dc, secretValue)
@@ -61,6 +61,8 @@ func TestSupportBundle(t *testing.T) {
6161
agents[0].Env["SECRET_VALUE"] = secretValue
6262
return agents
6363
}).Do()
64+
65+
ctx := testutil.Context(t, testutil.WaitShort)
6466
ws, err := client.Workspace(ctx, r.Workspace.ID)
6567
require.NoError(t, err)
6668
tempDir := t.TempDir()
@@ -72,6 +74,8 @@ func TestSupportBundle(t *testing.T) {
7274
defer agt.Close()
7375
coderdtest.NewWorkspaceAgentWaiter(t, client, r.Workspace.ID).Wait()
7476

77+
ctx = testutil.Context(t, testutil.WaitShort) // Reset timeout after waiting for agent.
78+
7579
// Insert a provisioner job log
7680
_, err = db.InsertProvisionerJobLogs(ctx, database.InsertProvisionerJobLogsParams{
7781
JobID: r.Build.JobID,

cli/testdata/coder_server_--help.golden

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -624,9 +624,9 @@ updating, and deleting workspace resources.
624624
in queued state for a long time, consider increasing this.
625625

626626
TELEMETRY OPTIONS:
627-
Telemetry is critical to our ability to improve Coder. We strip all
628-
personalinformation before sending data to our servers. Please only disable
629-
telemetrywhen required by your organization's security policy.
627+
Telemetry is critical to our ability to improve Coder. We strip all personal
628+
information before sending data to our servers. Please only disable telemetry
629+
when required by your organization's security policy.
630630

631631
--telemetry bool, $CODER_TELEMETRY_ENABLE (default: false)
632632
Whether telemetry is enabled or not. Coder collects anonymized usage

cli/testdata/server-config.yaml.golden

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -390,8 +390,8 @@ oidc:
390390
# (default: <unset>, type: bool)
391391
dangerousSkipIssuerChecks: false
392392
# Telemetry is critical to our ability to improve Coder. We strip all personal
393-
# information before sending data to our servers. Please only disable telemetry
394-
# when required by your organization's security policy.
393+
# information before sending data to our servers. Please only disable telemetry
394+
# when required by your organization's security policy.
395395
telemetry:
396396
# Whether telemetry is enabled or not. Coder collects anonymized usage data to
397397
# help improve our product.

coderd/autobuild/lifecycle_executor_test.go

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,6 @@ func TestExecutorAutostartUserSuspended(t *testing.T) {
364364
t.Parallel()
365365

366366
var (
367-
ctx = testutil.Context(t, testutil.WaitShort)
368367
sched = mustSchedule(t, "CRON_TZ=UTC 0 * * * *")
369368
tickCh = make(chan time.Time)
370369
statsCh = make(chan autobuild.Stats)
@@ -389,6 +388,8 @@ func TestExecutorAutostartUserSuspended(t *testing.T) {
389388
// Given: workspace is stopped, and the user is suspended.
390389
workspace = coderdtest.MustTransitionWorkspace(t, userClient, workspace.ID, database.WorkspaceTransitionStart, database.WorkspaceTransitionStop)
391390

391+
ctx := testutil.Context(t, testutil.WaitShort)
392+
392393
_, err := client.UpdateUserStatus(ctx, user.ID.String(), codersdk.UserStatusSuspended)
393394
require.NoError(t, err, "update user status")
394395

@@ -660,7 +661,6 @@ func TestExecuteAutostopSuspendedUser(t *testing.T) {
660661
t.Parallel()
661662

662663
var (
663-
ctx = testutil.Context(t, testutil.WaitShort)
664664
tickCh = make(chan time.Time)
665665
statsCh = make(chan autobuild.Stats)
666666
client = coderdtest.New(t, &coderdtest.Options{
@@ -681,6 +681,9 @@ func TestExecuteAutostopSuspendedUser(t *testing.T) {
681681
// Given: workspace is running, and the user is suspended.
682682
workspace = coderdtest.MustWorkspace(t, userClient, workspace.ID)
683683
require.Equal(t, codersdk.WorkspaceStatusRunning, workspace.LatestBuild.Status)
684+
685+
ctx := testutil.Context(t, testutil.WaitShort)
686+
684687
_, err := client.UpdateUserStatus(ctx, user.ID.String(), codersdk.UserStatusSuspended)
685688
require.NoError(t, err, "update user status")
686689

@@ -980,6 +983,9 @@ func TestExecutorRequireActiveVersion(t *testing.T) {
980983
activeVersion := coderdtest.CreateTemplateVersion(t, ownerClient, owner.OrganizationID, nil)
981984
coderdtest.AwaitTemplateVersionJobCompleted(t, ownerClient, activeVersion.ID)
982985
template := coderdtest.CreateTemplate(t, ownerClient, owner.OrganizationID, activeVersion.ID)
986+
987+
ctx = testutil.Context(t, testutil.WaitShort) // Reset context after setting up the template.
988+
983989
//nolint We need to set this in the database directly, because the API will return an error
984990
// letting you know that this feature requires an enterprise license.
985991
err = db.UpdateTemplateAccessControlByID(dbauthz.As(ctx, coderdtest.AuthzUserSubject(me, owner.OrganizationID)), database.UpdateTemplateAccessControlByIDParams{

coderd/database/db2sdk/db2sdk.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import (
1717

1818
"github.com/coder/coder/v2/coderd/database"
1919
"github.com/coder/coder/v2/coderd/rbac"
20+
"github.com/coder/coder/v2/coderd/rbac/policy"
2021
"github.com/coder/coder/v2/coderd/render"
2122
"github.com/coder/coder/v2/coderd/workspaceapps/appurl"
2223
"github.com/coder/coder/v2/codersdk"
@@ -694,3 +695,13 @@ func MatchedProvisioners(provisionerDaemons []database.ProvisionerDaemon, now ti
694695
}
695696
return matched
696697
}
698+
699+
func TemplateRoleActions(role codersdk.TemplateRole) []policy.Action {
700+
switch role {
701+
case codersdk.TemplateRoleAdmin:
702+
return []policy.Action{policy.WildcardSymbol}
703+
case codersdk.TemplateRoleUse:
704+
return []policy.Action{policy.ActionRead, policy.ActionUse}
705+
}
706+
return []policy.Action{}
707+
}

coderd/database/dbauthz/dbauthz.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3169,6 +3169,14 @@ func (q *querier) InsertUserLink(ctx context.Context, arg database.InsertUserLin
31693169

31703170
func (q *querier) InsertWorkspace(ctx context.Context, arg database.InsertWorkspaceParams) (database.WorkspaceTable, error) {
31713171
obj := rbac.ResourceWorkspace.WithOwner(arg.OwnerID.String()).InOrg(arg.OrganizationID)
3172+
tpl, err := q.GetTemplateByID(ctx, arg.TemplateID)
3173+
if err != nil {
3174+
return database.WorkspaceTable{}, xerrors.Errorf("verify template by id: %w", err)
3175+
}
3176+
if err := q.authorizeContext(ctx, policy.ActionUse, tpl); err != nil {
3177+
return database.WorkspaceTable{}, xerrors.Errorf("use template for workspace: %w", err)
3178+
}
3179+
31723180
return insert(q.log, q.auth, obj, q.db.InsertWorkspace)(ctx, arg)
31733181
}
31743182

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy