mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-22 06:19:47 +08:00
pull-request/2832
50
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
59479f492a |
feat(k8s): add namespace-per-workspace support (RFC 0011 Phase 3) (#2656)
* feat(k8s): add namespace-per-workspace support (RFC 0011 Phase 3) Implement three workspace namespace modes for the Kubernetes compute driver: shared (default, preserves current single-namespace behavior), managed (auto-creates/deletes namespaces per workspace), and operator (pre-provisioned namespaces with dynamic discovery via label selector or drop-in allowlist file). Key changes: - WorkspaceMode enum and namespace resolution in driver config - Managed namespace lifecycle with ServiceAccount and OpenShift SCC annotation propagation - Cluster-wide sandbox CR watchers for managed/operator modes - NamespaceValidator (Exact/Prefix/Allowlist) for SA token auth - Workspace-aware credential secret storage - Helm ClusterRole for multi-namespace RBAC - Gateway config, architecture, and reference docs Signed-off-by: Derek Carr <decarr@redhat.com> * test(k8s): add e2e tests for workspace namespace modes Add end-to-end tests for managed and operator workspace modes introduced in RFC 0011 Phase 3. The managed mode tests verify namespace creation with correct labels, ServiceAccount provisioning, sandbox CR placement, and namespace survival with remaining sandboxes. The operator mode tests verify rejection of unlabeled and nonexistent namespaces. The positive operator path (sandbox in labeled namespace) is known to fail due to an RBAC gap and will be addressed separately. Also fixes Helm 4 compatibility: move SPDX license headers inside conditional guards in 8 chart templates to prevent empty comment-only documents, and fix a trailing whitespace trimmer in clusterrole.yaml that concatenated the license header with apiVersion. Adds cleanup sweep in with-kube-gateway.sh to remove managed and operator namespaces before Helm uninstall, and mise tasks for running each mode independently. Signed-off-by: Derek Carr <decarr@redhat.com> * feat(k8s): add operator namespace label watcher Spawn a background kube::runtime::watcher in the K8s driver that watches namespaces matching the configured label selector and populates the OperatorNamespaceAllowlist at runtime. The driver owns the allowlist and exposes its Arc so the server can share the same set with the SA token authenticator. create_sandbox now gates pod creation on the allowlist in operator mode — workspaces whose namespace is not yet labeled are rejected at resource render time rather than silently proceeding. Workspace lifecycle itself is unaffected; only sandbox (resource) creation is gated. Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): harden operator mode and address review findings Close the fail-open gap in operator mode when only operator_namespace_file is configured: the allowlist is now created unconditionally in operator mode (fail-closed from startup). Implement the namespace file watcher using the notify crate, following the TLS hot-reload pattern (parent-directory watch, 1s debounce, ConfigMap symlink-swap safe). The file format is a JSON array of namespace name strings. Additional fixes from the 10-reviewer audit: - Change allowlist rejection from InvalidArgument to FailedPrecondition so callers know the request may succeed later once the namespace is provisioned. - NamespaceValidator::Allowlist now holds the OperatorNamespaceAllowlist newtype instead of a raw Arc<RwLock<BTreeSet>>, eliminating silent denial on RwLock poison. - Verify LABEL_MANAGED_BY and LABEL_GATEWAY_ID ownership before deleting a managed namespace. - Replace fixed 5s sleep in operator e2e test with a 30s poll loop. - Add Helm validation for workspaceMode values. - Fix Helm README type column and description for operator fields. - Add insert/remove methods to OperatorNamespaceAllowlist; label watcher now uses them instead of reaching through shared(). - Reject configs with both operator_namespace_label and operator_namespace_file set. Signed-off-by: Derek Carr <decarr@redhat.com> * feat(k8s): add workspace-level compute driver RPCs and harden RBAC Decouple namespace lifecycle from sandbox lifecycle by adding EnsureWorkspace/DeleteWorkspace RPCs to the ComputeDriver service. Namespace creation now happens before credential storage and namespace deletion happens on workspace delete, fixing credential storage in managed workspace mode. - Add EnsureWorkspace and DeleteWorkspace proto RPCs with implementations across all compute drivers (K8s managed delegates to ensure_namespace/delete_namespace_if_empty; others no-op) - Wire ensure_workspace into provider create/update/refresh paths so the namespace exists before the credential driver writes secrets - Wire delete_workspace into workspace deletion for cleanup - Remove delete_namespace_if_empty from sandbox deletion path - Scope ClusterRole secrets access to non-shared workspace modes - Add TODO for TLS cert hot-reload in sandbox gRPC client - Harden e2e tests with control-plane sandbox resolution assertions - Fix docker image save --platform flag for OCI index manifests Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): address re-review findings and add test coverage - Use server-side apply for TLS secret sync (fixes second sandbox creation failure when TLS is enabled) - Scope gateway-ID label selector unconditionally across all workspace modes (fixes operator reads/watches/deletes seeing foreign sandboxes) - Validate operator allowlist in EnsureWorkspace and DeleteWorkspace RPCs (prevents credential writes to namespaces outside the allowlist) - Extend ClusterRole secrets patch+delete to all non-shared modes with credential driver enabled (fixes operator credential storage RBAC) - Validate namespace ownership on 409 conflict in ensure_namespace (prevents adopting unowned namespaces in managed mode) - Replace delete_namespace_if_empty with unconditional delete_namespace letting Kubernetes cascade cleanup (fixes stuck terminating CRs) - Strengthen NetworkPolicy TODO to cover both managed and operator modes - Extract selector and ownership logic into testable free functions - Add unit tests for gateway-ID selectors and namespace ownership - Add Helm ClusterRole RBAC tests for operator credential driver Signed-off-by: Derek Carr <decarr@redhat.com> * ci(k8s): add workspace managed and operator mode e2e to CI Wire the existing e2e:kubernetes:workspace-managed and e2e:kubernetes:workspace-operator mise tasks into the branch-e2e workflow so they run alongside the other core Kubernetes e2e suites. Both are gated by run_core_e2e and included in the Core E2E result gate. Signed-off-by: Derek Carr <decarr@redhat.com> * test(k8s): add e2e tests for workspace namespace modes Add 7 new e2e tests covering workspace namespace lifecycle, TLS secret copying, ownership conflict detection, DNS-1123 validation, operator namespace preservation, and dynamic label watcher behavior. Fix async sandbox deletion race condition in existing tests by polling sandbox list instead of asserting immediately after delete. Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): grant secrets/patch unconditionally and backfill gateway-id labels Address two review findings: 1. RBAC: server-side apply (PATCH) is used for TLS secret sync in multi-namespace modes, but the ClusterRole only granted patch when the kubernetes-secrets credential driver was enabled. Grant patch unconditionally for non-shared modes since TLS sync always needs it; keep delete gated on the credential driver. 2. Upgrade safety: the new gateway-id label selector would orphan legacy Sandbox CRs that predate its introduction. Add a startup backfill in shared mode that patches any managed Sandbox CR missing the gateway-id label before the driver begins serving requests. Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): address workspace namespace review findings Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): address follow-up review findings Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): preserve workspace lookup after rebase Signed-off-by: Derek Carr <decarr@redhat.com> * fix(helm): allow managed secret creation Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): stop pods in workspace namespace Signed-off-by: Derek Carr <decarr@redhat.com> * test(k8s): scope pod deletion check to v1alpha1 Signed-off-by: Derek Carr <decarr@redhat.com> * fix(k8s): address workspace namespace review findings Signed-off-by: Derek Carr <decarr@redhat.com> --------- Signed-off-by: Derek Carr <decarr@redhat.com> |
||
|
|
35fb27ef14 |
feat(sdk): add TypeScript SDK (@nvidia/openshell-sdk) (#2122)
* feat(sdk): add TypeScript SDK (@nvidia/openshell-sdk) First native, per-language SDK for the OpenShell gateway: a thin, idiomatic TypeScript client over proto-generated gRPC stubs (connect-es), no FFI. Covers the v0.1 surface — sandbox lifecycle (create/get/list/delete + waitReady/ waitDeleted), health, and streamed exec. - sdk/typescript/: package, client/transport/errors, protoc + protoc-gen-es codegen (gen/ gitignored, absorbed into dist/ at build), committed lockfile. - tasks/typescript.toml: sdk:ts install/proto/typecheck/build/ci/publish; sdk:ts:typecheck wired into `check`; sdk-typescript job in branch-checks (typecheck, build, and a --dry-run publish that validates the release path). - Enforce SPDX headers on .ts/.tsx/.mts/.cts (skip node_modules and gen/); back-fill docs/_components/jsx.d.ts and fern/components/CustomFooter.tsx. - release.py gains an npm version format; release-tag.yml publishes to GitHub Packages on tag, stamping the version (0.0.0 placeholder in git); prerelease builds publish under the `next` dist-tag, not `latest`. Ships as @nvidia/openshell-sdk on GitHub Packages pre-GA; public npm (@openshell/sdk) follows at GA with an unchanged public API. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * chore(sdk): adopt TypeScript 6, tidy @types/node range - typescript ^5.7.2 -> ^6.0.3 (6.0 is now `latest`; the old caret capped at 5.x) - @types/node ^24.0.0 -> ^24 (same range, tidier) No source changes; codegen, typecheck, and build pass on 6.0.3. Verified the emitted d.ts still type-check for downstream consumers on TypeScript 5.0.4 through 5.9.3, so this does not raise the SDK's consumer TS floor. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * refactor(sdk): group operations under a composable SandboxClient Reshape the client from flat methods (createSandbox, listSandboxes, exec) to a scoped SandboxClient reached as `client.sandbox.create/get/list/delete/exec` (+ waitReady/waitDeleted), mirroring the CLI's noun-verb model and the Python SDK's SandboxClient. SandboxClient is also usable standalone via SandboxClient.connect(); OpenShellClient composes it over a single shared transport, so future service/provider clients reuse one connection. health() stays top-level as a gateway call. No behavior change; types are unchanged. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * chore(sdk): generate TypeScript SDK stubs with buf Replace the protoc gen.sh with `buf generate` + buf.gen.yaml. `buf` (@bufbuild/buf) is a package devDependency and self-compiles the protos, so the TS SDK no longer depends on the mise-pinned protoc; it drives the same connect-es plugin. Generation stays limited to the client-surface closure (openshell/sandbox/datamodel) via the input paths. Output is byte-identical to the previous protoc + protoc-gen-es pipeline. Lays the groundwork for a shared buf.yaml (lint/breaking/LSP) as a follow-up. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * build(proto): add repo-level buf module with lint Declare proto/ as a single buf v2 module in a root buf.yaml so buf generate, lint, breaking, and the editor LSP resolve imports the same way. Lint uses STANDARD with six documented exceptions for deviations the current protos intentionally make: the flat proto/ layout with nested packages (DIRECTORY_SAME_PACKAGE, PACKAGE_DIRECTORY_MATCH) and the established API shape with unsuffixed services and reused request/response messages (RPC_REQUEST_RESPONSE_UNIQUE, RPC_REQUEST_STANDARD_NAME, RPC_RESPONSE_STANDARD_NAME, SERVICE_SUFFIX). Every other STANDARD rule now enforces on future protos. Breaking uses FILE. Code generation stays package-scoped in sdk/typescript/buf.gen.yaml since it binds to that package's connect-es plugin and output dir; its inputs are unchanged and regeneration is byte-identical. Wire the check in via a proto:lint mise task that runs buf from the SDK devDependencies. It is a dependency of both sdk:ts:ci (so the TypeScript SDK CI job enforces it) and the top-level lint aggregate (so local pre-commit covers it). Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * chore(sdk): publish as unscoped openshell-sdk on public npm Rename the package from @nvidia/openshell-sdk to the unscoped openshell-sdk and target public npm (registry.npmjs.org) instead of GitHub Packages. GitHub Packages requires a scope matching the owning org, and the @openshell scope is blocked by an unrelated existing package, so an unscoped name on public npm is the lowest-friction distribution path and needs no org approval. Rework the release-tag publish job to auth against registry.npmjs.org with NPM_TOKEN (the job now only needs packages: read to pull the CI image). Update the README install instructions and usage imports. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * chore(sdk): publish @nvidia/openshell-sdk to GitHub Packages Revert the unscoped-name switch. GitHub Packages only accepts scoped names matching the owning org, so shipping there first (which needs no external npm org or NPM_TOKEN, just the repo's GITHUB_TOKEN) requires the @nvidia scope. Keeping the @nvidia/openshell-sdk name also lets a later public-npm release use the same install specifier, so adding public npm becomes a second publish step rather than a rename. Restore the GitHub Packages publish auth in the release-tag job and the scoped install instructions in the README (keeping the buf codegen note). Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * feat(sdk-ts): add streaming exec, forward, ssh, provider, and config methods Grow SandboxClient to the surface the first two consumers need. execStream yields stdout/stderr chunks as they arrive and exec now drains it, keeping its buffered ExecResult and signature unchanged. execInteractive is the TTY + stdin transport primitive (start-first framing, output/write/resize/close/done, no terminal glue). forward binds a local TCP listener that tunnels each accepted connection into the sandbox for the process lifetime, minting and revoking a per-socket SSH session token around a forwardTcp bidi. Adds createSshSession / revokeSshSession, attach/detach/listProviders, and getConfig / setPolicy / setSetting (sandbox-scoped, network-policy-only, with an optional wait poll). Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * build(sdk-ts): add Biome and Vitest tooling The TypeScript SDK had no formatter or linter and no test runner. Add Biome (format + lint, generated src/gen excluded) enforcing 2-space indent, single quotes, semicolons, and a 120-column width, and reformat the existing hand-written sources accordingly. Add Vitest for unit tests. Wire sdk:ts:format, sdk:ts:lint, and sdk:ts:test mise tasks into the fmt/lint aggregates, the root test suite, and sdk:ts:ci so they run in CI. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * test(sdk-ts): cover the sandbox surface with in-memory transport tests Exercise SandboxClient against an in-memory OpenShell service built with createRouterTransport: request assembly and id resolution, u64/int64 rendered as strings, enum lowercasing, fromConnect code mapping, the exec/execStream drain plus a backward-compat check on exec, execInteractive start-first ordering and done resolution, and a forward() byte relay against a loopback echo with close() teardown. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * docs(sdk-ts): document the new surface and connect/upload/download boundaries Document execStream, execInteractive, forward, ssh sessions, providers, and config/policy in the SDK README, and record the intentional boundaries: interactive connect / PTY ownership, upload/download (no file-transfer RPC), and detached forwards stay out of scope. Note the Biome/Vitest dev commands. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * feat(sdk-ts): support mTLS client authentication Add clientCert and clientKey to ConnectOptions so the SDK can authenticate to the default local gateway, which uses mTLS user authentication. Without a client certificate and key the SDK could verify the server but never authenticate the caller, so it could not connect to the standard Docker, VM, Homebrew, or Linux-package gateway. Validate the pair as both-or-neither and pass cert and key through to the Node TLS options for https gateways. The h2c path is unchanged. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * chore(sdk-ts): drop the demo script and its tsx dependency Remove src/demo.ts, the demo npm script, the tsx devDependency, and the tsconfig build exclude for the demo. The demo was never part of the published package, and dropping it also removes the only place that logged part of an SSH session token. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * fix(sdk-ts)!: harden exec streaming, waits, SSH, and forwarding Address review feedback on the sandbox surface. - Make the streamed command exit code observable from idiomatic for-await: the terminal exit is now an in-band ExecStreamEvent ({ type: 'exit', exitCode }) rather than the async generator return value, which for-await discards. A stream that ends without an exit event now throws instead of reporting success. - Bound waitReady, waitDeleted, and the setPolicy wait by their timeout: each poll RPC carries a per-iteration deadline and the waits accept an AbortSignal, so a stalled call can no longer leave a wait pending forever. Add waitTimeoutSecs to SetPolicyOptions. - Validate the CreateSshSession response against the proto charset and range contract before returning it or using its token, since the values feed an OpenSSH ProxyCommand. - Respect socket backpressure when relaying forwarded responses: pause reading the gRPC stream when the local socket buffer is full and resume on drain so memory stays bounded. - Expose create-time sandbox policy: add policy and an advanced rawSpec passthrough to SandboxSpec so the safety boundary is expressible at creation and new spec fields do not require an SDK change. BREAKING CHANGE: execStream and the interactive exec output now yield a terminal { type: 'exit', exitCode } event; consumers iterating the stream must handle that arm. The exit code is no longer the async generator return value. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * feat(sdk-ts): export error contract, enum unions, and caller cancellation Address Tier-1 review feedback on the TypeScript SDK public surface (PR #2122). - Errors: export SdkError and SdkErrorCode so callers can use instanceof and exhaustively switch on .code. fromConnect preserves the originating ConnectError as .cause and its status as .connectCode, maps Aborted to a new 'aborted' code for optimistic-concurrency conflicts, and maps Canceled and DeadlineExceeded to 'canceled'. errorCode() behavior is unchanged. - Enums: replace the string-typed phase, status, scope, and policySource fields with lowercase literal unions (SandboxPhaseName, HealthStatus, SettingScopeName, PolicySourceName) backed by exhaustive Record maps. The unions are a hand-maintained mirror of the generated proto enums; a new drift test pins each literal to its generated member name. - Cancellation: accept an optional AbortSignal on exec, execInteractive, and forward, threaded into both sandbox resolution and the streaming RPC. forward tears down its local listener on abort. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * feat(sdk-ts): add raw escape hatch for uncurated gateway RPCs The curated sub-clients reduce proto messages to ergonomic subsets (for example get() drops created_at_ms, the full spec, conditions, runtime endpoints, and current_policy_version), and not every gateway RPC has a typed helper yet. Rather than ship methods that exist but throw, expose a generated client for the full surface. OpenShellClient.raw and SandboxClient.raw are generated clients covering every gateway RPC, returning the verbatim wire messages so proto distinctions the curated types smooth over are preserved. .transport exposes the shared connection for building extra clients over one socket. Generated request/response types are published at the new @nvidia/openshell-sdk/raw subpath. Curated methods stay the default; raw is the always-available floor. Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * fix(sdk-ts): address review feedback on exec, forward, and auth transport Settle exec's `done` promise before yielding the exit event so a consumer that breaks on exit no longer leaves it pending forever, and give it a lone rejection handler plus a finally-settle so a stream error or early abandon can never surface as an unhandled rejection or a hang. Attach an 'error' listener to each accepted forward socket synchronously, before forwardConnection awaits CreateSshSession; a peer reset in that window previously emitted an unhandled 'error' and crashed the process. Reject ambiguous or unsafe transport configs at buildTransport: oidcToken and edgeToken together (silently OIDC-only), and any auth token sent over plaintext http:// to a non-loopback host unless allowInsecureAuth is set. Wrap versionPin so a non-u64 expectedResourceVersion raises SdkError('invalid_config') instead of a raw BigInt SyntaxError, and raise the Node engine floor to >=20.3 for AbortSignal.any(). Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> * fix(sdk-ts): address review feedback Signed-off-by: Drew Newberry <anewberry@nvidia.com> * docs(sdk-ts): defer published sdk guide Signed-off-by: Drew Newberry <anewberry@nvidia.com> --------- Signed-off-by: Max Dubrinsky <mdubrinsky@nvidia.com> Signed-off-by: Drew Newberry <anewberry@nvidia.com> Co-authored-by: Drew Newberry <anewberry@nvidia.com> |
||
|
|
2f96c53b8c |
feat(gateway,cli): windows compilation support (#2496)
* chore(windows): gate Unix-only workspace code for MSVC Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * feat(windows): stub unsupported compute drivers Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * ci(windows): add MSVC mise build lane Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * docs(windows): document MSVC build-only design Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * docs(agent): add Windows MSVC build skill Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * feat(windows): add Windows build support Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor(windows): consolidate Windows-specific dependencies and improve build logic Signed-off-by: Akber Raza <akberr@nvidia.com> * feat(windows): add libclang path resolution and update cargo commands with bundled Z3 features Signed-off-by: Akber Raza <akberr@nvidia.com> * chore(tooling): lock Windows tool artifacts Signed-off-by: Giedrius Burachas <gburachas@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * feat(windows): enhance libclang path resolution to support architecture-specific subdirectories Signed-off-by: Akber Raza <akberr@nvidia.com> * Fix Windows dependency gating after sync merge Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(z3): update Z3 header path requirements in Windows build documentation and scripts Signed-off-by: Akber Raza <akberr@nvidia.com> * docs(windows): relocate Windows MSVC build design to architecture/ Why: windows-msvc-build-design.mdx is a design document ("design decisions for the native Windows MSVC build lane"), but it lived in the published, user-facing docs/reference/ tree. Per AGENTS.md (Documentation) and architecture/README.md ("rfc/ vs architecture/"), design content belongs in architecture/ (or rfc/), not in published reference. It also shared Fern sidebar "position: 6" with the MXC compute-driver design page, colliding in the Reference nav ordering. What: - Move docs/reference/windows-msvc-build-design.mdx -> architecture/windows-msvc-build.md. - Strip the Fern publish frontmatter and add a plain H1, matching the other architecture docs. - Register it in the architecture doc index in architecture/README.md. - Repoint the inbound references (build-openshell-mxc-windows skill + reference, implement-openshell-mxc-driver skill) to the new path. With both design pages moved out of docs/reference/, the duplicate position-6 sidebar collision is resolved. Signed-off-by: Akber Raza <akberr@nvidia.com> * remove openshell-supervisor-network from unsupported driver package test exclusion list Signed-off-by: Akber Raza <akberr@nvidia.com> # Conflicts: # tasks/scripts/windows-msvc.ps1 * fix(interceptors): gate unix-only imports so the crate builds on Windows openshell-gateway-interceptors failed to compile on Windows (E0432: no UnixStream in tokio::net), breaking any Windows build of openshell-server (which depends on it unconditionally). The connect_unix_endpoint fn was already #[cfg(unix)]-gated, but the imports it uses (UnixStream, TokioIo, Uri, service_fn) were left ungated. Gate those four imports with #[cfg(unix)] too. No behavior change on unix; Windows now compiles (no errors, no unused-import warnings). Signed-off-by: Akber Raza <akberr@nvidia.com> * feat(windows): add native ARM64 test support Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(mise): skip Skaffold on Windows Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): harden ARM64 toolchain discovery Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): scope ARM64 toolchain preflight Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): restore compatibility after GitHub sync Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): avoid rate-limited Z3 source lookup Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(mise): skip Helm checks on Windows Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): support repository pre-commit checks Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): stabilize native MSVC validation Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): harden shared Z3 source cache Signed-off-by: Shailendra Singh <shailendras@nvidia.com> * fix(windows): avoid leaking MSVC flags into clang-cl Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): complete ARM64 migration audit Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): restore ARM64 Ninja discovery Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor(windows): separate platform crate roots Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): restore proto include cfg gating Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor: address lint errors * fix(windows): add preflight check for proxy auth file path * docs(windows): update GitHub checkout guidance Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): restore CI after dependency updates Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(mise): repair Windows sccache lock entry Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(windows): reconcile validation after rebase Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor(server): exclude unsupported drivers on Windows Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * refactor(server): isolate platform driver config Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> * fix(windows): repair unsupported driver contract test Signed-off-by: Akber Raza <akberr@nvidia.com> * fix(sandbox): remove stale dependencies Signed-off-by: Akber Raza <akberr@nvidia.com> * ci(windows): pin x64 workflow actions Signed-off-by: Akber Raza <akberr@nvidia.com> * ci(windows): align x64 Rust toolchain Signed-off-by: Akber Raza <akberr@nvidia.com> * ci(windows): align ARM64 workflow setup Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor(windows): exclude unsupported runtime crates Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor(windows): exclude unsupported crates at workspace boundary Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * refactor(server): gate builtin driver config by platform Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * fix(sandbox): restore crate documentation Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * ci(windows): make build workflow manual Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * ci(windows): temporarily enable pull request builds Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * ci(windows): cache Rust dependencies Signed-off-by: Akber Raza <akberr@nvidia.com> * refactor(windows): remove unnecessary platform changes Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * ci(windows): make build workflow manual Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * fix(ci): synchronize mise lockfile Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * fix(ci): normalize mise provenance metadata Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * refactor(python): isolate Windows atomic replace retry Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> * fix(python): type Windows permission test errors Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> --------- Signed-off-by: Shailendra Singh <shailendras@nvidia.com> Signed-off-by: Akber Raza <akberr@nvidia.com> Signed-off-by: Giedrius Burachas <gburachas@nvidia.com> Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> Signed-off-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> Co-authored-by: Shailendra Singh <shailendras@nvidia.com> Co-authored-by: Giedrius Burachas <gburachas@nvidia.com> Co-authored-by: Jamie King <jamiek@nvidia.com> Co-authored-by: Piotr Mlocek <pmlocek@nvidia.com> Co-authored-by: Piotr Mlocek <1116309+pimlock@users.noreply.github.com> |
||
|
|
170961997f |
chore(ci): disable telemetry in internal test runs (#2648)
* chore(ci): disable telemetry in internal test runs Signed-off-by: Matthew Grossman <mgrossman@nvidia.com> * test(ci): remove brittle telemetry wiring test Signed-off-by: Matthew Grossman <mgrossman@nvidia.com> * docs: trim CI telemetry guidance Signed-off-by: Matthew Grossman <mgrossman@nvidia.com> * test(e2e): share telemetry default with OpenShift Signed-off-by: Matthew Grossman <mgrossman@nvidia.com> --------- Signed-off-by: Matthew Grossman <mgrossman@nvidia.com> |
||
|
|
5548405fcb |
feat(credentials): add provider credential storage drivers (#2437)
* feat(credentials): add provider credential storage drivers Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(credentials): harden credential update handling Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(credentials): harden credential driver security, correctness, and performance Address review findings from the credential storage drivers PR: - Route additional_credentials through the driver on refresh to prevent silent data loss for multi-credential providers (e.g. AWS STS) - Clean up stored credential handles on CAS failure during refresh to prevent orphaned secrets in external backends - Enforce namespace validation in the Kubernetes Secrets driver to prevent cross-namespace credential access when allow_reference_namespace is not enabled - Cache Vault Kubernetes auth tokens with 80% TTL to avoid re-authenticating on every credential operation - Parallelize resolve_credentials in all three drivers using try_join_all for faster sandbox startup - Add existingSecret support for the KEK Secret to fix helm template/GitOps workflows where lookup returns empty and regenerates the key - Document RBAC blast radius for the Kubernetes Secrets credential driver and recommend a dedicated namespace Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com> Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * fix(credentials): add optimistic concurrency, fix thundering herd, parallelize operations Use resourceVersion optimistic concurrency with retry loop for K8s Secret ownership checks to prevent TOCTOU races. Switch Vault token cache from RwLock to Mutex with double-check pattern to prevent thundering herd on cache miss. Parallelize credential store and delete operations across independent keys using try_join_all. Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com> Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * fix(credentials): handle partial failures, add delete retry, consolidate cleanup Replace try_join_all with join_all in credential store/delete operations to handle partial failures — successfully-stored handles are cleaned up when another key fails. Add retry loop with conflict detection to db-credstore delete_credential, matching the K8s driver pattern. Consolidate 4 manual cleanup_pre_stored_provider_credentials call sites into a single error handler using an async block. Remove inconsistent .trim() from db-credstore validate_handle_owner. Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com> Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * fix(credentials): fix retry loop guard and remove unprotected validation Remove attempt-count guard from 409/Aborted match arms in retry loops so the post-loop Status::aborted error is reachable after exhausting retries. Previously, last-attempt conflicts fell through to the catch-all error arm, producing misleading Status::unavailable errors. Remove duplicate validation calls that ran after prepare_provider_credential_update but outside the cleanup-protected async block, which would leak pre-stored handles on failure. Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com> Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> * fix(credentials): add workspace/provider UUID to credential backend paths Include workspace and provider ID in credential backend object paths to ensure cross-workspace uniqueness and prevent credential collision (GATOR-1806c9be-01). - Updated credential driver proto to include workspace and provider_id fields - Modified Vault driver to include workspace/provider_id in managed_secret_path - Modified Kubernetes Secrets driver to include workspace/provider_id in credential_owner_id and managed_secret_name - Updated all credential runtime calls to pass workspace/provider_id - Updated tests to use the new signatures This prevents two workspaces sharing the same external credential store from colliding on provider names, which was a critical security issue (CWE-639). * fix(credentials): preserve provider-level expiration for handle-backed credentials Compute effective expiration from both provider and driver values using the earliest non-zero timestamp and skip expired values before insertion (GATOR-1806c9be-02). - Modified resolve_provider_handles to check provider credential_expires_at_ms - Skip expired credentials during resolution instead of returning them - Use effective expiration (min of provider and driver) in resolution results - Fix inference.rs to preserve earliest expiration when merging This ensures handle-backed credentials respect the same expiration semantics as inline credentials. * fix(credentials): stage refresh changes under new handles before validation Stage credential replacements under new immutable handles instead of reusing existing handles to prevent overwriting committed values before validation/CAS (GATOR-1806c9be-03). - Stage credentials with empty existing_handles map to force new handle creation - Validate and CAS before the new values are committed to backend storage - Delete old handles only after successful CAS - On CAS failure, delete only the newly staged handles - This prevents CWE-362/CWE-367 race conditions where failed refreshes could still modify or delete the active credential The fix ensures that a rejected refresh cannot modify the backend object still referenced by the committed provider record. * fix(credentials): add timeouts to credential driver RPCs Apply configured timeouts to both startup capability negotiation and runtime RPCs to prevent indefinite hangs (GATOR-1806c9be-05). - Add DEFAULT_CREDENTIAL_DRIVER_RPC_TIMEOUT_SECS constant (30s) - Apply timeout to GetCapabilities during startup connection - Apply timeout to all runtime RPCs (store, delete, resolve) - Use tokio::time::timeout to bound the entire GetCapabilities operation during startup, not just the socket connection - Return contextual deadline errors on timeout This prevents a faulty or overloaded driver from hanging gateway operations indefinitely. * fix(credentials): fix test to use consistent workspace/provider identity The Kubernetes auth Vault resolve test was constructing a managed path with test-workspace/test-provider-id but sending default/prov-123 in the request, causing validation to reject the request (GATOR-18e32351-01). - Update test to use test-workspace and test-provider-id in the request to match the logical_path construction - This ensures the test exercises the intended code path and validates Kubernetes auth resolution properly The test now passes and correctly validates identity enforcement. * fix(credentials): use unique staging ID for refresh to avoid overwrites Stage refresh replacements under genuinely distinct immutable handles using a unique staging ID to prevent overwriting committed values (GATOR-1806c9be-03). - Generate a unique staging ID using UUID for each refresh operation - Use this staging ID when storing credentials instead of the real provider ID - Pass the same staging ID during cleanup on failure to delete only staged objects - This ensures deterministic paths (Vault) and object names (K8s) don't collide with the committed provider's credentials The fix prevents failed refreshes from silently replacing active credentials or breaking providers by deleting still-referenced backend objects. * fix(credentials): wrap credential driver RPCs in local timeouts Add local tokio::time::timeout wrappers around credential driver RPCs to bound non-compliant or stalled UDS peers (GATOR-1806c9be-05). - Wrap StoreCredential, DeleteCredential, and ResolveCredentials in local timeouts - Return contextual deadline_exceeded errors when timeouts occur - Keep existing gRPC timeout metadata for compliant implementations - GetCapabilities during startup was already wrapped in previous commit This ensures a faulty local driver cannot hang gateway operations indefinitely, even if it accepts the connection but never responds to the RPC. * fix(credentials): preserve ownership for staged refreshes Signed-off-by: Seth Jennings <sjenning@redhat.com> * fix(credentials): bound startup capability probe Signed-off-by: Seth Jennings <sjenning@redhat.com> * test(provider): authenticate credential handler requests Signed-off-by: Seth Jennings <sjenning@redhat.com> * fix(ci): grant actions read to credential driver e2e Signed-off-by: Seth Jennings <sjenning@redhat.com> --------- Signed-off-by: Taylor Mutch <taylormutch@gmail.com> Signed-off-by: Varsha Prasad <varshaprasad96@gmail.com> Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> Signed-off-by: Seth Jennings <sjenning@redhat.com> Co-authored-by: Taylor Mutch <taylormutch@gmail.com> Co-authored-by: Varsha Prasad Narsing <varshaprasad96@gmail.com> |
||
|
|
fe15caa89f |
test(e2e): add VM-backed E2E suite runner (#2473)
* test(vm): add composable QEMU test guests Signed-off-by: Drew Newberry <anewberry@nvidia.com> * docs(vm): describe test VM directory structure Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(vm): replace shell catalog functions Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(vm): add Fedora release guest support Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(vm): enable rootless Podman socket Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(test-guest): add OCI-backed image caching Signed-off-by: Drew Newberry <anewberry@nvidia.com> * perf(test-guest): accelerate cached guest startup Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): address review feedback Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): verify OCI cache provenance Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): harden cached guest reuse Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): refresh runtime setup state Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(test-guest): support E2E runner inputs Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(test-guest): harden runner and OCI reuse Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(test-guest): prepare Podman E2E artifacts Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(e2e): add host and test VM runner Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(e2e): add VM-backed Podman shutdown suite Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): use renamed test guest app Signed-off-by: Drew Newberry <anewberry@nvidia.com> * chore(e2e): rename runner task Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): make guest smoke examples portable Signed-off-by: Drew Newberry <anewberry@nvidia.com> * test(e2e): remove Podman shutdown suite Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): use test guest Podman setup Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): run Rust suites directly Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): simplify suite runner Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(e2e): isolate runner runtime state Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(e2e): prepare Podman VM runtime Signed-off-by: Drew Newberry <anewberry@nvidia.com> * perf(e2e): speed up cached guest startup Signed-off-by: Drew Newberry <anewberry@nvidia.com> * perf(e2e): streamline guest gateway startup Signed-off-by: Drew Newberry <anewberry@nvidia.com> --------- Signed-off-by: Drew Newberry <anewberry@nvidia.com> |
||
|
|
9c019a93f5 |
Wire authorization into workspace model (#2445)
* feat(auth): implement RFC 0011 Phase 2 workspace authorization Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): address PR review feedback on workspace authorization - Docker e2e: add --health-port and switch readiness probe from `openshell status` to `curl /healthz`, fixing a false-positive readiness check in OIDC mode where the CLI exited 0 without actually contacting the gateway - ListWorkspaces: move membership filtering from post-query N+1 lookups into a SQL EXISTS subquery so pagination applies to the visible set, not the global ordering. Add generic list_with_membership to the persistence layer. - Descriptor validator: reject role/scope fields on unauthenticated and sandbox auth modes, and allow-list workspace_role as user/admin and global_role as platform_admin to catch typos at startup Signed-off-by: Derek Carr <decarr@redhat.com> * fix(server): use authed request in delete telemetry test The workspace authorization added by the Phase 2 auth changes requires a Principal on every delete request. The delete-telemetry test was still using a bare Request::new, so extract_principal failed before the handler could acquire the delete gate, causing a 5-second timeout flake. Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): address gator review findings for workspace authorization - Inject unauthenticated-local-dev principal in no-auth gateway mode so handlers that call extract_principal() always find one. - Cap label-selector membership query at MAX_PAGE_SIZE instead of u32::MAX to bound the in-memory read. - Authorize workspace membership before resolving workspace existence in all sandbox RPCs to prevent workspace-name enumeration by non-members. - Remove dead_code allow on AuthorizedWorkspace.workspace now that callers use the normalized name from the authz result. Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): close workspace-name oracle and label-selector truncation Swap authorize-before-resolve ordering in 27 handlers across provider.rs, service.rs, policy.rs, and workspace.rs to prevent CWE-203 workspace-name enumeration by non-members. Add combined membership+label SQL query (list_with_membership_and_selector) to both persistence backends so ListWorkspaces with label selectors no longer silently drops results beyond the first page of membership matches. Signed-off-by: Derek Carr <decarr@redhat.com> * test(auth): add non-member rejection and membership+label persistence tests Add comprehensive test coverage for workspace authorization changes: - Non-member rejection tests across all 44 workspace-scoped handlers (sandbox, provider, service, policy, workspace, inference) verifying PERMISSION_DENIED is returned instead of NOT_FOUND to prevent CWE-203 workspace-name oracle - Persistence test for list_with_membership_and_selector verifying SQL-level membership EXISTS + label filtering, multiple predicates, no-match cases, and pagination Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): format merged import line in sandbox tests Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): address gator re-review findings on workspace authorization - Fix TUI unconditionally setting providers_v2_enabled after provider refresh; read the actual gateway setting via GetGatewayConfig at startup instead - Fix SQLite json_extract with dotted label keys (e.g. example.com/env) by quoting the key in the JSON path - Add authed_request wrappers to upstream OCI identity tests that were missing a principal after rebase - Add test proving GetGatewayConfig is accessible without Platform Admin - Add test for dotted/prefixed Kubernetes-style label key filtering Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): address second gator re-review findings - Loosen GetGatewayConfig from platform_admin to scope-only so workspace users can discover providers_v2_enabled during sandbox creation with inferred-provider commands; update proto descriptor, descriptor validation, and RFC 0011 access table - Add validate_label_selector to handle_list_workspaces and escape single quotes in SQLite json_extract interpolation (CWE-89 defense-in-depth) - Re-fetch providers_v2_enabled after TUI gateway switch so the new gateway's capability is reflected - Add e2e test for workspace user with inferred-provider command - Add persistence test for adversarial label keys with SQL injection attempts - Add handler test for invalid label selector rejection in ListWorkspaces Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): address third gator review findings - Cap label selector pairs at 64 (CWE-400) to bound SQLite dynamic SQL - Add SCOPE_ONLY_METHODS allowlist for scope-without-role RPCs (CWE-863) - Normalize ID-based data-plane handlers to return NOT_FOUND for unauthorized sandboxes, closing the cross-workspace oracle (CWE-203) - Fix TUI provider profile cache lookup key mismatch for legacy providers with empty profile_workspace - Add whoami to CLI skill reference command tree - Update TUI skill doc with workspace, provider, and settings coverage - Document scope/workspace orthogonality on GetGatewayConfig proto Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): extend CWE-203 normalization to policy.rs sandbox handlers GetSandboxConfig and GetSandboxLogs in policy.rs had the same fetch-before-authorize pattern that leaked cross-workspace sandbox existence. Promote fetch_and_authorize_sandbox to pub(super) and use it from both sandbox.rs and policy.rs handlers. Signed-off-by: Derek Carr <decarr@redhat.com> * test(auth): update assertions for CWE-203 sandbox ID normalization Cross-workspace sandbox access via ID-based handlers now returns NOT_FOUND instead of PERMISSION_DENIED to prevent existence inference. Update the unit test and OIDC e2e assertion to match. Signed-off-by: Derek Carr <decarr@redhat.com> * fix(auth): narrow CWE-203 error mapping and correct whoami output formats Only remap PERMISSION_DENIED to NOT_FOUND in fetch_and_authorize_sandbox and RevokeSshSession, letting INTERNAL and UNAUTHENTICATED propagate as-is. Fix whoami --output format values in cli-reference.md to match the actual CLI (table/json/yaml, not text/json). Signed-off-by: Derek Carr <decarr@redhat.com> * fix(ci): share network namespace with Keycloak in containerized CI In GitHub Actions job containers, Docker port publishing lands on the host, not inside the job container. Detect this environment and attach Keycloak to the job container's network namespace instead, with hardened defaults (cap-drop ALL, no-new-privileges, loopback-only listener). Signed-off-by: Derek Carr <decarr@redhat.com> --------- Signed-off-by: Derek Carr <decarr@redhat.com> |
||
|
|
745512e325 |
fix(build): raise open-file limit for host musl cross-compile on macOS (#2307)
Closes #2112 The host `cargo zigbuild` for `*-unknown-linux-musl` opens ~333 `.rlib` files at once during the static link, exceeding macOS's default soft limit of 256 and failing with `ProcessFdQuotaExceeded`. This blocked the docker/podman `mise run gateway` paths for macOS contributors; only the VM driver path guarded against it. Extract the VM path's `ensure_build_nofile_limit` guard into a shared `tasks/scripts/build-env.sh` and call it from the host-staging chokepoint (`stage-prebuilt-binaries.sh`), fixing docker, podman, and all docker:*/multiarch host cross-compiles at once. De-duplicate the VM script to source the shared helper. The guard is a no-op on Linux and when cargo-zigbuild is absent, so CI and Linux dev are unaffected. The limit is read from `OPENSHELL_BUILD_NOFILE_LIMIT` (default 8192), honoring the legacy `OPENSHELL_VM_BUILD_NOFILE_LIMIT` for back-compat. Also correct the stale comment in gateway-docker.sh (the cross-compile runs on the host, not inside Linux containers) and document the guard in architecture/build.md. Adds tasks/scripts/test-build-env.sh, wired into `mise run test` via `test:build-env`. Signed-off-by: Jim Meyer <jim@meyer4hire.com> |
||
|
|
339eae5ad1 |
ci(e2e): reuse prebuilt CLI and gateway artifacts (#2311)
* ci(e2e): reuse prebuilt CLI artifacts Signed-off-by: Evan Lezar <elezar@nvidia.com> * ci(e2e): reuse prebuilt gateway artifacts Signed-off-by: Evan Lezar <elezar@nvidia.com> * ci(e2e): reuse prebuilt VM driver artifact Signed-off-by: Evan Lezar <elezar@nvidia.com> --------- Signed-off-by: Evan Lezar <elezar@nvidia.com> |
||
|
|
392ad63941 |
fix(driver-vm): run sandbox supervisor as guest pid 1 (#2299)
Signed-off-by: Drew Newberry <anewberry@nvidia.com> |
||
|
|
8eacb4779f |
feat(kubernetes): add sidecar supervisor topology (#2076)
* feat(kubernetes): add sidecar supervisor topology Add the Kubernetes sidecar supervisor topology, its Helm/Skaffold configuration, topology documentation, and sidecar e2e matrix coverage. Skip root-only sandbox identity rewriting when process enforcement is network-only so the low-permission sidecar process container can start successfully. Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(supervisor): avoid similar process id names Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(supervisor): avoid similar process id names Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(sandbox): avoid similar proxy id names Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * docs(kubernetes): clarify sidecar topology limits Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): keep sidecar process leaf capless Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): refresh sidecar provider env snapshots Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * test(supervisor): align hot-swap identity regression Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): stage sidecar mtls files before proxy chown Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): simplify sidecar supervisor topology Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * chore(helm): reuse sidecar skaffold values Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(supervisor): avoid similar iptables helper names Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(e2e): harden kube gateway wrapper setup Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(supervisor): avoid nft batch rollback on OCP Run nftables setup as individual commands so optional conntrack and log expressions can fail without rolling back required table, chain, and reject rules. Signed-off-by: Seth Jennings <sjenning@redhat.com> Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): preserve process identity in sidecar topology Render sidecar pods with a shared process namespace, keep binary-aware network policy enabled, and move Kubernetes sidecar settings under the nested sidecar config table. Also apply unprivileged Landlock/seccomp setup in NetworkOnly supervisor mode so sidecar topology keeps sandbox child hardening without privileged process setup. Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * refactor(kubernetes): replace sidecar snapshots with control socket Coordinate sidecar policy and provider bootstrap over a local Unix socket so the process leaf no longer reads policy/provider snapshot files. Report entrypoint startup through the control channel and keep gateway credentials confined to the network sidecar. Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * feat(kubernetes): support relaxed sidecar network identity Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(sandbox): satisfy sidecar clippy lint Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * refactor(kubernetes): standardize topology naming Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(sandbox): satisfy linux clippy timeout import Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): support kata sidecar on ipv4 pods Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): satisfy linux clippy for sidecar fallback Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * chore(kubernetes): remove stale supervisor topology references Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): enable sidecar binary policy inspection Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): harden sidecar control boundary Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): couple sidecar supervisor lifecycles Signed-off-by: Taylor Mutch <taylormutch@gmail.com> --------- Signed-off-by: Taylor Mutch <taylormutch@gmail.com> Signed-off-by: Seth Jennings <sjenning@redhat.com> Co-authored-by: Seth Jennings <sjenning@redhat.com> |
||
|
|
a226806026 |
test(e2e): run gpu workloads from manifest (#1709)
* test(e2e): add workload manifest build flow Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(e2e): add gpu workload validation tests Signed-off-by: Evan Lezar <elezar@nvidia.com> * ci(e2e): build gpu workloads before gpu e2e Signed-off-by: Evan Lezar <elezar@nvidia.com> --------- Signed-off-by: Evan Lezar <elezar@nvidia.com> |
||
|
|
7bce1223dc |
feat(policy): add JSON-RPC and MCP L7 policies (#1865)
Add policy schema, proto, provider profile, OPA, and L7 proxy support for `protocol: json-rpc` and `protocol: mcp`. Generic JSON-RPC endpoints match exact method names only, with `method: "*"` as the all-method sentinel; wildcard/glob methods and params matchers are rejected. Parse JSON-RPC request bodies and batches in the forward proxy, deny response-shaped client frames, limit receive-stream GET allowance to MCP endpoints, and redact params in decision logs. Preserve L7 rule params on the proto load path so MCP `tools/call` tool filters behave like YAML-loaded policies. Add MCP conformance coverage, JSON-RPC L7 e2e coverage, and docs for the new protocols and current matcher limitations. Signed-off-by: Kris Hicks <khicks@nvidia.com> Co-authored-by: ddurst <267424412+ddurst-nvidia@users.noreply.github.com> |
||
|
|
ba21bb32a2 |
feat(kubernetes): support agent-sandbox v1beta1 (#2009)
* feat(kubernetes): support agent-sandbox v1beta1 Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * ci(kubernetes): test agent-sandbox api versions Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): retry agent-sandbox raw 404s Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): harden agent-sandbox api setup Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * fix(kubernetes): cache agent-sandbox api version Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * docs(kubernetes): document agent-sandbox upgrade behavior Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * refactor(kubernetes): collapse agent-sandbox api selection Signed-off-by: Taylor Mutch <taylormutch@gmail.com> --------- Signed-off-by: Taylor Mutch <taylormutch@gmail.com> |
||
|
|
c7879a0a1d |
test(e2e): stop using custom e2e binary builds (#2000)
Remove the production-crate dev-settings feature so e2e tests build the same gateway, CLI, and supervisor binaries that we ship. Move settings coverage from dummy test-only keys to the production ocsf_json_enabled setting. Signed-off-by: Simon Scatton <sscatton@nvidia.com> |
||
|
|
f084eb39cb |
fix(sbom): release lock before sleeping in _rate_limit (#1896)
* fix(sbom): release lock before sleeping in _rate_limit time.sleep was called inside the _rate_lock block, blocking all threads from checking their own domain rate limit while one thread slept. With _MAX_WORKERS=12 querying crates.io, npm, and pypi concurrently, this made the thread pool effectively serial. Move the sleep outside the lock so threads for different domains can proceed concurrently. * fix(sbom): reserve next slot in _rate_limit to prevent same-domain races Use time.monotonic() and store next_req = max(now, last + interval) so concurrent same-domain callers each get a unique future slot rather than all sleeping the same amount. Add regression tests for same-domain spacing and different-domain non-blocking. * fix(sbom): wire rate-limit tests into test suite via test:sbom task Rename test_resolve_licenses.py to resolve_licenses_test.py to match repo *_test.py convention. Add test:sbom task to tasks/test.toml and include it in the top-level test depends so mise run test picks it up. * fix(sbom): add SPDX header, fix cross-domain regression test to exercise lock contention * fix(sbom): replace zip with itertools.pairwise to satisfy ruff lint |
||
|
|
f23c2c8e84 |
test(e2e): remove python gpu smoke test (#1948)
* fix(helm): build chart dependencies before lint Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(e2e): remove python gpu smoke test Remove the Python GPU smoke test and its fixture. The e2e:k3s:gpu task only depended on e2e:python:gpu and did not have a separate k3s implementation, so remove that stale alias with the task it pointed at. Signed-off-by: Evan Lezar <elezar@nvidia.com> (cherry picked from commit 221a10378e188656c710560740cbc9463c002db6) --------- Signed-off-by: Evan Lezar <elezar@nvidia.com> |
||
|
|
8c0153438c |
test(e2e): add GPU workload image artifacts (#1484)
* test(e2e): add GPU workload image artifacts Closes #1476 Define local GPU workload image sources for smoke-pass, smoke-fail, and cuda-basic validation, plus a mise build task that tags images with the source revision and records the latest local image refs. Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(e2e): add workload manifest build flow Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(e2e): fix gpu workload README lint Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(e2e): address gpu workload review feedback Signed-off-by: Evan Lezar <elezar@nvidia.com> --------- Signed-off-by: Evan Lezar <elezar@nvidia.com> |
||
|
|
6c8cf38b63 |
ci(docs): add docs website automation (#1788)
* ci(docs): add docs website automation * ci(docs): harden sync-docs inputs and add script tests Route free-form workflow_dispatch inputs through env vars to avoid shell injection, switch uv install to the approved setup-uv action, and add a pytest suite for sync_docs_website.py wired into the test task. |
||
|
|
c4ca283c1a | refactor(helm): require external postgres for ha (#1844) | ||
|
|
7cea9d9b2b |
fix(gateway): align package TLS bootstrap path (#1601)
* fix(gateway): align package TLS bootstrap path Closes #1593 Default package-managed gateway services to a stable local TLS directory and use that same value for certificate generation and runtime startup. Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * test(packaging): validate package asset paths exist Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * ci(e2e): pin mise in kubernetes job Signed-off-by: Taylor Mutch <taylormutch@gmail.com> --------- Signed-off-by: Taylor Mutch <taylormutch@gmail.com> |
||
|
|
f1ed347a40 |
fix(driver-podman): bind gateway to 0.0.0.0 in rootless mode (#1623)
Rootless Podman sandbox containers reach the host through pasta's local connection bypass, which translates L2 frames to L4 host sockets. The dev gateway script binds to 127.0.0.1 by default, which is not routable through pasta. Auto-detect rootless mode and bind to 0.0.0.0 so sandbox containers can connect to the gateway. - Auto-detect rootless Podman in gateway.sh and export OPENSHELL_BIND_ADDRESS=0.0.0.0 when not explicitly set - Add e2e:podman:rootless mise task and CI matrix entry to validate rootless Podman networking end-to-end - CI creates a non-root user inside the privileged container to trigger Podman's rootless code paths (pasta, user namespace isolation) Signed-off-by: Naveen Malik <nmalik@redhat.com> |
||
|
|
5007042e79 |
feat(helm): add optional PostgreSQL backing store (#1579)
* feat(helm): add optional PostgreSQL backing store with Secret-based credentials - Add postgres.enabled and postgres.deploy values to control database backend (SQLite vs PostgreSQL) and subchart deployment independently. - Introduce db-secret.yaml template for Opaque Secret with assembled postgresql:// connection string injected via OPENSHELL_DB_URL env var. - Add Bitnami PostgreSQL as optional subchart dependency keyed on postgres.deploy to prevent subchart deployment in external mode. - Externalize JWT signing key file mode via sandboxJwt.secretDefaultMode with 0400 default matching upstream. - Add validation guard for postgres.deploy=true without postgres.enabled. - Add helm unit tests covering internal, external, URL-override, special character encoding, and misconfiguration error paths. - Update README with Kubernetes and OpenShift install examples for bundled and external PostgreSQL configurations. - Add helm dependency build to lint and unittest tasks. * fix(helm): add database backend docs to README.md.gotmpl and regenerate The helm-docs CI check failed because the Database backend section was added directly to README.md instead of README.md.gotmpl. Move the content to the template and regenerate so the check passes. * fix(helm): use Secret-based DB credentials and support existingSecret Replace the inline db-url stringData pattern with a proper Secret containing individual fields plus a uri key. When postgres.deploy=true the Bitnami service-binding secret is referenced directly; when deploy=false users can supply postgres.external.existingSecret to bring their own Secret, or let the chart generate one from the external field values. Also restructures the README database section for clarity, adds helm-unittest coverage for the new secret resolution paths, and fixes a markdown lint issue in the root README. * refactor(helm): move OpenShift e2e script to e2e/rust/ and add mise task Move test-openshift-scenarios.sh from deploy/helm/openshell/ci/ to e2e/rust/e2e-openshift.sh, matching the existing e2e script naming convention. Register it as `e2e:openshift` in tasks/test.toml — not wired into the `test` or `e2e` aggregates so it only runs on explicit invocation against a live OpenShift cluster. * feat(e2e): add database backend scenarios to Kubernetes e2e Extend with-kube-gateway.sh with an optional multi-scenario loop gated by OPENSHELL_E2E_KUBE_DB_SCENARIOS=1. When enabled, the script installs the Helm chart three times — SQLite (default), bundled PostgreSQL, and external PostgreSQL with existingSecret — running the full test suite against each backend. When unset, existing single-install behavior is unchanged. Also adds helm dependency build before helm install, fixing CI failures caused by the missing PostgreSQL subchart dependency. * refactor(helm): simplify PostgreSQL config to two orthogonal controls Replace postgres.deploy and postgres.external.* with two simple controls: - postgres.enabled: deploy the bundled Bitnami PostgreSQL subchart - server.externalDbSecret: name of a pre-existing Secret with a uri key Delete db-secret.yaml — the chart no longer generates Secrets from individual credential fields. Users either get the Bitnami service-binding secret (bundled) or bring their own via server.externalDbSecret. Add validation that postgres.serviceBindings.enabled must stay true when using bundled PostgreSQL, preventing a confusing runtime failure. |
||
|
|
2bdc968ed9 |
fix(gateway): make readiness health checks dependency-aware (#1328)
* feat(gateway): add readiness probe metrics and test-only store close Emit Prometheus readiness metrics for database probes (healthy gauge and outcome-labeled latency histogram) with coverage in health HTTP tests. Restrict Store::close behind test support cfg to prevent accidental runtime pool shutdown under live traffic. Signed-off-by: Adrien Langou <alangou@nvidia.com> * test(e2e): add simple e2e test with kubernetes to test /readyz Signed-off-by: Adrien Langou <alangou@nvidia.com> --------- Signed-off-by: Adrien Langou <alangou@nvidia.com> |
||
|
|
7174983ff1 |
fix(sandbox): add mechanistic smoke test for L4 deny and document the L4/L7 split (#1412)
* fix(sandbox): add mechanistic smoke test for L4 deny and document the L4/L7 split The old smoke script exercised an L7 PUT which hung because the denial aggregator is only wired to L4 CONNECT denies, not L7 enforcement. Add mechanistic-smoke.sh which triggers an L4 deny, waits for the aggregator to flush, and asserts a pending chunk appears under openshell rule get --status pending. Document the intentional L4-only scope of the mechanistic mapper in architecture/sandbox.md. Fixes #1333 Signed-off-by: mesutoezdil <mesudozdil@gmail.com> * refactor(smoke): remove redundant variable inits and merge double step call Signed-off-by: mesutoezdil <mesudozdil@gmail.com> * fix(smoke): wire mechanistic smoke into mise and guard TMP_DIR - Initialize TMP_DIR before trap to prevent unbound variable on early exit - Add e2e:mechanistic-smoke mise task with gateway setup - Document mechanistic smoke in policy-advisor README * test(proxy): verify L4 deny enqueues a DenialEvent Signed-off-by: mesutoezdil <mesudozdil@gmail.com> * fix(proxy): remove unnecessary path qualifications in L4 denial smoke test --------- Signed-off-by: mesutoezdil <mesudozdil@gmail.com> |
||
|
|
0dc08a185e | fix(release): build host Linux binaries with glibc floor (#1490) | ||
|
|
dbba580e84 |
fix(security): refresh CI and gateway image dependencies (#1432)
Refresh the CI image tool pins so Go-built tools are rebuilt with patched Go releases and move the sandbox Python runtime to 3.14.5. Rebase the gateway runtime to a pinned distroless Debian 13 image with glibc 2.41-12+deb13u3 while preserving the existing UID/GID 1000 runtime identity for upgrade compatibility. Update rustls-webpki to 0.103.13 and clarify Linux k3d guidance now that k3d is not installed through mise on Linux. Signed-off-by: John Myers <9696606+johntmyers@users.noreply.github.com> |
||
|
|
9ea94b645d |
fix(sandbox): rewrite messaging credential placeholders (#1286)
* fix(sandbox): rewrite credential placeholders in websocket text frames Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(sandbox): harden websocket credential rewrite Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * feat(sandbox): add websocket l7 inspection and compression Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(sandbox): harden websocket upgrade validation Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * test(sandbox): cover route-selected websocket upgrades Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(sandbox): harden websocket negotiation parsing Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * test(sandbox): add websocket conformance relay matrix Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * test(e2e): add websocket conformance lane Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(policy): support websocket incremental rules Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * feat(policy): enable websocket credential rewrite updates Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(cli): make websocket rewrite endpoint-local Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * feat(sandbox): support graphql websocket policy Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(policy): allow private IPs for websocket endpoints * feat(sandbox): rewrite REST credential placeholders Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * refactor(sandbox): generalize credential aliases Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(sandbox): rewrite encoded form credentials Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(sandbox): close websocket policy and provider alias gaps Signed-off-by: Aaron Erickson <aerickson@nvidia.com> * fix(e2e): route websocket probe through host gateway * fix(e2e): stabilize websocket probe handshake * fix(e2e): exercise websocket probe through proxy * ci: remove websocket conformance workflow --------- Signed-off-by: Aaron Erickson <aerickson@nvidia.com> Co-authored-by: John Myers <9696606+johntmyers@users.noreply.github.com> |
||
|
|
59475aabf4 |
ci(kubernetes): add kube gateway e2e tests and gated CI workflow (#1251)
* test(helm): Add kube gateway e2e tests Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * ci(helm): add Branch Helm E2E workflow gated on test:e2e-helm Adds a label-gated GitHub Actions workflow that exercises the Helm chart end-to-end against the Rust e2e suite via `mise run e2e:helm`. Pipeline: - pr_metadata gates on the `test:e2e-helm` label via the pr-gate action. - build-gateway / build-supervisor build and push Docker images using the reusable docker-build.yml workflow. - helm-e2e (bare runner): apt-installs z3 build deps so cargo can compile the openshell-policy crate's z3-sys backend, creates a kind cluster via helm/kind-action, materializes the kind kubeconfig at the path mise's [env] block expects, side-loads the freshly built gateway/supervisor images, applies deploy/kube/manifests/agent-sandbox.yaml so the sandboxes.agents.x-k8s.io CRD and reconciling StatefulSet are in place, and finally runs `mise run e2e:helm`. Also expands the `e2e:helm` task to run the full Rust e2e suite (matching `e2e:podman`) instead of only the smoke test, with OPENSHELL_E2E_KUBE_TEST as an opt-in single-test override for local debugging. Extends the e2e-label-help workflow so applying `test:e2e-helm` posts the next-step hint pointing at this workflow. Signed-off-by: Taylor Mutch <taylormutch@gmail.com> * test(helm-e2e): run host-gateway tests on the kube driver Six tests previously skipped on the kubernetes driver — three in host_gateway_alias.rs plus the forward_proxy_l7 + graphql_l7 cases — relied on `host.openshell.internal` reaching either a host process or a sibling docker container. The Helm chart already supports this via `server.hostGatewayIP`, but the e2e wrapper never set it. - with-kube-gateway.sh: auto-detect the host-routable IP (CoreDNS `host.k3d.internal` first to handle Docker Desktop, docker network gateway as a fallback for kind on Linux CI) and pass it to helm install. Also import locally-built images into existing k3d clusters and wait for namespace deletion to complete before exit. - e2e/rust/Cargo.toml + e2e-helm.sh: add an `e2e-host-gateway` feature that gates the three test files; docker and podman runs imply it, helm runs opt in by default (overridable via OPENSHELL_E2E_HELM_FEATURES for remote clusters where the test host is unreachable from pods). - Drop the `skip_if_kube` helper and its callers — feature gating now decides whether the tests compile in. Verified against a local k3d cluster: all six previously-skipped tests pass, smoke regression intact. * refactor(e2e): rename e2e:helm to e2e:kubernetes The runner exercises the gateway on Kubernetes; helm is just the deployment mechanism. Names now describe the target environment. - mise task: `e2e:helm` -> `e2e:kubernetes` - script: e2e/rust/e2e-helm.sh -> e2e/rust/e2e-kubernetes.sh - env var: OPENSHELL_E2E_HELM_FEATURES -> OPENSHELL_E2E_KUBERNETES_FEATURES - workflow: branch-helm-e2e.yml -> branch-kubernetes-e2e.yml (display name "Branch Kubernetes E2E", job "kubernetes-e2e") - PR gate label: test:e2e-helm -> test:e2e-kubernetes (e2e-label-help hint workflow updated to match) PR #1251 needs the new label applied; the old label can be removed. * fix(e2e): prefer IPv4 host-gateway IP from dual-stack docker networks kind dual-stacks its network; the wrapper's awk picked the first non-empty gateway, which was the IPv6 entry (fc00:...). Sandbox pods can't reach the test host's IPv4 listener through that, so the L7 and host-gateway-alias tests failed in CI even though they passed locally against k3d (where host.k3d.internal in CoreDNS short-circuits the docker-network fallback). Restrict the awk filter to IPv4 octets. --------- Signed-off-by: Taylor Mutch <taylormutch@gmail.com> |
||
|
|
5c98604f0f |
feat(gpu): honor device IDs in Docker and Podman (#1253)
* feat(gpu): honor device IDs in Docker and Podman Signed-off-by: Evan Lezar <elezar@nvidia.com> * test(gpu): add Docker and Podman device selection e2e Signed-off-by: Evan Lezar <elezar@nvidia.com> * ci(gpu): run Docker GPU e2e workflow Signed-off-by: Evan Lezar <elezar@nvidia.com> --------- Signed-off-by: Evan Lezar <elezar@nvidia.com> |
||
|
|
70a0f6c547 | refactor(cli): remove gateway lifecycle management (#1221) | ||
|
|
23ad858a4f |
test(e2e): add podman rust suite (#1185)
Signed-off-by: Drew Newberry <anewberry@nvidia.com> |
||
|
|
4d388d2677 | ci(vm): cleanup vm build infra (#1186) | ||
|
|
d8b84773ca | feat(rpm): add RPM packaging with Packit/COPR and GHA release publishing (#1126) | ||
|
|
e4b4e923ae | test(e2e): run suites against docker gateway (#1153) | ||
|
|
08001ca616 | fix(docker): harden supervisor startup and gateway routing (#1128) | ||
|
|
f46b296daf |
test(e2e): skip docker gpu test in rust suite (#1103)
Signed-off-by: Piotr Mlocek <pmlocek@nvidia.com> |
||
|
|
0c0f3e32e1 | feat(docker): enable CDI GPU sandboxes (#1036) | ||
|
|
5975805424 | feat(server): add bundled docker compute driver (#888) | ||
|
|
d44d8a1e27 |
feat: Openshell driver podman (#904)
* feat(podman): add Podman compute driver for rootless sandbox management Adds openshell-driver-podman, a new compute driver that manages OpenShell sandboxes as rootless Podman containers via the Podman REST API over a Unix socket. Enables local workstation sandboxes without Kubernetes. Driver features: - Bridge networking with ephemeral host-port mapping for rootless SSH reachability - Named volumes for workspace storage, Podman native health checks, GPU via CDI - Supervisor binary sideloaded via image volume mount (BYOC-compatible) - SSH handshake secret injected via Podman secrets API (not plaintext env) - Typed ContainerSpec structs, input validation, and path-traversal guards - Cgroups v2 required; fails fast on v1 hosts - Bounded event stream buffer; watch stream reconnection handled by server watch_loop - Graceful shutdown and standalone driver binary with gRPC bridge Rootless-specific fixes: - Skip drop_privileges when user namespace lacks SETUID/SETGID/DAC_READ_SEARCH caps - Add /run/netns tmpfs mount for ip netns in rootless containers - Use secret_env map (not secrets array) for env-var injection in libpod API - Resolve SSH endpoint to 127.0.0.1:<host_port> instead of unreachable bridge IP Server/sandbox hardening: - Split loopback and link-local SSRF gates; Podman/VM drivers allow loopback - Close SSRF bypass in SSH tunnel Host path by resolving DNS before connecting - Prevent OPENSHELL_* env var override by user-supplied spec environment maps - Disable SQLite pool idle_timeout/max_lifetime for in-memory databases - Emit deleted_event on 404-during-inspect instead of regressing sandbox phase - Key delete cleanup by stable sandbox_id to survive container label drift CLI fixes: - Restore --name as a named flag on sandbox create (not positional) - Fix exec command arg parsing to not consume sandboxed-command flags - Propagate SSH verbosity via OPENSHELL_SSH_LOG_LEVEL Build tooling: - Add tasks/scripts/container-engine.sh: auto-detects Podman or Docker, exposes unified ce_* helpers; all build/cluster/VM scripts updated to use it - Add docker:build:supervisor mise task for standalone supervisor image - Add openshell-driver-podman to Dockerfile.images pre-fetch/build stages - Add e2e/rust/e2e-podman.sh and e2e:podman mise task for full lifecycle testing Signed-off-by: Adam Miller <admiller@redhat.com> * fix(driver-podman): derive grpc endpoint from server bind port When a user starts the gateway on a non-default port (e.g. --port 8081), sandbox containers were receiving OPENSHELL_ENDPOINT pointing at the default port 8080. The driver's auto-detection fallback read OPENSHELL_BIND_ADDRESS from the environment, which was stale or unset, and fell back to DEFAULT_SERVER_PORT. Add gateway_port to PodmanComputeConfig and thread config.bind_address.port() from the server into the driver so the fallback uses the actual listening port. Remove the OPENSHELL_BIND_ADDRESS env var read and the extract_port_from_bind_address helper which are no longer needed. Add --gateway-port / OPENSHELL_GATEWAY_PORT to the standalone driver binary for parity when the driver is run outside the embedded server path. Signed-off-by: Adam Miller <admiller@redhat.com> * fix(driver-podman): address PR feedback on env test safety and cluster DNS docs Replace hand-rolled unsafe TempEnvVar RAII guard with temp_env::with_vars and a static ENV_LOCK mutex, fixing a data race in parallel test execution. The prior safety comment incorrectly claimed Cargo runs tests single-threaded. Update debug-openshell-cluster skill to accurately document the DNS proxy strategy (setup_dns_proxy + public DNS fallback) and clarify the separation between cluster DNS and sandbox agent DNS enforcement. Signed-off-by: Adam Miller <admiller@redhat.com> * fix(e2e): resolve CI failures in auth timeout, test harness, and formatting - Short-circuit browser_auth_flow when OPENSHELL_NO_BROWSER=1 instead of waiting the full 120s AUTH_TIMEOUT for a callback that never arrives - Add timeout to SandboxGuard::create() and create_with_upload() to prevent indefinite hangs (matches create_keep() which already had one) - Add missing '--' separator in no_proxy test before command args - Add #![cfg(feature = "e2e")] gate to sandbox_lifecycle.rs - Run cargo fmt on openshell-driver-podman - Refine cluster DNS docs for Podman in debug-openshell-cluster skill Signed-off-by: Adam Miller <admiller@redhat.com> * refactor(server): remove allows_loopback_endpoints from ComputeRuntime SSRF protection is now handled at the network and proxy layers (openshell-core net.rs, openshell-sandbox proxy.rs) rather than requiring per-driver flags on ComputeRuntime. Update architecture docs to reflect supervisor relay SSH transport and add rootless networking deep-dive. Signed-off-by: Adam Miller <admiller@redhat.com> --------- Signed-off-by: Adam Miller <admiller@redhat.com> |
||
|
|
4483c860e0 | feat(server,driver-vm,e2e): gateway-owned readiness + VM compute driver e2e (#901) | ||
|
|
ddb85b1704 | feat(vm): add openshell-vm crate with libkrun microVM gateway (#611) | ||
|
|
e837849009 | feat(bootstrap): resume gateway from existing state and persist SSH handshake secret (#488) | ||
|
|
1a9eea5351 |
feat(tasks): wire e2e:gpu to bootstrap cluster with GPU support (#547)
Pass CLUSTER_GPU=1 inline in e2e:python:gpu's depends so that the cluster is bootstrapped with --gpu when GPU e2e tests are run. Add --gpu flag handling to cluster-bootstrap.sh and default OPENSHELL_E2E_GPU_IMAGE to an empty string so the server resolves the default sandbox image when no override is provided. Signed-off-by: Evan Lezar <elezar@nvidia.com> |
||
|
|
a831a8921b |
feat(settings): gateway-to-sandbox runtime settings channel (#474)
* feat(gateway/sandbox): add global and sandbox runtime settings flow |
||
|
|
72e0268028 |
feat(sandbox): add gpu sandbox scheduling support (#257)
* feat(sandbox): add gpu sandbox scheduling support Allow sandbox creation to request GPU resources explicitly or infer them from GPU image names. This wires GPU intent through bootstrap, validates gateway support, and adds dedicated GPU E2E coverage for follow-up cluster testing. |
||
|
|
fbd93a4632 | refactor: rename navigator- crate prefix to openshell- (#277) | ||
|
|
a8e9b43dcc | refactor(e2e): replace bash e2e tests with Rust integration tests (#150) | ||
|
|
780731f6ba |
feat(e2e): parallelize e2e tests with pytest-xdist (default -n 5) (#102)
Closes #101 Add pytest-xdist for parallel e2e test execution with configurable concurrency. Default to 5 workers; override via E2E_PARALLEL env var (accepts a number or 'auto' for CPU-count matching). Make session-scoped mock inference route fixtures worker-safe by incorporating the xdist worker_id into route names and routing hints. Co-authored-by: John Myers <johntmyers@users.noreply.github.com> |
||
|
|
90da02a7ed | chore: simplify contributing workflow and documentation (#92) |