Skip to content

Commit c7ae412

Browse files
committed
Add back the workspace timings endpoint
1 parent 65aeeea commit c7ae412

File tree

11 files changed

+399
-173
lines changed

11 files changed

+399
-173
lines changed

coderd/apidoc/docs.go

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

coderd/apidoc/swagger.json

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

coderd/coderd.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1150,6 +1150,7 @@ func New(options *Options) *API {
11501150
r.Post("/", api.postWorkspaceAgentPortShare)
11511151
r.Delete("/", api.deleteWorkspaceAgentPortShare)
11521152
})
1153+
r.Get("/timings", api.workspaceTimings)
11531154
})
11541155
})
11551156
r.Route("/workspacebuilds/{workspacebuild}", func(r chi.Router) {

coderd/database/dbauthz/dbauthz_test.go

Lines changed: 6 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2846,19 +2846,8 @@ func (s *MethodTestSuite) TestSystemFunctions() {
28462846
j := dbgen.ProvisionerJob(s.T(), db, nil, database.ProvisionerJob{
28472847
Type: database.ProvisionerJobTypeWorkspaceBuild,
28482848
})
2849-
_ = dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{JobID: j.ID, WorkspaceID: w.ID})
2850-
t := dbgen.ProvisionerJobTimings(s.T(), db, database.InsertProvisionerJobTimingsParams{
2851-
JobID: j.ID,
2852-
StartedAt: []time.Time{dbtime.Now(), dbtime.Now()},
2853-
EndedAt: []time.Time{dbtime.Now(), dbtime.Now()},
2854-
Stage: []database.ProvisionerJobTimingStage{
2855-
database.ProvisionerJobTimingStageInit,
2856-
database.ProvisionerJobTimingStagePlan,
2857-
},
2858-
Source: []string{"source1", "source2"},
2859-
Action: []string{"action1", "action2"},
2860-
Resource: []string{"resource1", "resource2"},
2861-
})
2849+
b := dbgen.WorkspaceBuild(s.T(), db, database.WorkspaceBuild{JobID: j.ID, WorkspaceID: w.ID})
2850+
t := dbgen.ProvisionerJobTimings(s.T(), db, b, 2)
28622851
check.Args(j.ID).Asserts(w, policy.ActionRead).Returns(t)
28632852
}))
28642853
s.Run("GetWorkspaceAgentScriptTimingsByBuildID", s.Subtest(func(db database.Store, check *expects) {
@@ -2873,31 +2862,11 @@ func (s *MethodTestSuite) TestSystemFunctions() {
28732862
agent := dbgen.WorkspaceAgent(s.T(), db, database.WorkspaceAgent{
28742863
ResourceID: resource.ID,
28752864
})
2876-
scripts := dbgen.WorkspaceAgentScripts(s.T(), db, database.InsertWorkspaceAgentScriptsParams{
2865+
script := dbgen.WorkspaceAgentScript(s.T(), db, database.WorkspaceAgentScript{
28772866
WorkspaceAgentID: agent.ID,
2878-
CreatedAt: time.Now(),
2879-
LogSourceID: []uuid.UUID{
2880-
uuid.New(),
2881-
},
2882-
LogPath: []string{""},
2883-
Script: []string{""},
2884-
Cron: []string{""},
2885-
StartBlocksLogin: []bool{false},
2886-
RunOnStart: []bool{false},
2887-
RunOnStop: []bool{false},
2888-
TimeoutSeconds: []int32{0},
2889-
DisplayName: []string{""},
2890-
ID: []uuid.UUID{
2891-
uuid.New(),
2892-
},
28932867
})
2894-
timing := dbgen.WorkspaceAgentScriptTiming(s.T(), db, database.InsertWorkspaceAgentScriptTimingsParams{
2895-
StartedAt: dbtime.Now(),
2896-
EndedAt: dbtime.Now(),
2897-
Stage: database.WorkspaceAgentScriptTimingStageStart,
2898-
ScriptID: scripts[0].ID,
2899-
ExitCode: 0,
2900-
Status: database.WorkspaceAgentScriptTimingStatusOk,
2868+
timing := dbgen.WorkspaceAgentScriptTiming(s.T(), db, database.WorkspaceAgentScriptTiming{
2869+
ScriptID: script.ID,
29012870
})
29022871
rows := []database.GetWorkspaceAgentScriptTimingsByBuildIDRow{
29032872
{
@@ -2907,7 +2876,7 @@ func (s *MethodTestSuite) TestSystemFunctions() {
29072876
ScriptID: timing.ScriptID,
29082877
ExitCode: timing.ExitCode,
29092878
Status: timing.Status,
2910-
DisplayName: scripts[0].DisplayName,
2879+
DisplayName: script.DisplayName,
29112880
},
29122881
}
29132882
check.Args(build.ID).Asserts(rbac.ResourceSystem, policy.ActionRead).Returns(rows)

coderd/database/dbgen/dbgen.go

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -189,14 +189,45 @@ func WorkspaceAgent(t testing.TB, db database.Store, orig database.WorkspaceAgen
189189
return agt
190190
}
191191

192-
func WorkspaceAgentScripts(t testing.TB, db database.Store, orig database.InsertWorkspaceAgentScriptsParams) []database.WorkspaceAgentScript {
193-
scripts, err := db.InsertWorkspaceAgentScripts(genCtx, orig)
192+
func WorkspaceAgentScript(t testing.TB, db database.Store, orig database.WorkspaceAgentScript) database.WorkspaceAgentScript {
193+
scripts, err := db.InsertWorkspaceAgentScripts(genCtx, database.InsertWorkspaceAgentScriptsParams{
194+
WorkspaceAgentID: takeFirst(orig.WorkspaceAgentID, uuid.New()),
195+
CreatedAt: takeFirst(orig.CreatedAt, dbtime.Now()),
196+
LogSourceID: []uuid.UUID{takeFirst(orig.LogSourceID, uuid.New())},
197+
LogPath: []string{takeFirst(orig.LogPath, "")},
198+
Script: []string{takeFirst(orig.Script, "")},
199+
Cron: []string{takeFirst(orig.Cron, "")},
200+
StartBlocksLogin: []bool{takeFirst(orig.StartBlocksLogin, false)},
201+
RunOnStart: []bool{takeFirst(orig.RunOnStart, false)},
202+
RunOnStop: []bool{takeFirst(orig.RunOnStop, false)},
203+
TimeoutSeconds: []int32{takeFirst(orig.TimeoutSeconds, 0)},
204+
DisplayName: []string{takeFirst(orig.DisplayName, "")},
205+
ID: []uuid.UUID{takeFirst(orig.ID, uuid.New())},
206+
})
194207
require.NoError(t, err, "insert workspace agent script")
195-
return scripts
208+
require.NotEmpty(t, scripts, "insert workspace agent script returned no scripts")
209+
return scripts[0]
196210
}
197211

198-
func WorkspaceAgentScriptTiming(t testing.TB, db database.Store, orig database.InsertWorkspaceAgentScriptTimingsParams) database.WorkspaceAgentScriptTiming {
199-
timing, err := db.InsertWorkspaceAgentScriptTimings(genCtx, orig)
212+
func WorkspaceAgentScriptTimings(t testing.TB, db database.Store, script database.WorkspaceAgentScript, count int) []database.WorkspaceAgentScriptTiming {
213+
timings := make([]database.WorkspaceAgentScriptTiming, count)
214+
for i := range count {
215+
timings[i] = WorkspaceAgentScriptTiming(t, db, database.WorkspaceAgentScriptTiming{
216+
ScriptID: script.ID,
217+
})
218+
}
219+
return timings
220+
}
221+
222+
func WorkspaceAgentScriptTiming(t testing.TB, db database.Store, orig database.WorkspaceAgentScriptTiming) database.WorkspaceAgentScriptTiming {
223+
timing, err := db.InsertWorkspaceAgentScriptTimings(genCtx, database.InsertWorkspaceAgentScriptTimingsParams{
224+
StartedAt: takeFirst(orig.StartedAt, dbtime.Now()),
225+
EndedAt: takeFirst(orig.EndedAt, dbtime.Now()),
226+
Stage: takeFirst(orig.Stage, database.WorkspaceAgentScriptTimingStageStart),
227+
ScriptID: takeFirst(orig.ScriptID, uuid.New()),
228+
ExitCode: takeFirst(orig.ExitCode, 0),
229+
Status: takeFirst(orig.Status, database.WorkspaceAgentScriptTimingStatusOk),
230+
})
200231
require.NoError(t, err, "insert workspace agent script")
201232
return timing
202233
}
@@ -947,12 +978,30 @@ func CryptoKey(t testing.TB, db database.Store, seed database.CryptoKey) databas
947978
return key
948979
}
949980

950-
func ProvisionerJobTimings(t testing.TB, db database.Store, seed database.InsertProvisionerJobTimingsParams) []database.ProvisionerJobTiming {
951-
timings, err := db.InsertProvisionerJobTimings(genCtx, seed)
952-
require.NoError(t, err, "insert provisioner job timings")
981+
func ProvisionerJobTimings(t testing.TB, db database.Store, build database.WorkspaceBuild, count int) []database.ProvisionerJobTiming {
982+
timings := make([]database.ProvisionerJobTiming, count)
983+
for i := range count {
984+
timings[i] = provisionerJobTiming(t, db, database.ProvisionerJobTiming{
985+
JobID: build.JobID,
986+
})
987+
}
953988
return timings
954989
}
955990

991+
func provisionerJobTiming(t testing.TB, db database.Store, seed database.ProvisionerJobTiming) database.ProvisionerJobTiming {
992+
timing, err := db.InsertProvisionerJobTimings(genCtx, database.InsertProvisionerJobTimingsParams{
993+
JobID: takeFirst(seed.JobID, uuid.New()),
994+
StartedAt: []time.Time{takeFirst(seed.StartedAt, dbtime.Now())},
995+
EndedAt: []time.Time{takeFirst(seed.EndedAt, dbtime.Now())},
996+
Stage: []database.ProvisionerJobTimingStage{takeFirst(seed.Stage, database.ProvisionerJobTimingStageInit)},
997+
Source: []string{takeFirst(seed.Source, "source")},
998+
Action: []string{takeFirst(seed.Action, "action")},
999+
Resource: []string{takeFirst(seed.Resource, "resource")},
1000+
})
1001+
require.NoError(t, err, "insert provisioner job timing")
1002+
return timing[0]
1003+
}
1004+
9561005
func must[V any](v V, err error) V {
9571006
if err != nil {
9581007
panic(err)

coderd/workspacebuilds.go

Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -661,52 +661,16 @@ func (api *API) workspaceBuildTimings(rw http.ResponseWriter, r *http.Request) {
661661
build = httpmw.WorkspaceBuildParam(r)
662662
)
663663

664-
provisionerTimings, err := api.Database.GetProvisionerJobTimingsByJobID(ctx, build.JobID)
665-
if err != nil && !errors.Is(err, sql.ErrNoRows) {
666-
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
667-
Message: "Internal error fetching workspace timings.",
668-
Detail: err.Error(),
669-
})
670-
return
671-
}
672-
673-
agentScriptTimings, err := api.Database.GetWorkspaceAgentScriptTimingsByBuildID(ctx, build.ID)
674-
if err != nil && !errors.Is(err, sql.ErrNoRows) {
664+
timings, err := api.buildTimings(ctx, build)
665+
if err != nil {
675666
httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{
676-
Message: "Internal error fetching workspace agent script timings.",
667+
Message: "Internal error fetching timings.",
677668
Detail: err.Error(),
678669
})
679670
return
680671
}
681672

682-
res := codersdk.WorkspaceBuildTimings{
683-
ProvisionerTimings: make([]codersdk.ProvisionerTiming, 0, len(provisionerTimings)),
684-
AgentScriptTimings: make([]codersdk.AgentScriptTiming, 0, len(agentScriptTimings)),
685-
}
686-
687-
for _, t := range provisionerTimings {
688-
res.ProvisionerTimings = append(res.ProvisionerTimings, codersdk.ProvisionerTiming{
689-
JobID: t.JobID,
690-
Stage: string(t.Stage),
691-
Source: t.Source,
692-
Action: t.Action,
693-
Resource: t.Resource,
694-
StartedAt: t.StartedAt,
695-
EndedAt: t.EndedAt,
696-
})
697-
}
698-
for _, t := range agentScriptTimings {
699-
res.AgentScriptTimings = append(res.AgentScriptTimings, codersdk.AgentScriptTiming{
700-
StartedAt: t.StartedAt,
701-
EndedAt: t.EndedAt,
702-
ExitCode: t.ExitCode,
703-
Stage: string(t.Stage),
704-
Status: string(t.Status),
705-
DisplayName: t.DisplayName,
706-
})
707-
}
708-
709-
httpapi.Write(ctx, rw, http.StatusOK, res)
673+
httpapi.Write(ctx, rw, http.StatusOK, timings)
710674
}
711675

712676
type workspaceBuildsData struct {
@@ -1072,3 +1036,44 @@ func convertWorkspaceStatus(jobStatus codersdk.ProvisionerJobStatus, transition
10721036
// return error status since we should never get here
10731037
return codersdk.WorkspaceStatusFailed
10741038
}
1039+
1040+
func (api *API) buildTimings(ctx context.Context, build database.WorkspaceBuild) (codersdk.WorkspaceBuildTimings, error) {
1041+
provisionerTimings, err := api.Database.GetProvisionerJobTimingsByJobID(ctx, build.JobID)
1042+
if err != nil && !errors.Is(err, sql.ErrNoRows) {
1043+
return codersdk.WorkspaceBuildTimings{}, xerrors.Errorf("fetching provisioner job timings: %w", err)
1044+
}
1045+
1046+
agentScriptTimings, err := api.Database.GetWorkspaceAgentScriptTimingsByBuildID(ctx, build.ID)
1047+
if err != nil && !errors.Is(err, sql.ErrNoRows) {
1048+
return codersdk.WorkspaceBuildTimings{}, xerrors.Errorf("fetching workspace agent script timings: %w", err)
1049+
}
1050+
1051+
res := codersdk.WorkspaceBuildTimings{
1052+
ProvisionerTimings: make([]codersdk.ProvisionerTiming, 0, len(provisionerTimings)),
1053+
AgentScriptTimings: make([]codersdk.AgentScriptTiming, 0, len(agentScriptTimings)),
1054+
}
1055+
1056+
for _, t := range provisionerTimings {
1057+
res.ProvisionerTimings = append(res.ProvisionerTimings, codersdk.ProvisionerTiming{
1058+
JobID: t.JobID,
1059+
Stage: string(t.Stage),
1060+
Source: t.Source,
1061+
Action: t.Action,
1062+
Resource: t.Resource,
1063+
StartedAt: t.StartedAt,
1064+
EndedAt: t.EndedAt,
1065+
})
1066+
}
1067+
for _, t := range agentScriptTimings {
1068+
res.AgentScriptTimings = append(res.AgentScriptTimings, codersdk.AgentScriptTiming{
1069+
StartedAt: t.StartedAt,
1070+
EndedAt: t.EndedAt,
1071+
ExitCode: t.ExitCode,
1072+
Stage: string(t.Stage),
1073+
Status: string(t.Status),
1074+
DisplayName: t.DisplayName,
1075+
})
1076+
}
1077+
1078+
return res, nil
1079+
}

0 commit comments

Comments
 (0)