mirror of
https://github.com/trailofbits/buttercup
synced 2026-06-21 14:11:39 +00:00
Add support for ARM (#207)
* Fix integration-test run * use the proper oss-fuzz-aixcc commit to run integration-test * determine OSS_FUZZ_CONTAINER_ORG at runtime * use `git diff` in the patcher to create the patch to fix a problem with patches affecting non-newline terminated files * fix parsing * fix program-model lint * Modify CRS to work on MacOS/ARM * Use LibUCL for testing * use example-libpng * fix linting * common: fix tests
This commit is contained in:
committed by
GitHub
parent
744a5ae2e6
commit
5cfa9bd26e
@@ -21,6 +21,7 @@ help:
|
||||
@echo ""
|
||||
@echo "Testing:"
|
||||
@echo " send-integration-task - Run integration-test task"
|
||||
@echo " send-libpng-task - Run libpng task"
|
||||
@echo ""
|
||||
@echo "Development:"
|
||||
@echo " install-cscope - Install cscope tool"
|
||||
@@ -128,6 +129,17 @@ send-integration-task:
|
||||
./orchestrator/scripts/task_integration_test.sh
|
||||
@pkill -f "kubectl port-forward" || true
|
||||
|
||||
send-libpng-task:
|
||||
@echo "Running libpng task..."
|
||||
@if ! kubectl get namespace $${BUTTERCUP_NAMESPACE:-crs} >/dev/null 2>&1; then \
|
||||
echo "Error: CRS namespace not found. Deploy first with 'make deploy'."; \
|
||||
exit 1; \
|
||||
fi
|
||||
kubectl port-forward -n $${BUTTERCUP_NAMESPACE:-crs} service/buttercup-ui 31323:1323 &
|
||||
@sleep 3
|
||||
./orchestrator/scripts/task_crs.sh
|
||||
@pkill -f "kubectl port-forward" || true
|
||||
|
||||
# Development targets
|
||||
lint:
|
||||
@echo "Linting all Python code..."
|
||||
@@ -148,6 +160,21 @@ lint-component:
|
||||
cd $(COMPONENT) && uv run mypy; \
|
||||
fi
|
||||
|
||||
reformat:
|
||||
@echo "Reformatting all Python code..."
|
||||
@for component in common orchestrator fuzzer program-model seed-gen patcher; do \
|
||||
make --no-print-directory reformat-component COMPONENT=$$component; \
|
||||
done
|
||||
|
||||
reformat-component:
|
||||
@if [ -z "$(COMPONENT)" ]; then \
|
||||
echo "Error: COMPONENT not specified. Usage: make reformat-component COMPONENT=<component>"; \
|
||||
echo "Available components: common, fuzzer, orchestrator, patcher, program-model, seed-gen"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "Reformatting $(COMPONENT)..."
|
||||
@cd $(COMPONENT) && uv sync -q --all-extras && uv run ruff format && uv run ruff check --fix
|
||||
|
||||
# Cleanup targets
|
||||
undeploy:
|
||||
@echo "Cleaning up deployment..."
|
||||
|
||||
@@ -120,10 +120,10 @@ buttercup-ui ClusterIP 10.106.49.166 <none> 1323/TCP
|
||||
All CRS pods up and running.
|
||||
```
|
||||
|
||||
3. **Submit the integration-test challenge to the CRS (for 30mins):**
|
||||
3. **Submit the libpng project to the CRS (for 30mins):**
|
||||
|
||||
```bash
|
||||
make send-integration-task
|
||||
make send-libpng-task
|
||||
```
|
||||
|
||||
**Alternative manual commands:**
|
||||
@@ -265,6 +265,7 @@ make status # Check the status of the deployment
|
||||
|
||||
# Testing
|
||||
make send-integration-task # Run integration test task
|
||||
make send-libpng-task # Run libpng test task
|
||||
|
||||
# Development
|
||||
make lint # Lint all Python code
|
||||
@@ -283,9 +284,6 @@ make lint
|
||||
|
||||
# Lint specific component
|
||||
make lint-component COMPONENT=orchestrator
|
||||
|
||||
# Run test task
|
||||
make send-integration-task
|
||||
```
|
||||
|
||||
**Alternative manual commands:**
|
||||
|
||||
+17
-4
@@ -14,8 +14,8 @@ dependencies = [
|
||||
"langfuse ~= 2.59.2",
|
||||
"langchain ~= 0.3.18",
|
||||
"six>=1.17.0",
|
||||
"openlit == 1.32.12", # 1.33 currently fails to import opentelemetry.sdk._events
|
||||
"langchain-community ~= 0.3.20", # implicit dep of openlit if you instrument langchain
|
||||
"openlit == 1.32.12", # 1.33 currently fails to import opentelemetry.sdk._events
|
||||
"langchain-community ~= 0.3.20", # implicit dep of openlit if you instrument langchain
|
||||
"langchain-text-splitters ~= 0.3.7", # implicit dep of openlit if you instrument langchain
|
||||
]
|
||||
|
||||
@@ -33,11 +33,24 @@ requires = ["hatchling"]
|
||||
build-backend = "hatchling.build"
|
||||
|
||||
[dependency-groups]
|
||||
dev = ["pytest>=8.3.4", "ruff>=0.9.2", "mypy>=1.15.0", "types-requests", "types-PyYAML", "types-redis"]
|
||||
dev = [
|
||||
"pytest>=8.3.4",
|
||||
"ruff>=0.9.2",
|
||||
"mypy>=1.15.0",
|
||||
"types-requests",
|
||||
"types-PyYAML",
|
||||
"types-redis",
|
||||
"dirty-equals>=0.9.0",
|
||||
]
|
||||
|
||||
[tool.ruff]
|
||||
line-length = 120
|
||||
exclude = ["./src/buttercup/common/datastructures", "./src/buttercup/common/clusterfuzz_env", "./src/buttercup/common/clusterfuzz_parser", "src/buttercup/common/clusterfuzz_utils.py"]
|
||||
exclude = [
|
||||
"./src/buttercup/common/datastructures",
|
||||
"./src/buttercup/common/clusterfuzz_env",
|
||||
"./src/buttercup/common/clusterfuzz_parser",
|
||||
"src/buttercup/common/clusterfuzz_utils.py",
|
||||
]
|
||||
|
||||
[tool.mypy]
|
||||
plugins = ["pydantic.mypy"]
|
||||
|
||||
@@ -19,6 +19,7 @@ from buttercup.common.utils import copyanything, get_diffs
|
||||
from buttercup.common.stack_parsing import get_crash_token
|
||||
from typing import Iterator
|
||||
import buttercup.common.node_local as node_local
|
||||
from buttercup.common.constants import ARCHITECTURE
|
||||
from packaging.version import Version
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -532,7 +533,7 @@ class ChallengeTask:
|
||||
*,
|
||||
pull_latest_base_image: bool = False,
|
||||
cache: bool | None = None,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
) -> CommandResult:
|
||||
logger.info(
|
||||
"Building image for project %s | pull_latest_base_image=%s | cache=%s | architecture=%s",
|
||||
@@ -560,7 +561,7 @@ class ChallengeTask:
|
||||
self,
|
||||
use_source_dir: bool = True,
|
||||
*,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
engine: str | None = None,
|
||||
sanitizer: str | None = None,
|
||||
env: Dict[str, str] | None = None,
|
||||
@@ -605,7 +606,7 @@ class ChallengeTask:
|
||||
self,
|
||||
use_source_dir: bool = True,
|
||||
*,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
engine: str | None = None,
|
||||
sanitizer: str | None = None,
|
||||
pull_latest_base_image: bool = True,
|
||||
@@ -634,7 +635,7 @@ class ChallengeTask:
|
||||
container_name: str,
|
||||
use_source_dir: bool = True,
|
||||
*,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
engine: str | None = None,
|
||||
sanitizer: str | None = None,
|
||||
pull_latest_base_image: bool = True,
|
||||
@@ -658,7 +659,7 @@ class ChallengeTask:
|
||||
def check_build(
|
||||
self,
|
||||
*,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
engine: str | None = None,
|
||||
sanitizer: str | None = None,
|
||||
env: Dict[str, str] | None = None,
|
||||
@@ -689,7 +690,7 @@ class ChallengeTask:
|
||||
crash_path: Path,
|
||||
fuzzer_args: list[str] | None = None,
|
||||
*,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
env: Dict[str, str] | None = None,
|
||||
) -> ReproduceResult:
|
||||
logger.info(
|
||||
@@ -735,7 +736,7 @@ class ChallengeTask:
|
||||
harness_name: str,
|
||||
fuzzer_args: list[str] | None = None,
|
||||
corpus_dir: Path | None = None,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
engine: str | None = None,
|
||||
sanitizer: str | None = None,
|
||||
env: Dict[str, str] | None = None,
|
||||
@@ -772,7 +773,7 @@ class ChallengeTask:
|
||||
self,
|
||||
harness_name: str,
|
||||
corpus_dir: str,
|
||||
architecture: str | None = None,
|
||||
architecture: str | None = ARCHITECTURE,
|
||||
env: Dict[str, str] | None = None,
|
||||
) -> CommandResult:
|
||||
logger.info(
|
||||
|
||||
@@ -1,6 +1,19 @@
|
||||
import platform
|
||||
|
||||
|
||||
def _detect_architecture() -> str:
|
||||
machine = platform.machine().lower()
|
||||
if machine in ("x86_64", "amd64"):
|
||||
return "x86_64"
|
||||
elif machine in ("aarch64", "arm64"):
|
||||
return "aarch64"
|
||||
else:
|
||||
raise RuntimeError(f"Unsupported architecture: {machine}")
|
||||
|
||||
|
||||
CORPUS_DIR_NAME = "buttercup_corpus"
|
||||
CRASH_DIR_NAME = "buttercup_crashes"
|
||||
|
||||
# This is fixed for every task, so we can hardcode it here
|
||||
ARCHITECTURE = "x86_64"
|
||||
ARCHITECTURE = _detect_architecture()
|
||||
ADDRESS_SANITIZER = "address"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
from pathlib import Path
|
||||
import pytest
|
||||
from unittest.mock import MagicMock, patch
|
||||
from dirty_equals import IsStr
|
||||
import subprocess
|
||||
import os
|
||||
import base64
|
||||
@@ -159,7 +160,15 @@ def test_build_image(challenge_task: ChallengeTask, mock_subprocess):
|
||||
|
||||
# Verify the command and working directory
|
||||
args, kwargs = mock_subprocess.call_args
|
||||
assert args[0] == ["python", "infra/helper.py", "build_image", "--no-pull", "example_project"]
|
||||
assert args[0] == [
|
||||
"python",
|
||||
"infra/helper.py",
|
||||
"build_image",
|
||||
"--no-pull",
|
||||
"--architecture",
|
||||
IsStr,
|
||||
"example_project",
|
||||
]
|
||||
assert kwargs["cwd"] == challenge_task.task_dir / challenge_task.get_oss_fuzz_subpath()
|
||||
|
||||
# Verify output was read
|
||||
@@ -181,6 +190,8 @@ def test_build_fuzzers(challenge_task: ChallengeTask, mock_subprocess):
|
||||
"python",
|
||||
"infra/helper.py",
|
||||
"build_fuzzers",
|
||||
"--architecture",
|
||||
IsStr,
|
||||
"--engine",
|
||||
"libfuzzer",
|
||||
"--sanitizer",
|
||||
@@ -202,6 +213,8 @@ def test_check_build(challenge_task: ChallengeTask, mock_subprocess):
|
||||
"python",
|
||||
"infra/helper.py",
|
||||
"check_build",
|
||||
"--architecture",
|
||||
IsStr,
|
||||
"--engine",
|
||||
"libfuzzer",
|
||||
"--sanitizer",
|
||||
@@ -222,7 +235,15 @@ def test_reproduce_pov(challenge_task: ChallengeTask, mock_subprocess):
|
||||
assert result.did_crash() is False
|
||||
mock_subprocess.assert_called_once()
|
||||
args, kwargs = mock_subprocess.call_args
|
||||
assert args[0][:-1] == ["python", "infra/helper.py", "reproduce", "example_project", "fuzz_target"]
|
||||
assert args[0][:-1] == [
|
||||
"python",
|
||||
"infra/helper.py",
|
||||
"reproduce",
|
||||
"--architecture",
|
||||
IsStr,
|
||||
"example_project",
|
||||
"fuzz_target",
|
||||
]
|
||||
assert args[0][-1].endswith("/crash-sample")
|
||||
assert kwargs["cwd"] == challenge_task.task_dir / challenge_task.get_oss_fuzz_subpath()
|
||||
|
||||
@@ -270,7 +291,15 @@ def test_build_image_custom_python(challenge_task_custom_python: ChallengeTask,
|
||||
assert result.success is True
|
||||
mock_subprocess.assert_called_once()
|
||||
args, kwargs = mock_subprocess.call_args
|
||||
assert args[0] == ["/usr/bin/python3", "infra/helper.py", "build_image", "--no-pull", "example_project"]
|
||||
assert args[0] == [
|
||||
"/usr/bin/python3",
|
||||
"infra/helper.py",
|
||||
"build_image",
|
||||
"--no-pull",
|
||||
"--architecture",
|
||||
IsStr,
|
||||
"example_project",
|
||||
]
|
||||
assert kwargs["cwd"] == challenge_task_custom_python.task_dir / challenge_task_custom_python.get_oss_fuzz_subpath()
|
||||
|
||||
|
||||
@@ -288,6 +317,8 @@ def test_build_fuzzers_custom_python(challenge_task_custom_python: ChallengeTask
|
||||
"/usr/bin/python3",
|
||||
"infra/helper.py",
|
||||
"build_fuzzers",
|
||||
"--architecture",
|
||||
IsStr,
|
||||
"--engine",
|
||||
"libfuzzer",
|
||||
"--sanitizer",
|
||||
|
||||
Generated
+12
-1
@@ -327,6 +327,7 @@ dependencies = [
|
||||
|
||||
[package.dev-dependencies]
|
||||
dev = [
|
||||
{ name = "dirty-equals" },
|
||||
{ name = "mypy" },
|
||||
{ name = "pytest" },
|
||||
{ name = "ruff" },
|
||||
@@ -353,6 +354,7 @@ requires-dist = [
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.4" },
|
||||
{ name = "ruff", specifier = ">=0.9.2" },
|
||||
@@ -433,6 +435,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/c6/ac0b6c1e2d138f1002bcf799d330bd6d85084fece321e662a14223794041/Deprecated-1.2.18-py2.py3-none-any.whl", hash = "sha256:bd5011788200372a32418f888e326a09ff80d0214bd961147cfed01b5c018eec", size = 9998, upload-time = "2025-01-27T10:46:09.186Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirty-equals"
|
||||
version = "0.9.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b0/99/133892f401ced5a27e641a473c547d5fbdb39af8f85dac8a9d633ea3e7a7/dirty_equals-0.9.0.tar.gz", hash = "sha256:17f515970b04ed7900b733c95fd8091f4f85e52f1fb5f268757f25c858eb1f7b", size = 50412, upload-time = "2025-01-11T23:23:40.491Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/77/0c/03cc99bf3b6328604b10829de3460f2b2ad3373200c45665c38508e550c6/dirty_equals-0.9.0-py3-none-any.whl", hash = "sha256:ff4d027f5cfa1b69573af00f7ba9043ea652dbdce3fe5cbe828e478c7346db9c", size = 28226, upload-time = "2025-01-11T23:23:37.489Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "distro"
|
||||
version = "1.9.0"
|
||||
@@ -456,7 +467,7 @@ name = "exceptiongroup"
|
||||
version = "1.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" }
|
||||
wheels = [
|
||||
|
||||
@@ -2,11 +2,11 @@ enabled: true
|
||||
|
||||
resources:
|
||||
limits:
|
||||
cpu: 300m
|
||||
cpu: 500m
|
||||
memory: 1Gi
|
||||
requests:
|
||||
cpu: 100m
|
||||
memory: 512Mi
|
||||
cpu: 250m
|
||||
memory: 256Mi
|
||||
|
||||
dind:
|
||||
resources:
|
||||
|
||||
@@ -13,7 +13,7 @@ RUN uv python install python3.10
|
||||
FROM base-image AS runner-base
|
||||
RUN apt-get update
|
||||
# TODO(Ian): maybe we should have a different base image for the builder
|
||||
RUN apt-get install ca-certificates curl
|
||||
RUN apt-get install -y ca-certificates curl
|
||||
RUN install -m 0755 -d /etc/apt/keyrings
|
||||
RUN curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc
|
||||
RUN chmod a+r /etc/apt/keyrings/docker.asc
|
||||
|
||||
Generated
+5
-1
@@ -395,9 +395,13 @@ requires-dist = [
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.4" },
|
||||
{ name = "ruff", specifier = ">=0.9.2" },
|
||||
{ name = "types-pyyaml" },
|
||||
{ name = "types-redis" },
|
||||
{ name = "types-requests" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -448,7 +452,7 @@ name = "exceptiongroup"
|
||||
version = "1.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" }
|
||||
wheels = [
|
||||
|
||||
@@ -51,8 +51,16 @@ Welcome to the documentation page for the AIxCC Final Competition.
|
||||
- [Challenge Sequencing](round_info/exhibition-round-1.md#challenge-sequencing)
|
||||
|
||||
- [Exhibition Round 2](round_info/exhibition-round-2.md#exhibition-round-2)
|
||||
|
||||
- [Repositories](round_info/exhibition-round-2.md#repositories)
|
||||
- [Challenge Tasks Archive](round_info/exhibition-round-2.md#challenge-tasks-archive)
|
||||
- [Sequencing](round_info/exhibition-round-2.md#sequencing)
|
||||
- [Notes](round_info/exhibition-round-2.md#notes)
|
||||
|
||||
- [Exhibition Round 3](round_info/exhibition-round-3.md#exhibition-round-3)
|
||||
- [Repositories](round_info/exhibition-round-3.md#repositories)
|
||||
- [Challenge Tasks Archive](round_info/exhibition-round-3.md#challenge-tasks-archive)
|
||||
- [Sequencing](round_info/exhibition-round-3.md#sequencing)
|
||||
- [Notes](round_info/exhibition-round-3.md#notes)
|
||||
|
||||
- [LLM Models](llm-models/README.md#llm-providers-and-models)
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
|
||||
* `ArchitectureX8664` (value: `'x86_64'`)
|
||||
|
||||
* `ArchitectureAArch64` (value: `'aarch64'`)
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
||||
|
||||
@@ -94,6 +94,79 @@ Here is an example curl you may use to trigger the integration testing task.
|
||||
curl -u 11111111-1111-1111-1111-111111111111:pY8rLk7FvQ2hZm9GwUx3Ej5BnTcV4So0 -X 'POST' 'https://api.aixcc.tech/v1/request/delta/' -H 'Content-Type: application/json' -d '{"duration_secs": 3600 }'
|
||||
```
|
||||
|
||||
### Request Arbitrary Exhibition 3 Task
|
||||
|
||||
We have updated the production Competition API /v1/request/ endpoint to include all exhibition3 challenges. Exercising this endpoint should look the same as exercising the /v1/request/delta/ endpoint, but
|
||||
instead of putting delta in the URL path, you can input the challenge name.
|
||||
|
||||
For example:
|
||||
|
||||
```bash
|
||||
curl -u <team-id>:<secret> -X 'POST' 'https://api.aixcc.tech/v1/request/ex3-tk-full-01/' --json '{"duration_secs":43200}'
|
||||
```
|
||||
|
||||
You may, of course, still use /v1/request/delta/, and you will get the same integration test challenge as you would have before Exhibition 3. In order to get a list of the challenges that are available, you may use
|
||||
the /v1/request/list/ endpoint:
|
||||
|
||||
```bash
|
||||
curl -u <team-id>:<secret> -X 'GET' 'https://api.aixcc.tech/v1/request/list/'
|
||||
```
|
||||
|
||||
Some teams have noted that the hosted competitor test servers were having issues scaling to respond to the number of submissions. Unfortunately, this is a limit. The official competition API, however, is built to
|
||||
handle hundreds of POVs at the same time. So if you are running into any issues with the competitor test server, we highly recommend you use this new endpoint. We will still also still be updating the competitor test
|
||||
servers as we have been before when updates are made to evaluation scripts.
|
||||
|
||||
Use the following URL/hostname configurations in order to use this new requesting feature:
|
||||
|
||||
**CRS API URL**: `https://<team-moniker>-final.tail7e9b4c.ts.net`
|
||||
|
||||
**Competition API URL**: `https://api.tail7e9b4c.ts.net`
|
||||
|
||||
Here's a reference for which challenge names correspond to which repos:
|
||||
|
||||
- **Apache Commons Compress**
|
||||
- ex3-cc-delta-02
|
||||
- ex3-cc-delta-03
|
||||
- ex3-cc-full-01
|
||||
- **FreeRDP**
|
||||
- ex3-fp-delta-01
|
||||
- ex3-fp-full-01
|
||||
- **Integration Test** (There should be no significant differences between "ex3-integration-test-delta-01" and "delta")
|
||||
- ex3-integration-test-delta-01
|
||||
- ex3-integration-test-unharnessed-delta-01
|
||||
- delta
|
||||
- **libpng**
|
||||
- ex3-lp-delta-01
|
||||
- **libxml2**
|
||||
- ex3-lx-delta-01
|
||||
- ex3-lx-delta-02
|
||||
- **sqlite3**
|
||||
- ex3-sq-delta-01
|
||||
- ex3-sq-delta-02
|
||||
- ex3-sq-delta-03
|
||||
- ex3-sq-full-01
|
||||
- **Apache Tika**
|
||||
- ex3-tk-full-01
|
||||
- ex3-tk-delta-02
|
||||
- ex3-tk-delta-03
|
||||
- ex3-tk-delta-04
|
||||
- ex3-tk-delta-05
|
||||
- **Apache Zookeeper**
|
||||
- ex3-zk-delta-01
|
||||
- ex3-zk-delta-02
|
||||
- ex3-zk-full-01
|
||||
- **Curl**
|
||||
- ex3-cu-full-01
|
||||
- ex3-cu-delta-01
|
||||
- **libexif**
|
||||
- ex3-ex-delta-01
|
||||
- **libpostal**
|
||||
- ex3-libpostal-full-01
|
||||
- **s2n-tls**
|
||||
- ex3-s2n_tls-full-01
|
||||
- **IPF**
|
||||
- ex3-ipf-full-01
|
||||
|
||||
## CRS API Task Statuses
|
||||
|
||||
The CRS API has a status endpoint which provides a summary of tasks by status, among other things. The statuses which tasks go through are documented in the state diagram below.
|
||||
|
||||
@@ -864,8 +864,8 @@
|
||||
"definitions": {
|
||||
"types.Architecture": {
|
||||
"type": "string",
|
||||
"enum": ["x86_64"],
|
||||
"x-enum-varnames": ["ArchitectureX8664"]
|
||||
"enum": ["x86_64", "aarch64"],
|
||||
"x-enum-varnames": ["ArchitectureX8664", "ArchitectureAArch64"]
|
||||
},
|
||||
"types.Assessment": {
|
||||
"type": "string",
|
||||
|
||||
@@ -2,9 +2,11 @@ definitions:
|
||||
types.Architecture:
|
||||
enum:
|
||||
- x86_64
|
||||
- aarch64
|
||||
type: string
|
||||
x-enum-varnames:
|
||||
- ArchitectureX8664
|
||||
- ArchitectureAArch64
|
||||
types.Assessment:
|
||||
enum:
|
||||
- correct
|
||||
|
||||
@@ -13,3 +13,10 @@ See more at [Exhibition Round 1](./exhibition-round-1.md)
|
||||
9 Delta Challenges (6 C, 3 Java), 6 Full Scan Challenges (4 C, 2 Java).
|
||||
|
||||
See more at [Exhibition Round 2](./exhibition-round-2.md)
|
||||
|
||||
## Exhibition 3
|
||||
|
||||
19 Delta Challenges (10 C, 9 Java), 8 Full Scan Challenges (5 C, 3 Java),
|
||||
1 Unharnessed Delta Challenege (C), 2 Unharnessed Full Scan Challenges (1 C, 1 Java).
|
||||
|
||||
See more at [Exhibition Round 3](./exhibition-round-3.md)
|
||||
|
||||
@@ -0,0 +1,113 @@
|
||||
# Exhibition Round 3
|
||||
|
||||
19 Delta Challenges (10 C, 9 Java), 8 Full Scan Challenges (5 C, 3 Java), 1 Unharnessed Delta Challenege (C), 2 Unharnessed Full Scan Challenges (1 C, 1 Java).
|
||||
|
||||
## Repositories
|
||||
|
||||
The following repositories were used during the Round:
|
||||
|
||||
- Libxml2 (C)
|
||||
- Libpng (C)
|
||||
- AIxCC Integration Test (C)
|
||||
- FreeRDP (C)
|
||||
- Sqlite (C)
|
||||
- Dropbear (C)
|
||||
- Curl (C)
|
||||
- Libexif (C)
|
||||
- Libpostal (C)
|
||||
- s2n-tls
|
||||
- Tika (Java)
|
||||
- Zookeeper (Java)
|
||||
- Apache Commons Compress (Java)
|
||||
- IPF (Java)
|
||||
|
||||
## Challenge Tasks Archive
|
||||
|
||||
Download all challenge tasks that were sent during the Round: [exhibition3_challenge_tasks.tar.gz](./exhibition3_challenge_tasks.tar.gz). _See notes below_.
|
||||
|
||||
Note: Times included in tasks.json are descriptive of when the Competition API generated the task,
|
||||
and not the exact times of when the message was broadcast to each CRS (it should be close though!).
|
||||
|
||||
## Sequencing
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
subgraph A["Challenge Set #1 (12 hr)"]
|
||||
direction LR
|
||||
A0["freerdp: Full 1"]
|
||||
B0["sqlite: Full 1"]
|
||||
C0["dropbear: Full 1"]
|
||||
D0["libpostal: Full 1"]
|
||||
E0["curl: Full 1"]
|
||||
|
||||
end
|
||||
|
||||
subgraph B["Challenge Set #2 (12 hr)"]
|
||||
direction LR
|
||||
A1["commons-compress: Full 1"]
|
||||
B1["zookeeper: Full 1"]
|
||||
C1["tika: Full 1"]
|
||||
end
|
||||
|
||||
subgraph C["Challenge Set #3 (6 hr)"]
|
||||
direction LR
|
||||
A2["freerdp: Delta 1"]
|
||||
B2["integration-test: Delta 1"]
|
||||
C2["libpng: Delta 1"]
|
||||
F2["curl: Delta 1"]
|
||||
E2["libexif: Delta 1"]
|
||||
end
|
||||
|
||||
subgraph D["Challenge Set #4 (6 hr)"]
|
||||
direction LR
|
||||
A3["sqlite: Delta 1"]
|
||||
B3["sqlite: Delta 2"]
|
||||
C3["sqlite: Delta 3"]
|
||||
D3["libxml2: Delta 1"]
|
||||
E3["libxml2: Delta 2"]
|
||||
end
|
||||
|
||||
subgraph E["Challenge Set #5 (6 hr)"]
|
||||
direction LR
|
||||
A4["tika: Delta 1"]
|
||||
B4["tika: Delta 2"]
|
||||
C4["tika: Delta 3"]
|
||||
D4["tika: Delta 4"]
|
||||
E4["tika: Delta 5"]
|
||||
end
|
||||
|
||||
subgraph F["Challenge Set #6 (6 hr)"]
|
||||
direction LR
|
||||
A5["zookeeper: Delta 1"]
|
||||
B5["zookeeper: Delta 2"]
|
||||
C5["commons-compress: Delta 2"]
|
||||
D5["commons-compress: Delta 3"]
|
||||
end
|
||||
|
||||
subgraph G["Challenge Set #7 (12 hr)"]
|
||||
direction LR
|
||||
A6["ipf (Unharnessed): Full 1"]
|
||||
B6["s2n-tls (Unharnessed): Full 1"]
|
||||
end
|
||||
|
||||
subgraph H["Challenge Set #8 (6 hr)"]
|
||||
direction LR
|
||||
A7["integration-test (Unharnessed): Delta 1"]
|
||||
end
|
||||
|
||||
A --> B --> C --> D --> E --> F --> G --> H
|
||||
```
|
||||
|
||||
## Notes
|
||||
|
||||
\* There were three challenges that, as sent to competitors, would have prevented meaningful POV and Patch submissions. These challenges were a part of the Tika challenge repository.
|
||||
The challenges are:
|
||||
|
||||
- tk-delta-01 (task_id: `01974bc3-f9ed-73a2-9c76-bfe9d5311d3d`)
|
||||
- tk-delta-03 (task_id: `01974bd4-0df0-7d96-aad6-4e3db89d190d`)
|
||||
- tk-delta-05 (task_id: `01974bd4-10e9-784a-b6c7-2c5dc5151cf6`)
|
||||
|
||||
All of these challenges had diffs that would fail to apply.
|
||||
For tk-delta-03 and tk-delta-05, they would fail to apply because of binary contents within the diff.
|
||||
For tk-delta-01, the issue is related to inconsistent filenames in diff headers. We have fixed the root causes of the issues for these three challenges.
|
||||
These Competition API fixes are now available via the new request/challenges endpoint and competitor-test-api.
|
||||
@@ -1,11 +1,10 @@
|
||||
#!/bin/bash
|
||||
curl -X 'POST' 'http://127.0.0.1:31323/webhook/trigger_task' -H 'Content-Type: application/json' -d '{
|
||||
"challenge_repo_url": "git@github.com:tob-challenges/example-libpng.git",
|
||||
"challenge_repo_base_ref": "0cc367aaeaac3f888f255cee5d394968996f736e",
|
||||
"challenge_repo_head_ref": "fdacd5a1dcff42175117d674b0fda9f8a005ae88",
|
||||
"fuzz_tooling_url": "git@github.com:tob-challenges/oss-fuzz-aixcc.git",
|
||||
"fuzz_tooling_ref": "d5fbd68fca66e6fa4f05899170d24e572b01853d",
|
||||
"challenge_repo_url": "https://github.com/tob-challenges/example-libpng",
|
||||
"challenge_repo_base_ref": "5bf8da2d7953974e5dfbd778429c3affd461f51a",
|
||||
"challenge_repo_head_ref": "challenges/lp-delta-01",
|
||||
"fuzz_tooling_url": "https://github.com/google/oss-fuzz",
|
||||
"fuzz_tooling_ref": "master",
|
||||
"fuzz_tooling_project_name": "libpng",
|
||||
"harnesses_included": true,
|
||||
"duration": 7200
|
||||
"duration": 1800
|
||||
}'
|
||||
|
||||
Executable
+9
@@ -0,0 +1,9 @@
|
||||
#!/bin/bash
|
||||
curl -X 'POST' 'http://127.0.0.1:31323/webhook/trigger_task' -H 'Content-Type: application/json' -d '{
|
||||
"challenge_repo_url": "https://github.com/vstakhov/libucl",
|
||||
"challenge_repo_head_ref": "8a0294f9eaa4e70342e562cb92792bbe3df90e70",
|
||||
"fuzz_tooling_url": "https://github.com/google/oss-fuzz",
|
||||
"fuzz_tooling_ref": "master",
|
||||
"fuzz_tooling_project_name": "libucl",
|
||||
"duration": 1800
|
||||
}'
|
||||
@@ -22,7 +22,8 @@ PROJECT_DIR=$(dirname "$SCRIPT_DIR")
|
||||
|
||||
cd "$PROJECT_DIR" || exit 1
|
||||
|
||||
git clone git@github.com:tob-challenges/example-crs-architecture.git || true
|
||||
# Clone the repo, but ignore LFS files to avoid downloading large files
|
||||
GIT_LFS_SKIP_SMUDGE=1 git clone git@github.com:tob-challenges/example-crs-architecture.git || true
|
||||
git -C example-crs-architecture pull
|
||||
|
||||
cp -rv example-crs-architecture/docs/ "$OUTPUT_DIR/src/buttercup/orchestrator/docs/"
|
||||
|
||||
@@ -1 +1 @@
|
||||
7.14.0-SNAPSHOT
|
||||
7.14.0
|
||||
|
||||
+1
@@ -27,6 +27,7 @@ class TypesArchitecture(str, Enum):
|
||||
allowed enum values
|
||||
"""
|
||||
ArchitectureX8664 = 'x86_64'
|
||||
ArchitectureAArch64 = 'aarch64'
|
||||
|
||||
@classmethod
|
||||
def from_json(cls, json_str: str) -> Self:
|
||||
|
||||
@@ -9,6 +9,7 @@ from opentelemetry import trace
|
||||
from opentelemetry.trace import Status, StatusCode
|
||||
import buttercup.common.node_local as node_local
|
||||
from pathlib import Path
|
||||
from buttercup.common.constants import ARCHITECTURE
|
||||
from buttercup.common.queues import ReliableQueue, QueueFactory, QueueNames
|
||||
from buttercup.common.sets import PoVReproduceStatus
|
||||
from buttercup.common.datastructures.msg_pb2 import (
|
||||
@@ -269,7 +270,7 @@ class CompetitionAPI:
|
||||
|
||||
# Create submission payload from crash data
|
||||
submission = TypesPOVSubmission(
|
||||
architecture=TypesArchitecture.ArchitectureX8664,
|
||||
architecture=TypesArchitecture(ARCHITECTURE),
|
||||
engine=crash.crash.target.engine,
|
||||
fuzzer_name=crash.crash.harness_name,
|
||||
sanitizer=crash.crash.target.sanitizer,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
# generated by fastapi-codegen:
|
||||
# filename: /tmp/tmp.VWuWL8tFKl/openapi.json
|
||||
# timestamp: 2025-07-08T08:17:32+00:00
|
||||
# filename: /var/folders/ck/j9600dhj1t3f1901qw9vs2bh0000gn/T/tmp.YsQ74ZHmdF/openapi.json
|
||||
# timestamp: 2025-07-30T12:54:58+00:00
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# generated by fastapi-codegen:
|
||||
# filename: /tmp/tmp.VWuWL8tFKl/openapi.json
|
||||
# timestamp: 2025-07-08T08:17:32+00:00
|
||||
# filename: /var/folders/ck/j9600dhj1t3f1901qw9vs2bh0000gn/T/tmp.YsQ74ZHmdF/openapi.json
|
||||
# timestamp: 2025-07-30T12:54:58+00:00
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
@@ -12,6 +12,7 @@ from pydantic import BaseModel, Field, constr
|
||||
|
||||
class Architecture(Enum):
|
||||
ArchitectureX8664 = "x86_64"
|
||||
ArchitectureAArch64 = "aarch64"
|
||||
|
||||
|
||||
class Assessment(Enum):
|
||||
|
||||
Generated
+1
@@ -289,6 +289,7 @@ requires-dist = [
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.4" },
|
||||
{ name = "ruff", specifier = ">=0.9.2" },
|
||||
|
||||
Generated
+5
-1
@@ -244,9 +244,13 @@ requires-dist = [
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.4" },
|
||||
{ name = "ruff", specifier = ">=0.9.2" },
|
||||
{ name = "types-pyyaml" },
|
||||
{ name = "types-redis" },
|
||||
{ name = "types-requests" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1113,7 +1117,7 @@ requires-dist = [
|
||||
{ name = "flake8", marker = "extra == 'tests'", specifier = ">=7.1.1" },
|
||||
{ name = "langchain", specifier = "~=0.3.20" },
|
||||
{ name = "langchain-community", specifier = ">=0.3.16" },
|
||||
{ name = "langgraph", specifier = "==0.5.2" },
|
||||
{ name = "langgraph", specifier = "~=0.5.2" },
|
||||
{ name = "langgraph-checkpoint", specifier = ">=2.0.25" },
|
||||
{ name = "mypy", marker = "extra == 'tests'", specifier = ">=1.15.0" },
|
||||
{ name = "openai", specifier = ">=1.60.2" },
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ARG BASE_IMAGE=ubuntu:24.04@sha256:f8b860e4f9036f2694571770da292642eebcc4c2ea0c70a1a9244c2a1d436cd9
|
||||
ARG BASE_IMAGE=ubuntu:24.04
|
||||
|
||||
FROM $BASE_IMAGE AS base
|
||||
RUN apt-get update && apt-get install -y software-properties-common
|
||||
|
||||
Generated
+5
-1
@@ -343,9 +343,13 @@ requires-dist = [
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.4" },
|
||||
{ name = "ruff", specifier = ">=0.9.2" },
|
||||
{ name = "types-pyyaml" },
|
||||
{ name = "types-redis" },
|
||||
{ name = "types-requests" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -396,7 +400,7 @@ name = "exceptiongroup"
|
||||
version = "1.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.11'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0b/9f/a65090624ecf468cdca03533906e7c69ed7588582240cfe7cc9e770b50eb/exceptiongroup-1.3.0.tar.gz", hash = "sha256:b241f5885f560bc56a59ee63ca4c6a8bfa46ae4ad651af316d4e81817bb9fd88", size = 29749, upload-time = "2025-05-10T17:42:51.123Z" }
|
||||
wheels = [
|
||||
|
||||
+40
-25
@@ -44,6 +44,21 @@ check_not_root() {
|
||||
fi
|
||||
}
|
||||
|
||||
# Portable sed in-place editing function
|
||||
# Usage: portable_sed "pattern" "file"
|
||||
portable_sed() {
|
||||
local pattern="$1"
|
||||
local file="$2"
|
||||
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
# macOS requires empty string after -i
|
||||
sed -i '' "$pattern" "$file"
|
||||
else
|
||||
# Linux doesn't accept backup extension
|
||||
sed -i "$pattern" "$file"
|
||||
fi
|
||||
}
|
||||
|
||||
# Function to install Docker
|
||||
install_docker() {
|
||||
print_status "Installing Docker..."
|
||||
@@ -272,7 +287,7 @@ read_and_set_config() {
|
||||
|
||||
# Only update if value is not empty
|
||||
if [ -n "$value" ]; then
|
||||
sed -i "s|.*export $var_name=.*|export $var_name=\"$value\"|" deployment/env
|
||||
portable_sed "s|.*export $var_name=.*|export $var_name=\"$value\"|" deployment/env
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
@@ -286,11 +301,11 @@ configure_ghcr_optional() {
|
||||
|
||||
# Compute GHCR_AUTH
|
||||
ghcr_auth=$(echo -n "$ghcr_username:$ghcr_pat" | base64 --wrap=0)
|
||||
sed -i "s|.*export GHCR_AUTH=.*|export GHCR_AUTH=\"$ghcr_auth\"|" deployment/env
|
||||
portable_sed "s|.*export GHCR_AUTH=.*|export GHCR_AUTH=\"$ghcr_auth\"|" deployment/env
|
||||
return 0
|
||||
else
|
||||
# Clear GHCR_AUTH if skipped
|
||||
sed -i "s|.*export GHCR_AUTH=.*|export GHCR_AUTH=\"\"|" deployment/env
|
||||
portable_sed "s|.*export GHCR_AUTH=.*|export GHCR_AUTH=\"\"|" deployment/env
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -303,8 +318,8 @@ configure_docker_hub() {
|
||||
echo
|
||||
|
||||
# Set Docker credentials (handles both commented and uncommented lines)
|
||||
sed -i "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"$docker_username\"|" deployment/env
|
||||
sed -i "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"$docker_pat\"|" deployment/env
|
||||
portable_sed "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"$docker_username\"|" deployment/env
|
||||
portable_sed "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"$docker_pat\"|" deployment/env
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
@@ -365,11 +380,11 @@ configure_simple_api_key() {
|
||||
fi
|
||||
|
||||
if [ -n "$value" ]; then
|
||||
sed -i "s|.*export $var_name=.*|export $var_name=\"$value\"|" deployment/env
|
||||
portable_sed "s|.*export $var_name=.*|export $var_name=\"$value\"|" deployment/env
|
||||
return 0
|
||||
else
|
||||
# Clear the key if skipped (set to empty string)
|
||||
sed -i "s|.*export $var_name=.*|export $var_name=\"\"|" deployment/env
|
||||
portable_sed "s|.*export $var_name=.*|export $var_name=\"\"|" deployment/env
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -384,13 +399,13 @@ configure_docker_hub_optional() {
|
||||
echo
|
||||
|
||||
# Set Docker credentials
|
||||
sed -i "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"$docker_username\"|" deployment/env
|
||||
sed -i "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"$docker_pat\"|" deployment/env
|
||||
portable_sed "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"$docker_username\"|" deployment/env
|
||||
portable_sed "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"$docker_pat\"|" deployment/env
|
||||
return 0
|
||||
else
|
||||
# Clear Docker credentials if skipped
|
||||
sed -i "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"\"|" deployment/env
|
||||
sed -i "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"\"|" deployment/env
|
||||
portable_sed "s|.*export DOCKER_USERNAME=.*|export DOCKER_USERNAME=\"\"|" deployment/env
|
||||
portable_sed "s|.*export DOCKER_PAT=.*|export DOCKER_PAT=\"\"|" deployment/env
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -403,18 +418,18 @@ configure_otel_wrapper() {
|
||||
echo
|
||||
|
||||
# Update the env file
|
||||
sed -i "s|.*export OTEL_ENDPOINT=.*|export OTEL_ENDPOINT=\"$otel_endpoint\"|" deployment/env
|
||||
sed -i "s|.*export OTEL_PROTOCOL=.*|export OTEL_PROTOCOL=\"$otel_protocol\"|" deployment/env
|
||||
portable_sed "s|.*export OTEL_ENDPOINT=.*|export OTEL_ENDPOINT=\"$otel_endpoint\"|" deployment/env
|
||||
portable_sed "s|.*export OTEL_PROTOCOL=.*|export OTEL_PROTOCOL=\"$otel_protocol\"|" deployment/env
|
||||
|
||||
if [ -n "$otel_token" ]; then
|
||||
sed -i "s|.*export OTEL_TOKEN=.*|export OTEL_TOKEN=\"$otel_token\"|" deployment/env
|
||||
portable_sed "s|.*export OTEL_TOKEN=.*|export OTEL_TOKEN=\"$otel_token\"|" deployment/env
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
# Disable OTEL
|
||||
sed -i "s|.*export OTEL_ENDPOINT=.*|# export OTEL_ENDPOINT=\"\"|" deployment/env
|
||||
sed -i "s|.*export OTEL_PROTOCOL=.*|# export OTEL_PROTOCOL=\"http\"|" deployment/env
|
||||
sed -i "s|.*export OTEL_TOKEN=.*|# export OTEL_TOKEN=\"\"|" deployment/env
|
||||
portable_sed "s|.*export OTEL_ENDPOINT=.*|# export OTEL_ENDPOINT=\"\"|" deployment/env
|
||||
portable_sed "s|.*export OTEL_PROTOCOL=.*|# export OTEL_PROTOCOL=\"http\"|" deployment/env
|
||||
portable_sed "s|.*export OTEL_TOKEN=.*|# export OTEL_TOKEN=\"\"|" deployment/env
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -427,17 +442,17 @@ configure_langfuse_wrapper() {
|
||||
echo
|
||||
|
||||
# Update the env file
|
||||
sed -i "s|.*export LANGFUSE_ENABLED=.*|export LANGFUSE_ENABLED=true|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_HOST=.*|export LANGFUSE_HOST=\"$langfuse_host\"|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_PUBLIC_KEY=.*|export LANGFUSE_PUBLIC_KEY=\"$langfuse_public_key\"|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_SECRET_KEY=.*|export LANGFUSE_SECRET_KEY=\"$langfuse_secret_key\"|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_ENABLED=.*|export LANGFUSE_ENABLED=true|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_HOST=.*|export LANGFUSE_HOST=\"$langfuse_host\"|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_PUBLIC_KEY=.*|export LANGFUSE_PUBLIC_KEY=\"$langfuse_public_key\"|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_SECRET_KEY=.*|export LANGFUSE_SECRET_KEY=\"$langfuse_secret_key\"|" deployment/env
|
||||
return 0
|
||||
else
|
||||
# Disable and clear LangFuse configuration
|
||||
sed -i "s|.*export LANGFUSE_ENABLED=.*|export LANGFUSE_ENABLED=false|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_HOST=.*|export LANGFUSE_HOST=\"\"|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_PUBLIC_KEY=.*|export LANGFUSE_PUBLIC_KEY=\"\"|" deployment/env
|
||||
sed -i "s|.*export LANGFUSE_SECRET_KEY=.*|export LANGFUSE_SECRET_KEY=\"\"|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_ENABLED=.*|export LANGFUSE_ENABLED=false|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_HOST=.*|export LANGFUSE_HOST=\"\"|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_PUBLIC_KEY=.*|export LANGFUSE_PUBLIC_KEY=\"\"|" deployment/env
|
||||
portable_sed "s|.*export LANGFUSE_SECRET_KEY=.*|export LANGFUSE_SECRET_KEY=\"\"|" deployment/env
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ verify_setup() {
|
||||
print_success "Setup verification completed successfully!"
|
||||
print_status "Next steps:"
|
||||
echo " 1. Run: make deploy-local"
|
||||
echo " 2. Test with: make send-integration-task"
|
||||
echo " 2. Test with: make send-libpng-task"
|
||||
else
|
||||
print_error "Setup verification failed. Run 'make validate' for details."
|
||||
exit 1
|
||||
|
||||
Generated
+1
@@ -244,6 +244,7 @@ requires-dist = [
|
||||
|
||||
[package.metadata.requires-dev]
|
||||
dev = [
|
||||
{ name = "dirty-equals", specifier = ">=0.9.0" },
|
||||
{ name = "mypy", specifier = ">=1.15.0" },
|
||||
{ name = "pytest", specifier = ">=8.3.4" },
|
||||
{ name = "ruff", specifier = ">=0.9.2" },
|
||||
|
||||
Reference in New Issue
Block a user