CompleteJob is triggered by a provision daemon to mark a provisioner job as completed.
(ctx context.Context, completed *proto.CompletedJob)
| 1618 | |
| 1619 | // CompleteJob is triggered by a provision daemon to mark a provisioner job as completed. |
| 1620 | func (s *server) CompleteJob(ctx context.Context, completed *proto.CompletedJob) (*proto.Empty, error) { |
| 1621 | ctx, span := s.startTrace(ctx, tracing.FuncName()) |
| 1622 | defer span.End() |
| 1623 | |
| 1624 | //nolint:gocritic // Provisionerd has specific authz rules. |
| 1625 | ctx = dbauthz.AsProvisionerd(ctx) |
| 1626 | jobID, err := uuid.Parse(completed.JobId) |
| 1627 | if err != nil { |
| 1628 | return nil, xerrors.Errorf("parse job id: %w", err) |
| 1629 | } |
| 1630 | s.Logger.Debug(ctx, "stage CompleteJob starting", slog.F("job_id", jobID)) |
| 1631 | job, err := s.Database.GetProvisionerJobByID(ctx, jobID) |
| 1632 | if err != nil { |
| 1633 | return nil, xerrors.Errorf("get job by id: %w", err) |
| 1634 | } |
| 1635 | if job.WorkerID.UUID.String() != s.ID.String() { |
| 1636 | return nil, xerrors.Errorf("you don't own this job") |
| 1637 | } |
| 1638 | |
| 1639 | telemetrySnapshot := &telemetry.Snapshot{} |
| 1640 | // Items are added to this snapshot as they complete! |
| 1641 | defer s.Telemetry.Report(telemetrySnapshot) |
| 1642 | |
| 1643 | switch jobType := completed.Type.(type) { |
| 1644 | case *proto.CompletedJob_TemplateImport_: |
| 1645 | err = s.completeTemplateImportJob(ctx, job, jobID, jobType, telemetrySnapshot) |
| 1646 | if err != nil { |
| 1647 | return nil, err |
| 1648 | } |
| 1649 | case *proto.CompletedJob_WorkspaceBuild_: |
| 1650 | err = s.completeWorkspaceBuildJob(ctx, job, jobID, jobType, telemetrySnapshot) |
| 1651 | if err != nil { |
| 1652 | return nil, err |
| 1653 | } |
| 1654 | case *proto.CompletedJob_TemplateDryRun_: |
| 1655 | err = s.completeTemplateDryRunJob(ctx, job, jobID, jobType, telemetrySnapshot) |
| 1656 | if err != nil { |
| 1657 | return nil, err |
| 1658 | } |
| 1659 | default: |
| 1660 | if completed.Type == nil { |
| 1661 | return nil, xerrors.Errorf("type payload must be provided") |
| 1662 | } |
| 1663 | return nil, xerrors.Errorf("unknown job type %q; ensure coderd and provisionerd versions match", |
| 1664 | reflect.TypeOf(completed.Type).String()) |
| 1665 | } |
| 1666 | |
| 1667 | data, err := json.Marshal(provisionersdk.ProvisionerJobLogsNotifyMessage{EndOfLogs: true}) |
| 1668 | if err != nil { |
| 1669 | return nil, xerrors.Errorf("marshal job log: %w", err) |
| 1670 | } |
| 1671 | err = s.Pubsub.Publish(provisionersdk.ProvisionerJobLogsNotifyChannel(jobID), data) |
| 1672 | if err != nil { |
| 1673 | s.Logger.Error(ctx, "failed to publish end of job logs", slog.F("job_id", jobID), slog.Error(err)) |
| 1674 | return nil, xerrors.Errorf("publish end of job logs: %w", err) |
| 1675 | } |
| 1676 | |
| 1677 | s.Logger.Debug(ctx, "stage CompleteJob done", slog.F("job_id", jobID)) |
nothing calls this directly
no test coverage detected