Parallel Builds and Runs
oss-crs supports running multiple builds and runs in parallel through build and run identifiers.
Build ID
The --build-id flag isolates build artifacts, allowing parallel builds of different target versions or configurations.
Default behavior:
build-target: Generates a new timestamp-based ID (e.g.,1739819274ab), creating a fresh build each timerun: Uses the latest existing build, or generates a new one if none exists
To reuse an existing build (avoid rebuilding), explicitly specify --build-id:
# Build fresh artifacts
uv run oss-crs build-target \
--compose-file ./crs-compose.yaml \
--fuzz-proj-path ~/oss-fuzz/projects/libxml2
# Pin to a specific build ID to reuse across invocations
uv run oss-crs build-target \
--compose-file ./crs-compose.yaml \
--fuzz-proj-path ~/oss-fuzz/projects/libxml2 \
--build-id my-pinned-build
Build artifacts are stored at:
{work_dir}/{sanitizer}/builds/{build-id}/crs/{crs-name}/{target}/BUILD_OUT_DIR/
Multiple runs can share the same build by specifying the same --build-id.
Target Build Options
oss-crs uses framework defaults for target build options:
SANITIZER=addressFUZZING_ENGINE=libfuzzerARCHITECTURE=x86_64FUZZING_LANGUAGE=c
If project.yaml exists and is parseable, its values are used as fallback target defaults. Users can override through additional_env (CRS entry level and CRS module/build-step level), or by using the --sanitizer CLI flag on build-target, run, and artifacts commands. The CLI flag takes highest precedence when provided.
Effective precedence:
- CLI
--sanitizerflag (highest priority when provided) - compose CRS-entry
additional_env(user) - CRS module/build-step
additional_env(crs.yaml) project.yamlfallback values- framework defaults (
address,libfuzzer,x86_64,c)
Notes:
additional_envkeys must follow env-var format:[A-Za-z_][A-Za-z0-9_]*.OSS_CRS_*keys are reserved for framework-owned values. If provided inadditional_env,oss-crswarns (ENV001/ENV002).- Framework-owned
OSS_CRS_*keys in the active phase override user values. UnknownOSS_CRS_*keys are warned and may pass through. - If multiple CRS entries specify conflicting
SANITIZERvalues and no explicit sanitizer is provided,build-target/runfails fast with a conflict error.
Only sanitizer affects artifact directory partitioning.
uv run oss-crs build-target \
--compose-file ./crs-compose.yaml \
--fuzz-proj-path ~/oss-fuzz/projects/libxml2
All artifacts are stored under {work_dir}/{sanitizer}/....
Run ID
The --run-id flag isolates run artifacts (seeds, PoVs, shared state), allowing multiple experiments against the same build.
uv run oss-crs run \
--compose-file ./crs-compose.yaml \
--fuzz-proj-path ~/oss-fuzz/projects/libxml2 \
--target-harness xml \
--build-id my-pinned-build \
--run-id experiment-1 \
--timeout 3600
| Command | Default |
|---|---|
run | Auto-generated timestamp + random bytes (e.g., 1739819274ab) |
artifacts | Interactive selection in reverse chronological order |
Run artifacts are stored at:
{work_dir}/{sanitizer}/runs/{run-id}/BUILD_ID # records which build was used
{work_dir}/{sanitizer}/runs/{run-id}/crs/{crs-name}/{target}/SUBMIT_DIR/{harness}/povs/
{work_dir}/{sanitizer}/runs/{run-id}/crs/{crs-name}/{target}/SUBMIT_DIR/{harness}/seeds/
{work_dir}/{sanitizer}/runs/{run-id}/crs/{crs-name}/{target}/SUBMIT_DIR/{harness}/bug-candidates/
{work_dir}/{sanitizer}/runs/{run-id}/crs/{crs-name}/{target}/SUBMIT_DIR/{harness}/patches/
{work_dir}/{sanitizer}/runs/{run-id}/crs/{crs-name}/{target}/SHARED_DIR/{harness}/
{work_dir}/{sanitizer}/runs/{run-id}/EXCHANGE_DIR/{target}/{harness}/ # shared across all CRSs
{work_dir}/{sanitizer}/runs/{run-id}/logs/{target}/{harness}/ # compose/service logs
Cleanup Semantics
- At run start,
oss-crscleans run-scoped directories for the selectedrun-id(includingEXCHANGE_DIRand per-CRSSHARED_DIR) before services start. - At run cleanup,
docker compose downis always attempted, and project-scoped compose image cleanup is attempted best-effort (warnings are emitted on failures).
Artifacts Command
The artifacts command uses --fuzz-proj-path, --target-source-path, --target-harness, --run-id, --build-id, and --sanitizer to compute artifact paths from the compose file.
oss-crs artifacts \
--compose-file ./crs-compose.yaml \
--fuzz-proj-path ~/oss-fuzz/projects/libxml2 \
--target-harness xml \
--run-id my-new-run
Default behavior:
--run-id: Interactive selection if omitted--build-id: Reads from the run'sBUILD_IDfile, falls back to latest build by sanitizer (timestamp in ID if present, otherwise build directory mtime)--sanitizer: If omitted, resolves from compose/project defaults (SANITIZERin CRS-entryadditional_env->project.yaml->address)
Resolution behavior:
--run-idsupports pre-run deterministic resolution (if the run does not exist yet, paths are still computed)--build-idis validated against existing builds when explicitly provided
Interactive Run Selection
If --run-id is omitted, an interactive prompt lists available runs sorted by timestamp:
? Select run-id:
> 2025-02-17 16:01:57 (1739819274ab)
2025-02-17 15:58:30 (test-explicit)
2025-02-17 15:55:00 (experiment-1)
Output Format
{
"build_id": "1739819200cd",
"run_id": "1739819274ab",
"sanitizer": "address",
"exchange_dir": {
"base": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml",
"pov": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml/povs",
"seed": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml/seeds",
"bug_candidate": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml/bug-candidates",
"patch": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml/patches",
"diff": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml/diffs"
},
"run_logs": {
"base": "/path/to/address/runs/1739819274ab/logs/target/xml",
"compose_stdout_log": "/path/to/address/runs/1739819274ab/logs/target/xml/docker-compose.stdout.log",
"compose_stderr_log": "/path/to/address/runs/1739819274ab/logs/target/xml/docker-compose.stderr.log",
"service_logs": "/path/to/address/runs/1739819274ab/logs/target/xml/services"
},
"crs": {
"crs-libfuzzer": {
"build": "/path/to/address/builds/1739819200cd/crs/crs-libfuzzer/target/BUILD_OUT_DIR",
"submit_dir": "/path/to/address/runs/1739819274ab/crs/crs-libfuzzer/target/SUBMIT_DIR/xml",
"pov": "/path/to/address/runs/1739819274ab/crs/crs-libfuzzer/target/SUBMIT_DIR/xml/povs",
"seed": "/path/to/address/runs/1739819274ab/crs/crs-libfuzzer/target/SUBMIT_DIR/xml/seeds",
"bug_candidate": "/path/to/address/runs/1739819274ab/crs/crs-libfuzzer/target/SUBMIT_DIR/xml/bug-candidates",
"patch": "/path/to/address/runs/1739819274ab/crs/crs-libfuzzer/target/SUBMIT_DIR/xml/patches",
"fetch": "/path/to/address/runs/1739819274ab/EXCHANGE_DIR/target/xml",
"shared": "/path/to/address/runs/1739819274ab/crs/crs-libfuzzer/target/SHARED_DIR/xml"
}
}
}
- All computed paths are returned regardless of whether they exist on disk
build_idisnullif no build is associated with the run- If
--target-harnessis not provided, onlybuildis returned