Repository navigation
Conversation
…sigs#1549) * examples/agent-sandbox-rl: create the namespace in setup * examples/agent-sandbox-rl: use the same namespace throughout * examples/agent-sandbox-rl: reword the namespace step, update reaper docstring * examples/agent-sandbox-rl: update remaining namespace references
…ubernetes-sigs#1589) olm/Makefile pinned an older version of golangci-lint (v2.1.0) and used its own go install flow, causing presubmit-agent-sandbox-lint-olm to fail under recent CI Go toolchain updates. Point olm/Makefile's GOLANGCI_LINT to repo-wide dev/tools/go.mod via go tool so linting uses a single source of truth across the repository. In addition, regenerate packages/sandboxd/spec/process/v1/process.pb.go to drop redundant blank comment lines formatted away by newer go/format, resolving presubmit-test-autogen-up-to-date failures.
Add an Ed25519 scoped-token format that signs the key ID and canonical sandbox target fields. Multiple verification keys allow overlap while legacy HMAC readers require an exclusive cutoff when both formats run. Normalize the target after routing so authorization binds the Sandbox UID, port, method, and exact upstream escaped path. Keep v1-only configuration compatible and require cache mode when v2 is enabled. Same-name replacement fencing remains separate because cache resolution must first return and enforce its canonical Sandbox UID.
…netes-sigs#1488) (kubernetes-sigs#1503) * feat(rl): OpenHands fleet adapter — workspaces on fleet-acquired pods adapters/openhands.py inverts pod ownership for AgentSandboxWorkspace the same way adapters/r2egym.py does for R2E-Gym: FleetWorkspaceClient is a duck-typed sandbox_client whose create_sandbox() is fleet.acquire(task) and whose handle view's terminate() is fleet.release(handle) — the workspace never deletes, the fleet owns pools/placement/TTLs. Fleet-owned kwargs (warmpool, ttl_s, sandbox_client) are rejected at the seam. Module-level imports stay OpenHands-free (lazy import with a clear hint), matching the r2egym adapter's optional-dependency pattern; 8 tests run against fakes plus a sys.modules stub of the integration. * feat: advisory server-version skew check on attach After RemoteWorkspace init, compare the agent-server's /server_info version with the installed openhands-sdk and warn loudly on mismatch (the SDK and server image are released together; skew means protocol drift). Advisory only — never fails the attach; check_server_version field disables it for offline tests. Closes the remaining item from the seam spec. * feat(rl): handle-bound OpenHands workspaces + fleet fan-out example make_handle_workspace(handle) is the fleet.run-native form of the adapter: fleet.run acquires the handle before process_fn(task, handle) and releases it after, so the workspace binds without acquiring and its terminate() is a no-op on the pod (BoundHandleClient). namespace defaults from the handle's cluster for router-mode headers; fleet-owned kwargs still raise. The view-building is shared with FleetWorkspaceClient (_handle_view). examples/run_openhands_fleet.py is the OpenHands twin of run_swebench_fleet.py: one warm pool of agent-server pods (TemplateSpec keepalive_command restates the image entrypoint since it renders as the container command; extra_pod_spec merges the load-bearing /health readinessProbe and the pool session key), N concurrent conversations via fleet.run, and a no-LLM smoke mode so the fan-out is testable with cluster access alone. * fix: address self-review — pool depth follows concurrency, realistic probe budget, helper ordering max_warmpool_size (default 8) would silently cap the example's pool below MAX_CONCURRENT and throttle claims — size it to the concurrency with an env override. Probe budget raised to 5 min (agent-server cold boots were measured at ~4 min on runc; pool-fill time, off the claim path). Move _handle_view above its first user. * docs(rl): document the OpenHands adapter across README, architecture, and rl_integration * fix: address kubernetes-sigs#1503 review round 1 - example: LLM_API_KEY without openhands-tools now warns once and falls back to smoke mode instead of failing every rollout identically - workspace cleanup: keep the claim reference until termination succeeds so later cleanup() calls can retry (a no-ttl claim would otherwise leak warm-pool capacity); owned client stays open while retry is possible; regression test added (fail once -> retry succeeds -> idempotent) - template: gvisor commented out with guidance (repo precedent: template must admit on clusters without the RuntimeClass; strongly recommended note kept) and resource limits added (cpu/memory/ephemeral-storage) — limits are part of the documented isolation posture - pyproject: floor raised to openhands-sdk>=1.44.1 (the release the template pins); exact pin rejected deliberately — it would block every SDK patch release, and the attach-time version-skew check flags drift * docs: address kubernetes-sigs#1503 review round 2 — conversation guard in snippet, Python 3.12 floor noted The rl_integration.md rollout snippet closed the conversation in a flat finally, so a Conversation(...) constructor failure would raise UnboundLocalError and mask the original error — restructured to nested try/finally, matching the runnable example (which never had the bug). Python >= 3.12 (the openhands-sdk floor) is now called out at all three places that say pip install openhands-k8s-agent-sandbox. * fix: address kubernetes-sigs#1503 review round 3 — narrow version-check errors, honest detach log, pool-cap override notice - workspace._log_version_skew: only transport/HTTP errors (httpx.HTTPError), a non-JSON body, or a missing openhands-sdk distribution are swallowed at debug level; a non-dict /server_info payload and any unexpected exception now log at WARNING (the latter with traceback) instead of silently disabling the advisory on every attach. The check still never fails the attach. httpx is declared as a direct dependency since it is now imported. - Injected sandbox views may set releases_on_terminate=False; cleanup then logs "Detached from sandbox ..." instead of "Released sandbox claim ...". BoundHandleClient (handle-bound mode, fleet.run) sets it, so the workspace no longer claims a release the fleet performs later. - run_openhands_fleet: when MAX_WARMPOOL_SIZE is below MAX_CONCURRENT the raise is logged (WARNING if set explicitly, INFO for the default) with the resulting replica count, instead of happening silently. - Tests: expected-quiet failures parametrized (transport, not-json), missing SDK dist quiet, non-dict payload warns, check bug is loud but not fatal, release vs detach log lines, adapter views carry the flag. * fix: address kubernetes-sigs#1503 review round 4 — always derive host from the claimed sandbox; drop redundant test import - workspace: a caller-supplied host no longer survives the claim (it would have sent commands and the pool session key to an unrelated server while the claimed pod sat idle). host is always set from _endpoint_url(sandbox); a supplied value is logged as ignored, with a pointer to router_url / endpoint_template for gateway paths. Regression test with host set. - tests: drop the redundant in-test import of logging (module-level import already present).
…ernetes-sigs#1556) * rl-sdk: allow adopting warm pools provisioned by the fleet layer * addressed comments * addressed more cr comments
…olicy (kubernetes-sigs#1539) * fix(router): add app: sandbox-router label to router deployment Add the app: sandbox-router label to the Go sandbox-router deployment metadata and pod template. This allows the controller's default NetworkPolicy (which permits ingress from pods labeled app: sandbox-router in the agent-sandbox-system namespace) to accept traffic from the Go sandbox-router. * olm: regenerate bundle * spec: regenerate process protobuf definitions
…l shaping flags (kubernetes-sigs#1593) * docs: document high-throughput tuning, connection sharding, and refill shaping flags Under high sustained claim rates (e.g. 10-20+ claims/sec) or large warm pools (>1,000 replicas), default controller deployments can experience API server write spikes and warm pool replenishment stalls caused by HTTP/2 stream saturation and watch frame queueing behind write bursts (the expectations gate fallback). Document the recently added flags in docs/configuration.md and site/content/docs/performance-assessment/_index.md: - API transport settings (--separate-watch-connection, --api-connections) - Warm pool replenishment shaping (--sandbox-warm-pool-max-refill-rate, --sandbox-warm-pool-replenish-delay) - API write optimizations (--disable-claim-events, --disable-claim-observability-annotations, --cache-label-selectors, --sandbox-write-behind-window) Include a dedicated High-Throughput & Scale Tuning guide and sample Deployment manifest with recommended flag combinations. * docs: address review comments on Deployment manifest, warm pool workers, and burst flag - Make high-throughput Deployment manifest valid by adding spec.selector, matching pod template labels, serviceAccountName, and image. - Clarify that warm-pool workers provide concurrency across distinct pools rather than within a single pool due to workqueue key serialization. - Remove ineffective kube-api-burst from high-throughput args and explain that burst only applies when kube-api-qps is set to a positive value. - Add adoption caveat for --cache-label-selectors in performance assessment table. * docs: clarify required tracking label value for pre-provisioned adoption
…tes-sigs#1463) * ci(helm): require a chart version bump for generated content Fails presubmit when the generated chart content changes without an increase to the helm/Chart.yaml version. Co-authored-by: pandaji <a0094028@u.nus.edu> * test(helm): disable commit signing in scratch git repos The chart version tests make real commits, which inherited a global commit.gpgsign=true and failed for every test. Also pin the CI env vars inside patch.dict rather than popping them after start. * ci(helm): address review comments * ci(helm): fall back to local base branch tip * ci(helm): scope the chart version check to its own workflow * ci(helm): drop GHA workflow, quoted versions, PULL_BASE_SHA * ci(helm): Clear PULL_BASE_SHA in chart-version tests * ci(helm): fix PULL_BASE_SHA handling per review, add tests --------- Co-authored-by: pandaji <a0094028@u.nus.edu>
…s-sigs#1574) * fix(python-sdk): keep the connection open on 4xx responses The connector caught every RequestException, including a 404, and reset the resolved Pod IP and closed the port-forward tunnel. A 4xx is a successful round trip, so a normal missing-file read tore the tunnel down and forced the next call to rebuild it. Only reset the Pod IP and close the connection for genuine transport failures (no response, or a 5xx). SandboxRequestError is still raised with status_code so callers can branch on it. Add tests asserting a 404 keeps the connection and a transport failure still closes it. Signed-off-by: Vincent <0426vincent@gmail.com> * fix(python-sdk): also keep the connection open on 5xx responses Tear down cached routing state only when there is no response (a transport failure). Any HTTP response, 4xx or 5xx, means the sandbox or router answered and the connection is still usable, matching the Go SDK and the async connector. Signed-off-by: Vincent <0426vincent@gmail.com> * fix(python-sdk): clear pod IP on 5xx, keep it on 4xx * test(python-sdk): stub retry backoff in 5xx cache test * fix(python-sdk): preserve 5xx status when retries are exhausted * fix(python-sdk): invalidate in-cluster pod IP cache on 5xx --------- Signed-off-by: Vincent <0426vincent@gmail.com>
…bernetes-sigs#1576) * feat: implement PodIP dialing * feat: implement incluster service name dialing * doc(go-sdk): add inClusterStrategy.Connect docstring * fix(go-sdk): clear serviceFQDN * fix(go-sdk): tracing label and comment typo * fix: address comments * fix: regenerate make all * docs(go-sdk): revert docstring deletion * Revert "docs(go-sdk): revert docstring deletion" This reverts commit 95a34ef. * doc(go-sdk): TTL caveat and specify in-cluster requirements --------- Co-authored-by: Kai <nankeen@users.noreply.github.com>
…1339) * feat(mcp): add /healthz and /readyz probe endpoints The server ships a Dockerfile that serves streamable HTTP on 0.0.0.0:8000, so it is deployed as a long-running network service, but it exposed no probe endpoints. A Deployment therefore had no way to tell a wedged replica from a healthy one, or to keep traffic away from one that cannot reach the Kubernetes API. Add the two-endpoint split sandbox-router already uses (sandbox-router/server/server.go): - /healthz -- liveness. Returns 200 as soon as the ASGI app routes the request, and never contacts the Kubernetes API. Wiring liveness to an external dependency would turn a transient control-plane blip into a rolling restart of every replica, which is worse than briefly serving no traffic. A test asserts it makes no Kubernetes call. - /readyz -- readiness. Lists SandboxClaims in a configurable probe_namespace, which exercises everything a tool call needs: credential loading, client construction and one real apiserver request. Returns 503 while starting and when the API is unreachable, with a generic reason so the underlying exception is not exposed to an unauthenticated caller. Two implementation notes. The readiness check deliberately calls the public list_sandbox_claims rather than the private _ensure_initialized: the latter only loads credentials without reaching the apiserver, and nothing else in the repo depends on SDK internals. And the lifespan's yielded mapping reaches tools through ctx.lifespan_context but is not published on the ASGI app, so the client is stashed on the FastMCP server object, which routes reach as request.app.state.fastmcp_server. httpx is now declared in the test extra. The probe tests drive the ASGI app with it, and it was only available transitively through fastmcp. * docs(mcp): document the /readyz response body accurately The README said /readyz returns 503 with {"ready": false}, but the handler also returns a "reason" field. Document the real shape, including both reason values, and note that the reason is generic on purpose because the endpoint is unauthenticated. Also assert the full body in the failure test rather than just the "ready" key, so the documented contract cannot drift again silently -- it already had.
…ubernetes-sigs#1587) * docs: clarify restartPolicy interaction with claim lifecycle cleanup When restartPolicy is omitted, Kubernetes defaults to Always, which prevents TTL-based cleanup from ever firing because the container restarts indefinitely and the sandbox never reaches a terminal state. Add a "Restart Policy and Cleanup Interaction" section to the lifecycle docs explaining the restartPolicy x TTL/shutdownTime matrix and the two failure modes (zombie sandboxes, unbounded CrashLoopBackOff). Set explicit restartPolicy on 13 critical examples where the implicit Always default could cause resource leaks: - Never for one-shot kata demos (kata-gke, kata-aks) - OnFailure for interactive/gateway workloads (warmpool-quickstart, hermes, aider, gemini-cu, sandboxd, latebind-storage, kata-aks template) Signed-off-by: vvoronko <vvoronko@redhat.com> * docs: fix ttlSecondsAfterFinished casing in lifecycle page Use lower camelCase to match the actual API field name. Signed-off-by: vvoronko <vvoronko@redhat.com> * docs: fix inaccurate API field references in lifecycle page Review caught two issues: maxLifetimeSeconds does not exist in the current API (planned for kubernetes-sigs#1420), and ttlSecondsAfterFinished was not attributed to its actual location in the extensions API. Signed-off-by: vvoronko <vvoronko@redhat.com> --------- Signed-off-by: vvoronko <vvoronko@redhat.com>
…orphan leaks (kubernetes-sigs#1379) exec.CommandContext only sends SIGKILL to the child PID on context cancellation, not its process group. Since Start/Execute use Setpgid: true, grandchildren survive as orphans when the parent is killed (e.g. client disconnect). Fix: Replace exec.CommandContext with exec.Command, add killProcessGroupOnContextDone helper that signals -PGID (whole process group) on context cancellation. Also check context before forking to avoid starting commands we'd immediately kill. Layered kill strategy works across container runtimes: 1. syscall.Kill(-PGID, SIGKILL) — whole group, one syscall 2. /proc/<pid>/task/<tid>/children scan — gVisor fallback that iterates all threads (multithreaded parents fork from any TID) 3. Direct PID kill — last resort WaitDelay bounds cmd.Wait on I/O drain after the child exits, so a grandchild holding stdout/stderr write ends cannot block the RPC indefinitely. Non-blocking done check in killProcessGroupOnContextDone narrows the PID-reuse race window between Wait reaping and done closing. Release note: ```release-note Fixed orphan process leak in sandboxd when clients disconnect from long-running commands with grandchildren. ```
…ubernetes-sigs#1359) Adds docs/performance-tuning.md with the benchmark evidence and sizing rationale behind the high-throughput flag recommendations: worker-count and flag A/B results from GKE live testing, kops warm-adoption latency data, write-behind trade-offs, and burst-vs-sustained profile guidance including the replenish-delay pool-drain fragility finding. docs/configuration.md (kubernetes-sigs#1593) remains the canonical flag reference; this guide cross-links it instead of duplicating flag documentation, and the two docs now agree on sizing rules (refill rate >= per-pool arrival rate, warm-pool workers sized to pool count, batch size default under the expectations gate). Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
…repo rename (kubernetes-sigs#1620) * examples/envd-sandbox: repin envd after upstream repo rename broke e2e The e2b-dev/infra repository was renamed to e2b-dev/runtime and its history restructured (Sep 2026). The commit previously pinned in ENVD_VERSION is no longer reachable from any branch or tag, so the 'git checkout' in the image build fails with 'fatal: unable to read tree', which breaks the required presubmit-agent-sandbox-test-e2e job for every PR (the e2e harness builds all example images during setup). Repin to the upstream release tag envd-v0.6.13 (commit 2acf2d51bd1e) — a tag survives upstream rebases, unlike a bare SHA — and point the clone URL and doc links at the renamed repository. Verified: fresh clone + checkout of envd-v0.6.13 succeeds, and envd compiles at that tag with the Dockerfile's exact build flags. * examples/envd-sandbox: verify the pinned tag resolves to the expected commit Address review: a tag is mutable, so checking it out alone cannot prove future builds compile the documented source. Keep the tag as the pin (it survives upstream rebases, which is what broke the bare-SHA pin) and fail the build loudly if it ever resolves to a different commit. --------- Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
…up (kubernetes-sigs#1623) When setting up the test cluster, dev/ci/presubmits/test-e2e previously invoked push-images without specifying --images, defaulting to building and loading all Dockerfiles across the repository (including all 21 example images). This caused presubmit failures when unrelated example images encountered build or upstream network issues (such as git tree checkout errors during example Dockerfile builds). Scope E2ETestRunner.setup_cluster to only build and push the images actually required by the E2E suites: - agent-sandbox-controller - sandbox-router - sandboxd - python-runtime-sandbox - chrome-sandbox
…ubernetes-sigs#1516) Bumps the pip group with 1 update in the /examples/mcp-server-sandbox directory: [mcp](https://github.com/modelcontextprotocol/python-sdk). Bumps the pip group with 2 updates in the /examples/gemini-cu-sandbox directory: [idna](https://github.com/kjd/idna) and [python-multipart](https://github.com/Kludex/python-multipart). Bumps the pip group with 4 updates in the /examples/analytics-tool/analytics-tool directory: [idna](https://github.com/kjd/idna), [python-multipart](https://github.com/Kludex/python-multipart), [fonttools](https://github.com/fonttools/fonttools) and [pillow](https://github.com/python-pillow/Pillow). Bumps the pip group with 2 updates in the /clients/python/agentic-sandbox-client/sandbox-router directory: [idna](https://github.com/kjd/idna) and [starlette](https://github.com/Kludex/starlette). Updates `mcp` from 1.27.2 to 1.28.1 - [Release notes](https://github.com/modelcontextprotocol/python-sdk/releases) - [Changelog](https://github.com/modelcontextprotocol/python-sdk/blob/main/RELEASE.md) - [Commits](modelcontextprotocol/python-sdk@v1.27.2...v1.28.1) Updates `idna` from 3.10 to 3.15 - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md) - [Commits](kjd/idna@v3.10...v3.15) Updates `python-multipart` from 0.0.20 to 0.0.31 - [Release notes](https://github.com/Kludex/python-multipart/releases) - [Changelog](https://github.com/Kludex/python-multipart/blob/main/CHANGELOG.md) - [Commits](Kludex/python-multipart@0.0.20...0.0.31) Updates `idna` from 3.10 to 3.15 - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md) - [Commits](kjd/idna@v3.10...v3.15) Updates `python-multipart` from 0.0.20 to 0.0.31 - [Release notes](https://github.com/Kludex/python-multipart/releases) - [Changelog](https://github.com/Kludex/python-multipart/blob/main/CHANGELOG.md) - [Commits](Kludex/python-multipart@0.0.20...0.0.31) Updates `fonttools` from 4.60.1 to 4.60.2 - [Release notes](https://github.com/fonttools/fonttools/releases) - [Changelog](https://github.com/fonttools/fonttools/blob/main/NEWS.rst) - [Commits](fonttools/fonttools@4.60.1...4.60.2) Updates `pillow` from 12.0.0 to 12.3.0 - [Release notes](https://github.com/python-pillow/Pillow/releases) - [Changelog](https://github.com/python-pillow/Pillow/blob/main/CHANGES.rst) - [Commits](python-pillow/Pillow@12.0.0...12.3.0) Updates `idna` from 3.13 to 3.15 - [Release notes](https://github.com/kjd/idna/releases) - [Changelog](https://github.com/kjd/idna/blob/master/HISTORY.md) - [Commits](kjd/idna@v3.10...v3.15) Updates `starlette` from 1.1.0 to 1.3.1 - [Release notes](https://github.com/Kludex/starlette/releases) - [Changelog](https://github.com/Kludex/starlette/blob/main/docs/release-notes.md) - [Commits](Kludex/starlette@1.1.0...1.3.1) --- updated-dependencies: - dependency-name: mcp dependency-version: 1.28.1 dependency-type: direct:production dependency-group: pip - dependency-name: idna dependency-version: '3.15' dependency-type: indirect dependency-group: pip - dependency-name: python-multipart dependency-version: 0.0.31 dependency-type: direct:production dependency-group: pip - dependency-name: idna dependency-version: '3.15' dependency-type: indirect dependency-group: pip - dependency-name: python-multipart dependency-version: 0.0.31 dependency-type: direct:production dependency-group: pip - dependency-name: fonttools dependency-version: 4.60.2 dependency-type: indirect dependency-group: pip - dependency-name: pillow dependency-version: 12.3.0 dependency-type: indirect dependency-group: pip - dependency-name: idna dependency-version: '3.15' dependency-type: indirect dependency-group: pip - dependency-name: starlette dependency-version: 1.3.1 dependency-type: indirect dependency-group: pip ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…netes-sigs#1590) Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.83.1 to 1.83.2. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](grpc/grpc-go@v1.83.1...v1.83.2) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-version: 1.83.2 dependency-type: direct:production ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…dates (kubernetes-sigs#1591) Bumps the npm_and_yarn group with 1 update in the /test/e2e/clients/typescript directory: [postcss](https://github.com/postcss/postcss). Updates `@vitest/mocker` from 4.1.8 to 5.0.0 - [Release notes](https://github.com/vitest-dev/vitest/releases) - [Changelog](https://github.com/vitest-dev/vitest/blob/main/docs/releases.md) - [Commits](https://github.com/vitest-dev/vitest/commits/v5.0.0/packages/mocker) Updates `postcss` from 8.5.15 to 8.5.28 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.15...8.5.28) --- updated-dependencies: - dependency-name: "@vitest/mocker" dependency-version: 5.0.0 dependency-type: indirect dependency-group: npm_and_yarn - dependency-name: postcss dependency-version: 8.5.28 dependency-type: indirect dependency-group: npm_and_yarn ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…3 updates (kubernetes-sigs#1578) Bumps the npm-dependencies group with 3 updates in the /site directory: [autoprefixer](https://github.com/postcss/autoprefixer), [postcss](https://github.com/postcss/postcss) and [postcss-cli](https://github.com/postcss/postcss-cli). Updates `autoprefixer` from 10.5.4 to 10.5.5 - [Release notes](https://github.com/postcss/autoprefixer/releases) - [Changelog](https://github.com/postcss/autoprefixer/blob/main/CHANGELOG.md) - [Commits](postcss/autoprefixer@10.5.4...10.5.5) Updates `postcss` from 8.5.26 to 8.5.28 - [Release notes](https://github.com/postcss/postcss/releases) - [Changelog](https://github.com/postcss/postcss/blob/main/CHANGELOG.md) - [Commits](postcss/postcss@8.5.26...8.5.28) Updates `postcss-cli` from 11.0.1 to 12.0.0 - [Release notes](https://github.com/postcss/postcss-cli/releases) - [Changelog](https://github.com/postcss/postcss-cli/blob/master/CHANGELOG.md) - [Commits](postcss/postcss-cli@11.0.1...12.0.0) --- updated-dependencies: - dependency-name: autoprefixer dependency-version: 10.5.5 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: postcss dependency-version: 8.5.28 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: npm-dependencies - dependency-name: postcss-cli dependency-version: 12.0.0 dependency-type: direct:production update-type: version-update:semver-major dependency-group: npm-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…broken runs as infra (kubernetes-sigs#1626) * fix(flake-report): stop counting aborted, clone-failed, and pre-test-broken runs as infra The infra heuristic in analyze_tab counted every red Overall column with no failing junit testcase as an infrastructure failure. Three benign run shapes match that exact TestGrid signature: - aborted runs (a newer push to the PR supersedes the running job), - stale-PR clone failures (the PR no longer merges onto main), and - PRs that break a pre-test gate (compile/vet/mypy) while junit stays clean. On presubmit-test-unit this inflated "infra failures" to 49 red runs — 35 aborted + 7 clone conflicts + 7 PR-caused pre-test failures, zero real infra — and filed a false-alarm infra tracker; the kwok scalability lane tracker was mostly clone conflicts for the same reason. Resolve each red column against the run's GCS artifacts (fetched over HTTPS, only for red columns): finished.json identifies ABORTED runs, and clone-records.json identifies failed clones (falling back to the missing "revision" field in finished.json). Junit-present-but-nothing-failed columns are reported as pre-test PR breakage in a new report section; only "pod started, no junit, not aborted or clone-failed" remains infra. Aborted runs are also excluded from per-test flake tallies and the consistent-failure check, closing the known limitation where junit errors from cancelled runs counted as flakes. The --json payload keeps the existing flaky/consistent/infra keys and adds aborted_runs, clone_failures, and pretest_failures per tab. * flake-report: verify merge conflicts before blaming stale PRs; drop aborted cells everywhere Address review: clone-records.json sets failed=true for network and ref-fetch errors too, so only records whose git output shows a merge conflict may be reported as stale-PR failures — everything else stays in the infra count, as does a junit-less red run with no clone-records at all. Aborted columns are now also excluded from pass and flaky cells, so an aborted rerun can no longer manufacture a retest flip or a flake finding. * flake-report: take the last column-ID segment and treat flaky cells as test failures Address review: extract the build ID as the last U+E000-separated segment so a name-prefixed column ID cannot misdirect artifact fetches (live dashboards emit the leading-separator form; verified), and count FLAKY_STATUS cells as failing testcases when classifying red runs so a run whose only failure flaked-then-passed is a test story rather than pre-test PR breakage. --------- Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
…Go (kubernetes-sigs#1586) The sandboxed-tools example hardcoded a small ad-hoc tool surface (run_command/ls/read/write) and its system prompt, so trying a different agent profile meant editing the agent loop. This makes the tools and prompt pluggable and adds a second profile that reproduces gemini-cli. A toolset (pkg/toolsets) bundles a system prompt, the LLM-callable tools, and the sandbox image they expect, selected with the new -toolset flag. The existing tools become the 'basic' toolset. The new 'geminicli' toolset (pkg/toolsets/geminicli) reproduces the tool surface and system prompt of gemini-cli (Apache-2.0): same tool names, parameter schemas, descriptions, and result formats (list_directory, read_file, write_file, replace, glob, grep_search, read_many_files, run_shell_command), so model behavior tuned for gemini-cli transfers directly. The tools are reimplemented in Go: the filesystem tools are compiled into a geminicli-toolbox binary that runs inside the sandbox (JSON args on stdin, result on stdout). images/geminicli-toolbox provides the sandbox image (debian-slim + bash/git + the toolbox binary). Gaps relative to gemini-cli's full tool manifest (web_fetch, google_web_search, write_todos, ask_user, plan mode, skills, memory, and per-tool parity items) are documented as TODOs in pkg/toolsets/geminicli so the missing functionality is inventoried even where we may choose not to implement it.
…ith 13 updates (kubernetes-sigs#1627) Bumps the gomod-dependencies group with 6 updates in the / directory: | Package | From | To | | --- | --- | --- | | [github.com/prometheus/client_model](https://github.com/prometheus/client_model) | `0.6.2` | `0.6.3` | | [github.com/prometheus/common](https://github.com/prometheus/common) | `0.70.1` | `0.71.0` | | [go.opentelemetry.io/contrib/bridges/prometheus](https://github.com/open-telemetry/opentelemetry-go-contrib) | `0.70.0` | `0.71.0` | | [go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc](https://github.com/open-telemetry/opentelemetry-go) | `1.45.0` | `1.46.0` | | [go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc](https://github.com/open-telemetry/opentelemetry-go) | `1.45.0` | `1.46.0` | | [golang.org/x/net](https://github.com/golang/net) | `0.58.0` | `0.59.0` | Bumps the gomod-dependencies group with 1 update in the /olm directory: [github.com/onsi/ginkgo/v2](https://github.com/onsi/ginkgo). Updates `github.com/prometheus/client_model` from 0.6.2 to 0.6.3 - [Release notes](https://github.com/prometheus/client_model/releases) - [Commits](prometheus/client_model@v0.6.2...v0.6.3) Updates `github.com/prometheus/common` from 0.70.1 to 0.71.0 - [Release notes](https://github.com/prometheus/common/releases) - [Changelog](https://github.com/prometheus/common/blob/main/CHANGELOG.md) - [Commits](prometheus/common@v0.70.1...v0.71.0) Updates `go.opentelemetry.io/contrib/bridges/prometheus` from 0.70.0 to 0.71.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go-contrib/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go-contrib/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go-contrib@zpages/v0.70.0...zpages/v0.71.0) Updates `go.opentelemetry.io/otel` from 1.45.0 to 1.46.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.45.0...v1.46.0) Updates `go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc` from 1.45.0 to 1.46.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.45.0...v1.46.0) Updates `go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc` from 1.45.0 to 1.46.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.45.0...v1.46.0) Updates `go.opentelemetry.io/otel/sdk` from 1.45.0 to 1.46.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.45.0...v1.46.0) Updates `go.opentelemetry.io/otel/sdk/metric` from 1.45.0 to 1.46.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.45.0...v1.46.0) Updates `go.opentelemetry.io/otel/trace` from 1.45.0 to 1.46.0 - [Release notes](https://github.com/open-telemetry/opentelemetry-go/releases) - [Changelog](https://github.com/open-telemetry/opentelemetry-go/blob/main/CHANGELOG.md) - [Commits](open-telemetry/opentelemetry-go@v1.45.0...v1.46.0) Updates `golang.org/x/net` from 0.58.0 to 0.59.0 - [Commits](golang/net@v0.58.0...v0.59.0) Updates `golang.org/x/sync` from 0.22.0 to 0.23.0 - [Commits](golang/sync@v0.22.0...v0.23.0) Updates `github.com/onsi/ginkgo/v2` from 2.22.0 to 2.32.1 - [Release notes](https://github.com/onsi/ginkgo/releases) - [Changelog](https://github.com/onsi/ginkgo/blob/master/CHANGELOG.md) - [Commits](onsi/ginkgo@v2.22.0...v2.32.1) Updates `github.com/onsi/gomega` from 1.36.1 to 1.40.0 - [Release notes](https://github.com/onsi/gomega/releases) - [Changelog](https://github.com/onsi/gomega/blob/master/CHANGELOG.md) - [Commits](onsi/gomega@v1.36.1...v1.40.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_model dependency-version: 0.6.3 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: gomod-dependencies - dependency-name: github.com/prometheus/common dependency-version: 0.71.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/contrib/bridges/prometheus dependency-version: 0.71.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/otel dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetricgrpc dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracegrpc dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/otel/sdk dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/otel/sdk/metric dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: go.opentelemetry.io/otel/trace dependency-version: 1.46.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: golang.org/x/net dependency-version: 0.59.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: golang.org/x/sync dependency-version: 0.23.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: github.com/onsi/ginkgo/v2 dependency-version: 2.32.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies - dependency-name: github.com/onsi/gomega dependency-version: 1.40.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: gomod-dependencies ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…ernetes-sigs#1592) * ci: unify olm golangci-lint config with dev/tools/.golangci.yaml Now that olm/Makefile uses repo-wide dev/tools/go.mod to run golangci-lint, it still maintained its own boilerplate olm/.golangci.yml from operator-sdk. This allowed linter rules and binary versions to drift apart over time. Remove olm/.golangci.yml and configure olm/Makefile lint targets to pass --config $(REPO_ROOT)/dev/tools/.golangci.yaml. Also fix minor lint issues flagged in olm by the shared config: - Add doc comment trailing periods (godot) in olm/test/utils - Replace interface{} with any and strings.Split with SplitSeq (modernize) - Add inline nolint:revive annotations on Ginkgo/Gomega dot-imports in e2e tests * ci: enable ginkgolinter in shared golangci-lint config Keep matcher-misuse checks for the Ginkgo/Gomega test suite in olm/test/e2e following the migration to the shared linter configuration.
… and transient infra errors (kubernetes-sigs#1624) * Harden the kwok scalability presubmit against invisible gate failures and transient infra errors Of the 25 real failures on presubmit-agent-sandbox-test-e2e-scalability-kwok since Aug 3, 8 were perf-gate violations that were invisible in junit: ClusterLoader2 succeeds, junit reports failures=0, and then scrape_controller_metrics.py fails the job with the violation printed only to stdout, so Spyglass/TestGrid render the run as "failed before tests ran". Two more were transient infra errors (a GitHub 503 while kwokctl create cluster downloaded etcd on a cold cache, and a proxy.golang.org stream error during the ClusterLoader2 go build), and the sleep 3 after launching the controller with go run is not a readiness wait: a cold-pod compile can exceed it, and ClusterLoader2 starting before the controller serves inflates the very latency samples the gate measures. - scrape_controller_metrics.py now writes ${ARTIFACTS}/junit_controller-metrics.xml with one testcase per validated percentile; failures carry the measured value vs target. Job exit behavior is unchanged. - kwokctl create cluster is retried up to 3 times, deleting the partial cluster between attempts, mirroring the curl --retry already used for the kwokctl binary download. - GOPROXY gains a |direct fallback so proxy incidents do not fail the build (the Prow job env pins proxy-only). - The sleep 3 is replaced with a bounded poll of the controller's :8082/readyz endpoint that dumps controller.log and fails loudly on timeout. * kwok presubmit: gate on worker startup, bound readiness probes, test the gate CLI Address review: /readyz is a healthz.Ping check that only proves the probe server responds, so the readiness wait now also requires controller-runtime's "Starting workers" log line (post leader election and cache sync) before ClusterLoader2 starts. Each curl probe carries connect/max timeouts so a wedged connection cannot outlive the loop's 120s budget. The metrics gate now has end-to-end CLI tests covering the violating, unreachable, and passing paths (exit code + junit contents). --------- Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
etcd's default quota is 2GiB. When we exceed it, etcd raises the NOSPACE alarm and rejects every write with 'mvcc: database space exceeded' until the alarm is cleared. 8GiB puts the limit far from any benchmark workload; etcd only uses the space it actually writes. Overridable via STRESS_ETCD_QUOTA_BYTES.
…ter (kubernetes-sigs#1595) The controller and sandbox-router previously offered no way to tune TLS parameters, requiring consumers to accept the compiled defaults. Controller: add --metrics-secure-serving, --metrics-cert-dir, --tls-min-version, and --tls-cipher-suites flags to configure the metrics server's TLS settings. The metrics endpoint remains plain HTTP by default; enabling secure serving is opt-in. Sandbox-router: add --tls-min-version and --tls-cipher-suites flags (also settable via TLS_MIN_VERSION / TLS_CIPHER_SUITES env vars and the config file). The existing TLS 1.2 minimum default is preserved when the flags are unset. A downstream operator or platform integrator can inject profile-derived values via Deployment args or environment variables without changes to this project. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
…ments (kubernetes-sigs#1628) Dependabot's python:3.14-bookworm bump (kubernetes-sigs#1506) has failed the e2e presubmit on five consecutive heads because requirements.txt pins pydantic-core 2.33.2, which ships no cp314 wheels (PyO3 caps at 3.13), so pip falls back to a maturin source build that aborts during the image build. Dependabot only edits the Dockerfile and cannot recompile the lockfile, so this supersedes kubernetes-sigs#1506. - bump pydantic to 2.12.0 in requirements.in, matching the pin in google-gemini/computer-use-preview so both pip installs in the Dockerfile agree; pydantic 2.12.0 resolves to pydantic-core 2.41.1, which ships cp314 wheels - recompile requirements.txt with pip-compile --generate-hashes under Python 3.14 (also picks up typing-inspection 0.4.4) - bump the base image to python:3.14-bookworm Verified locally: every pin has a linux cp314-compatible wheel and all hashes match PyPI; the image builds; uvicorn serves / with status ok; test_main.py passes (4/4) both in a local 3.14 venv and inside the built container (Python 3.14.7, pydantic-core 2.41.1). Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
…sigs#1698) Address review nit from PR kubernetes-sigs#1661. Since t.Fatalf terminates execution, the else branch after errors.AsType is unreachable; declare httpErr up front so the subsequent assertions stay unnested. Signed-off-by: dongjiang1989 <dongjiang1989@126.com>
…gs#1645) * docs: publish and align sandboxd runtime API reference * docs: correct sandboxd runtime API guarantees * docs: fix sandboxd SDK examples and comments * docs: align sandboxd protocol examples * docs: document policy requirements for direct sandboxd access * docs: clarify sandboxd example connectivity * docs: correct sandboxd transport and error semantics * docs: separate router protocol and reachability constraints
…rgets (kubernetes-sigs#1710) Several components, SDKs, and tooling targets added since AGENTS.md was last updated were missing or outdated, which can cause AI agents to miss repository conventions or run incomplete checks. Update AGENTS.md to reflect current HEAD: - Add sandbox-router, packages/sandboxd, helm, olm, clients/typescript, and clients/integrations to the repository layout table. - List the available skills in .agents/skills/ and note CLAUDE.md import. - Update make all, make build, make test-unit, make fix-api-docs, and make verify-chart-version / bump-chart-version descriptions, plus helm/ CRD/RBAC generation in codegen.go. - Update Hugo docs mounts in site/hugo.yaml (generated reference docs, sandboxd user guide, nemo-gym integration README). - Update Python SDK dependencies/extras (grpc, prometheus-client) and document mypy typecheck enforcement in make test-unit. - Add TypeScript SDK conventions section.
kubernetes-sigs#1653) * docs(configuration): cover every controller flag in the flag reference configuration.md is the canonical flag reference, and performance-tuning.md points readers at it for the pprof flags in particular, but eleven of the flags the controller registers were absent from it: the four profiling flags, --enable-tracing, --extensions, --leader-elect, --leader-election-namespace, --metrics-bind-address, --health-probe-bind-address and --version. The standard controller-manager flags join Cluster Settings. Tracing and profiling get their own section that states which endpoints each flag enables — --enable-pprof exposes only the CPU profile, --enable-pprof-debug adds the sensitive ones and /debug/fgprof — along with the sampling semantics of the two rate flags, the fact that negative values are clamped at startup, and the warning about exposing process internals. The reference now covers all 34 flags the controller accepts. * docs(configuration): state the leader-election-namespace default explicitly The flag is registered with an empty default, and the controller auto-detects the namespace it is running in when the value is unset — that is the case the binary logs about when leader election is enabled. Documenting the default as "the controller's own namespace" conflated the default with the behaviour it triggers. Addresses the review comment on kubernetes-sigs#1653. * docs(configuration): point at the zap logging flags the manager binds The manager binds controller-runtime's standard zap flags through opts.BindFlags, which made them the one group still missing from the reference, and the claim in the previous commit that every accepted flag is now covered was therefore not accurate. List the flags and point at controller-runtime for their semantics rather than duplicating documentation that lives upstream. Addresses the review note on kubernetes-sigs#1653. * docs(configuration): split manager flags and tighten profiling notes Cluster Settings mixed manager process behavior — the endpoints it serves, leader election, and controller registration — with --cluster-domain, the only cluster-wide flag, so the manager flags get their own section. The tracing and pprof entries also left out details readers need: the OTLP exporter is configured through standard OpenTelemetry environment variables and the controller exits at startup when it cannot initialize, and only the duration-based profilers reject concurrent requests. The zap flags link now points at the released controller-runtime version rather than main.
…gs#1605) * feat(clients/ts): support automatic sandbox expiration TypeScript clients need a controller-enforced cleanup fallback when they exit before deleting their sandboxes. Add optional shutdownAfterSeconds to set an absolute claim deadline with the Delete policy, matching the Python SDK. Validate the duration before provisioning and preserve behavior when the option is omitted. * review: spell out the full lifecycle field paths for shutdownAfterSeconds The option's doc comment and README named shutdownPolicy without its spec.lifecycle prefix, so a reader could not tell which SandboxClaim fields the option writes. Give both field paths in full.
…ubernetes-sigs#1700) Bumps the pip group with 1 update in the /clients/python/agentic-sandbox-client/sandbox-router directory: [anyio](https://github.com/agronholm/anyio). Bumps the pip group with 1 update in the /examples/analytics-tool/analytics-tool directory: [anyio](https://github.com/agronholm/anyio). Bumps the pip group with 1 update in the /examples/gemini-cu-sandbox directory: [anyio](https://github.com/agronholm/anyio). Bumps the pip group with 1 update in the /examples/python-runtime-sandbox directory: [anyio](https://github.com/agronholm/anyio). Updates `anyio` from 4.13.0 to 4.14.2 - [Release notes](https://github.com/agronholm/anyio/releases) - [Commits](agronholm/anyio@4.13.0...4.14.2) Updates `anyio` from 4.10.0 to 4.14.2 - [Release notes](https://github.com/agronholm/anyio/releases) - [Commits](agronholm/anyio@4.13.0...4.14.2) Updates `anyio` from 4.10.0 to 4.14.2 - [Release notes](https://github.com/agronholm/anyio/releases) - [Commits](agronholm/anyio@4.13.0...4.14.2) Updates `anyio` from 4.14.0 to 4.14.2 - [Release notes](https://github.com/agronholm/anyio/releases) - [Commits](agronholm/anyio@4.13.0...4.14.2) --- updated-dependencies: - dependency-name: anyio dependency-version: 4.14.2 dependency-type: indirect dependency-group: pip - dependency-name: anyio dependency-version: 4.14.2 dependency-type: indirect dependency-group: pip - dependency-name: anyio dependency-version: 4.14.2 dependency-type: indirect dependency-group: pip - dependency-name: anyio dependency-version: 4.14.2 dependency-type: indirect dependency-group: pip ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…es-sigs#976 (kubernetes-sigs#1535) * fix(clients/ts): address non-blocking review follow-ups from kubernetes-sigs#976 The initial TypeScript SDK PR (kubernetes-sigs#976) landed with five non-blocking review notes deferred to a follow-up. This clears them: - `SandboxClient.getSandboxClaimWarmpoolName()` declared `Promise<string>` but returned `warmPoolRef.name` unchecked, which is `undefined` at runtime for a claim that is not warm-pool-backed (a cold-pool or direct-template claim). Widen the return type to `string | undefined` — matching the Python SDK, which reads the same field as optional — so callers are forced to handle the absent case instead of hitting it as an untyped `undefined`. No consumers yet (`private: true`), so this is not a break in practice. - The e2e `TestContext` resolves its Kubernetes client from an explicit kubeconfig (`$KUBECONFIG`, else `bin/KUBECONFIG`), but its `kubectl` subprocesses — `apply` and the watch-timeout `describe` / `get pods` diagnostics — used the ambient current-context, so a developer whose context drifted after `make deploy-kind` would apply manifests to and dump state from a different cluster than the test client talks to. Pass `--kubeconfig` explicitly. - `dev/tools/test-e2e`'s `ensure_extensions_enabled()` has the same split: it patches the controller Deployment via `kubectl` against the ambient context. Thread the repo root in and target the same kubeconfig the SDK frameworks use. - Drop the unused `shutil` and `time` imports from `dev/tools/test-e2e`. - Drop the `allowScripts` block from the e2e `package.json`: its key had a five-segment `../` path where the dependency spec has four, and nothing in the repo reads `allowScripts` (there is no lavamoat), so it was dead config either way. * fix(dev): propagate the resolved kubeconfig to e2e SDK test processes The previous change pointed only ensure_extensions_enabled()'s controller kubectl calls at the resolved kubeconfig ($KUBECONFIG, else bin/KUBECONFIG). The SDK e2e frameworks that run afterwards never saw it: the Python framework's apply_manifest_text() shells out to `kubectl apply` with no --kubeconfig, so manifests could land on kubectl's ambient current-context instead of the cluster the test client talks to. Resolve the kubeconfig once in main() and pin it in the environment every test subprocess inherits (Go, Python, TypeScript), so the API clients and their kubectl invocations all target the same cluster. ensure_extensions_enabled() now takes that env instead of re-resolving the path itself. Signed-off-by: Hirotaka Kawashima <24205015+khirotaka@users.noreply.github.com> * fix(dev): preserve multi-file KUBECONFIG in test-e2e's kubectl calls ensure_extensions_enabled passed KUBECONFIG to kubectl via --kubeconfig, but that flag treats its value as a single filename and does not merge paths. When KUBECONFIG held multiple colon-separated paths, kubectl would fail to find that literal filename and abort the E2E suite. Drop --kubeconfig and pass env=env to each subprocess.run call instead, so kubectl resolves KUBECONFIG natively (merging multi-file values) while still honoring the bin/KUBECONFIG fallback pinned by main(). Signed-off-by: Hirotaka Kawashima <24205015+khirotaka@users.noreply.github.com> * fix(clients/ts): align kubeconfig merging with kubectl in TestContext Signed-off-by: Hirotaka Kawashima <24205015+khirotaka@users.noreply.github.com> * fix(clients/ts): skip missing KUBECONFIG entries like kubectl in TestContext Signed-off-by: Hirotaka Kawashima <24205015+khirotaka@users.noreply.github.com> --------- Signed-off-by: Hirotaka Kawashima <24205015+khirotaka@users.noreply.github.com>
…name is too long (kubernetes-sigs#1630) A Sandbox name may be up to 253 characters (like any Pod/CR name), but the controller derives the headless Service name directly from the Sandbox name, and a Service name is a DNS-1035 label capped at 63 characters. A Sandbox with spec.service and a name of 64+ characters therefore backs a Pod that runs fine but a Service the apiserver permanently rejects. The reconciler returned that Invalid error from Reconcile, so controller-runtime requeued it with rate limiting and re-logged an error-level stacktrace on every pass -- a permanent user misconfiguration treated as a transient failure, hot-looping forever while the Sandbox stayed stuck at Ready=False/ReconcilerError. Classify permanent apiserver Invalid errors from child-resource reconciliation as terminal: surface them through a new, specific Ready=False reason (InvalidConfiguration) with the apiserver message, and keep them out of the error returned from Reconcile so the request is not requeued. Non-Invalid (transient) errors are unchanged and still returned for retry. Also log the Service create rejection at info rather than error level, since retrying cannot help. Adds a computeConditions case for the new reason and an interceptor-based Reconcile regression test asserting the permanent error is not returned and the Sandbox reports Ready=False/InvalidConfiguration.
…ns (kubernetes-sigs#1532) * feat(sandbox): emit Kubernetes Events for Sandbox lifecycle transitions SandboxReconciler emits no Kubernetes Events today, so kubectl describe sandbox stays silent on lifecycle transitions -- unlike the extensions' SandboxClaimReconciler, which already emits SandboxProvisioned, SandboxAdopted, and ClaimExpired via events.EventRecorder. The Recorder field, its main.go wiring, and the RBAC markers were already added in lifecycle coverage: SandboxPodCreated, SandboxPodCreateFailed (Pod creation failing), SandboxReady, SandboxExpired, SandboxSuspended, and the Pod reaching a terminal phase on its own (PodSucceeded/PodFailed). SandboxReady, SandboxExpired, SandboxSuspended, and the pod-completion events are emitted from updateStatus, after the status patch has actually persisted, gated on the Ready condition's Reason having just transitioned. This piggybacks on updateStatus's existing DeepEqual short-circuit: a reconcile that doesn't change the Ready reason never reaches the patch or the event, so nothing re-fires on retries or steady-state reconciles, and a failed patch never produces a misleading event. It also means SandboxExpired naturally only fires for ShutdownPolicy=Retain: ShutdownPolicy=Delete deletes the Sandbox before updateStatus would ever be called on that path. SandboxPodCreated and SandboxPodCreateFailed (create failure) are emitted directly at the r.Create call site in reconcilePod, matching the existing recordMultiplePodsEvent convention -- pod creation is itself the durable fact being reported, and a later reconcile finds the pod via Get rather than re-entering this code path. * feat(sandbox): add --disable-sandbox-events flag main.go wired the Sandbox controller's recorder unconditionally, so the new per-sandbox lifecycle events (SandboxPodCreated and SandboxReady at minimum) had no way to be switched off during large warm-pool fills. Mirror --disable-claim-events, which exists for exactly that reason on the SandboxClaim controller: a nil recorder cleanly no-ops every Eventf call in the Sandbox controller too, since they're all already nil-guarded.
* feat(sdks): avoid buffering large file downloads * fix(sdks): harden streaming download failures * docs(go-sdk): regenerate reference for streaming downloads * fix(sdks): handle streaming download edge cases * fix(sdks): address streaming review feedback * fix(sdks): preserve auth across streaming retries * fix(sdks): preserve streaming error responses * fix(sdks): close cancelled streaming responses * fix(sdks): preserve main connector error handling
…rnetes-sigs#1696) update_issues dedups findings against open kind/flake issues only, so closing a flake issue whose stale failing columns are still inside the 100-run TestGrid window causes the next nightly run to file a duplicate. Maintainers have had to leave verified false positives open purely to suppress re-filing. When no open issue matches a finding's marker, also look for the most recently closed issue with the same marker. If the finding's newest failure is not newer than that issue's closedAt, skip filing: the closer already judged those failures. A failure strictly newer than the close still files a fresh issue (genuine recurrences must surface) and links the prior issue in the body for lineage. Applies to both per-test flaky issues and infra-tab issues. An unparsable or missing close time files rather than suppresses. Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
* fix(python): harden async sandboxd cleanup * fix(python): make sandboxd cleanup retryable * fix(python): make sync port-forward cleanup retryable * fix(python): keep failed sandbox cleanup retryable * fix(python): reap sync port-forward after kill
…ion, and wrapper bypasses (kubernetes-sigs#1690) is_denied() from kubernetes-sigs#1456 only checked a command's first parsed token, a gap its own README documented (chaining/substitution reach sandbox.commands.run() unchecked). Extracts the classifier into governed_run.py, adds raw-text + segment-split layers covering shell chaining (;, &&, ||, |, &), command substitution ($(...)/backticks, nested), and sudo/env/xargs/command wrapper stripping, with a test_governed_run.py regression suite and a dev/tools/test-unit registration. Also makes the segment-level rm/wrapper exe and long-flag matching case-insensitive, and strips bare `VAR=val` env-assignment prefixes (not just `env VAR=val`), closing a bypass where `RM --recursive --force /`, `SUDO rm --recursive --force /`, or `FOO=bar rm --recursive --force /` slipped through uncaught since the raw-text safety net only recognizes short -rf-style flags. Per CodeRabbit review: tracks each wrapper's own arg-taking flags by both short and long form (`sudo -u`/`--user`, `env -u`/`--unset`, `xargs -n`/`--max-args`, ...) instead of a single shared set, since an unrecognized arg-taking flag left its argument (e.g. "root", "FOO", "1") sitting where the wrapped executable should be, so it was never classified. Also strips the bash `command` builtin launcher, which previously passed straight through unrecognized. Also per CodeRabbit review: replaces the fixed, non-recursive $(...) / backtick regex with a depth-tracking extractor, since a regex can't match an outer $(...) whose own body contains another $(...) (`echo $(rm --recursive --force $(printf /))` left the outer rm unclassified); the new extractor also fails closed (denies) on an unterminated $( or backtick instead of silently skipping it. And `env -S`/`--split-string` is now denied outright rather than having its argument (itself a shell command string subject to further word splitting) silently discarded as an opaque flag value. Also per CodeRabbit review: accepts unambiguous GNU-style abbreviated long options for rm (`rm --rec --for /` really is `--recursive --force` under GNU getopt_long), since `_has_flag()` previously required an exact full-name match and let abbreviated invocations through unclassified. Matches any prefix of the full option name rather than only rm's actual unambiguous abbreviations - deliberately over-inclusive, since a denylist should err toward denying too much rather than missing a real invocation. Per reviewer feedback (aditya-shantanu) and CodeRabbit: recognizes `nohup`/`nice`/`stdbuf` as passthrough launchers in _strip_wrapper (previously left as argv[0], so `nohup rm --recursive --force /` skipped the token-aware rm check entirely), and denies outright any command whose executable-position token contains a shell-expansion or glob character ($, `, *, ?, [) rather than trying to evaluate it - closing `$(printf rm) --recursive --force /` (substitution generates the exe name), `/bin/r[m] -rf /` (glob-expanded path), and `rm$IFS-rf$IFS/` (IFS word-splitting glues the whole invocation into one token that never matches "rm") in one check, since correctly resolving any of these would mean being a shell. README's scope section updated to describe this fail-closed behavior explicitly rather than overclaiming blanket coverage of "direct invocations". Per CodeRabbit review: `xargs` is no longer treated as a transparent wrapper for `rm`/`mkfs`/`dd`. Unlike sudo/env/nice/etc., xargs appends argv tokens read from its own stdin - typically the previous stage of a pipeline, a segment this checker can't see - to the command it wraps, so a visible absence of `-rf`/`of=` on the xargs line (`find / | xargs rm`) doesn't mean the executed command lacks them. _strip_wrapper now tracks whether an xargs layer was stripped anywhere in the chain, and any such invocation targeting rm/mkfs/dd is denied unconditionally regardless of visible flags. Per GitHub Copilot review: adds sudo's `-D`/`--chdir` and `-R`/`--chroot` (both consume a separate following token) to `_SUDO_FLAGS_WITH_ARG`, which previously let their argument leak through as the apparent wrapped executable (`sudo -D /tmp rm --recursive --force /` reduced to checking `/tmp` instead of `rm`). Also fixes the reverse mistake found while auditing xargs's table for the same class of bug: `-i`/`-l` (lowercase) are deprecated forms whose replacement string/line-count argument is optional and must be attached to the flag itself, never a separate token - treating them as separate-token-consuming (as before) let `xargs -i rm -rf /` swallow "rm" as if it were `-i`'s own value. Only `-I`/`-L`/`--replace`/`--max-lines` (which do require a separate token) remain in that set. Also fixes a POSIX line-continuation bypass: `command.splitlines()` treated `rm \` followed by `-rf /` on the next physical line as two separately benign commands, but a shell removes an unquoted backslash-newline entirely and joins the following line onto the current one with no inserted whitespace - so that really is one command, `rm -rf /`. `is_denied()` now strips `\\\n` continuations before both the raw-text check and line-splitting see the command. Per PR review feedback (upramod, Santoshkumarpuppala): closes an `env -S` attached-form bypass - `env -S'rm --recursive --force /'` (no space) is a single shlex token that never equals the bare "-S" or "--split-string" the fail-closed check compared against, so it slipped through as an unrecognized flag. `_is_env_split_string_flag()` now also matches the attached short (`-S...`) and long (`--split-string=...`) forms. Also recognizes `timeout` and `exec` as wrapper launchers - `timeout 5 rm --recursive --force /` and `exec rm --recursive --force /` previously reached the same class of gap CodeRabbit's nohup/nice/stdbuf finding closed, just for two launchers that weren't in that set yet; `timeout` additionally strips its mandatory `DURATION` positional before reaching the wrapped command. Adds regression tests pinning _DESTRUCTIVE_SYNTAX_PATTERNS directly (fork bomb, curl|sh, wget|bash), since nothing in the existing suite exercised that layer on its own. Per reviewer feedback (aditya-shantanu): adds `{`/`}` to _EXPANSION_CHARS, closing a brace-expansion bypass where `{rm,-rf,/}` is one literal token to this checker but three words - `rm -rf /` - once bash expands it. Also extends the expansion fail-closed check from just the executable token to every argument token of an rm/mkfs/dd segment, since `FLAGS=-rf; rm $FLAGS /` and `X=ve; rm --recursi$X --force /` both pass the literal flag check (neither token is a literal `-rf`/`--recursive`) yet execute `rm -rf /` once the shell expands the variable. Signed-off-by: Karim Mehalebi <kmehaleb@gmail.com>
kubernetes-sigs#1738) Signed-off-by: Yuedong Wu <dwcn22@outlook.com>
… isolation for concurrent runs (kubernetes-sigs#1737) * fix(rl-sdk): run-scoped teardown, fail-fast on deleted pools, run isolation Two agent-sandbox-rl runs sharing a namespace can destroy each other. SandboxFleet._teardown() listed claims, pools and templates by the namespace-wide managed label (app=agent-sandbox-rl), so the first run to finish deleted every other run's warm fleet; in one incident a single teardown removed 159 pools in 0.4 s, 31 of them a concurrent run's. The victim's wait_for_pool_ready() then read the DELETED watch event as "0/N ready" and idled for the full ready_timeout (900 s). Names are image-derived, so runs on the same image also share, resize and delete one pool by accident. - teardown selects by this run's id label (run_selector()), as the reaper and the breaker already did; the namespace-wide sweep remains only as the explicit reap(all_managed=True). - wait_for_pool_ready() returns False immediately on a DELETED watch event or a 404 on the dropped-watch re-check. - unwarm_image() / set_pool_replicas() refuse to delete or resize a pool labelled with another run's id and log which run owns it. - FleetConfig.run_isolation: "names" bakes the run id into template and pool names for runs sharing a namespace; "namespace" gives each run <namespace>-<run id>, created on first use and deleted at teardown if the fleet created it (run_namespace_labels, run_namespace_setup hook); "none" (default) keeps today's naming. A {run_id} placeholder is accepted in template_name_prefix / pool_name_format in any mode. Issue: kubernetes-sigs#1736 * rl-sdk: address review on run isolation (kubernetes-sigs#1737) - Validate name formats with a run-id stand-in distinct from the image hash stand-in, so pool-{run_id} no longer passes the per-image uniqueness check. - In "names" mode scope the template prefix and the pool format independently: each gets the run id unless it already carries the placeholder (or, for pools, {template}). - _owns_pool fails closed when the pool cannot be read. - _warm_entry checks ownership before writing; a colliding pool owned by another run is used read-only with adopt semantics instead of being resized (409 reconcile) and relabelled (ensure_template). - wait_for_pool_ready returns False on a 404 in the fast path too; a watch opened without a resourceVersion would not replay that deletion. - _ensure_run_namespaces is all-or-nothing per attempt: a create or setup hook failure rolls back the namespaces created in that attempt, so a failure before run() enters its teardown scope leaves nothing behind and a retry re-runs the hook. ensure_namespace treats a Terminating namespace as an error rather than "existing". - Tests for each; README and CHANGELOG wording. Issue: kubernetes-sigs#1736 * rl-sdk: self-review follow-ups on run isolation (kubernetes-sigs#1737) A mutation pass over the new tests found one that did not test what it claimed: the fast-path 404 test raised from the fake watch, the dropped-watch handler swallowed that, and the re-check returned False anyway. It now records whether the watch was opened and asserts it was not. The rest are hardening and accuracy: - unit test for namespace mode through the default registry (the path real callers take), and for the ApiException branch of the re-check - _ensure_run_namespaces takes a dedicated lock: plan() is reachable from concurrent warm threads and create/rollback must not interleave - adopt_existing with run_isolation="namespace" is rejected at config time (a per-run namespace holds nothing to adopt) - ensure_namespace reads the phase with getattr instead of relying on an AttributeError being swallowed - _owns_pool takes the caller's action for its log line, so a warm-path collision logs once instead of twice with different wording - docstrings for _owns_pool (fail closed), wait_for_pool_ready (initial 404) and ensure_namespace (Terminating); CHANGELOG clause for all-or-nothing namespace creation Issue: kubernetes-sigs#1736 * rl-sdk: make cross-run pool writes conditional, revalidate names after run-id injection Review round 2 on run isolation. The ownership guard was a snapshot: two fleets in "none" mode could still race between the check and the write (one creates the pool after the other saw none; the 409 reconcile then resized it, ensure_template relabelled its template, and a same-named pool created after an unwarm's 404 check could be deleted). Make each write conditional on what was inspected instead of trusting the check: - delete_warmpool takes the inspected pool's uid as a delete precondition (409 = replaced meanwhile, tolerated, pool left standing) - create_warmpool(reconcile=True, owner_run_id=...) re-reads the pool at the 409, refuses to resize one labelled with another run's id, and patches with that object's resourceVersion (409 = changed concurrently, back off); returns False in both cases so _warm_entry falls back to read-only adopt semantics and set_pool_replicas skips - ensure_template(owner_run_id=...) does not relabel a template that carries another live run's id - _check_resolved_names re-validates the rendered template and pool names after the run id is injected; "names" mode adds 13 characters and a prefix valid at the 253-char limit no longer is - rollback keeps the ownership record for a namespace it failed to delete, so a retry reuses it and ordinary teardown still removes it Tests for each; README and CHANGELOG describe the conditional writes. Issue: kubernetes-sigs#1736 * rl-sdk: fail on pool-name collisions, tri-state unwarm ownership, keep namespace state (kubernetes-sigs#1737) Review round 3 found that the round-2 guards could still stall or leak: - Warming a pool name held by another run used that pool read-only, but recorded it at this run's replica count. A later re-warm hit the reuse short-circuit and waited for the full count on a pool sized by someone else, which is the ready_timeout stall this PR exists to remove. Warming now raises a FleetError naming the owning run and pointing at run_isolation="names", adopt_existing=True, or the reaper. Deliberate sharing already has adopt_existing; a collision is not a second way in. - The ownership pre-checks in the warm and set_pool_replicas paths were redundant with create_warmpool's 409-time owner check, cost an extra read on the reuse path, and turned a transient read error into a silently dropped scale change. They are gone. create_warmpool now re-inspects on a resourceVersion conflict (the controller writes status continuously, so a conflict on our own pool is normal) and on losing a re-create race, instead of reporting a collision or raising a raw 409. - An unwarm that could not read the pool retired the image without releasing its reserved replicas. It now keeps the image and raises, like a failed delete, so a retry releases exactly once. A pool already gone gets no delete by name, which could hit a pool re-created under that name. - Teardown dropped namespace ownership even when the delete failed, and a namespace kept after a failed rollback skipped run_namespace_setup on the next attempt. Ownership is now dropped only on a successful delete, and setup completion is tracked separately, so the hook re-runs until it succeeds once. Issue: kubernetes-sigs#1736 * rl-sdk: guard the template side of run collisions (kubernetes-sigs#1737) The pool guards left templates exposed. ensure_template returned False both for "already existed" and for "another run's, not relabelled", and the warm path discarded it. When another run's pool was gone but its template was still there, create_warmpool succeeded with no 409, so this run built its pool on the other run's template. Unwarm then deleted that template by name with no ownership check or uid precondition, the same cross-run write the pool guards stop. - ensure_template(owner_run_id=...) raises OwnedByAnotherRunError for a template labelled with another run's id, including one created concurrently and found at the 409. The warm path turns that into the collision FleetError and writes nothing. - Template deletes on unwarm and on an on-demand claim's rollback read the template first. Another run's template is left standing, a missing one gets no delete by name, and our own is deleted with its uid as a precondition. The on-demand rollback's pool delete gets the same ownership and uid guard. Issue: kubernetes-sigs#1736
…bernetes-sigs#1741) The kops-GCP benchmark presubmits intermittently die before tests run: cluster bring-up on shared boskos projects sometimes hits a GCE resourceNotReady stall on the API ForwardingRule, leaving control-plane static pods still starting when the 15m validation wait expires. About a tenth of recent runs on both CNI lanes failed this way, each wasting a full benchmark job and a retest. Raise the initial validation default to 25m. Successful runs are unaffected (validation returns as soon as the cluster is ready); only the slow-bring-up path waits longer, which is still far cheaper than a rerun. The post-cilium-restart re-validation keeps its 5m default. Co-authored-by: Aditya Shantanu <aditya-shantanu@users.noreply.github.com>
…ernetes-sigs#1286) * docs: runtime-aware CI proposal for timing regression visibility Propose adding gVisor and kata CI jobs to exercise the controller under non-runc timing profiles. The controller is runtime-agnostic by design, so the value is not catching runtime-specific bugs — it is regression visibility on timing-sensitive changes (reconciler refactors, timeout tuning, slowStartBatch adjustments) that look harmless at runc's 0.3s cold starts but may disproportionately affect 8-12s kata cold starts. Three steps: - Step 1: gVisor on KIND (no infra changes, mild timing diversity) - Step 2: kata on kOps with GCE nested virt (extreme timing diversity, plus the full VMM family — QEMU, Cloud Hypervisor, Firecracker — for free once KVM is available) - Optional: bare-metal kata for production-grade baselines Depends on PR kubernetes-sigs#1262 (RuntimeClass-aware test harness). Signed-off-by: vvoronko <vvoronko@redhat.com> * docs: address CodeRabbit and Copilot review comments - Remove n2d from nested virt footnote (AMD does not support it) - Clarify gVisor KIND prerequisites (runsc binaries + RuntimeClass) - Change gVisor presubmit to always_run (controller changes are the primary regression signal, not just test/example changes) - Fix broken reference link to non-existent README, point to PR kubernetes-sigs#1262 Signed-off-by: vvoronko <vvoronko@redhat.com> * docs(kata-ci-proposal): address aditya review comments - Add optional: true to gVisor presubmit so it doesn't block merge, matching the "no new requirements on contributors" promise in the doc - Update isVMRuntime() description to reflect 300% CPU overprovisioning in TestRuntimeClassBurstRecovery (strict cap only in Benchmark*) - Remove SANDBOX_SETTLE_SEC reference (removed in test implementation) Signed-off-by: vvoronko <vvoronko@redhat.com> --------- Signed-off-by: vvoronko <vvoronko@redhat.com>
…es-sigs#1685) The include-file shortcode ran the Markdown through RenderString and returned HTML, but almost every page invokes it with {{% %}}, which tells Hugo the output is Markdown and renders it again. The second pass wrapped blank lines inside fenced blocks in <p> tags and turned --> into an en-dash, so every mermaid diagram that contained a blank line failed to parse on the published site (network-policy-api-sandbox, demo-cilium-egress, openclaw-fleet-gke), and a few other code blocks picked up stray tags. Return the transformed Markdown instead and let Hugo render it once. The result is marked safeHTML because the included files contain raw HTML (the root README header) and <#anchor> link destinations (gomarkdoc output) that html/template would otherwise escape. Switch the single {{< >}} caller to {{% %}} so all pages take the same path.
* Document port changes required when enabling secure metrics serving The TLS args were commented out with instructions to uncomment, but the corresponding Service port, containerPort, and helm chart port had no indication they also need to change from 8080 to 8443. Add inline comments and expand the TLS args comment block to list all required port changes. Also add ALPN NextProtos (h2, http/1.1) to buildMetricsTLSOpts — required for HTTP/2 negotiation and expected by compliant TLS clients. The cluster TLS profile does not set NextProtos. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> * docs: add end-to-end checklist for enabling secure metrics serving The TLS flags, Service port, containerPort, NetworkPolicy, helm chart, and certificate provisioning all need to change together when enabling --metrics-secure-serving, but the instructions were scattered across individual file comments with no single overview. Add a numbered checklist to docs/configuration.md listing every manifest that must be updated. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> * olm: add commented-out prometheus resource to default kustomization The ServiceMonitor in config/prometheus/ was not reachable from the default kustomization, so downstream distributions enabling metrics scraping had to discover and wire it up manually. Add it as a commented-out resource with a pointer to the secure-metrics checklist in docs/configuration.md. Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> * router: add tls args and volumes commented out Add comments to easily guide the user on how to enable tls Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> * apply coderabbit comments Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com> --------- Signed-off-by: Emanuele Giuseppe Esposito <eesposit@redhat.com>
…s#1721) * fix(python-runtime): preserve literal percent escapes Signed-off-by: 1fanwang <1fannnw@gmail.com> * test(python-runtime): run path regressions in CI Signed-off-by: 1fanwang <1fannnw@gmail.com> --------- Signed-off-by: 1fanwang <1fannnw@gmail.com>
…1616) * test-unit: include cluster-free e2e framework tests The unit test runner excludes all packages under test/e2e, including the framework's fake-client tests that do not require a cluster. Include the framework package and its subpackages so these tests run with the unit suite's race detector. Keep other e2e packages excluded. Add a regression test for package selection, per-module execution, and JUnit output. Part of kubernetes-sigs#1200 * test-unit: document package selection regression test The module docstring does not cover the test function in function-level docstring checks. Describe the behavior verified by the regression test.
* build: enforce LF line endings via .gitattributes On a clean Windows clone with the default core.autocrlf=true, git checks text files out with CRLF line endings. mdtoc, which dev/tools/verify-toc runs to validate the KEP tables of contents, does not handle CRLF: fenced code blocks are not recognized, so comment lines inside fenced shell examples are collected as headings, `make toc-verify` fails on a pristine checkout, and `make toc-update` would rewrite READMEs that are correct. Add a .gitattributes that normalizes text files to LF on checkout and checkin (`* text=auto eol=lf`), the same setting kubernetes/kubernetes uses, so the TOC tooling sees identical input on every platform. PNG and WebP assets are marked binary explicitly. The tracked tree is already entirely LF, so this introduces no renormalization churn. Existing CRLF working trees need a re-checkout for the attribute to take effect, for example `git rm -r --cached . && git reset --hard`. * build: mark common image and document formats as binary Only PNG and WebP assets exist in the tree today, so the initial .gitattributes listed just those two. Also list GIF, JPEG, ICO and PDF so that any such file added later is exempt from line-ending normalization from the start, rather than relying on git's text/binary heuristic to get it right.
| try: | ||
| daemon_bind(pod, employee, action="unbind", retries=3) | ||
| except Exception as e: # noqa: BLE001 - already-unmounted is fine | ||
| print(f"unbind {employee}: {e}", flush=True) |
| except ValueError: | ||
| return JSONResponse(status_code=403, content={"message": "Access denied"}) | ||
|
|
||
| if os.path.isfile(full_path): | ||
| return FileResponse(path=full_path, media_type='application/octet-stream', filename=decoded_path) | ||
| return FileResponse(path=full_path, media_type='application/octet-stream', filename=encoded_file_path) |
| # a supplied [], false or "" must 400, not silently become {}. | ||
| config = validate_config(body["config"]) if "config" in body else {} | ||
| except ValueError as e: | ||
| return jsonify(error=str(e)), 400 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Updated the paths in the workflow to include the sandbox-router directory and modified the build context for Docker.
Signed-off-by: Nicolás Georger info@sredevops.org#### What this PR does / why we need it:
Which issue(s) this PR is related to:
Release Note
examples/agent-sandbox-rl: create the namespace in setup
examples/agent-sandbox-rl: use the same namespace throughout
examples/agent-sandbox-rl: reword the namespace step, update reaper docstring
examples/agent-sandbox-rl: update remaining namespace references