export buildkit history and structured lifecycle telemetry at teardown - #128
export buildkit history and structured lifecycle telemetry at teardown#128piob-io wants to merge 2 commits into
Conversation
🤖 Devin AI EngineerI'll be helping with this pull request! Here's what you should know: ✅ I will automatically:
Note: I can only respond to comments from users who have write access to this repository. ⚙️ Control Options:
|
5ce4997 to
303b922
Compare
| // Export this job's build history (raw record + trace bytes) and delete | ||
| // the records afterwards so history.db and its content-store attachments | ||
| // never get committed to the sticky disk. Must happen before shutdown. | ||
| const builds = await exportBuildHistory(buildkitdAddr, lifecycle); |
There was a problem hiding this comment.
is this valid? The sticky disk as a block io device doesn't know about which logical files have been deleted, right?
There was a problem hiding this comment.
Right — the block device has no notion of file deletion, so residual bytes can remain in freed blocks after commit; we don't claim physical scrubbing. What the delete does guarantee is filesystem-level: it happens via buildkitd's UpdateBuildHistory{Delete} API (BoltDB record delete + content-store blob unref) before buildkitd shutdown → integrity check → unmount → commit, so the committed filesystem no longer references those records. The purpose is (1) history.db doesn't grow unboundedly across runs and (2) the next job's export doesn't re-export prior jobs' records — not data erasure. I've reworded the comment to say exactly that (was misleadingly phrased as "never get committed").
303b922 to
87c7d43
Compare
|
@devin do we bound the size of the report we generate in terms of bytes? I think we need a way to hard bound it somewhere around 10s of MiB and under 128 MiB |
|
Yes — the report is hard-bounded to ~10 MiB worst case, enforced at assembly time in
Everything else in the report (lifecycle facts, du totals, per-cache-mount rows) is small fixed-size fields, so the whole |
At post-step teardown, export the job's raw BuildKit history records (plus solve-status traces, logs excluded, size-capped) via ListenBuildHistory, delete them so history.db and its content-store attachments are never committed to the sticky disk, and ship them with the runner _diag step timeline and structured lifecycle facts (builder mode/fallback reason, commit decision/skip reason, integrity outcome, buildctl du totals incl. per-cache-mount, fs usage) to the vm-agent's new ReportDockerBuild RPC. docker_build_ids are issued host-side; all reporting is fail-soft with bounded timeouts and never fails the customer job. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
87c7d43 to
b357178
Compare
A whole-job report could exceed the vm-agent's default 4 MiB gRPC MaxRecvMsgSize (a 24-build job produced a 6.3 MB message that was rejected with resource_exhausted, dropping all telemetry). Builds are now split across multiple unary ReportDockerBuild calls with a ~3 MiB per-request budget covering the runner step timeline plus record and trace bytes. The timeline ships in every chunk (workflow-step attribution is per-request server-side); the lifecycle message ships only in the first chunk so the agent never double-emits lifecycle metrics. Per-record/trace caps and fail-soft behavior are unchanged, and each chunk gets its own report timeout. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Summary
At teardown, the action exports the job's BuildKit build history and ships it — with structured lifecycle telemetry — to the vm-agent's
ReportDockerBuildRPC. The guest ships raw bytes; all semantic parsing lives host-side in the fa agent so BuildKit format drift is absorbed by an agent deploy, not an action release.What ships
Control.ListenBuildHistory({EarlyExit:true})streams the job'sBuildHistoryRecords. Each record is decoded as a typed protobuf-es message only to readRef(for post-export deletion),CompletedAt(incomplete flag), and the trace descriptor, and to clearlogs; it is then re-serialized and shipped opaquely (protobuf-es preserves unknown fields across the round trip, so fields newer than our vendored proto still reach the agent). Records are pruned viaControl.UpdateBuildHistory(Delete:true)after export.Content.Read(digest), size-capped (2 MiB per trace; oversized → shipped without trace, markedtruncated)._diag/Worker_*.logread verbatim, tail-capped at 1 MiB; parsing is agent-side.buildctl du -vcache breakdown (per-mount sizes), fs used/size, prune decision/bytes, hotload/buildkitd-ready/shutdown timers, SIGKILL flag, export-timeout/prune-failed flags.Chunked reporting
A whole-job report can exceed the vm-agent's default 4 MiB gRPC
MaxRecvMsgSize(staging: a 24-build job produced a 6.3 MB message rejected withresource_exhausted).reportDockerBuildtherefore splits builds across multiple unaryReportDockerBuildRequestcalls viachunkBuilds, with a ~3 MiB per-request budget covering timeline + record + trace bytes:Protos
BuildKit
control.proto(+ deps) and containerdcontent.protoare vendored verbatim from pinned upstream releases (buildkit v0.32.2, containerd v2.3.4, googleapis pinned commit) viascripts/fetch-protos.sh;stickydisk.protocomes frombuf.build/blacksmith/vm-agent. Generation is dev-time only:buf generate→src/gen/→pnpm build→ checked-indist/. Nothing is fetched or compiled during an action run, and no hand-authored proto content or hand-rolled wire parsing remains.Ordering
Post-step teardown: du snapshot → history export → history prune → buildkitd shutdown → integrity check → fs usage → unmount → commit/skip decision → report.
Identity
The guest sends only
expose_id,vm_id, git sha/branch, and build facts; keys, entity, run/job attribution are stamped host-side by the vm-agent.Companion PRs: agent-side parsing/insertion FastActions/fa#5232 (merged) + OTLP JSON trace-parser fix FastActions/fa#5277; ClickHouse schema useblacksmith/web#11965 (merged).
Link to Devin session: https://app.devin.ai/sessions/0c6ebc2a6de54933bebe821e21ab8b76
Open in Devin Desktop: https://app.devin.ai/desktop/session/0c6ebc2a6de54933bebe821e21ab8b76?variant=devin
Requested by: @piob-io
Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.