Skip to content

Commit cc7d01d

Browse files
committed
Merge branch 'main' into bq/workspace-filter
2 parents 8a95c55 + d203f52 commit cc7d01d

File tree

97 files changed

+7334
-1714
lines changed

Some content is hidden

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

97 files changed

+7334
-1714
lines changed

.github/workflows/ci.yaml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ jobs:
4141

4242
# Check for any typos!
4343
- name: Check for typos
44-
uses: crate-ci/typos@v1.14.9
44+
uses: crate-ci/typos@v1.14.10
4545
with:
4646
config: .github/workflows/typos.toml
4747
- name: Fix the typos
@@ -184,6 +184,8 @@ jobs:
184184
run: go install golang.org/x/tools/cmd/goimports@latest
185185
- name: Install yq
186186
run: go run github.com/mikefarah/yq/v4@v4.30.6
187+
- name: Install mockgen
188+
run: go install github.com/golang/mock/mockgen@v1.6.0
187189

188190
- name: Install Protoc
189191
run: |

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,7 @@ lint/shellcheck: $(SHELL_SRC_FILES)
420420
gen: \
421421
coderd/database/dump.sql \
422422
coderd/database/querier.go \
423+
coderd/database/dbmock/store.go \
423424
provisionersdk/proto/provisioner.pb.go \
424425
provisionerd/proto/provisionerd.pb.go \
425426
site/src/api/typesGenerated.ts \
@@ -441,6 +442,7 @@ gen/mark-fresh:
441442
files="\
442443
coderd/database/dump.sql \
443444
coderd/database/querier.go \
445+
coderd/database/dbmock/store.go \
444446
provisionersdk/proto/provisioner.pb.go \
445447
provisionerd/proto/provisionerd.pb.go \
446448
site/src/api/typesGenerated.ts \
@@ -476,6 +478,10 @@ coderd/database/dump.sql: coderd/database/gen/dump/main.go $(wildcard coderd/dat
476478
coderd/database/querier.go: coderd/database/sqlc.yaml coderd/database/dump.sql $(wildcard coderd/database/queries/*.sql) coderd/database/gen/enum/main.go
477479
./coderd/database/generate.sh
478480

481+
482+
coderd/database/dbmock/store.go: coderd/database/db.go coderd/database/querier.go
483+
go generate ./coderd/database/dbmock/
484+
479485
provisionersdk/proto/provisioner.pb.go: provisionersdk/proto/provisioner.proto
480486
protoc \
481487
--go_out=. \

cli/agent.go

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -125,18 +125,20 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
125125
_ = pprof.Handler
126126
pprofSrvClose := ServeHandler(ctx, logger, nil, pprofAddress, "pprof")
127127
defer pprofSrvClose()
128-
// Do a best effort here. If this fails, it's not a big deal.
129-
if port, err := urlPort(pprofAddress); err == nil {
128+
if port, err := extractPort(pprofAddress); err == nil {
130129
ignorePorts[port] = "pprof"
131130
}
132131

133132
prometheusSrvClose := ServeHandler(ctx, logger, prometheusMetricsHandler(), prometheusAddress, "prometheus")
134133
defer prometheusSrvClose()
135-
// Do a best effort here. If this fails, it's not a big deal.
136-
if port, err := urlPort(prometheusAddress); err == nil {
134+
if port, err := extractPort(prometheusAddress); err == nil {
137135
ignorePorts[port] = "prometheus"
138136
}
139137

138+
if port, err := extractPort(debugAddress); err == nil {
139+
ignorePorts[port] = "debug"
140+
}
141+
140142
// exchangeToken returns a session token.
141143
// This is abstracted to allow for the same looping condition
142144
// regardless of instance identity auth type.
@@ -225,10 +227,6 @@ func (r *RootCmd) workspaceAgent() *clibase.Cmd {
225227

226228
debugSrvClose := ServeHandler(ctx, logger, agnt.HTTPDebug(), debugAddress, "debug")
227229
defer debugSrvClose()
228-
// Do a best effort here. If this fails, it's not a big deal.
229-
if port, err := urlPort(debugAddress); err == nil {
230-
ignorePorts[port] = "debug"
231-
}
232230

233231
<-ctx.Done()
234232
return agnt.Close()

cli/agent_internal_test.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ func Test_extractPort(t *testing.T) {
4646
urlString: "6060",
4747
wantErr: true,
4848
},
49+
{
50+
name: "127.0.0.1",
51+
urlString: "127.0.0.1:2113",
52+
want: 2113,
53+
wantErr: false,
54+
},
4955
}
5056
for _, tt := range tests {
5157
tt := tt

cli/templatedelete_test.go

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -51,15 +51,13 @@ func TestTemplateDelete(t *testing.T) {
5151

5252
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
5353
user := coderdtest.CreateFirstUser(t, client)
54-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
55-
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
56-
templates := []codersdk.Template{
57-
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID),
58-
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID),
59-
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID),
60-
}
54+
templates := []codersdk.Template{}
6155
templateNames := []string{}
62-
for _, template := range templates {
56+
for i := 0; i < 3; i++ {
57+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
58+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
59+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
60+
templates = append(templates, template)
6361
templateNames = append(templateNames, template.Name)
6462
}
6563

@@ -78,15 +76,13 @@ func TestTemplateDelete(t *testing.T) {
7876

7977
client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true})
8078
user := coderdtest.CreateFirstUser(t, client)
81-
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
82-
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
83-
templates := []codersdk.Template{
84-
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID),
85-
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID),
86-
coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID),
87-
}
79+
templates := []codersdk.Template{}
8880
templateNames := []string{}
89-
for _, template := range templates {
81+
for i := 0; i < 3; i++ {
82+
version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil)
83+
_ = coderdtest.AwaitTemplateVersionJob(t, client, version.ID)
84+
template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID)
85+
templates = append(templates, template)
9086
templateNames = append(templateNames, template.Name)
9187
}
9288

coderd/apidoc/docs.go

Lines changed: 6 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/apidoc/swagger.json

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/autobuild/executor/lifecycle_executor.go

Lines changed: 23 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package executor
22

33
import (
44
"context"
5-
"encoding/json"
5+
"database/sql"
66
"sync/atomic"
77
"time"
88

@@ -13,8 +13,8 @@ import (
1313
"cdr.dev/slog"
1414
"github.com/coder/coder/coderd/database"
1515
"github.com/coder/coder/coderd/database/dbauthz"
16-
"github.com/coder/coder/coderd/provisionerdserver"
1716
"github.com/coder/coder/coderd/schedule"
17+
"github.com/coder/coder/coderd/wsbuilder"
1818
)
1919

2020
// Executor automatically starts or stops workspaces.
@@ -168,20 +168,35 @@ func (e *Executor) runOnce(t time.Time) Stats {
168168
)
169169
return nil
170170
}
171-
172-
log.Info(e.ctx, "scheduling workspace transition", slog.F("transition", validTransition))
173-
174-
stats.Transitions[ws.ID] = validTransition
175-
if err := build(e.ctx, db, ws, validTransition, priorHistory, priorJob); err != nil {
171+
builder := wsbuilder.New(ws, validTransition).
172+
SetLastWorkspaceBuildInTx(&priorHistory).
173+
SetLastWorkspaceBuildJobInTx(&priorJob)
174+
175+
switch validTransition {
176+
case database.WorkspaceTransitionStart:
177+
builder = builder.Reason(database.BuildReasonAutostart)
178+
case database.WorkspaceTransitionStop:
179+
builder = builder.Reason(database.BuildReasonAutostop)
180+
default:
181+
log.Error(e.ctx, "unsupported transition", slog.F("transition", validTransition))
182+
return nil
183+
}
184+
if _, _, err := builder.Build(e.ctx, db, nil); err != nil {
176185
log.Error(e.ctx, "unable to transition workspace",
177186
slog.F("transition", validTransition),
178187
slog.Error(err),
179188
)
180189
return nil
181190
}
191+
stats.Transitions[ws.ID] = validTransition
192+
193+
log.Info(e.ctx, "scheduling workspace transition", slog.F("transition", validTransition))
182194

183195
return nil
184-
}, nil)
196+
197+
// Run with RepeatableRead isolation so that the build process sees the same data
198+
// as our calculation that determines whether an autobuild is necessary.
199+
}, &sql.TxOptions{Isolation: sql.LevelRepeatableRead})
185200
if err != nil {
186201
log.Error(e.ctx, "workspace scheduling failed", slog.Error(err))
187202
}
@@ -248,92 +263,3 @@ func getNextTransition(
248263
return "", time.Time{}, xerrors.Errorf("last transition not valid for autostart or autostop")
249264
}
250265
}
251-
252-
// TODO(cian): this function duplicates most of api.postWorkspaceBuilds. Refactor.
253-
// See: https://github.com/coder/coder/issues/1401
254-
func build(ctx context.Context, store database.Store, workspace database.Workspace, trans database.WorkspaceTransition, priorHistory database.WorkspaceBuild, priorJob database.ProvisionerJob) error {
255-
template, err := store.GetTemplateByID(ctx, workspace.TemplateID)
256-
if err != nil {
257-
return xerrors.Errorf("get workspace template: %w", err)
258-
}
259-
260-
priorBuildNumber := priorHistory.BuildNumber
261-
262-
// This must happen in a transaction to ensure history can be inserted, and
263-
// the prior history can update it's "after" column to point at the new.
264-
workspaceBuildID := uuid.New()
265-
input, err := json.Marshal(provisionerdserver.WorkspaceProvisionJob{
266-
WorkspaceBuildID: workspaceBuildID,
267-
})
268-
if err != nil {
269-
return xerrors.Errorf("marshal provision job: %w", err)
270-
}
271-
provisionerJobID := uuid.New()
272-
now := database.Now()
273-
274-
var buildReason database.BuildReason
275-
switch trans {
276-
case database.WorkspaceTransitionStart:
277-
buildReason = database.BuildReasonAutostart
278-
case database.WorkspaceTransitionStop:
279-
buildReason = database.BuildReasonAutostop
280-
default:
281-
return xerrors.Errorf("Unsupported transition: %q", trans)
282-
}
283-
284-
lastBuildParameters, err := store.GetWorkspaceBuildParameters(ctx, priorHistory.ID)
285-
if err != nil {
286-
return xerrors.Errorf("fetch prior workspace build parameters: %w", err)
287-
}
288-
289-
return store.InTx(func(db database.Store) error {
290-
newProvisionerJob, err := store.InsertProvisionerJob(ctx, database.InsertProvisionerJobParams{
291-
ID: provisionerJobID,
292-
CreatedAt: now,
293-
UpdatedAt: now,
294-
InitiatorID: workspace.OwnerID,
295-
OrganizationID: template.OrganizationID,
296-
Provisioner: template.Provisioner,
297-
Type: database.ProvisionerJobTypeWorkspaceBuild,
298-
StorageMethod: priorJob.StorageMethod,
299-
FileID: priorJob.FileID,
300-
Tags: priorJob.Tags,
301-
Input: input,
302-
})
303-
if err != nil {
304-
return xerrors.Errorf("insert provisioner job: %w", err)
305-
}
306-
workspaceBuild, err := store.InsertWorkspaceBuild(ctx, database.InsertWorkspaceBuildParams{
307-
ID: workspaceBuildID,
308-
CreatedAt: now,
309-
UpdatedAt: now,
310-
WorkspaceID: workspace.ID,
311-
TemplateVersionID: priorHistory.TemplateVersionID,
312-
BuildNumber: priorBuildNumber + 1,
313-
ProvisionerState: priorHistory.ProvisionerState,
314-
InitiatorID: workspace.OwnerID,
315-
Transition: trans,
316-
JobID: newProvisionerJob.ID,
317-
Reason: buildReason,
318-
})
319-
if err != nil {
320-
return xerrors.Errorf("insert workspace build: %w", err)
321-
}
322-
323-
names := make([]string, 0, len(lastBuildParameters))
324-
values := make([]string, 0, len(lastBuildParameters))
325-
for _, param := range lastBuildParameters {
326-
names = append(names, param.Name)
327-
values = append(values, param.Value)
328-
}
329-
err = db.InsertWorkspaceBuildParameters(ctx, database.InsertWorkspaceBuildParametersParams{
330-
WorkspaceBuildID: workspaceBuild.ID,
331-
Name: names,
332-
Value: values,
333-
})
334-
if err != nil {
335-
return xerrors.Errorf("insert workspace build parameters: %w", err)
336-
}
337-
return nil
338-
}, nil)
339-
}

coderd/coderd.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,10 @@ func New(options *Options) *API {
393393

394394
derpHandler := derphttp.Handler(api.DERPServer)
395395
derpHandler, api.derpCloseFunc = tailnet.WithWebsocketSupport(api.DERPServer, derpHandler)
396+
cors := httpmw.Cors(options.DeploymentValues.Dangerous.AllowAllCors.Value())
396397

397398
r.Use(
399+
cors,
398400
httpmw.Recover(api.Logger),
399401
tracing.StatusWriterMiddleware,
400402
tracing.Middleware(api.TracerProvider),
@@ -799,6 +801,10 @@ func New(options *Options) *API {
799801
// Add CSP headers to all static assets and pages. CSP headers only affect
800802
// browsers, so these don't make sense on api routes.
801803
cspMW := httpmw.CSPHeaders(func() []string {
804+
if api.DeploymentValues.Dangerous.AllowAllCors {
805+
// In this mode, allow all external requests
806+
return []string{"*"}
807+
}
802808
if f := api.WorkspaceProxyHostsFn.Load(); f != nil {
803809
return (*f)()
804810
}
@@ -813,7 +819,7 @@ func New(options *Options) *API {
813819
// This is the only route we add before all the middleware.
814820
// We want to time the latency of the request, so any middleware will
815821
// interfere with that timing.
816-
rootRouter.Get("/latency-check", LatencyCheck(api.AccessURL))
822+
rootRouter.Get("/latency-check", cors(LatencyCheck(options.DeploymentValues.Dangerous.AllowAllCors.Value(), api.AccessURL)).ServeHTTP)
817823
rootRouter.Mount("/", r)
818824
api.RootHandler = rootRouter
819825

0 commit comments

Comments
 (0)