Commit 484d79f
committed
feat(sdk): add NAS/OSS mount syntax sugar across Kotlin, Python, TypeScript, Go, and C#
Expose `sandbox.mount(NfsMountOptions | OssfsMountOptions)` and
`sandbox.umount(mountPoint)` on the sandbox facade in all five SDKs. The
helpers build the appropriate `mount -t nfs` / `ossfs` / `ossfs2` shell
command and run it via `commands.run`, so no server change is required. The
sandbox image must have the corresponding mount binary installed, or the
options.installation field can install it at mount time.
Cross-SDK behavior is aligned so callers can rely on the same semantics:
- Version selection: `OssfsMountOptions.version` defaults to ossfs 1.x when
omitted, ossfs 2.x when set to "2.0".
- `bucketDirectory` is supported in both ossfs 1.x (`bucket:/dir`) and
ossfs 2.x (`--oss_bucket_prefix=<dir>/`).
- STS `securityToken` appends to the ossfs 1.x password file and exports
`OSS_SESSION_TOKEN` for ossfs 2.x.
- Failures raise a new `MountFailedException` / `MountFailedError` that
extends the SDK's existing sandbox exception hierarchy and carries the
failing `Execution` for diagnostics.
Security-hardened compared to the internal reference implementation:
1. The ossfs 1.x password file is created with mode 0600 atomically using
`install -m 600 /dev/null /etc/ossfspass` before `printf %s <passwd>`,
removing the world-readable window a naive `echo > file; chmod 600`
would create.
2. The ossfs 1.x cleanup step is wrapped in `( ossfs ... ); __rc=$?;
rm -f /etc/ossfspass; exit $__rc` so the password file is unlinked even
when the ossfs binary itself exits non-zero.
3. The ossfs 2.x configuration file is written to
`/tmp/opensandbox-ossfs-<uuid>.conf` with mode 600 rather than dropped
in the current working directory.
4. All shell arguments are single-quoted with proper escaping.
While pinning the ossfs 2.x conf mode to 600 the existing SDK convention
was verified: `WriteEntry.mode` is serialized as a JSON number and parsed
server-side via `strconv.ParseUint(strconv.Itoa(mode), 8, 32)` (see
`components/execd/pkg/web/controller/utils.go`), so callers must pass the
decimal literal `600` rather than an octal literal such as `0o600` (which
would serialize to 384 and fail the octal parse). The Kotlin, TypeScript,
Go, and C# implementations all pass `600`; Python passes `mode=600` as
before.
The `createIsolatedOssSession` helper from the internal Java SDK (bwrap
seccomp workaround that pre-mounts OSSFS on the host side and bind-mounts
it into the isolated session) is intentionally out of scope of this
change and will be added separately if needed.
Test results (unit only; e2e requires real NAS/OSS backends):
- Kotlin: `./gradlew :sandbox:test` -> 216 pass
- Python: `uv run pytest tests/` -> 302 pass
- TypeScript: `pnpm run test` -> 70 pass
- Go: `go test ./...` -> all pass
- C#: not verified locally (no dotnet SDK available on the workstation);
code is written to match the existing patterns in the C# SDK and passes
static review, but `dotnet test` still needs to run in CI.1 parent 5b3afaa commit 484d79f
37 files changed
Lines changed: 5383 additions & 2 deletions
File tree
- sdks/sandbox
- csharp
- src/OpenSandbox
- Core
- Internal
- Models
- tests/OpenSandbox.Tests
- go
- javascript
- src
- core
- mount
- tests
- kotlin
- sandbox/src
- main/kotlin/com/alibaba/opensandbox/sandbox
- domain
- exceptions
- models/mount
- mount
- test/kotlin/com/alibaba/opensandbox/sandbox/mount
- python
- src/opensandbox
- exceptions
- mount
- sync
- tests/mount
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
226 | 226 | | |
227 | 227 | | |
228 | 228 | | |
| 229 | + | |
| 230 | + | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
229 | 263 | | |
230 | 264 | | |
231 | 265 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
43 | 43 | | |
44 | 44 | | |
45 | 45 | | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
46 | 51 | | |
47 | 52 | | |
48 | 53 | | |
| |||
231 | 236 | | |
232 | 237 | | |
233 | 238 | | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
0 commit comments