(ctx context.Context, build database.WorkspaceBuild)
| 1351 | } |
| 1352 | |
| 1353 | func (api *API) buildTimings(ctx context.Context, build database.WorkspaceBuild) (codersdk.WorkspaceBuildTimings, error) { |
| 1354 | provisionerTimings, err := api.Database.GetProvisionerJobTimingsByJobID(ctx, build.JobID) |
| 1355 | if err != nil && !errors.Is(err, sql.ErrNoRows) { |
| 1356 | return codersdk.WorkspaceBuildTimings{}, xerrors.Errorf("fetching provisioner job timings: %w", err) |
| 1357 | } |
| 1358 | |
| 1359 | //nolint:gocritic // Already checked if the build can be fetched. |
| 1360 | agentScriptTimings, err := api.Database.GetWorkspaceAgentScriptTimingsByBuildID(dbauthz.AsSystemRestricted(ctx), build.ID) |
| 1361 | if err != nil && !errors.Is(err, sql.ErrNoRows) { |
| 1362 | return codersdk.WorkspaceBuildTimings{}, xerrors.Errorf("fetching workspace agent script timings: %w", err) |
| 1363 | } |
| 1364 | |
| 1365 | resources, err := api.Database.GetWorkspaceResourcesByJobID(ctx, build.JobID) |
| 1366 | if err != nil && !errors.Is(err, sql.ErrNoRows) { |
| 1367 | return codersdk.WorkspaceBuildTimings{}, xerrors.Errorf("fetching workspace resources: %w", err) |
| 1368 | } |
| 1369 | resourceIDs := make([]uuid.UUID, 0, len(resources)) |
| 1370 | for _, resource := range resources { |
| 1371 | resourceIDs = append(resourceIDs, resource.ID) |
| 1372 | } |
| 1373 | //nolint:gocritic // Already checked if the build can be fetched. |
| 1374 | agents, err := api.Database.GetWorkspaceAgentsByResourceIDs(dbauthz.AsSystemRestricted(ctx), resourceIDs) |
| 1375 | if err != nil && !errors.Is(err, sql.ErrNoRows) { |
| 1376 | return codersdk.WorkspaceBuildTimings{}, xerrors.Errorf("fetching workspace agents: %w", err) |
| 1377 | } |
| 1378 | |
| 1379 | res := codersdk.WorkspaceBuildTimings{ |
| 1380 | ProvisionerTimings: make([]codersdk.ProvisionerTiming, 0, len(provisionerTimings)), |
| 1381 | AgentScriptTimings: make([]codersdk.AgentScriptTiming, 0, len(agentScriptTimings)), |
| 1382 | AgentConnectionTimings: make([]codersdk.AgentConnectionTiming, 0, len(agents)), |
| 1383 | } |
| 1384 | |
| 1385 | for _, t := range provisionerTimings { |
| 1386 | // Ref: #15432: agent script timings must not have a zero start or end time. |
| 1387 | if t.StartedAt.IsZero() || t.EndedAt.IsZero() { |
| 1388 | api.Logger.Debug(ctx, "ignoring provisioner timing with zero start or end time", |
| 1389 | slog.F("workspace_id", build.WorkspaceID), |
| 1390 | slog.F("workspace_build_id", build.ID), |
| 1391 | slog.F("provisioner_job_id", t.JobID), |
| 1392 | ) |
| 1393 | continue |
| 1394 | } |
| 1395 | |
| 1396 | res.ProvisionerTimings = append(res.ProvisionerTimings, codersdk.ProvisionerTiming{ |
| 1397 | JobID: t.JobID, |
| 1398 | Stage: codersdk.TimingStage(t.Stage), |
| 1399 | Source: t.Source, |
| 1400 | Action: t.Action, |
| 1401 | Resource: t.Resource, |
| 1402 | StartedAt: t.StartedAt, |
| 1403 | EndedAt: t.EndedAt, |
| 1404 | }) |
| 1405 | } |
| 1406 | for _, t := range agentScriptTimings { |
| 1407 | // Ref: #15432: agent script timings must not have a zero start or end time. |
| 1408 | if t.StartedAt.IsZero() || t.EndedAt.IsZero() { |
| 1409 | api.Logger.Debug(ctx, "ignoring agent script timing with zero start or end time", |
| 1410 | slog.F("workspace_id", build.WorkspaceID), |
no test coverage detected