Skip to content

Commit c716995

Browse files
committed
Merge branch 'main' of github.com:coder/coder into bq/add-diff
2 parents 7585ab1 + a973c35 commit c716995

Some content is hidden

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

55 files changed

+1342
-103
lines changed

.github/workflows/coder.yaml

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,14 @@ jobs:
336336
echo ::set-output name=cover::false
337337
fi
338338
set -x
339-
gotestsum --junitfile="gotests.xml" --packages="./..." --debug -- -parallel=8 -timeout=3m -short -failfast $COVERAGE_FLAGS
339+
gotestsum --junitfile="gotests.xml" --jsonfile="gotestsum.json" --packages="./..." --debug -- -parallel=8 -timeout=3m -short -failfast $COVERAGE_FLAGS
340+
341+
- uses: actions/upload-artifact@v3
342+
if: success() || failure()
343+
with:
344+
name: gotestsum-debug-${{ matrix.os }}.json
345+
path: ./gotestsum.json
346+
retention-days: 7
340347

341348
- uses: codecov/codecov-action@v3
342349
# This action has a tendency to error out unexpectedly, it has
@@ -399,6 +406,13 @@ jobs:
399406
- name: Test with PostgreSQL Database
400407
run: make test-postgres
401408

409+
- uses: actions/upload-artifact@v3
410+
if: success() || failure()
411+
with:
412+
name: gotestsum-debug-postgres.json
413+
path: ./gotestsum.json
414+
retention-days: 7
415+
402416
- uses: codecov/codecov-action@v3
403417
# This action has a tendency to error out unexpectedly, it has
404418
# the `fail_ci_if_error` option that defaults to `false`, but

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ vendor
1515
yarn-error.log
1616
gotests.coverage
1717
gotests.xml
18+
gotestsum.json
1819
.idea
1920
.gitpod.yml
2021
.DS_Store

Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -471,7 +471,10 @@ test: test-clean
471471
test-postgres: test-clean test-postgres-docker
472472
# The postgres test is prone to failure, so we limit parallelism for
473473
# more consistent execution.
474-
DB=ci DB_FROM=$(shell go run scripts/migrate-ci/main.go) gotestsum --junitfile="gotests.xml" --packages="./..." -- \
474+
DB=ci DB_FROM=$(shell go run scripts/migrate-ci/main.go) gotestsum \
475+
--junitfile="gotests.xml" \
476+
--jsonfile="gotestsum.json" \
477+
--packages="./..." -- \
475478
-covermode=atomic -coverprofile="gotests.coverage" -timeout=20m \
476479
-parallel=4 \
477480
-coverpkg=./... \

cli/server.go

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
112112
notifyCtx, notifyStop := signal.NotifyContext(ctx, InterruptSignals...)
113113
defer notifyStop()
114114

