refactor(builder-sidecar): ephemeral builder containers launched from host#162
refactor(builder-sidecar): ephemeral builder containers launched from host#162
Conversation
| repo_hash = self.__get_repo_hash() | ||
| return f"{self.name}:{repo_hash}-{sanitizer}-snapshot" | ||
|
|
||
| def _snapshot_lock_path(self, snapshot_tag: str) -> Path: |
There was a problem hiding this comment.
Do we need to restore this locking logic?
| cached_hash = cache_file.read_text().strip() | ||
| return cached_hash == base_image_hash and self._snapshot_exists(snapshot_tag) | ||
|
|
||
| def create_snapshot( |
There was a problem hiding this comment.
In general, seems odd we're completely removing snapshot logic from this module.
There was a problem hiding this comment.
@acorn421 Can you check out these verify-patch-* scripts and make something similar using CRSBench for E2E testing?
…s context conflict) Signed-off-by: Dongkwan Kim <0xdkay@gmail.com>
…source Signed-off-by: Dongkwan Kim <0xdkay@gmail.com>
There was a problem hiding this comment.
@acorn421 Testing logic here for rebuild sidecar
Builder-sidecar: FastAPI server that spawns ephemeral Docker containers for builds and tests via Docker socket. Extracts build CMD from image via docker inspect, disables REPLAY_ENABLED, uses oss_crs_handler.sh for both build (image CMD) and test (test.sh). Runner-sidecar: FastAPI server on base-runner for POV reproduction via OSS-Fuzz reproduce script. Simplify oss_crs_handler.sh to: git apply + run $OSS_CRS_BUILD_CMD. Signed-off-by: Andrew Chin <achin34@gatech.edu>
…-test - apply-patch-build: submit patch to builder-sidecar, poll for result - apply-patch-test: renamed from run-test, takes patch_path explicitly - run-pov: submit POV to runner-sidecar - download-build-output: fetch versioned artifacts as zip - Remove _last_patch_path stateful hack (broken across CLI invocations) Signed-off-by: Andrew Chin <achin34@gatech.edu>
…builder - Sidecar injection triggered by any CRS with snapshot builds - Remove _builder_crs property and "at most one builder" restriction - Remove is_builder gates from LLM, bug-finding, and compose template - Fix BASE_IMAGE to use snapshot image instead of raw target - Add get_rebuild_out_dir to workdir for sidecar artifact storage Signed-off-by: Andrew Chin <achin34@gatech.edu>
- Unit tests for builder-sidecar, runner-sidecar, and libCRS sidecar methods - Integration tests for sidecar lifecycle - sandbox/crs-sidecar-test: manual e2e test CRS with ground-truth patch - Remove old builder/ directory (replaced by builder-sidecar) Signed-off-by: Andrew Chin <achin34@gatech.edu>
…g properties - Remove snapshot: bool from BuildConfig - Remove run_snapshot: bool from CRSRunPhaseModule - Update validate_dockerfile_requirement: all modules always require dockerfile - Remove snapshot_builds, has_snapshot, has_builder_module properties from CRSConfig - Delete test_snapshot_flag, test_snapshot_module_can_omit_dockerfile tests - Add test_module_requires_dockerfile_always test Signed-off-by: Andrew Chin <achin34@gatech.edu>
- Remove _any_needs_snapshot property from CRSCompose - Remove snapshot creation block from CRSCompose.build_target() - Remove snapshot image check and snapshot_image_tag assignment from CRSCompose.run() - Replace non_snapshot_builds filter with plain builds in CRS.build_target() and is_target_built() - Remove snapshot_image_tag attr, create_snapshot(), get_snapshot_image_name(), _snapshot_lock_path(), _snapshot_exists(), _is_snapshot_reusable(), _get_base_image_hash() from Target - Remove tempfile import (no longer needed) - Update renderer.py: disable sidecar injection (has_sidecar=False), remove snapshot_image_tag from target reference, remove run_snapshot logic from module env computation - Update Jinja2 template: remove run_snapshot conditional blocks - Delete test_crs_compose_snapshot_sanitizer.py and test_target_snapshot.py Signed-off-by: Andrew Chin <achin34@gatech.edu>
- Remove has_sidecar conditional; sidecars now always injected as infra - Compute rebuild_out_dir unconditionally from crs_list[0] - Remove snapshot_image_tag, has_sidecar, sidecar_crs_name from context - Template: replace single sidecar_crs_name alias with crs_list loop - Template: BASE_IMAGE uses target.get_docker_image_name() unconditionally - Sandbox crs.yaml: remove inc-builder snapshot build entry Signed-off-by: Andrew Chin <achin34@gatech.edu>
- Add --incremental-build store_true arg to build-target subcommand - Add --incremental-build store_true arg to run subcommand - Pass incremental_build=args.incremental_build in both CLI dispatch sites - Add incremental_build: bool = False to CRSCompose.build_target() signature - Add incremental_build: bool = False to CRSCompose.run() signature - Thread incremental_build through __run(), __run_local(), __prepare_local_running_env() - 4 unit tests verify flag parsing on both subcommands (present/absent) Signed-off-by: Andrew Chin <achin34@gatech.edu>
- get_test_image() signature drops builder_name parameter per D-05
- run_ephemeral_test() snapshot_tag and commit tag use test-{build_id}
- server.py _handle_test() updated to call get_test_image() without builder_name
- All sidecar tests updated to assert test-{build_id} format (no builder_name)
Signed-off-by: Andrew Chin <achin34@gatech.edu>
- Add docker/requests.exceptions imports to crs_compose.py
- _snapshot_one(): helper to run a container from base_image and commit on success
- _create_incremental_snapshots(): commit builder snapshots (build-{name}-{build_id}) and
project image snapshot (test-{build_id}) with all-or-nothing cleanup on failure (D-04/D-05/D-06)
- _check_snapshots_exist(): pre-run validation returning clear error with oss-crs build-target
--incremental-build instructions when any snapshot is missing (SNAP-05/D-09)
- Wire _create_incremental_snapshots into build_target() after success, gated by incremental_build
- Wire _check_snapshots_exist into run() before compose starts, gated by incremental_build
- 9 unit tests passing with mocked Docker SDK
Signed-off-by: Andrew Chin <achin34@gatech.edu>
- _handle_test() now reads PROJECT_BASE_IMAGE env var directly (not BASE_IMAGE_*) - Raises ValueError if PROJECT_BASE_IMAGE is not set (clear error message) - Template unconditionally emits PROJECT_BASE_IMAGE on builder-sidecar service - Module docstring documents the new env var Signed-off-by: Andrew Chin <achin34@gatech.edu>
…ts on --incremental-build flag - Bundle oss_crs_handler.sh in sidecar image and bind-mount into ephemeral build/test containers via HANDLER_SCRIPT_PATH env var - Sidecar only uses snapshot images when INCREMENTAL_BUILD=true (fresh base image otherwise), enforcing SNAP-04 - Forward OSS-Fuzz env vars (FUZZING_ENGINE, SANITIZER, ARCHITECTURE, FUZZING_LANGUAGE) from sidecar to ephemeral containers - Stream ephemeral container logs to sidecar stdout with [build:name]/[test:id] prefix while still capturing for response - Extract OSS_FUZZ_TARGET_ENV constant in env_policy.py to dedup env var definitions Signed-off-by: Andrew Chin <achin34@gatech.edu>
…rce limits
- Replace v1/v2 versioning with rebuild_id (auto-incrementing int, optional
override). Output dir: /rebuild_out/{crs_name}/{rebuild_id}/
- Merge download_rebuild_output into download_build_output: with rebuild_id
fetches from sidecar, without uses local filesystem. Ephemeral containers
auto-try sidecar via OSS_CRS_REBUILD_ID env var, fallback to local.
- Rename build_id to rebuild_id on sidecar endpoints; add crs_name form field
- Forward CRS resource limits (cpuset, mem_limit) per-request to ephemeral containers
- Replace sequential job queue with ThreadPoolExecutor (MAX_PARALLEL_JOBS=4)
- Remove dead include_snapshot code from env_policy and renderer
Signed-off-by: Andrew Chin <achin34@gatech.edu>
…ardized response files - builder defaults to BUILDER_MODULE env var; run_pov defaults to runner-sidecar - builder_name param separates service routing from image resolution - submit_build_output validates OSS_CRS_CURRENT_PHASE: local at build-target, sidecar upload at run - response dir files standardized: retcode, stdout.log, stderr.log, rebuild_id - run_pov takes rebuild_id (int) instead of build_id (str) Signed-off-by: Andrew Chin <achin34@gatech.edu>
…_output_dir - POST /upload-build-output on builder sidecar for run-phase artifact pre-staging - rebuild_output_dir() extracted as shared path helper - runner-sidecar: build_id -> rebuild_id, stdout added to POVResult Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
…OSS_CRS_PROJ_PATH/test.sh) - New run_tests.sh script resolves test script with fallback chain - Mounted into both sidecar ephemeral containers and orchestrator snapshot containers - Replaces hardcoded test.sh references in docker_ops.py and crs_compose.py - Test snapshot is optional (skip if no test script found) Signed-off-by: Andrew Chin <achin34@gatech.edu>
…ecified Signed-off-by: Andrew Chin <achin34@gatech.edu>
…{crs_name}/{rebuild_id}/
- Replace /out bind mount with container.get_archive() to preserve snapshot
state + new files (bind mount was shadowing snapshot's prebuilt /out)
- Runner sidecar takes crs_name, resolves harness at /out/{crs_name}/{rebuild_id}/
- libCRS run_pov sends crs_name to runner
Signed-off-by: Andrew Chin <achin34@gatech.edu>
…compile) Signed-off-by: Andrew Chin <achin34@gatech.edu>
…(OOM on compile)" This reverts commit 1f5a6bd0ee7f10b973f54c63806ed0c3a1660cb5. Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
There was a problem hiding this comment.
Pull request overview
Refactors the builder/runner sidecar architecture to use framework-injected, host-launched ephemeral containers (optionally backed by operator-controlled snapshot images via --incremental-build), and updates libCRS + compose generation + tests/docs accordingly.
Changes:
- Injects new FastAPI-based builder-sidecar and runner-sidecar services into the run-phase docker-compose template, with a shared rebuild artifact directory.
- Adds
--incremental-buildtooss-crs build-targetandoss-crs run, plus snapshot creation/validation logic inCRSCompose. - Updates libCRS contracts/CLI/docs (rename
run-test→apply-patch-test,build_id→rebuild_id, response fields) and refreshes unit/integration tests.
Reviewed changes
Copilot reviewed 71 out of 77 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| uv.lock | Adds dev dependencies required for sidecar servers/tests (FastAPI, uvicorn, httpx, python-multipart, etc.). |
| scripts/verify.py | New repo-level “verify” script to run ruff/pyright/unit tests. |
| scripts/verify-patch-no-inc.sh | New helper script to run a patch-verify flow without incremental snapshots. |
| scripts/verify-patch-inc.sh | New helper script to run a patch-verify flow with --incremental-build. |
| scripts/verify-patch-all.py | New benchmark runner for patch verification across multiple CRSBench projects. |
| scripts/init.py | Makes scripts importable as a package for the new verify entrypoint. |
| registry/crs-codex.yaml | Updates the referenced crs-codex ref. |
| pyproject.toml | Moves lint/type tools to dev group and adds verify console script + sidecar dev deps. |
| oss-crs-infra/runner-sidecar/server.py | New FastAPI runner-sidecar service implementing /run-pov. |
| oss-crs-infra/runner-sidecar/requirements.txt | Runner-sidecar Python requirements. |
| oss-crs-infra/runner-sidecar/Dockerfile | Container image for runner-sidecar (based on OSS-Fuzz base-runner). |
| oss-crs-infra/builder-sidecar/server.py | New FastAPI builder-sidecar service orchestrating ephemeral build/test containers. |
| oss-crs-infra/builder-sidecar/run_tests.sh | Script to resolve and run project tests with OSS-Fuzz conventions/fallbacks. |
| oss-crs-infra/builder-sidecar/requirements.txt | Builder-sidecar Python requirements (FastAPI + docker SDK). |
| oss-crs-infra/builder-sidecar/oss_crs_handler.sh | Patch-apply + build handler run inside ephemeral builder containers. |
| oss-crs-infra/builder-sidecar/Dockerfile | Container image for builder-sidecar service. |
| oss-crs-infra/builder-sidecar/docker_ops.py | Docker SDK lifecycle for ephemeral build/test containers + snapshot selection. |
| oss_crs/tests/unit/test_target_snapshot.py | Removes legacy target snapshot unit tests. |
| oss_crs/tests/unit/test_runner_sidecar.py | Adds unit tests for runner-sidecar behavior (mocked subprocess/fs). |
| oss_crs/tests/unit/test_renderer_run_compose.py | Updates compose rendering tests for always-injected sidecars + env var emission. |
| oss_crs/tests/unit/test_incremental_snapshots.py | Adds unit tests for incremental snapshot creation/validation logic. |
| oss_crs/tests/unit/test_env_policy.py | Updates env-policy tests to remove snapshot env and assert BUILDER_MODULE injection. |
| oss_crs/tests/unit/test_crs_compose_snapshot_sanitizer.py | Removes legacy snapshot sanitizer precedence tests. |
| oss_crs/tests/unit/test_cli_incremental_build.py | Adds unit tests for CLI parsing of --incremental-build. |
| oss_crs/tests/unit/config/test_crs.py | Updates config validation tests for removal of snapshot/run_snapshot fields. |
| oss_crs/tests/integration/test_sidecar_lifecycle.py | Adds integration tests for ephemeral container lifecycle and snapshot reuse. |
| oss_crs/tests/integration/test_resource_limits.py | Adjusts integration test timing to be less flaky. |
| oss_crs/tests/integration/test_builder_sidecar_lite.py | Adds “lite” E2E flow test for patch verification via sidecars. |
| oss_crs/tests/integration/test_builder_sidecar_full.py | Adds “full” E2E flow test (multi-builder + coverage + POV + test). |
| oss_crs/tests/integration/fixtures/mock-c-patches/patch_0.diff | Adds fixture patch used by integration/E2E tests. |
| oss_crs/tests/integration/fixtures/builder-sidecar-lite/oss-crs/patcher.Dockerfile | Adds patcher container for lite E2E. |
| oss_crs/tests/integration/fixtures/builder-sidecar-lite/oss-crs/docker-bake.hcl | Adds bake file (intentionally empty) for lite fixture. |
| oss_crs/tests/integration/fixtures/builder-sidecar-lite/oss-crs/crs.yaml | Adds lite CRS config fixture. |
| oss_crs/tests/integration/fixtures/builder-sidecar-lite/oss-crs/builder.Dockerfile | Adds builder Dockerfile fixture for lite. |
| oss_crs/tests/integration/fixtures/builder-sidecar-lite/bin/verify_patch | Adds patch verification script used in lite E2E. |
| oss_crs/tests/integration/fixtures/builder-sidecar-lite/bin/compile_target | Adds compile+submit script used in lite builder image. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/test-e2e.sh | Adds shell-based E2E test script for full fixture. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/test-e2e.py | Adds Python-API E2E test script for full fixture. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/test-e2e-all.sh | Runs both shell + Python E2E scripts sequentially. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/patcher.Dockerfile | Adds patcher container for full E2E. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/example-compose.yaml | Adds example compose doc fixture (now sidecar-oriented). |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/docker-bake.hcl | Adds bake file (intentionally empty) for full fixture. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/crs.yaml | Adds full CRS config fixture (multi-builder). |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/coverage-builder.Dockerfile | Adds coverage builder Dockerfile fixture. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/oss-crs/builder.Dockerfile | Adds default builder Dockerfile fixture for full. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/bin/compile_target_coverage | Adds coverage compile+submit script for full. |
| oss_crs/tests/integration/fixtures/builder-sidecar-full/bin/compile_target | Adds compile+submit script for full. |
| oss_crs/src/workdir.py | Adds get_rebuild_out_dir() path helper for rebuild artifact storage. |
| oss_crs/src/utils.py | Adds deterministic preserved-builder and snapshot tag helpers. |
| oss_crs/src/ui.py | Excludes preserved builder images from docker_compose_down cleanup. |
| oss_crs/src/templates/run-crs-compose.docker-compose.yaml.j2 | Injects builder/runner sidecars and mounts rebuild-out dir into CRS modules. |
| oss_crs/src/templates/renderer.py | Wires rebuild-out dir + incremental build into compose rendering context. |
| oss_crs/src/templates/oss_crs_handler.sh | Updates template handler script to accept patch path + dynamic build command. |
| oss_crs/src/target.py | Removes legacy target snapshot creation logic. |
| oss_crs/src/env_policy.py | Adds OSS_FUZZ_TARGET_ENV mapping + injects rebuild-out dir + BUILDER_MODULE. |
| oss_crs/src/crs.py | Preserves builder images via deterministic retagging during build-target. |
| oss_crs/src/crs_compose.py | Adds snapshot creation/validation/cleanup for incremental runs. |
| oss_crs/src/constants.py | Adds PRESERVED_BUILDER_REPO constant for preserved builder images. |
| oss_crs/src/config/crs.py | Removes snapshot/run_snapshot fields; makes dockerfile mandatory for run modules. |
| oss_crs/src/cli/crs_compose.py | Adds --incremental-build to build-target/run CLI args and passes through. |
| libCRS/README.md | Updates command list for apply-patch-test. |
| libCRS/libCRS/local.py | Implements new builder/runner sidecar flows, rebuild artifact download, new response fields. |
| libCRS/libCRS/cli/main.py | Updates CLI commands/flags for rebuild IDs and apply-patch-test. |
| libCRS/libCRS/base.py | Updates abstract interface contracts for rebuild-id-aware build outputs and new commands. |
| libCRS/install.sh | Installs libCRS both as a CLI tool and as a system package for Python API users. |
| docs/README.md | Documents --incremental-build behavior in build-target/run. |
| docs/design/libCRS.md | Updates libCRS design docs for new sidecar injection + new commands/fields. |
| docs/design/architecture.md | Updates architecture docs for new builder-sidecar functions. |
| docs/crs-development-guide.md | Updates dev guide for framework-injected sidecars + new libCRS commands/vars. |
| docs/config/crs.md | Updates CRS config docs removing snapshot/run_snapshot and noting framework sidecars. |
| CHANGELOG.md | Records breaking changes and new flags/commands/env vars. |
| builder/README.md | Removes legacy builder CRS documentation. |
| builder/oss-crs/server.Dockerfile | Removes legacy builder server Dockerfile. |
| builder/oss-crs/crs.yaml | Removes legacy builder CRS config. |
| .github/workflows/ci.yml | Replaces explicit ruff/pyright/pytest steps with uv run verify; tightens smoke test failure conditions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| """Submit a rebuild job. rebuild_id auto-increments if not provided.""" | ||
| patch_content = await patch.read() | ||
| job_id = _make_job_id(patch_content, builder_name) | ||
|
|
||
| if job_id in job_results: | ||
| existing = job_results[job_id] | ||
| if existing["status"] in ("queued", "running"): | ||
| return JobResponse(id=job_id, status=existing["status"]) | ||
| if existing["status"] == "done": | ||
| result = existing.get("result") | ||
| if result is not None and result.get("exit_code") == 0: | ||
| return existing | ||
|
|
||
| # Resolve rebuild_id if not provided | ||
| if rebuild_id is None: | ||
| rebuild_out_dir = Path(os.environ.get("REBUILD_OUT_DIR", "/rebuild_out")) | ||
| rebuild_id = next_rebuild_id(rebuild_out_dir, crs_name) | ||
|
|
There was a problem hiding this comment.
job_id is derived only from patch content (+ builder_name) and ignores a caller-supplied rebuild_id. If a client retries the same patch with a different rebuild_id, the server can return a cached successful result pointing at the previous rebuild’s artifacts, violating the request and potentially overwriting/misrouting outputs. Consider either including rebuild_id in the cache key when provided, or rejecting rebuild_id when a cached job already exists, or making rebuild_id generation fully server-side only.
| job_results: dict[str, dict] = {} | ||
| _executor = ThreadPoolExecutor( | ||
| max_workers=int(os.environ.get("MAX_PARALLEL_JOBS", "4")) | ||
| ) | ||
|
|
There was a problem hiding this comment.
job_results is a shared global dict that is read/updated by both the request handlers and the ThreadPoolExecutor worker threads without synchronization. This can lead to races (e.g., status/result updates being lost or partially written) under concurrent load. Add a threading.Lock (or use a thread-safe structure) around all accesses/mutations of job_results (including in _run_job).
| # Resolve harness path: /out/{crs_name}/{rebuild_id}/build/{harness_name} | ||
| # Build artifacts are placed under build/ by submit-build-output. | ||
| rebuild_out = os.path.join(out_dir, crs_name, str(rebuild_id), "build") | ||
| harness_path = os.path.join(rebuild_out, harness_name) | ||
| if not os.path.exists(harness_path): | ||
| return JSONResponse( | ||
| status_code=404, | ||
| content={"error": f"Harness binary not found: {harness_path}"}, | ||
| ) |
There was a problem hiding this comment.
crs_name and harness_name are interpolated into filesystem paths and can contain path separators like ../, allowing path traversal outside the intended /out/{crs}/{rebuild_id}/build/ tree (and reading arbitrary files from the bind-mounted host directory). Validate these inputs (e.g., reject path separators, enforce a strict filename regex, and/or use os.path.realpath checks to ensure the resolved path stays under rebuild_out).
| #!/bin/sh | ||
| # Usage: verify-patch-inc.sh <fuzz-proj-path> <harness> <diff> <pov-dir> [compose-file] | ||
| set -eu | ||
|
|
||
| PROJ=${1:?Usage: $0 <fuzz-proj-path> <harness> <diff> <pov-dir> [compose-file]} | ||
| HARNESS=${2:?} | ||
| DIFF=${3:?} | ||
| POV_DIR=${4:?} | ||
|
|
||
| COMPOSE=${5:-example/crs-verify-patch/compose.yaml} | ||
| BUILD_ID="vp-$(basename "$PROJ")" | ||
|
|
||
| uv run oss-crs prepare --compose-file "$COMPOSE" | ||
| uv run oss-crs build-target --compose-file "$COMPOSE" \ | ||
| --incremental-build \ | ||
| --build-id "$BUILD_ID" \ | ||
| --fuzz-proj-path "$PROJ" | ||
| uv run oss-crs run --compose-file "$COMPOSE" \ | ||
| --fuzz-proj-path "$PROJ" \ | ||
| --target-harness "$HARNESS" \ | ||
| --diff "$DIFF" \ | ||
| --incremental-build \ | ||
| --build-id "$BUILD_ID" \ | ||
| --run-id "$BUILD_ID" \ | ||
| --pov-dir "$POV_DIR" | ||
| RUN_RC=$? | ||
|
|
There was a problem hiding this comment.
Because the script runs with set -e, a non-zero exit from uv run oss-crs run ... will terminate the script immediately and RUN_RC=$? will never execute. If the intent is to always print timing logs and then exit with the run status, wrap the oss-crs run invocation with set +e / set -e (or use RUN_RC=0; ... || RUN_RC=$?).
| #!/bin/sh | ||
| # Usage: verify-patch-no-inc.sh <fuzz-proj-path> <harness> <diff> <pov-dir> [compose-file] | ||
| set -eu | ||
|
|
||
| PROJ=${1:?Usage: $0 <fuzz-proj-path> <harness> <diff> <pov-dir> [compose-file]} | ||
| HARNESS=${2:?} | ||
| DIFF=${3:?} | ||
| POV_DIR=${4:?} | ||
|
|
||
| COMPOSE=${5:-example/crs-verify-patch/compose.yaml} | ||
| BUILD_ID="vp-$(basename "$PROJ")" | ||
|
|
||
| uv run oss-crs prepare --compose-file "$COMPOSE" | ||
| uv run oss-crs build-target --compose-file "$COMPOSE" \ | ||
| --build-id "$BUILD_ID" \ | ||
| --fuzz-proj-path "$PROJ" | ||
| uv run oss-crs run --compose-file "$COMPOSE" \ | ||
| --fuzz-proj-path "$PROJ" \ | ||
| --target-harness "$HARNESS" \ | ||
| --diff "$DIFF" \ | ||
| --build-id "$BUILD_ID" \ | ||
| --run-id "$BUILD_ID" \ | ||
| --pov-dir "$POV_DIR" | ||
| RUN_RC=$? | ||
|
|
There was a problem hiding this comment.
Because the script runs with set -e, a non-zero exit from uv run oss-crs run ... will terminate the script immediately and RUN_RC=$? will never execute. If the intent is to always print timing logs and then exit with the run status, wrap the oss-crs run invocation with set +e / set -e (or use RUN_RC=0; ... || RUN_RC=$?).
| run_pov_parser.add_argument( | ||
| "--builder", | ||
| type=str, | ||
| required=True, | ||
| help="Builder sidecar module name (resolved to URL via get-service-domain)", | ||
| default=None, | ||
| help="Runner sidecar module name (defaults to BUILDER_MODULE env var)", | ||
| ) |
There was a problem hiding this comment.
The run-pov CLI flag is still named --builder and its help text says it defaults to BUILDER_MODULE, but the implementation treats this value as the runner sidecar service name (and LocalCRSUtils defaults to RUNNER_MODULE / runner-sidecar). This is confusing and can lead to misconfiguration; consider renaming the flag/help to --runner (or at least change the help text and wiring to reference RUNNER_MODULE).
There was a problem hiding this comment.
Need to figure out what RUNNER_MODULE is about. builder as CLI arg is fine.
| base_image = _TEST_IMAGE | ||
| build_id = "integration-test-001" | ||
| builder_name = "integ-builder" | ||
| crs_name = "integ-crs" | ||
| rebuild_out_dir = tmp_path / "rebuild_out" | ||
| rebuild_out_dir.mkdir() | ||
|
|
||
| # Create a minimal patch (empty is fine for lifecycle test) | ||
| result = run_ephemeral_build( | ||
| base_image=base_image, | ||
| rebuild_id=build_id, | ||
| builder_name=builder_name, | ||
| crs_name=crs_name, | ||
| patch_bytes=b"", | ||
| rebuild_out_dir=rebuild_out_dir, | ||
| timeout=60, | ||
| ) |
There was a problem hiding this comment.
run_ephemeral_build is annotated/implemented with rebuild_id: int, but this test passes string values (e.g. build_id = "integration-test-001" and then rebuild_id=build_id). This makes the test inconsistent with the service/API contract (and can hide bugs related to numeric ID allocation). Use integer rebuild IDs in these tests (and keep build_id as a separate string if needed).
| def test_container_cleanup_on_failure(tmp_path): | ||
| """TST-02: Container is removed even when build fails.""" | ||
| from docker_ops import run_ephemeral_build | ||
|
|
||
| # Use base image to force failure at command execution (no oss_crs_handler.sh) | ||
| result = run_ephemeral_build( | ||
| base_image=_TEST_IMAGE, | ||
| rebuild_id="cleanup-test", | ||
| builder_name="integ-builder", | ||
| crs_name="integ-crs", | ||
| patch_bytes=b"", | ||
| rebuild_out_dir=tmp_path, | ||
| timeout=10, | ||
| ) |
There was a problem hiding this comment.
run_ephemeral_build is annotated/implemented with rebuild_id: int, but this test passes a string (rebuild_id="cleanup-test"). If rebuild_id is intended to be numeric for directory scanning and API consistency, keep tests aligned and pass an int here as well (or broaden the function signature/validation to accept strings explicitly).
There was a problem hiding this comment.
rebuild_id should be string, not int
| try: | ||
| container = client.containers.create( | ||
| base_image, | ||
| command=[ | ||
| "bash", | ||
| "/usr/local/bin/oss_crs_handler.sh", | ||
| "/OSS_CRS_BUILD_OUT_DIR/patch.diff", | ||
| "/out", | ||
| ], | ||
| volumes=volumes, | ||
| environment={ | ||
| "OSS_CRS_BUILD_ID": str(rebuild_id), | ||
| "OSS_CRS_REBUILD_ID": str(rebuild_id), | ||
| "OSS_CRS_BUILD_CMD": build_cmd, | ||
| "OSS_CRS_BUILD_OUT_DIR": "/OSS_CRS_BUILD_OUT_DIR", | ||
| "OSS_CRS_PROJ_PATH": "/OSS_CRS_PROJ_PATH", | ||
| "OSS_CRS_NAME": crs_name, | ||
| "OSS_CRS_RUN_ENV_TYPE": "local", | ||
| "REPLAY_ENABLED": "", | ||
| **_oss_fuzz_env(), | ||
| }, |
There was a problem hiding this comment.
The ephemeral container env sets OSS_CRS_BUILD_ID to rebuild_id. Elsewhere OSS_CRS_BUILD_ID refers to the operator-supplied build-target build ID (used for snapshot tags), while OSS_CRS_REBUILD_ID refers to the per-patch rebuild. To avoid confusing tooling/scripts inside the builder image, keep OSS_CRS_BUILD_ID consistent with the build-target build ID (or omit it here) and rely on OSS_CRS_REBUILD_ID for the per-rebuild identifier.
| # Sidecar services are always injected as infrastructure (per D-04: single parent mount) | ||
| rebuild_out_dir = str( | ||
| crs_compose.work_dir.get_rebuild_out_dir( | ||
| crs_compose.crs_list[0].name, target, run_id, sanitizer, create=True | ||
| ) | ||
| ) |
There was a problem hiding this comment.
rebuild_out_dir is computed using crs_compose.crs_list[0].name, but the sidecar volume is shared across all CRSs in the run. This makes the on-host storage location depend on list ordering and nests shared infra state under a single CRS’s run directory. Consider adding a WorkDir helper for a run-scoped rebuild-out root (not CRS-scoped) and use that here to avoid surprising paths/collisions when multiple CRSs are present.
There was a problem hiding this comment.
Need to further investigate what this returned rebuild out dir is used for. Ideally all CRSs should have their dirs used in this context.
chore: update atlantis-java repo url
…iner Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
f18de48 to
0810201
Compare
Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
…e RTS in content key Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
…call in verify_patch Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
…gistry entries Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
refactor: replace download-source with mount-based API
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
Signed-off-by: Andrew Chin <achin34@gatech.edu>
…mits Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
ce735ef to
32306ff
Compare
Signed-off-by: Youngjoon Kim <acorn421@gmail.com>
Summary
Refactors the builder sidecar architecture per #125. Instead of CRS-declared long-running builder containers with snapshot configs (
snapshot: true/run_snapshot: true), the framework now:crs.yaml--incremental-buildflag (operator-controlled) tobuild-targetandrunfor Docker snapshot-based fast rebuildsrun-testtoapply-patch-test— patches are now applied in a fresh container rather than reusing a stateful buildBreaking changes
snapshotandrun_snapshotfields removed fromcrs.yamlOSS_CRS_SNAPSHOT_IMAGEenv var removedlibCRS run-testreplaced bylibCRS apply-patch-test--build-idin sidecar commands replaced by--rebuild-idbuild_exit_code→retcode,build_id→rebuild_idTest plan
test_builder_sidecar_full— E2E: prepare → build-target → run with patch, POV, and test.sh through the full sidecar pipeline. Tests multiple builder configs (default-build + coverage-build) to verify custom/multi-builder support, coverage instrumentation verification, and rebuild artifact download.test_builder_sidecar_lite— E2E: prepare → build-target → run with patch verification (build, rebuild, POV, test)test_sidecar_lifecycle— Ephemeral container lifecycle: start, build, snapshot creation/reuse, cleanup on failuretest_env_policy— Framework injectsBUILDER_MODULEand CRS cannot override itapply-patch-build/run-pov/apply-patch-test)