Bake provenance JSON into images and auto-populate post_results.py args - #338
Bake provenance JSON into images and auto-populate post_results.py args#338misiugodfrey wants to merge 13 commits into
Conversation
Writes /opt/velox-testing/provenance.json into each Presto image at build time (both native_build.dockerfile and provenance_labels.dockerfile), so run_context.py can read it from the container filesystem in both Docker and SLURM/Enroot environments. run_context.py: reads the provenance file and merges presto_sha/branch/repo and velox_sha/branch/repo into the benchmark context dict. post_results.py: auto-populates --velox-branch, --velox-repo, --presto-branch, --presto-repo from the benchmark_result.json context section; CLI args still take precedence. BenchmarkMetadata gains 6 optional provenance fields. presto-build.yml: replaces the labels: input on the deps and coordinator build steps with a second provenance_labels.dockerfile wrapper step, so CI and local builds both write the provenance file (buildx labels: applies OCI metadata only and does not execute RUN steps).
|
Auto-sync is disabled for draft pull requests in this repository. Workflows must be run manually. Contributors can view more details about this message here. |
The provenance.json baked into images at /opt/velox-testing/provenance.json
is only visible from inside the container, but pytest runs on the host in
the Docker flow (run_benchmark.sh:294) and inside the coord container in
SLURM/Enroot. The host has no /opt/velox-testing/provenance.json, so
run_context.py's _get_image_provenance() returned {} and the six provenance
fields were silently missing from benchmark_result.json's context.
Have each launch script copy the baked-in file into LOGS_DIR at startup
(worker_provenance.json from launch_presto_servers.sh, coordinator_provenance.json
from launch_coordinator.sh). In Docker the dir is bind-mounted to the host,
so pytest reads it directly. In SLURM, add ${LOGS}:/opt/presto-server/logs
to both coord and worker srun --container-mounts so the same scheme works
across the cluster, and export LOGS_DIR=/opt/presto-server/logs in
run_queries so the in-container pytest looks in the right place.
run_context.py replaces the hardcoded path constant with a resolver that
prefers worker_provenance.json (full presto+velox fields) over
coordinator_provenance.json (presto only in CI builds), then falls back to
the original /opt/velox-testing/provenance.json for callers running
directly inside a container that has the file baked in.
…nance # Conflicts: # presto/slurm/presto-nvl72/functions.sh
The 'Apply provenance labels to Presto deps image' step reconstructed the deps image tag by hand but omitted the build_variant and run_id segments that the build-and-push step includes, so it resolved a tag that was never pushed (buildx: 'not found'). Align BASE_IMAGE and the output tag with the deps build tag.
Add presto_sha/velox_sha as their own engine_config entries alongside the existing branch/repo fields, sourced from the baked image provenance in the benchmark context. Provenance fields are now emitted individually with empties omitted, so a coordinator-only image contributes just its presto entries. Derive query_engine.commit_hash from the SHAs as 'presto-<sha>-velox-<sha>' (or 'presto-<sha>' when velox is absent) when --commit-hash is not given; explicit --commit-hash still wins, and it stays 'unknown' when no SHAs exist. Degrades gracefully on older result files with no provenance.
| build-args: | | ||
| CUDA_VERSION=${{ matrix.cuda_version }} | ||
| ARM_BUILD_TARGET=generic | ||
| labels: | |
There was a problem hiding this comment.
Docker labels were lost if we convert docker images to sqsh images, so instead we store that information in a provenance.json file which is preserved inside the image regardless of conversion.
| validation_results: dict | None = None, | ||
| velox_branch: str | None = None, | ||
| velox_repo: str | None = None, | ||
| velox_sha: str | None = None, |
There was a problem hiding this comment.
Usually only branch or sha is used, but decided it was better to have separate values than try to overload the meaning of one value.
| # Derive commit_hash from the image provenance SHAs when not explicitly given: | ||
| # "presto-<sha>-velox-<sha>" (worker), "presto-<sha>" (coordinator, no velox). | ||
| if commit_hash is None: | ||
| commit_hash = "unknown" |
There was a problem hiding this comment.
commit_hash doesn't apply well to presto-velox builds since they are combination, but this is a top-level value in the benchmarking DB, so it seems useful to fill it with a concatenation of both.
The deps and coordinator provenance wrapper steps were near-identical build-push-action invocations differing only in base image, tags, and the velox fields. Extract them into .github/actions/apply-provenance-labels so the pinned action SHA, provenance dockerfile wiring, and outputs live in one place (mirroring the repo's existing container-registry-login/delete-arch-tags composite actions), removing the risk of the two steps drifting. Coordinator omits the velox_* inputs (default empty), preserving its presto-only provenance. Behaviour is unchanged.
ruff format (v0.14.x) expands the frozenset literal to one element per line; run the formatter to satisfy the check-style pre-commit hook.
patdevinwilson
left a comment
There was a problem hiding this comment.
Nice approach — baking a readable provenance.json (instead of relying on OCI labels that disappear in .sqsh conversion) and surfacing it via LOGS_DIR is clean. A few nits below; otherwise LGTM once the real submission path is confirmed.
|
|
||
| # Fall back to image provenance labels captured in the benchmark context. | ||
| velox_branch = velox_branch or benchmark_metadata.velox_branch | ||
| velox_repo = velox_repo or benchmark_metadata.velox_repo |
There was a problem hiding this comment.
I think we should normalize these repository values before persisting them. Local builds populate them from the raw output of git remote get-url origin, and HTTPS remotes can contain credentials such as https://user:TOKEN@github.com/.... This fallback would submit that value in engine_config. It would also already be present in the baked file, shared logs, and benchmark result.. yet, we definitely don't want them in the engine_config.
Could we strip URL userinfo in capture_build_provenance and store either owner/repo or a credential-free URL? Sanitizing at capture time seems preferable because it protects every downstream artifact, not just the API submission.
There was a problem hiding this comment.
I've added a credential-stripping step to capture_build_provenance that should handle the https cases.
- provenance_labels/native_build dockerfiles: build provenance.json via python json.dump instead of printf so branch/repo values are properly JSON-escaped. - common_functions.sh: strip credentials (userinfo) from http(s) repo remote URLs at capture time so tokens never land in provenance labels, the baked file, shared logs, or benchmark results. - start_presto_helper.sh / slurm_common.sh: clear stale worker/coordinator provenance files at LOGS_DIR setup so a run that doesn't write them (Java worker, or an image without baked provenance) can't report a prior run's values. - launch_java_worker.sh: copy baked provenance into the shared logs dir like the native worker launcher so Java benchmarks report their own provenance. - functions.sh: comment that all workers write the same worker_provenance.json (last writer wins; same image). - post_results.py: document in --commit-hash help that provenance SHAs are not CLI-overridable (no --presto-sha/--velox-sha).
…nance # Conflicts: # presto/slurm/presto-nvl72/functions.sh
Use 12-char short SHAs so the composite commit_hash stays compact (~38 chars instead of ~94), avoiding any DB column-length concern. The full SHAs are still submitted in the presto_sha/velox_sha engine_config entries, so no precision is lost.
Summary
Capture the Presto/Velox source that built an image and thread it into benchmark reports so results are traceable to their build. Follow-up to #316 (image labels).
/opt/velox-testing/provenance.jsoninto each Presto image at build time (bothnative_build.dockerfileandprovenance_labels.dockerfile). Unlike the OCI labels from Add image labels #316, a file is readable from inside a running container.launch_presto_servers.sh,launch_coordinator.sh) copies that file into the sharedLOGS_DIRat container startup asworker_provenance.json/coordinator_provenance.json, sorun_context.pyrunning on the host (Docker) or inside the coordinator container (SLURM/Enroot) can read it via the existing logs bind-mount. The in-container/opt/velox-testing/provenance.jsonpath is kept as a fallback for callers running directly inside an image that has the file baked in.functions.sh: adds${LOGS}:/opt/presto-server/logsto both coordinator and workersrun --container-mountsso the same scheme works across the cluster, mirrors the provenancecpin the inline worker bash andCOORD_SCRIPT, and exportsLOGS_DIR=/opt/presto-server/logsinrun_queriesso the in-container pytest looks at the mounted path.run_context.pyreads the provenance file and mergespresto_sha/branch/repoandvelox_sha/branch/repointo the benchmark context dict written tobenchmark_result.json. Empty values are dropped, and the resolver prefersworker_provenance.json(full presto+velox fields) overcoordinator_provenance.json(presto only on CI builds).post_results.pysubmission:--velox-branch,--velox-repo,--presto-branch,--presto-repofrom thebenchmark_result.jsoncontext; explicit CLI args still take precedence.presto_sha/velox_shaas their ownengine_configentries alongside branch/repo. Provenance fields are added individually with empties omitted, so a coordinator-only image contributes just its presto entries.query_engine.commit_hashfrom the SHAs aspresto-<sha>-velox-<sha>(orpresto-<sha>when velox is absent) when--commit-hashis not given; explicit--commit-hashstill wins, and it staysunknownwhen no SHAs exist.commit_hash=unknown, no error).presto-build.yml:labels:input on the deps and coordinator build steps with a secondprovenance_labels.dockerfilewrapper step — buildxlabels:applies OCI metadata only and does not executeRUNsteps, so the provenance file would not have been written via that path.-<build_variant>-<run_id>segments, so buildx failed withnot found).Notes / follow-ups
commit_hash = presto-<sha>-velox-<sha>, and branch fields only appear for locally-built images that baked a branch.engine_configkeys (presto_sha/velox_sha, and the existing branch/repo keys) have so far only been exercised via--dry-run; server-side acceptance should be confirmed with a real submission.Test plan
presto/scripts/start_native_cpu_presto.shdocker run --rm presto-native-worker-cpu:$USER cat /opt/velox-testing/provenance.jsonpresto/scripts/run_benchmark.sh -b tpch -s bench_sf1benchmark_result.jsoncontext hasvelox_branch,velox_repo,presto_branch,presto_repopopulatedpost_results.py --dry-runwithout branch/repo args; confirm payloadengine_configshows values auto-populated from the result file--velox-branch override; confirm CLI value wins over the labelengine_configandcommit_hashisunknown, without errorpresto-build.yml; confirm all deps/coordinator/worker images build and push with the provenance step green (run 29847632984)provenance.jsonin the CI images: coordinator has presto-only fields; worker has both presto and velox (repo + sha), branches emptypost_results.pysubmission is accepted withcommit_hash = presto-<sha>-velox-<sha>and the separate sha/repo entriesCloses: #381