mirror of
https://github.com/norandom/OpenUltraSAST.git
synced 2026-10-19 13:10:03 +00:00
plane(2.2): runner -- delivery {put, inputs} in the start body, PUT to the store
StartGate.offer validates an optional `delivery` beside the credentials: https URLs to a hostname (never an address, no userinfo; AX_RUNNER_INSECURE_DELIVERY=1 admits http in unit tests only), names ^[A-Z][A-Z0-9_]*$, a 400 that names the field and echoes no URL. The runner PUTs its output tar to delivery.put and GETs each declared input from delivery.inputs[NAME] (deliver() gains a method; log lines and DeliveryError carry the URL without its query, so no presigned signature reaches a log, a marker or a summary). OUSAST_ARTIFACT_URL/DIAL stay honoured until task 2.6 so both paths run in the same build; the completion marker and the retry-only boot are unchanged, and a re-start brings a fresh URL for the retry. Router.start_task carries `delivery` in the body and redacts its URLs like credential values. Tests: the gate's acceptance and refusals, an end-to-end PUT/GET against the S3-shaped fake with no URL in any log or file, the failed-PUT-then-retry-only boot, deliver() with PUT. Gates: pytest 2024 passed, 42 skipped, exit 0; ruff check 0; ruff format 0; mypy 0. Co-Authored-By: Claude Fable 5.1 <[email protected]> Claude-Session: https://claude.ai/code/session_01EmM1j46qgKMh3zqD1QMwEo
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
35d8032c0a
commit
9506a18b56
@@ -28,6 +28,7 @@ import time
|
||||
import urllib.error
|
||||
import urllib.request
|
||||
from collections.abc import Callable, Iterable, Iterator, Mapping
|
||||
from typing import Any
|
||||
|
||||
from .manifests import Model
|
||||
|
||||
@@ -77,7 +78,9 @@ class Router:
|
||||
def __init__(self, url: str) -> None:
|
||||
self.url = url.rstrip("/")
|
||||
|
||||
def starter(self, atespace: str, task: str, run: str, credentials: Mapping[str, str]) -> Callable[[], str | None]:
|
||||
def starter(
|
||||
self, atespace: str, task: str, run: str, credentials: Mapping[str, str], delivery: Mapping[str, Any] | None = None
|
||||
) -> Callable[[], str | None]:
|
||||
""":meth:`start_task` bound to one task, returning the refusal text instead of raising (None once accepted).
|
||||
|
||||
The reconciler calls it again after a re-resume, since a resumed actor may have rebooted and wait for a
|
||||
@@ -90,20 +93,30 @@ class Router:
|
||||
nonlocal calls
|
||||
calls += 1
|
||||
try:
|
||||
self.start_task(atespace, task, run, credentials)
|
||||
self.start_task(atespace, task, run, credentials, delivery)
|
||||
except StartError as exc:
|
||||
return None if calls > 1 and ALREADY_STARTED in str(exc) else str(exc)
|
||||
return None
|
||||
|
||||
return start
|
||||
|
||||
def start_task(self, atespace: str, task: str, run: str, credentials: Mapping[str, str]) -> None:
|
||||
"""Start ``<atespace>/<task>``'s command once; :class:`StartError` on 409, another 4xx, or the timeout."""
|
||||
body = json.dumps({"run": run, "task": task, "credentials": dict(credentials)}).encode("utf-8")
|
||||
def start_task(
|
||||
self, atespace: str, task: str, run: str, credentials: Mapping[str, str], delivery: Mapping[str, Any] | None = None
|
||||
) -> None:
|
||||
"""Start ``<atespace>/<task>``'s command once; :class:`StartError` on 409, another 4xx, or the timeout.
|
||||
``delivery`` (``{put, inputs}`` presigned URLs, ``delivery.py``) rides in the body like the credentials and is
|
||||
redacted like them."""
|
||||
payload: dict[str, Any] = {"run": run, "task": task, "credentials": dict(credentials)}
|
||||
if delivery:
|
||||
payload["delivery"] = dict(delivery)
|
||||
body = json.dumps(payload).encode("utf-8")
|
||||
headers = {"Content-Type": "application/json", TARGET_HEADER: f"{atespace}/{task}"}
|
||||
limit = float(os.environ.get("OUSAST_START_TIMEOUT") or 300)
|
||||
deadline, backoff, last = time.monotonic() + limit, 0.5, "no attempt made"
|
||||
secrets = list(credentials.values())
|
||||
if delivery:
|
||||
secrets.append(str(delivery.get("put") or ""))
|
||||
secrets.extend(str(u) for u in (delivery.get("inputs") or {}).values())
|
||||
while True:
|
||||
request = urllib.request.Request(self.url + START_PATH, data=body, method="POST", headers=headers)
|
||||
try:
|
||||
|
||||
Reference in New Issue
Block a user