115+
// Ensure we have a unique cache directory for this process.
116+
cacheDir := filepath.Join(cfg.CacheDirectory.Value, uuid.NewString())
117+
err = os.MkdirAll(cacheDir, 0o700)
118+
if err != nil {
119+
return xerrors.Errorf("create cache directory: %w", err)
120+
}
121+
defer os.RemoveAll(cacheDir)
122+
115123
// Clean up idle connections at the end, e.g.
116124
// embedded-postgres can leave an idle connection
117125
// which is caught by goleaks.
@@ -355,7 +363,7 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
355363
Database: databasefake.New(),
356364
DERPMap: derpMap,
357365
Pubsub: database.NewPubsubInMemory(),
358-
CacheDir: cfg.CacheDirectory.Value,
366+
CacheDir: cacheDir,
359367
GoogleTokenValidator: googleTokenValidator,
360368
GitAuthConfigs: gitAuthConfigs,
361369
RealIPConfig: realIPConfig,
@@ -632,7 +640,8 @@ func Server(vip *viper.Viper, newAPI func(context.Context, *coderd.Options) (*co
632640
}()
633641
provisionerdMetrics := provisionerd.NewMetrics(options.PrometheusRegistry)
634642
for i := 0; i < cfg.Provisioner.Daemons.Value; i++ {
635-
daemon, err := newProvisionerDaemon(ctx, coderAPI, provisionerdMetrics, logger, cfg, errCh, false)
643+
daemonCacheDir := filepath.Join(cacheDir, fmt.Sprintf("provisioner-%d", i))
644+
daemon, err := newProvisionerDaemon(ctx, coderAPI, provisionerdMetrics, logger, cfg, daemonCacheDir, errCh, false)
636645
if err != nil {
637646
return xerrors.Errorf("create provisioner daemon: %w", err)
638647
}
@@ -902,6 +911,7 @@ func newProvisionerDaemon(
902911
metrics provisionerd.Metrics,
903912
logger slog.Logger,
904913
cfg *codersdk.DeploymentConfig,
914+
cacheDir string,
905915
errCh chan error,
906916
dev bool,
907917
) (srv *provisionerd.Server, err error) {
@@ -912,9 +922,9 @@ func newProvisionerDaemon(
912922
}
913923
}()
914924

915-
err = os.MkdirAll(cfg.CacheDirectory.Value, 0o700)
925+
err = os.MkdirAll(cacheDir, 0o700)
916926
if err != nil {
917-
return nil, xerrors.Errorf("mkdir %q: %w", cfg.CacheDirectory.Value, err)
927+
return nil, xerrors.Errorf("mkdir %q: %w", cacheDir, err)
918928
}
919929

920930
terraformClient, terraformServer := provisionersdk.MemTransportPipe()
@@ -930,7 +940,7 @@ func newProvisionerDaemon(
930940
ServeOptions: &provisionersdk.ServeOptions{
931941
Listener: terraformServer,
932942
},
933-
CachePath: cfg.CacheDirectory.Value,
943+
CachePath: cacheDir,
934944
Logger: logger,
935945
})
936946
if err != nil && !xerrors.Is(err, context.Canceled) {

coderd/audit.go

Lines changed: 37 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,11 @@ func (api *API) convertAuditLogs(ctx context.Context, dblogs []database.GetAudit
160160
return alogs
161161
}
162162

163+
type AdditionalFields struct {
164+
WorkspaceName string
165+
BuildNumber string
166+
}
167+
163168
func (api *API) convertAuditLog(ctx context.Context, dblog database.GetAuditLogsOffsetRow) codersdk.AuditLog {
164169
ip, _ := netip.AddrFromSlice(dblog.Ip.IPNet.IP)
165170

@@ -185,12 +190,29 @@ func (api *API) convertAuditLog(ctx context.Context, dblog database.GetAuditLogs
185190
}
186191
}
187192

188-
isDeleted := api.auditLogIsResourceDeleted(ctx, dblog)
189-
var resourceLink string
193+
var (
194+
additionalFieldsBytes = []byte(dblog.AdditionalFields)
195+
additionalFields AdditionalFields
196+
err = json.Unmarshal(additionalFieldsBytes, &additionalFields)
197+
)
198+
if err != nil {
199+
api.Logger.Error(ctx, "unmarshal additional fields", slog.Error(err))
200+
resourceInfo := map[string]string{
201+
"workspaceName": "unknown",
202+
"buildNumber": "unknown",
203+
}
204+
dblog.AdditionalFields, err = json.Marshal(resourceInfo)
205+
api.Logger.Error(ctx, "marshal additional fields", slog.Error(err))
206+
}
207+
208+
var (
209+
isDeleted = api.auditLogIsResourceDeleted(ctx, dblog)
210+
resourceLink string
211+
)
190212
if isDeleted {
191213
resourceLink = ""
192214
} else {
193-
resourceLink = api.auditLogResourceLink(ctx, dblog)
215+
resourceLink = auditLogResourceLink(dblog, additionalFields)
194216
}
195217

196218
return codersdk.AuditLog{
@@ -209,23 +231,28 @@ func (api *API) convertAuditLog(ctx context.Context, dblog database.GetAuditLogs
209231
StatusCode: dblog.StatusCode,
210232
AdditionalFields: dblog.AdditionalFields,
211233
User: user,
212-
Description: auditLogDescription(dblog),
234+
Description: auditLogDescription(dblog, additionalFields),
213235
ResourceLink: resourceLink,
214236
IsDeleted: isDeleted,
215237
}
216238
}
217239

218-
func auditLogDescription(alog database.GetAuditLogsOffsetRow) string {
240+
func auditLogDescription(alog database.GetAuditLogsOffsetRow, additionalFields AdditionalFields) string {
219241
str := fmt.Sprintf("{user} %s",
220242
codersdk.AuditAction(alog.Action).FriendlyString(),
221243
)
222244

223245
// Strings for starting/stopping workspace builds follow the below format:
224-
// "{user} started build for workspace {target}"
246+
// "{user} started build #{build_number} for workspace {target}"
225247
// where target is a workspace instead of a workspace build
226248
// passed in on the FE via AuditLog.AdditionalFields rather than derived in request.go:35
227249
if alog.ResourceType == database.ResourceTypeWorkspaceBuild && alog.Action != database.AuditActionDelete {
228-
str += " build for"
250+
if len(additionalFields.BuildNumber) == 0 {
251+
str += " build for"
252+
} else {
253+
str += fmt.Sprintf(" build #%s for",
254+
additionalFields.BuildNumber)
255+
}
229256
}
230257

231258
// We don't display the name (target) for git ssh keys. It's fairly long and doesn't
@@ -295,12 +322,7 @@ func (api *API) auditLogIsResourceDeleted(ctx context.Context, alog database.Get
295322
}
296323
}
297324

298-
type AdditionalFields struct {
299-
WorkspaceName string
300-
BuildNumber string
301-
}
302-
303-
func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAuditLogsOffsetRow) string {
325+
func auditLogResourceLink(alog database.GetAuditLogsOffsetRow, additionalFields AdditionalFields) string {
304326
switch alog.ResourceType {
305327
case database.ResourceTypeTemplate:
306328
return fmt.Sprintf("/templates/%s",
@@ -312,11 +334,8 @@ func (api *API) auditLogResourceLink(ctx context.Context, alog database.GetAudit
312334
return fmt.Sprintf("/@%s/%s",
313335
alog.UserUsername.String, alog.ResourceTarget)
314336
case database.ResourceTypeWorkspaceBuild:
315-
additionalFieldsBytes := []byte(alog.AdditionalFields)
316-
var additionalFields AdditionalFields
317-
err := json.Unmarshal(additionalFieldsBytes, &additionalFields)
318-
if err != nil {
319-
api.Logger.Error(ctx, "unmarshal workspace name", slog.Error(err))
337+
if len(additionalFields.WorkspaceName) == 0 || len(additionalFields.BuildNumber) == 0 {
338+
return ""
320339
}
321340
return fmt.Sprintf("/@%s/%s/builds/%s",
322341
alog.UserUsername.String, additionalFields.WorkspaceName, additionalFields.BuildNumber)

coderd/database/databasefake/databasefake.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ type data struct {
122122
deploymentID string
123123
derpMeshKey string
124124
lastUpdateCheck []byte
125+
serviceBanner []byte
125126
lastLicenseID int32
126127
}
127128

@@ -3331,6 +3332,25 @@ func (q *fakeQuerier) GetLastUpdateCheck(_ context.Context) (string, error) {
33313332
return string(q.lastUpdateCheck), nil
33323333
}
33333334

3335+
func (q *fakeQuerier) InsertOrUpdateServiceBanner(_ context.Context, data string) error {
3336+
q.mutex.RLock()
3337+
defer q.mutex.RUnlock()
3338+
3339+
q.serviceBanner = []byte(data)
3340+
return nil
3341+
}
3342+
3343+
func (q *fakeQuerier) GetServiceBanner(_ context.Context) (string, error) {
3344+
q.mutex.RLock()
3345+
defer q.mutex.RUnlock()
3346+
3347+
if q.serviceBanner == nil {
3348+
return "", sql.ErrNoRows
3349+
}
3350+
3351+
return string(q.serviceBanner), nil
3352+
}
3353+
33343354
func (q *fakeQuerier) InsertLicense(
33353355
_ context.Context, arg database.InsertLicenseParams,
33363356
) (database.License, error) {

coderd/database/querier.go

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries.sql.go

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

coderd/database/queries/siteconfig.sql

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@ ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'last_update
1616

1717
-- name: GetLastUpdateCheck :one
1818
SELECT value FROM site_configs WHERE key = 'last_update_check';
19+
20+
-- name: InsertOrUpdateServiceBanner :exec
21+
INSERT INTO site_configs (key, value) VALUES ('service_banner', $1)
22+
ON CONFLICT (key) DO UPDATE SET value = $1 WHERE site_configs.key = 'service_banner';
23+
24+
-- name: GetServiceBanner :one
25+
SELECT value FROM site_configs WHERE key = 'service_banner';

coderd/provisionerdserver/provisionerdserver.go

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -531,23 +531,23 @@ func (server *Server) FailJob(ctx context.Context, failJob *proto.FailedJob) (*p
531531
auditor := server.Auditor.Load()
532532
build, getBuildErr := server.Database.GetWorkspaceBuildByJobID(ctx, job.ID)
533533
if getBuildErr != nil {
534-
server.Logger.Error(ctx, "failed to create audit log - get build err", slog.Error(err))
534+
server.Logger.Error(ctx, "audit log - get build", slog.Error(err))
535535
} else {
536536
auditAction := auditActionFromTransition(build.Transition)
537537
workspace, getWorkspaceErr := server.Database.GetWorkspaceByID(ctx, build.WorkspaceID)
538538
if getWorkspaceErr != nil {
539-
server.Logger.Error(ctx, "failed to create audit log - get workspace err", slog.Error(err))
539+
server.Logger.Error(ctx, "audit log - get workspace", slog.Error(err))
540540
} else {
541541
// We pass the below information to the Auditor so that it
542542
// can form a friendly string for the user to view in the UI.
543-
workspaceResourceInfo := map[string]string{
543+
buildResourceInfo := map[string]string{
544544
"workspaceName": workspace.Name,
545545
"buildNumber": strconv.FormatInt(int64(build.BuildNumber), 10),
546546
}
547547

548-
wriBytes, err := json.Marshal(workspaceResourceInfo)
548+
wriBytes, err := json.Marshal(buildResourceInfo)
549549
if err != nil {
550-
server.Logger.Error(ctx, "could not marshal workspace name", slog.Error(err))
550+
server.Logger.Error(ctx, "marshal workspace resource info for failed job", slog.Error(err))
551551
}
552552

553553
audit.BuildAudit(ctx, &audit.BuildAuditParams[database.WorkspaceBuild]{
@@ -756,14 +756,14 @@ func (server *Server) CompleteJob(ctx context.Context, completed *proto.Complete
756756

757757
// We pass the below information to the Auditor so that it
758758
// can form a friendly string for the user to view in the UI.
759-
workspaceResourceInfo := map[string]string{
759+
buildResourceInfo := map[string]string{
760760
"workspaceName": workspace.Name,
761761
"buildNumber": strconv.FormatInt(int64(workspaceBuild.BuildNumber), 10),
762762
}
763763

764-
wriBytes, err := json.Marshal(workspaceResourceInfo)
764+
wriBytes, err := json.Marshal(buildResourceInfo)
765765
if err != nil {
766-
server.Logger.Error(ctx, "marshal resource info", slog.Error(err))
766+
server.Logger.Error(ctx, "marshal resource info for successful job", slog.Error(err))
767767
}
768768

769769
audit.BuildAudit(ctx, &audit.BuildAuditParams[database.WorkspaceBuild]{

0 commit comments

Comments
 (0)