@@ -416,12 +416,253 @@ jobs:
416416 path : artifacts/*.tar.gz
417417 retention-days : 5
418418
419+ # ---------------------------------------------------------------------------
420+ # Build openshell-driver-vm binary (Linux — native on each arch)
421+ # ---------------------------------------------------------------------------
422+ build-driver-vm-linux :
423+ name : Build Driver VM (Linux ${{ matrix.arch }})
424+ needs : [compute-versions, download-kernel-runtime, build-rootfs]
425+ strategy :
426+ matrix :
427+ include :
428+ - arch : arm64
429+ runner : build-arm64
430+ target : aarch64-unknown-linux-gnu
431+ platform : linux-aarch64
432+ guest_arch : aarch64
433+ - arch : amd64
434+ runner : build-amd64
435+ target : x86_64-unknown-linux-gnu
436+ platform : linux-x86_64
437+ guest_arch : x86_64
438+ runs-on : ${{ matrix.runner }}
439+ timeout-minutes : 30
440+ container :
441+ image : ghcr.io/nvidia/openshell/ci:latest
442+ credentials :
443+ username : ${{ github.actor }}
444+ password : ${{ secrets.GITHUB_TOKEN }}
445+ options : --privileged
446+ env :
447+ MISE_GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
448+ SCCACHE_MEMCACHED_ENDPOINT : ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
449+ OPENSHELL_IMAGE_TAG : dev
450+ steps :
451+ - uses : actions/checkout@v4
452+ with :
453+ fetch-depth : 0
454+
455+ - name : Mark workspace safe for git
456+ run : git config --global --add safe.directory "$GITHUB_WORKSPACE"
457+
458+ - name : Fetch tags
459+ run : git fetch --tags --force
460+
461+ - name : Install tools
462+ run : mise install
463+
464+ - name : Cache Rust target and registry
465+ uses : Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
466+ with :
467+ shared-key : driver-vm-linux-${{ matrix.arch }}
468+ cache-directories : .cache/sccache
469+ cache-targets : " true"
470+
471+ - name : Install zstd
472+ run : apt-get update && apt-get install -y --no-install-recommends zstd && rm -rf /var/lib/apt/lists/*
473+
474+ - name : Download kernel runtime tarball
475+ uses : actions/download-artifact@v4
476+ with :
477+ name : kernel-runtime-tarballs
478+ path : runtime-download/
479+
480+ - name : Download rootfs tarball
481+ uses : actions/download-artifact@v4
482+ with :
483+ name : rootfs-${{ matrix.arch }}
484+ path : rootfs-download/
485+
486+ - name : Stage compressed runtime for embedding
487+ run : |
488+ set -euo pipefail
489+ COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed"
490+ mkdir -p "$COMPRESSED_DIR"
491+
492+ # Extract kernel runtime tarball and re-compress individual files
493+ EXTRACT_DIR=$(mktemp -d)
494+ zstd -d "runtime-download/vm-runtime-${{ matrix.platform }}.tar.zst" --stdout \
495+ | tar -xf - -C "$EXTRACT_DIR"
496+
497+ echo "Extracted runtime files:"
498+ ls -lah "$EXTRACT_DIR"
499+
500+ for file in "$EXTRACT_DIR"/*; do
501+ [ -f "$file" ] || continue
502+ name=$(basename "$file")
503+ [ "$name" = "provenance.json" ] && continue
504+ zstd -19 -f -q -T0 -o "${COMPRESSED_DIR}/${name}.zst" "$file"
505+ done
506+
507+ # Copy rootfs tarball (already zstd-compressed)
508+ cp rootfs-download/rootfs.tar.zst "${COMPRESSED_DIR}/rootfs.tar.zst"
509+
510+ echo "Staged compressed artifacts:"
511+ ls -lah "$COMPRESSED_DIR"
512+
513+ - name : Scope workspace to driver-vm crates
514+ run : |
515+ set -euo pipefail
516+ sed -i 's|members = \["crates/\*"\]|members = ["crates/openshell-driver-vm", "crates/openshell-core"]|' Cargo.toml
517+
518+ - name : Patch workspace version
519+ if : needs.compute-versions.outputs.cargo_version != ''
520+ run : |
521+ set -euo pipefail
522+ sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${{ needs.compute-versions.outputs.cargo_version }}"'"/}' Cargo.toml
523+
524+ - name : Build openshell-driver-vm
525+ run : |
526+ set -euo pipefail
527+ OPENSHELL_VM_RUNTIME_COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed" \
528+ mise x -- cargo build --release -p openshell-driver-vm
529+
530+ - name : sccache stats
531+ if : always()
532+ run : mise x -- sccache --show-stats
533+
534+ - name : Package binary
535+ run : |
536+ set -euo pipefail
537+ mkdir -p artifacts
538+ tar -czf "artifacts/openshell-driver-vm-${{ matrix.target }}.tar.gz" \
539+ -C target/release openshell-driver-vm
540+ ls -lh artifacts/
541+
542+ - name : Upload artifact
543+ uses : actions/upload-artifact@v4
544+ with :
545+ name : driver-vm-linux-${{ matrix.arch }}
546+ path : artifacts/*.tar.gz
547+ retention-days : 5
548+
549+ # ---------------------------------------------------------------------------
550+ # Build openshell-driver-vm binary (macOS ARM64 via osxcross)
551+ # ---------------------------------------------------------------------------
552+ build-driver-vm-macos :
553+ name : Build Driver VM (macOS)
554+ needs : [compute-versions, download-kernel-runtime, build-rootfs]
555+ runs-on : build-amd64
556+ timeout-minutes : 60
557+ container :
558+ image : ghcr.io/nvidia/openshell/ci:latest
559+ credentials :
560+ username : ${{ github.actor }}
561+ password : ${{ secrets.GITHUB_TOKEN }}
562+ options : --privileged
563+ volumes :
564+ - /var/run/docker.sock:/var/run/docker.sock
565+ env :
566+ MISE_GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
567+ SCCACHE_MEMCACHED_ENDPOINT : ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
568+ steps :
569+ - uses : actions/checkout@v4
570+ with :
571+ fetch-depth : 0
572+
573+ - name : Mark workspace safe for git
574+ run : git config --global --add safe.directory "$GITHUB_WORKSPACE"
575+
576+ - name : Fetch tags
577+ run : git fetch --tags --force
578+
579+ - name : Log in to GHCR
580+ run : echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
581+
582+ - name : Set up Docker Buildx
583+ uses : ./.github/actions/setup-buildx
584+
585+ - name : Install zstd
586+ run : apt-get update && apt-get install -y --no-install-recommends zstd && rm -rf /var/lib/apt/lists/*
587+
588+ - name : Download kernel runtime tarball
589+ uses : actions/download-artifact@v4
590+ with :
591+ name : kernel-runtime-tarballs
592+ path : runtime-download/
593+
594+ - name : Download rootfs tarball (arm64)
595+ uses : actions/download-artifact@v4
596+ with :
597+ name : rootfs-arm64
598+ path : rootfs-download/
599+
600+ - name : Prepare compressed runtime directory
601+ run : |
602+ set -euo pipefail
603+ COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed-macos"
604+ mkdir -p "$COMPRESSED_DIR"
605+
606+ # Extract the darwin runtime tarball and re-compress for embedding.
607+ # The macOS embedded.rs expects: libkrun.dylib.zst, libkrunfw.5.dylib.zst, gvproxy.zst
608+ EXTRACT_DIR=$(mktemp -d)
609+ zstd -d "runtime-download/vm-runtime-darwin-aarch64.tar.zst" --stdout \
610+ | tar -xf - -C "$EXTRACT_DIR"
611+
612+ echo "Extracted darwin runtime files:"
613+ ls -lah "$EXTRACT_DIR"
614+
615+ for file in "$EXTRACT_DIR"/*; do
616+ [ -f "$file" ] || continue
617+ name=$(basename "$file")
618+ [ "$name" = "provenance.json" ] && continue
619+ zstd -19 -f -q -T0 -o "${COMPRESSED_DIR}/${name}.zst" "$file"
620+ done
621+
622+ # The macOS VM guest is always Linux ARM64, so use the arm64 rootfs
623+ cp rootfs-download/rootfs.tar.zst "${COMPRESSED_DIR}/rootfs.tar.zst"
624+
625+ echo "Staged macOS compressed artifacts:"
626+ ls -lah "$COMPRESSED_DIR"
627+
628+ - name : Build macOS binary via Docker (osxcross)
629+ run : |
630+ set -euo pipefail
631+ docker buildx build \
632+ --file deploy/docker/Dockerfile.driver-vm-macos \
633+ --build-arg OPENSHELL_CARGO_VERSION="${{ needs.compute-versions.outputs.cargo_version }}" \
634+ --build-arg OPENSHELL_IMAGE_TAG=dev \
635+ --build-arg CARGO_TARGET_CACHE_SCOPE="${{ github.sha }}" \
636+ --build-context vm-runtime-compressed="${PWD}/target/vm-runtime-compressed-macos" \
637+ --target binary \
638+ --output type=local,dest=out/ \
639+ .
640+
641+ - name : Package binary
642+ run : |
643+ set -euo pipefail
644+ mkdir -p artifacts
645+ tar -czf artifacts/openshell-driver-vm-aarch64-apple-darwin.tar.gz \
646+ -C out openshell-driver-vm
647+ ls -lh artifacts/
648+
649+ - name : Upload artifact
650+ uses : actions/upload-artifact@v4
651+ with :
652+ name : driver-vm-macos
653+ path : artifacts/*.tar.gz
654+ retention-days : 5
655+
419656 # ---------------------------------------------------------------------------
420657 # Upload all VM binaries to the vm-dev rolling release
421658 # ---------------------------------------------------------------------------
422659 release-vm-dev :
423660 name : Release VM Dev
424- needs : [build-vm-linux, build-vm-macos]
661+ needs :
662+ - build-vm-linux
663+ - build-vm-macos
664+ - build-driver-vm-linux
665+ - build-driver-vm-macos
425666 runs-on : build-amd64
426667 timeout-minutes : 10
427668 steps :
@@ -430,29 +671,38 @@ jobs:
430671 - name : Download all VM binary artifacts
431672 uses : actions/download-artifact@v4
432673 with :
433- pattern : vm-*
674+ pattern : " { vm-*,driver-vm-*} "
434675 path : release/
435676 merge-multiple : true
436677
437678 - name : Filter to only binary tarballs
438679 run : |
439680 set -euo pipefail
440681 mkdir -p release-final
441- # Only include the openshell-vm binary tarballs, not kernel runtime
442- cp release/openshell-vm-*.tar.gz release-final/
443- count=$(ls release-final/openshell-vm-*.tar.gz 2>/dev/null | wc -l)
444- if [ "$count" -eq 0 ]; then
445- echo "ERROR: No VM binary tarballs found in release/" >&2
682+ # Include both openshell-vm and openshell-driver-vm binary tarballs.
683+ # Exclude kernel runtime tarballs (they come from release-vm-kernel.yml).
684+ for pattern in 'openshell-vm-*.tar.gz' 'openshell-driver-vm-*.tar.gz'; do
685+ for file in release/${pattern}; do
686+ [ -f "$file" ] || continue
687+ cp "$file" release-final/
688+ done
689+ done
690+ vm_count=$(ls release-final/openshell-vm-*.tar.gz 2>/dev/null | wc -l)
691+ driver_count=$(ls release-final/openshell-driver-vm-*.tar.gz 2>/dev/null | wc -l)
692+ if [ "$vm_count" -eq 0 ] || [ "$driver_count" -eq 0 ]; then
693+ echo "ERROR: Missing binary tarballs (openshell-vm=${vm_count}, openshell-driver-vm=${driver_count})" >&2
694+ ls -la release/ || true
446695 exit 1
447696 fi
448- echo "Release artifacts (${count} binaries ):"
697+ echo "Release artifacts (openshell-vm=${vm_count}, openshell-driver-vm=${driver_count} ):"
449698 ls -lh release-final/
450699
451700 - name : Generate checksums
452701 run : |
453702 set -euo pipefail
454703 cd release-final
455- sha256sum openshell-vm-*.tar.gz > vm-binary-checksums-sha256.txt
704+ sha256sum openshell-vm-*.tar.gz openshell-driver-vm-*.tar.gz \
705+ > vm-binary-checksums-sha256.txt
456706 cat vm-binary-checksums-sha256.txt
457707
458708 - name : Ensure vm-dev tag exists
@@ -479,7 +729,11 @@ jobs:
479729 }
480730 // Delete old VM binary assets (keep kernel runtime assets)
481731 for (const asset of release.data.assets) {
482- if (asset.name.startsWith('openshell-vm-') || asset.name === 'vm-binary-checksums-sha256.txt') {
732+ if (
733+ asset.name.startsWith('openshell-vm-') ||
734+ asset.name.startsWith('openshell-driver-vm-') ||
735+ asset.name === 'vm-binary-checksums-sha256.txt'
736+ ) {
483737 core.info(`Deleting stale asset: ${asset.name}`);
484738 await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: asset.id });
485739 }
@@ -520,6 +774,18 @@ jobs:
520774 | Linux x86_64 | `openshell-vm-x86_64-unknown-linux-gnu.tar.gz` |
521775 | macOS ARM64 | `openshell-vm-aarch64-apple-darwin.tar.gz` |
522776
777+ ### VM Compute Driver Binaries
778+
779+ `openshell-driver-vm` binaries with embedded kernel runtime and sandbox rootfs.
780+ Launched by the gateway when `--drivers=vm` is configured. Rebuilt on every
781+ push to main alongside the openshell-vm binaries.
782+
783+ | Platform | Artifact |
784+ |----------|----------|
785+ | Linux ARM64 | `openshell-driver-vm-aarch64-unknown-linux-gnu.tar.gz` |
786+ | Linux x86_64 | `openshell-driver-vm-x86_64-unknown-linux-gnu.tar.gz` |
787+ | macOS ARM64 | `openshell-driver-vm-aarch64-apple-darwin.tar.gz` |
788+
523789 ### Quick install
524790
525791 ```
@@ -532,4 +798,7 @@ jobs:
532798 release-final/openshell-vm-aarch64-unknown-linux-gnu.tar.gz
533799 release-final/openshell-vm-x86_64-unknown-linux-gnu.tar.gz
534800 release-final/openshell-vm-aarch64-apple-darwin.tar.gz
801+ release-final/openshell-driver-vm-aarch64-unknown-linux-gnu.tar.gz
802+ release-final/openshell-driver-vm-x86_64-unknown-linux-gnu.tar.gz
803+ release-final/openshell-driver-vm-aarch64-apple-darwin.tar.gz
535804 release-final/vm-binary-checksums-sha256.txt
0 commit comments