feat: support ascend and nvidia accelerators with runc #170
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| workflow_dispatch: | |
| pull_request: | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: ci-${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} | |
| cancel-in-progress: true | |
| jobs: | |
| sdk-unit-tests: | |
| name: Python SDK unit tests (${{ matrix.python-version }}) | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 15 | |
| strategy: | |
| fail-fast: false | |
| matrix: | |
| python-version: | |
| - "3.10" | |
| - "3.11" | |
| - "3.12" | |
| - "3.13" | |
| - "3.14" | |
| 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: ${{ matrix.python-version }} | |
| cache: pip | |
| cache-dependency-path: sdk/python/pyproject.toml | |
| - name: Install SDK dependencies | |
| run: | | |
| python -m pip install -e './sdk/python[all]' | |
| - name: Run unit tests | |
| run: | | |
| 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 | |
| timeout-minutes: 5 | |
| 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" | |
| - name: Check deployment script syntax | |
| run: | | |
| make deploy-script-check | |
| accelerator-unit-build: | |
| name: Accelerator provider build and unit tests | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Initialize accelerator submodules | |
| run: | | |
| git submodule update --init src/sandboxd third_party/mind-cluster | |
| - name: Test sandboxd XPU and OCI integration on Linux | |
| run: | | |
| docker run --rm \ | |
| --volume "${GITHUB_WORKSPACE}:/workspace" \ | |
| --workdir /workspace/src/sandboxd \ | |
| golang:1.25.5-bookworm \ | |
| go test ./pkg/xpumanager ./pkg/runtime ./internal/server ./pkg/resourcemanager ./config | |
| - name: Verify sandboxd protobuf output | |
| run: | | |
| make -C src/sandboxd protos | |
| git -C src/sandboxd diff --exit-code -- api | |
| - name: Build and test the Ascend OCI adapter on Linux | |
| run: | | |
| docker run --rm \ | |
| --volume "${GITHUB_WORKSPACE}:/workspace" \ | |
| --workdir /workspace/tools/ascend-oci-adapter \ | |
| golang:1.25.5-bookworm \ | |
| bash -ceu 'go mod tidy && go test ./... && go build -trimpath -o /tmp/ascend-oci-adapter .' | |
| git diff --exit-code -- tools/ascend-oci-adapter/go.mod tools/ascend-oci-adapter/go.sum | |
| - name: Build the optional adapter image stage | |
| run: | | |
| docker build \ | |
| --file builder/node.Dockerfile \ | |
| --target ascend-adapter \ | |
| --build-arg AKERNEL_ENABLE_ASCEND=true \ | |
| --tag akernel-ci/ascend-adapter:${GITHUB_SHA} \ | |
| . | |
| - name: Render default and Ascend Helm profiles | |
| run: | | |
| docker run --rm \ | |
| --volume "${GITHUB_WORKSPACE}:/workspace" \ | |
| --workdir /workspace \ | |
| alpine/helm:3.18.4 \ | |
| template test deploy/akernel/charts/core >/tmp/akernel-default.yaml | |
| docker run --rm \ | |
| --volume "${GITHUB_WORKSPACE}:/workspace" \ | |
| --workdir /workspace \ | |
| alpine/helm:3.18.4 \ | |
| template test deploy/akernel/charts/core \ | |
| --set node.config.sandboxd.enableRunc=true \ | |
| --set node.config.sandboxd.enableAscend=true >/tmp/akernel-ascend.yaml | |
| grep -q '\[plugin.xpu.ascend\]' /tmp/akernel-ascend.yaml | |
| grep -q '/usr/local/libexec/akernel/ascend-oci-adapter' /tmp/akernel-ascend.yaml | |
| if docker run --rm \ | |
| --volume "${GITHUB_WORKSPACE}:/workspace" \ | |
| --workdir /workspace \ | |
| alpine/helm:3.18.4 \ | |
| template test deploy/akernel/charts/core \ | |
| --set node.config.sandboxd.enableAscend=true; then | |
| echo "Ascend profile unexpectedly rendered without runc" >&2 | |
| exit 1 | |
| fi | |
| standalone-e2e: | |
| name: Standalone E2E | |
| runs-on: ubuntu-22.04 | |
| timeout-minutes: 45 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| - name: Initialize build submodules | |
| run: | | |
| git submodule update --init src/sandboxd src/distill-fs | |
| - name: Set up Python | |
| uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0 | |
| with: | |
| python-version: "3.12" | |
| cache: pip | |
| cache-dependency-path: sdk/python/pyproject.toml | |
| - name: Install SDK dependencies | |
| run: | | |
| python -m pip install -e './sdk/python[all]' | |
| - name: Prepare host kernel modules | |
| run: | | |
| sudo modprobe tun | |
| sudo modprobe loop | |
| sudo modprobe erofs | |
| sudo modprobe br_netfilter | |
| test -c /dev/net/tun | |
| sudo sysctl -w net.bridge.bridge-nf-call-iptables=1 | |
| - name: Build all-in-one image | |
| run: | | |
| AKERNEL_ENABLE_KATA=false \ | |
| make build \ | |
| IMAGE_REPOSITORY=akernel-ci/all-in-one \ | |
| IMAGE_TAG="${GITHUB_SHA}" \ | |
| RUNTIME_PROFILE=rrt | |
| - name: Start standalone AKernel | |
| run: | | |
| IMAGE="akernel-ci/all-in-one:${GITHUB_SHA}" \ | |
| AKERNEL_NAT_BACKEND=iptables \ | |
| ./deploy/standalone/start.sh | |
| - name: Run SDK end-to-end examples | |
| run: | | |
| gateway_ip="$(docker inspect \ | |
| --format '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' \ | |
| akernel-traefik)" | |
| test -n "${gateway_ip}" | |
| token="$(cat deploy/standalone/data/token)" | |
| export AKERNEL_TOKEN="${token}" | |
| export AKERNEL_SERVER_ADDRESS="${gateway_ip}" | |
| export PYTHONPATH="${GITHUB_WORKSPACE}/sdk/python" | |
| examples=( | |
| basic_usage.py | |
| command_stdin.py | |
| custom_image.py | |
| dockerfile_launch.py | |
| named_sandbox.py | |
| network_policy.py | |
| port_forwarding.py | |
| pty.py | |
| reverse_tunnel.py | |
| storage_sandbox.py | |
| ) | |
| for example in "${examples[@]}"; do | |
| echo "=== Running ${example} ===" | |
| timeout 120s python "sdk/python/examples/${example}" | |
| done | |
| - name: Show standalone diagnostics | |
| if: failure() | |
| run: | | |
| docker ps -a | |
| for container in akernel-node akernel-traefik; do | |
| if docker container inspect "${container}" >/dev/null 2>&1; then | |
| echo "=== ${container}: docker logs ===" | |
| docker logs --tail 500 "${container}" 2>&1 || true | |
| fi | |
| done | |
| if docker container inspect akernel-node >/dev/null 2>&1; then | |
| echo "=== akernel-node: service journal ===" | |
| docker exec akernel-node journalctl --no-pager -n 500 \ | |
| -u sandboxd.service -u yuanrong.service || true | |
| fi | |
| - name: Stop standalone AKernel | |
| if: always() | |
| run: | | |
| if [[ -x ./deploy/standalone/stop.sh ]]; then | |
| ./deploy/standalone/stop.sh | |
| else | |
| docker rm -f akernel-traefik akernel-node >/dev/null 2>&1 || true | |
| fi |