From 6217d3b753351af8835071421e28cccbc934e50c Mon Sep 17 00:00:00 2001 From: Tianyu Zhou Date: Wed, 19 Aug 2026 20:08:37 +0800 Subject: [PATCH 1/4] feat(sdk): delegate sandbox runtime validation Accept arbitrary non-empty runtime identifiers in the public Sandbox API and backend contracts. Remove SDK-owned runtime and resource compatibility checks so YuanRong and sandboxd remain the source of truth. Update the benchmark, tests, and documentation to cover backend-owned validation while preserving the runsc default and basic input checks. Signed-off-by: Tianyu Zhou --- AGENTS.md | 11 +++--- sdk/python/README.md | 22 ++++++++---- sdk/python/akernel_sdk/_backends/base.py | 5 ++- .../_backends/openyuanrong_sandbox.py | 1 - .../_backends/openyuanrong_sdk_impl.py | 4 --- sdk/python/akernel_sdk/sandbox.py | 30 +++++++--------- sdk/python/benchmarks/sandbox_pressure.py | 1 - sdk/python/tests/unit/test_backends.py | 8 ++--- .../tests/unit/test_openyuanrong_sdk_impl.py | 16 ++++----- sdk/python/tests/unit/test_sandbox.py | 34 ++++++++++++------- 10 files changed, 70 insertions(+), 62 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index c778f55..8d240ea 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -9,11 +9,12 @@ project guidance. AKernel provides cluster-backed remote sandbox environments for agents and developer workflows. The current public user-facing surface is the Python `akernel-sdk`, including the `akernel_sdk.Sandbox` API and the `ak` CLI. -The default sandbox runtime is gVisor runsc; callers may select Kata -Containers when the cluster has a KVM-capable node. Creation-time network -policies support unrestricted networking, blocking new flows except the -YuanRong control and published sandbox-port routes, or denying exact and -leading-wildcard DNS names. +The default sandbox runtime is gVisor runsc. Runtime identifiers are forwarded +to the selected backend, which owns availability and compatibility checks; the +bundled deployment also advertises Kata Containers on KVM-capable nodes. +Creation-time network policies support unrestricted networking, blocking new +flows except the YuanRong control and published sandbox-port routes, or denying +exact and leading-wildcard DNS names. Experimental whole-device NVIDIA GPU and configurable writable-storage requests currently require runsc. diff --git a/sdk/python/README.md b/sdk/python/README.md index 3e0d969..56b981d 100644 --- a/sdk/python/README.md +++ b/sdk/python/README.md @@ -115,8 +115,9 @@ with Sandbox(xpu="gpu:l20:1") as sandbox: The `type:model:count` value is case-insensitive and canonicalized to lower case. The model is required and matched exactly; wildcard models are not -supported. GPU sandboxes currently require the gVisor `runsc` runtime and a -node configured for gVisor nvproxy. +supported. The bundled backend currently requires the gVisor `runsc` runtime +and a node configured for gVisor nvproxy. Runtime compatibility is validated +by the backend rather than the SDK. Set the writable root filesystem quota in MiB: @@ -125,9 +126,10 @@ with Sandbox(storage_mb=20 * 1024) as sandbox: print(sandbox.commands.run("df -h /").stdout) ``` -An explicit `storage_mb` quota currently requires `runsc` and uses sandboxd's -disk-backed XFS filestore. When it is omitted, sandboxd retains its configured -default 10 GiB memory-backed writable overlay. See +The bundled backend currently requires `runsc` for an explicit `storage_mb` +quota and uses sandboxd's disk-backed XFS filestore. Runtime compatibility is +validated by the backend. When `storage_mb` is omitted, sandboxd retains its +configured default 10 GiB memory-backed writable overlay. See [`examples/gpu_sandbox.py`](./examples/gpu_sandbox.py) and [`examples/storage_sandbox.py`](./examples/storage_sandbox.py). @@ -195,7 +197,10 @@ configuration, as described in the ## Sandbox runtimes -AKernel uses the gVisor `runsc` runtime when `runtime` is omitted. Callers may also select `runsc` explicitly or request Kata Containers: +AKernel uses the gVisor `runsc` runtime when `runtime` is omitted. Runtime +identifiers are forwarded to the selected backend instead of being restricted +by an SDK-owned registry. The bundled deployment advertises `runsc` and Kata +Containers: ```python default_sandbox = Sandbox() @@ -203,7 +208,10 @@ runsc_sandbox = Sandbox(runtime="runsc") kata_sandbox = Sandbox(runtime="kata") ``` -Kata requires at least one cluster node whose sandboxd instance successfully initialized the Kata runtime with a usable `/dev/kvm` device. Nodes without KVM remain available for runsc workloads and do not advertise Kata; when no eligible Kata node exists, the scheduler returns a no-resource error. +Kata requires at least one cluster node whose sandboxd instance successfully +initialized the Kata runtime with a usable `/dev/kvm` device. Nodes without +KVM remain available for runsc workloads and do not advertise Kata. A runtime +that is unavailable in the cluster fails scheduling or backend validation. See [`examples/sandbox_runtime.py`](./examples/sandbox_runtime.py) for a runnable example. diff --git a/sdk/python/akernel_sdk/_backends/base.py b/sdk/python/akernel_sdk/_backends/base.py index 910cee2..1fae783 100644 --- a/sdk/python/akernel_sdk/_backends/base.py +++ b/sdk/python/akernel_sdk/_backends/base.py @@ -19,7 +19,7 @@ from collections.abc import Mapping from dataclasses import dataclass, field from enum import Enum, auto -from typing import Literal, Protocol +from typing import Protocol from .._addresses import Endpoint from ..types import ( @@ -37,7 +37,6 @@ class Capability(Enum): """Features whose availability differs between backends.""" - KATA_RUNTIME = auto() S3_ROOTFS = auto() NODE_PLACEMENT = auto() CUSTOM_REVERSE_TUNNEL_PORTS = auto() @@ -59,7 +58,7 @@ class SandboxSpec: image: str | None rootfs: S3Config | None - runtime: Literal["runsc", "kata"] + runtime: str cpu: int memory: int cpu_limit: int diff --git a/sdk/python/akernel_sdk/_backends/openyuanrong_sandbox.py b/sdk/python/akernel_sdk/_backends/openyuanrong_sandbox.py index 4e28777..715bcf9 100644 --- a/sdk/python/akernel_sdk/_backends/openyuanrong_sandbox.py +++ b/sdk/python/akernel_sdk/_backends/openyuanrong_sandbox.py @@ -278,7 +278,6 @@ class OpenYuanRongSandboxBackend: namespace = _NAMESPACE capabilities = frozenset( { - Capability.KATA_RUNTIME, Capability.S3_ROOTFS, Capability.NODE_PLACEMENT, } diff --git a/sdk/python/akernel_sdk/_backends/openyuanrong_sdk_impl.py b/sdk/python/akernel_sdk/_backends/openyuanrong_sdk_impl.py index 9706b46..87503e2 100644 --- a/sdk/python/akernel_sdk/_backends/openyuanrong_sdk_impl.py +++ b/sdk/python/akernel_sdk/_backends/openyuanrong_sdk_impl.py @@ -171,10 +171,6 @@ def build_options( raise ValueError("mem_limit must be 0 or greater than or equal to memory") normalized_xpu = normalize_xpu(xpu) validate_storage_mb(storage_mb) - if normalized_xpu is not None and runtime != "runsc": - raise ValueError("xpu is currently supported only by runsc") - if storage_mb is not None and runtime != "runsc": - raise ValueError("storage_mb is currently supported only by runsc") options = yr.InvokeOptions() # A Sandbox is driven by one sequential SDK client. Disabling ordered RPC diff --git a/sdk/python/akernel_sdk/sandbox.py b/sdk/python/akernel_sdk/sandbox.py index 90f95e0..02d426d 100644 --- a/sdk/python/akernel_sdk/sandbox.py +++ b/sdk/python/akernel_sdk/sandbox.py @@ -22,7 +22,6 @@ import urllib.request from collections.abc import Mapping, Sequence from types import MappingProxyType -from typing import Literal, cast from ._addresses import Endpoint, api_endpoint_from_env, gateway_endpoint_from_env from ._backends.base import BackendSession, SandboxSpec @@ -33,7 +32,6 @@ from .pty import Pty from .types import HttpReverseTunnel, Mount, NetworkPolicy, S3Config, SandboxInfo -_SUPPORTED_RUNTIMES = ("runsc", "kata") _traefik_internal_ip_cache: str | None = None logger = logging.getLogger(__name__) @@ -108,8 +106,8 @@ def _get_traefik_internal_ip(gateway: Endpoint) -> tuple[str, int]: class Sandbox: """A remote AKernel sandbox. - The public API is backend-neutral. AKernel supports the gVisor ``runsc`` - runtime and Kata Containers on KVM-capable nodes. + The public API is backend-neutral. The selected backend and cluster + determine which sandbox runtime identifiers are available. """ def __init__( @@ -141,7 +139,8 @@ def __init__( Args: image: OCI image used as the sandbox root filesystem. rootfs: S3-compatible EROFS root filesystem configuration. - runtime: Sandbox runtime name: ``runsc`` or ``kata``. + runtime: Sandbox runtime identifier. Defaults to ``runsc``; + availability is determined by the backend and cluster. cpu: Requested CPU in millicores. memory: Requested memory in MiB. cpu_limit: CPU limit in millicores, or zero to follow ``cpu``. @@ -158,10 +157,11 @@ def __init__( node_id: Require placement on a specific AKernel node. xpu: Experimental whole-device accelerator request in ``type:model:count`` format. Currently only exact-model NVIDIA - GPU requests with the ``runsc`` runtime are supported. + GPU requests are supported. The backend validates runtime + compatibility. storage_mb: Experimental writable root filesystem quota in MiB. When omitted, the configured default is used. Explicit quotas - currently require the ``runsc`` runtime. + are validated against the selected runtime by the backend. network_policy: Optional creation-time network policy. Omitting it leaves sandbox networking unrestricted. @@ -177,21 +177,17 @@ def __init__( raise TypeError("rootfs must be an S3Config") if image is not None and rootfs is not None: raise ValueError("image and rootfs are mutually exclusive") - if runtime not in _SUPPORTED_RUNTIMES: - raise ValueError( - f"unsupported runtime {runtime!r}; " - f"supported runtimes: {', '.join(_SUPPORTED_RUNTIMES)}" - ) + if not isinstance(runtime, str): + raise TypeError("runtime must be a string") + runtime = runtime.strip() + if not runtime: + raise ValueError("runtime must be a non-empty string") normalized_xpu = normalize_xpu(xpu) validate_storage_mb(storage_mb) if network_policy is not None and not isinstance( network_policy, NetworkPolicy ): raise TypeError("network_policy must be a NetworkPolicy or None") - if normalized_xpu is not None and runtime != "runsc": - raise ValueError("xpu is currently supported only by runsc") - if storage_mb is not None and runtime != "runsc": - raise ValueError("storage_mb is currently supported only by runsc") _validate_integer("cpu", cpu, minimum=1) _validate_integer("memory", memory, minimum=1) _validate_integer("cpu_limit", cpu_limit, minimum=0) @@ -255,7 +251,7 @@ def __init__( spec = SandboxSpec( image=image, rootfs=rootfs, - runtime=cast(Literal["runsc", "kata"], runtime), + runtime=runtime, cpu=cpu, memory=memory, cpu_limit=cpu_limit, diff --git a/sdk/python/benchmarks/sandbox_pressure.py b/sdk/python/benchmarks/sandbox_pressure.py index 57296f6..5f6e334 100644 --- a/sdk/python/benchmarks/sandbox_pressure.py +++ b/sdk/python/benchmarks/sandbox_pressure.py @@ -419,7 +419,6 @@ def _percentiles(label, samples_s): ) parser.add_argument( "--runtime", - choices=("runsc", "kata"), default=DEFAULT_RUNTIME, help="sandbox runtime (default: AKERNEL_PRESSURE_RUNTIME or runsc)", ) diff --git a/sdk/python/tests/unit/test_backends.py b/sdk/python/tests/unit/test_backends.py index 98e8623..430ab03 100644 --- a/sdk/python/tests/unit/test_backends.py +++ b/sdk/python/tests/unit/test_backends.py @@ -147,20 +147,20 @@ def test_connection_config_maps_to_yr_environment(self): self.assertEqual(os.environ["YR_GATEWAY_TLS"], "0") self.assertEqual(os.environ["YR_TOKEN"], "secret") - def test_kata_without_explicit_rootfs_passes_runtime_config_override(self): + def test_runtime_identifier_without_explicit_rootfs_is_forwarded(self): native = MagicMock() - native.id = "default-kata" + native.id = "default-gvisor-next" with patch.object( openyuanrong_sandbox.yr_sandbox, "Sandbox", return_value=native, ) as sandbox_type: - self.backend.create(_spec(runtime="kata")) + self.backend.create(_spec(runtime="gvisor-next")) # YuanRong applies this runtime as a configuration override to the # deployed default rootfs; the adapter does not build a filesystem # overlay. - self.assertEqual(sandbox_type.call_args.kwargs["runtime"], "kata") + self.assertEqual(sandbox_type.call_args.kwargs["runtime"], "gvisor-next") self.assertIsNone(sandbox_type.call_args.kwargs["rootfs"]) def test_runsc_without_explicit_rootfs_passes_runtime_config_override(self): diff --git a/sdk/python/tests/unit/test_openyuanrong_sdk_impl.py b/sdk/python/tests/unit/test_openyuanrong_sdk_impl.py index 109e577..1dd3a29 100644 --- a/sdk/python/tests/unit/test_openyuanrong_sdk_impl.py +++ b/sdk/python/tests/unit/test_openyuanrong_sdk_impl.py @@ -112,8 +112,10 @@ def test_resource_limit_validation(self): ): self.build_options(schedule_timeout=value) - def test_xpu_and_storage_translation(self): - options = self.build_options(xpu="GPU:L20:2", storage_mb=256) + def test_xpu_and_storage_translation_is_runtime_agnostic(self): + options = self.build_options( + runtime="gvisor-next", xpu="GPU:L20:2", storage_mb=256 + ) self.assertEqual( options.custom_resources, { @@ -121,12 +123,10 @@ def test_xpu_and_storage_translation(self): "storage": float(256 * 1024 * 1024), }, ) - - def test_xpu_and_storage_require_runsc(self): - with self.assertRaisesRegex(ValueError, "xpu.*runsc"): - self.build_options(runtime="kata", xpu="gpu:l20:1") - with self.assertRaisesRegex(ValueError, "storage_mb.*runsc"): - self.build_options(runtime="kata", storage_mb=256) + self.assertEqual( + json.loads(options.custom_extensions["rootfs"]), + {"runtime": "gvisor-next"}, + ) def test_network_policy_uses_custom_extension_wire_format(self): options = self.build_options( diff --git a/sdk/python/tests/unit/test_sandbox.py b/sdk/python/tests/unit/test_sandbox.py index 9dfcf23..3aec282 100644 --- a/sdk/python/tests/unit/test_sandbox.py +++ b/sdk/python/tests/unit/test_sandbox.py @@ -136,17 +136,30 @@ def test_rootfs_requires_s3_config(self): ) self.backend.create.assert_not_called() - def test_supported_runtimes(self): - sandbox = Sandbox(runtime="kata") + def test_runtime_identifier_is_normalized_and_passed_to_backend(self): + sandbox = Sandbox(runtime=" gvisor-next ") + spec = self.backend.create.call_args.args[0] + self.assertEqual(spec.runtime, "gvisor-next") sandbox.kill() - with self.assertRaisesRegex(ValueError, "unsupported runtime"): - Sandbox(runtime="unknown") + def test_runtime_identifier_validation(self): + for value in (None, 1): + with self.subTest(value=value), self.assertRaisesRegex( + TypeError, "runtime must be a string" + ): + Sandbox(runtime=value) + for value in ("", " "): + with self.subTest(value=value), self.assertRaisesRegex( + ValueError, "runtime must be a non-empty string" + ): + Sandbox(runtime=value) + self.backend.create.assert_not_called() - def test_xpu_request_is_normalized_and_passed_to_backend(self): - sandbox = Sandbox(xpu=" GPU:L20:02 ") + def test_xpu_request_is_normalized_and_delegated_to_backend(self): + sandbox = Sandbox(runtime="gpu-runtime", xpu=" GPU:L20:02 ") self.assertEqual(sandbox.get_info().xpu, "gpu:l20:2") spec = self.backend.create.call_args.args[0] + self.assertEqual(spec.runtime, "gpu-runtime") self.assertEqual(spec.xpu, "gpu:l20:2") sandbox.kill() @@ -163,14 +176,13 @@ def test_xpu_request_validation(self): for value, error_type in invalid: with self.subTest(value=value), self.assertRaises(error_type): Sandbox(xpu=value) - with self.assertRaisesRegex(ValueError, "xpu.*runsc"): - Sandbox(runtime="kata", xpu="gpu:l20:1") self.backend.create.assert_not_called() - def test_storage_request_is_passed_to_backend(self): - sandbox = Sandbox(storage_mb=256) + def test_storage_request_is_delegated_to_backend(self): + sandbox = Sandbox(runtime="storage-runtime", storage_mb=256) self.assertEqual(sandbox.get_info().storage_mb, 256) spec = self.backend.create.call_args.args[0] + self.assertEqual(spec.runtime, "storage-runtime") self.assertEqual(spec.storage_mb, 256) sandbox.kill() @@ -178,8 +190,6 @@ def test_storage_request_validation(self): for value in (True, 0, -1, 1.5): with self.subTest(value=value), self.assertRaises((TypeError, ValueError)): Sandbox(storage_mb=value) - with self.assertRaisesRegex(ValueError, "storage_mb.*runsc"): - Sandbox(runtime="kata", storage_mb=256) self.backend.create.assert_not_called() def test_block_network_policy_is_passed_to_backend(self): From 3b5f80291b912e65eb78b850e92304410c00d1b2 Mon Sep 17 00:00:00 2001 From: Tianyu Zhou Date: Wed, 19 Aug 2026 20:48:57 +0800 Subject: [PATCH 2/4] style(sdk): wrap gateway assertion Wrap the gateway endpoint assertion to satisfy Ruff's configured line-length limit. This restores a clean full SDK lint run. Signed-off-by: Tianyu Zhou --- sdk/python/tests/unit/test_addresses.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sdk/python/tests/unit/test_addresses.py b/sdk/python/tests/unit/test_addresses.py index 96671ed..938f2b0 100644 --- a/sdk/python/tests/unit/test_addresses.py +++ b/sdk/python/tests/unit/test_addresses.py @@ -51,7 +51,9 @@ def test_explicit_server_port_uses_plain_http_gateway(self): gateway_expected = ("http", "10.0.0.1", 8888, False) self.assertEqual(endpoint_tuple(api_endpoint_from_env()), expected) self.assertEqual(endpoint_tuple(exec_endpoint_from_env()), expected) - self.assertEqual(endpoint_tuple(gateway_endpoint_from_env()), gateway_expected) + self.assertEqual( + endpoint_tuple(gateway_endpoint_from_env()), gateway_expected + ) def test_gateway_override_defaults_to_plain_http(self): with patch.dict( From 0ecf444ab085c7408332dfcfa93fa420fd43ca90 Mon Sep 17 00:00:00 2001 From: Tianyu Zhou Date: Wed, 19 Aug 2026 20:51:38 +0800 Subject: [PATCH 3/4] ci: check SDK quality before release Run the SDK lint and type checks in the regular pull request and main workflow so failures are caught before release tags are created. Make sdk-check stop immediately when Ruff or mypy fails instead of allowing a later successful command to hide the earlier failure. Signed-off-by: Tianyu Zhou --- .github/workflows/ci.yml | 24 ++++++++++++++++++++++++ Makefile | 3 ++- 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fdd7ee9..62d1581 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,30 @@ jobs: unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY make sdk-test + sdk-quality: + name: Python SDK lint and type checks + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Check out repository + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + + - name: Set up Python + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 + with: + python-version: "3.10" + cache: pip + cache-dependency-path: sdk/python/pyproject.toml + + - name: Install SDK development dependencies + run: | + python -m pip install -e './sdk/python[dev]' + + - name: Run SDK quality checks + run: | + make sdk-check + deployment-script-syntax: name: Deployment script syntax runs-on: ubuntu-latest diff --git a/Makefile b/Makefile index 88300cf..0953c33 100644 --- a/Makefile +++ b/Makefile @@ -145,7 +145,8 @@ sdk-test: .PHONY: sdk-check sdk-check: sdk-test - @cd sdk/python; \ + @set -e; \ + cd sdk/python; \ python3 -m ruff check akernel_sdk tests; \ python3 -m mypy akernel_sdk From 04bc9bcecfecc383cac0a64d8ca04e17eddeb082 Mon Sep 17 00:00:00 2001 From: Tianyu Zhou Date: Wed, 19 Aug 2026 20:54:04 +0800 Subject: [PATCH 4/4] ci: remove agent-only shell setup Remove proxy cleanup commands from CI and release workflows because they are an agent-side execution concern, not part of project commands. Keeping them out of versioned workflows avoids encoding local environment handling in CI. Signed-off-by: Tianyu Zhou --- .github/workflows/ci.yml | 11 ----------- .github/workflows/release-python.yml | 6 ------ 2 files changed, 17 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 62d1581..5cc7701 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -41,12 +41,10 @@ jobs: - name: Install SDK dependencies run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY python -m pip install -e './sdk/python[all]' - name: Run unit tests run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY make sdk-test sdk-quality: @@ -89,7 +87,6 @@ jobs: - name: Check deployment script syntax run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY make deploy-script-check standalone-e2e: @@ -105,7 +102,6 @@ jobs: - name: Initialize build submodules run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY git submodule update --init src/sandboxd src/distill-fs - name: Set up Python @@ -117,12 +113,10 @@ jobs: - name: Install SDK dependencies run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY python -m pip install -e './sdk/python[all]' - name: Prepare host kernel modules run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY sudo modprobe loop sudo modprobe erofs sudo modprobe br_netfilter @@ -130,7 +124,6 @@ jobs: - name: Build all-in-one image run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY AKERNEL_ENABLE_KATA=false \ make build \ IMAGE_REPOSITORY=akernel-ci/all-in-one \ @@ -139,14 +132,12 @@ jobs: - name: Start standalone AKernel run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY IMAGE="akernel-ci/all-in-one:${GITHUB_SHA}" \ AKERNEL_NAT_BACKEND=iptables \ ./deploy/standalone/start.sh - name: Run SDK end-to-end examples run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY gateway_ip="$(docker inspect \ --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ akernel-traefik)" @@ -175,7 +166,6 @@ jobs: - name: Show standalone diagnostics if: failure() run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY docker ps -a for container in akernel-node akernel-traefik; do if docker container inspect "${container}" >/dev/null 2>&1; then @@ -192,7 +182,6 @@ jobs: - name: Stop standalone AKernel if: always() run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY if [[ -x ./deploy/standalone/stop.sh ]]; then ./deploy/standalone/stop.sh else diff --git a/.github/workflows/release-python.yml b/.github/workflows/release-python.yml index 31f7bfc..2693da5 100644 --- a/.github/workflows/release-python.yml +++ b/.github/workflows/release-python.yml @@ -35,8 +35,6 @@ jobs: env: RELEASE_TAG: ${{ github.event.release.tag_name }} run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY - if [[ ! "${RELEASE_TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+$ ]]; then echo "Release tag must use the stable vX.Y.Z format: ${RELEASE_TAG}" >&2 exit 1 @@ -68,18 +66,15 @@ jobs: - name: Install build dependencies run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY python -m pip install --upgrade pip python -m pip install -e './sdk/python[dev]' 'twine>=5,<7' - name: Check SDK run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY make sdk-check - name: Build distributions run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY rm -rf sdk/python/dist python -m build --outdir sdk/python/dist sdk/python test "$(find sdk/python/dist -maxdepth 1 -name '*.whl' | wc -l)" -eq 1 @@ -88,7 +83,6 @@ jobs: - name: Test installed wheel run: | - unset http_proxy https_proxy HTTP_PROXY HTTPS_PROXY all_proxy ALL_PROXY no_proxy NO_PROXY python -m venv /tmp/akernel-wheel-test /tmp/akernel-wheel-test/bin/python -m pip install \ --no-deps sdk/python/dist/*.whl