| 828 | } |
| 829 | |
| 830 | func (r *Runner) commitQuota(ctx context.Context, cost int32) *proto.FailedJob { |
| 831 | r.logger.Debug(ctx, "committing quota", |
| 832 | slog.F("cost", cost), |
| 833 | ) |
| 834 | if cost == 0 { |
| 835 | return nil |
| 836 | } |
| 837 | |
| 838 | const stage = "Commit quota" |
| 839 | |
| 840 | resp, err := r.quotaCommitter.CommitQuota(ctx, &proto.CommitQuotaRequest{ |
| 841 | JobId: r.job.JobId, |
| 842 | DailyCost: cost, |
| 843 | }) |
| 844 | if err != nil { |
| 845 | r.queueLog(ctx, &proto.Log{ |
| 846 | Source: proto.LogSource_PROVISIONER, |
| 847 | Level: sdkproto.LogLevel_ERROR, |
| 848 | CreatedAt: time.Now().UnixMilli(), |
| 849 | Output: fmt.Sprintf("Failed to commit quota: %+v", err), |
| 850 | Stage: stage, |
| 851 | }) |
| 852 | return r.failedJobf("commit quota: %+v", err) |
| 853 | } |
| 854 | for _, line := range []string{ |
| 855 | fmt.Sprintf("Build cost — %v", cost), |
| 856 | fmt.Sprintf("Budget — %v", resp.Budget), |
| 857 | fmt.Sprintf("Credits consumed — %v", resp.CreditsConsumed), |
| 858 | } { |
| 859 | r.queueLog(ctx, &proto.Log{ |
| 860 | Source: proto.LogSource_PROVISIONER, |
| 861 | Level: sdkproto.LogLevel_INFO, |
| 862 | CreatedAt: time.Now().UnixMilli(), |
| 863 | Output: line, |
| 864 | Stage: stage, |
| 865 | }) |
| 866 | } |
| 867 | |
| 868 | if !resp.Ok { |
| 869 | r.queueLog(ctx, &proto.Log{ |
| 870 | Source: proto.LogSource_PROVISIONER, |
| 871 | Level: sdkproto.LogLevel_WARN, |
| 872 | CreatedAt: time.Now().UnixMilli(), |
| 873 | Output: "This build would exceed your quota. Failing.", |
| 874 | Stage: stage, |
| 875 | }) |
| 876 | return r.failedWorkspaceBuildfCode( |
| 877 | InsufficientQuotaErrorCode, |
| 878 | insufficientQuotaErrorText, |
| 879 | ) |
| 880 | } |
| 881 | return nil |
| 882 | } |
| 883 | |
| 884 | func (r *Runner) runWorkspaceBuild(ctx context.Context) (*proto.CompletedJob, *proto.FailedJob) { |
| 885 | ctx, span := r.startTrace(ctx, tracing.FuncName()) |