Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ jobs:
basic_usage.py
command_stdin.py
custom_image.py
dockerfile_launch.py
named_sandbox.py
network_policy.py
port_forwarding.py
Expand Down
21 changes: 21 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ tunnels. The project overview and deployment quick start are in
- `sdk/python/` - AKernel Python SDK and CLI.
- `sdk/python/akernel_sdk/` - SDK implementation for `Sandbox`, commands,
filesystem, PTY support, instance plumbing, and CLI helpers.
- `sdk/python/akernel_sdk/_dockerfile_launch.py` - lightweight public
Dockerfile direct-launch configuration, independent of the parser and backend.
- `sdk/python/examples/` - maintained AKernel SDK examples.
- `sdk/python/tests/` - maintained AKernel SDK tests.
- `src/yuanrong/` - pinned openYuanRong mirror checkout, including its
Expand Down Expand Up @@ -347,6 +349,25 @@ Keep public `Sandbox`, `Commands`, `Filesystem`, and value types independent
of both native packages; all native conversions belong under
`akernel_sdk._backends`.

Dockerfile direct launch is a supported AKernel SDK capability through
`DockerContext` and
`Sandbox(dockerfile=DockerfileLaunch(context=..., auto_start_cmd=..., run_timeout=...))`.
The capability will remain available. Its documented strict subset evolves
incrementally with production experience, while unsupported inputs continue to
fail closed. The specific API surface may evolve; material changes require
documentation and migration guidance. Read
[`sdk/python/docs/launch-from-dockerfile.md`](./sdk/python/docs/launch-from-dockerfile.md)
before changing this path. `FROM` supplies only the root filesystem; inherited
OCI configuration is not applied. Runtime availability and compatibility remain
backend-owned. `DockerContext.walk()` exposes public structured file and
directory entries, including modes and empty directories; context transfer must
remain backend-neutral, reject unsafe manifests and unsupported syntax
fail-closed, and preserve documented Dockerfile-specific ignore-file
precedence. Dockerfiles and active or root ignore files remain ordinary context
entries unless the active matcher excludes them. Keep the public types, unit
tests, SDK README, Dockerfile launch guide, and
`examples/dockerfile_launch.py` in sync.

When changing a public SDK method, update its type annotations and docstring,
add or update unit coverage, and keep the SDK README and maintained examples in
sync. Benchmark programs under `sdk/python/benchmarks/` are manual tools and
Expand Down
32 changes: 32 additions & 0 deletions sdk/python/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ It supports two backends:
- [Port forwarding](#port-forwarding)
- [Reverse tunnels](#reverse-tunnels)
- [Rootfs and mounts](#rootfs-and-mounts)
- [Launch from a Dockerfile](#launch-from-a-dockerfile)
- [Resources and lifecycle](#resources-and-lifecycle)
- [CLI](#cli)
- [Examples and tests](#examples-and-tests)
Expand Down Expand Up @@ -101,6 +102,7 @@ Sandbox(
xpu: str | None = None,
storage_mb: int | None = None,
network_policy: NetworkPolicy | None = None,
dockerfile: DockerfileLaunch | None = None,
)
```

Expand Down Expand Up @@ -410,6 +412,31 @@ OCI images can also be mounted read-only:
mount = Mount(target="/opt/tools", image_url="ubuntu:24.04")
```

## Launch from a Dockerfile

Dockerfile direct launch is a supported AKernel SDK capability and will remain
available. Its documented strict subset evolves incrementally with production
experience; unsupported inputs continue to fail closed. The specific API surface
may evolve, with documentation and migration guidance for material changes. It
is not a general-purpose Docker build.

`FROM` supplies only the root filesystem; inherited OCI configuration is not
applied. Precheck the context, then pass its launch configuration to `Sandbox`:

```python
from akernel_sdk import DockerfileLaunch, LocalDockerContext, Sandbox, check_direct_launch
context = LocalDockerContext("Dockerfile", context_dir=".")
if check_direct_launch(context).direct_launchable:
with Sandbox(dockerfile=DockerfileLaunch(context, run_timeout=300)) as sandbox:
pass
```

`RUN`, `COPY`, and `ADD` run on every launch without a snapshot or cache;
unsupported Dockerfiles must be built externally. Read the complete contract,
security boundaries, and supported syntax in
[the Dockerfile launch guide](./docs/launch-from-dockerfile.md). See the
[runnable example](./examples/dockerfile_launch.py).

## Resources and lifecycle

`resources()` returns stable `NodeInfo` values rather than backend objects:
Expand Down Expand Up @@ -461,6 +488,7 @@ Maintained examples are under [`examples/`](./examples):
- `basic_usage.py`
- `command_stdin.py`
- `custom_image.py`
- `dockerfile_launch.py`
- `gpu_sandbox.py`
- `named_sandbox.py`
- `network_policy.py`
Expand Down Expand Up @@ -501,3 +529,7 @@ not part of the default test suite.
| `Mount` | `target`, one source, and `type` |
| `HttpReverseTunnel` | `target`, `reverse_port`, `listen_port`, `connect_timeout` |
| `NetworkPolicy` | `block_network`, `dns_blacklist` |
| `DockerfileLaunch` | `context`, `auto_start_cmd`, `run_timeout` |
| `DockerContext` | Abstract Dockerfile and build-context source |
| `DockerContextEntry` | `path`, `kind`, `mode` |
| `LocalDockerContext` | Local Dockerfile and context implementation |
26 changes: 26 additions & 0 deletions sdk/python/akernel_sdk/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,19 @@
"BackendNotInstalledError",
"UnsupportedBackendFeatureError",
"BackendOperationError",
"DockerContext",
"DockerfileLaunch",
"DockerContextEntry",
"LocalDockerContext",
"parse_dockerfile",
"check_direct_launch",
"apply_dockerfile",
"ParsedDockerfile",
"DockerfileApplyResult",
"DockerfileCheckResult",
"DockerfileBuildError",
"DockerfileParseError",
"BuildInstruction",
]

_LAZY_IMPORTS = {
Expand All @@ -65,6 +78,19 @@
"PtySession": (".pty", "PtySession"),
"PtyError": (".pty", "PtyError"),
"resources": ("._resources", "resources"),
"DockerContext": ("._dockercontext", "DockerContext"),
"DockerfileLaunch": ("._dockerfile_launch", "DockerfileLaunch"),
"DockerContextEntry": ("._dockercontext", "DockerContextEntry"),
"LocalDockerContext": ("._dockercontext", "LocalDockerContext"),
"parse_dockerfile": ("._dockerfile", "parse_dockerfile"),
"check_direct_launch": ("._dockerfile", "check_direct_launch"),
"ParsedDockerfile": ("._dockerfile", "ParsedDockerfile"),
"DockerfileCheckResult": ("._dockerfile", "DockerfileCheckResult"),
"DockerfileParseError": ("._dockerfile", "DockerfileParseError"),
"BuildInstruction": ("._dockerfile", "BuildInstruction"),
"apply_dockerfile": ("._dockerfile_runner", "apply_dockerfile"),
"DockerfileApplyResult": ("._dockerfile_runner", "DockerfileApplyResult"),
"DockerfileBuildError": ("._dockerfile", "DockerfileBuildError"),
}


Expand Down
Loading