mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-17 05:31:16 +08:00
feat(vm): add openshell-vm crate with libkrun microVM gateway (#611)
This commit is contained in:
@@ -0,0 +1,518 @@
|
||||
name: Release VM Dev
|
||||
|
||||
# Build openshell-vm binaries for all supported platforms and upload them to
|
||||
# the rolling "vm-dev" GitHub Release. Each binary is self-extracting: it
|
||||
# embeds pre-built kernel runtime artifacts (from release-vm-kernel.yml) and a
|
||||
# base rootfs tarball.
|
||||
#
|
||||
# Prerequisites: the vm-dev release must already contain kernel runtime
|
||||
# tarballs. Run the "Release VM Kernel" workflow first if they are missing.
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
packages: read
|
||||
|
||||
# Serialize with release-vm-kernel.yml — both update the vm-dev release.
|
||||
concurrency:
|
||||
group: vm-dev-release
|
||||
cancel-in-progress: false
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Compute versions (reuse the same logic as release-dev.yml)
|
||||
# ---------------------------------------------------------------------------
|
||||
compute-versions:
|
||||
name: Compute Versions
|
||||
runs-on: build-amd64
|
||||
timeout-minutes: 5
|
||||
container:
|
||||
image: ghcr.io/nvidia/openshell/ci:latest
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
outputs:
|
||||
cargo_version: ${{ steps.v.outputs.cargo }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Mark workspace safe for git
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags --force
|
||||
|
||||
- name: Compute versions
|
||||
id: v
|
||||
run: |
|
||||
set -euo pipefail
|
||||
echo "cargo=$(uv run python tasks/scripts/release.py get-version --cargo)" >> "$GITHUB_OUTPUT"
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Download kernel runtime tarballs from the vm-dev release
|
||||
# ---------------------------------------------------------------------------
|
||||
download-kernel-runtime:
|
||||
name: Download Kernel Runtime
|
||||
runs-on: build-amd64
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download all runtime tarballs
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p runtime-artifacts
|
||||
|
||||
for platform in linux-aarch64 linux-x86_64 darwin-aarch64; do
|
||||
echo "Downloading vm-runtime-${platform}.tar.zst..."
|
||||
gh release download vm-dev \
|
||||
--repo "${GITHUB_REPOSITORY}" \
|
||||
--pattern "vm-runtime-${platform}.tar.zst" \
|
||||
--dir runtime-artifacts \
|
||||
--clobber
|
||||
done
|
||||
|
||||
echo "Downloaded runtime artifacts:"
|
||||
ls -lah runtime-artifacts/
|
||||
|
||||
- name: Verify downloads
|
||||
run: |
|
||||
set -euo pipefail
|
||||
for platform in linux-aarch64 linux-x86_64 darwin-aarch64; do
|
||||
file="runtime-artifacts/vm-runtime-${platform}.tar.zst"
|
||||
if [ ! -f "$file" ]; then
|
||||
echo "ERROR: Missing ${file}" >&2
|
||||
echo "" >&2
|
||||
echo "The vm-dev release does not have kernel runtime artifacts." >&2
|
||||
echo "Run the 'Release VM Kernel' workflow first:" >&2
|
||||
echo " gh workflow run release-vm-kernel.yml" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "OK: ${file} ($(du -sh "$file" | cut -f1))"
|
||||
done
|
||||
|
||||
- name: Upload as workflow artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: kernel-runtime-tarballs
|
||||
path: runtime-artifacts/vm-runtime-*.tar.zst
|
||||
retention-days: 1
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build base rootfs tarballs (architecture-specific)
|
||||
# ---------------------------------------------------------------------------
|
||||
build-rootfs:
|
||||
name: Build Rootfs (${{ matrix.arch }})
|
||||
needs: [compute-versions]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: arm64
|
||||
runner: build-arm64
|
||||
guest_arch: aarch64
|
||||
- arch: amd64
|
||||
runner: build-amd64
|
||||
guest_arch: x86_64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 30
|
||||
container:
|
||||
image: ghcr.io/nvidia/openshell/ci:latest
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
options: --privileged
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
env:
|
||||
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
OPENSHELL_IMAGE_TAG: dev
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Mark workspace safe for git
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
|
||||
- name: Install tools
|
||||
run: mise install
|
||||
|
||||
- name: Build base rootfs tarball
|
||||
run: |
|
||||
set -euo pipefail
|
||||
crates/openshell-vm/scripts/build-rootfs.sh \
|
||||
--base \
|
||||
--arch ${{ matrix.guest_arch }} \
|
||||
target/rootfs-build
|
||||
|
||||
mkdir -p target/vm-runtime-compressed
|
||||
tar -C target/rootfs-build -cf - . \
|
||||
| zstd -19 -T0 -o target/vm-runtime-compressed/rootfs.tar.zst
|
||||
|
||||
echo "Rootfs tarball: $(du -sh target/vm-runtime-compressed/rootfs.tar.zst | cut -f1)"
|
||||
|
||||
- name: Upload rootfs artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: rootfs-${{ matrix.arch }}
|
||||
path: target/vm-runtime-compressed/rootfs.tar.zst
|
||||
retention-days: 1
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build openshell-vm binary (Linux — native on each arch)
|
||||
# ---------------------------------------------------------------------------
|
||||
build-vm-linux:
|
||||
name: Build VM (Linux ${{ matrix.arch }})
|
||||
needs: [compute-versions, download-kernel-runtime, build-rootfs]
|
||||
strategy:
|
||||
matrix:
|
||||
include:
|
||||
- arch: arm64
|
||||
runner: build-arm64
|
||||
target: aarch64-unknown-linux-gnu
|
||||
platform: linux-aarch64
|
||||
guest_arch: aarch64
|
||||
- arch: amd64
|
||||
runner: build-amd64
|
||||
target: x86_64-unknown-linux-gnu
|
||||
platform: linux-x86_64
|
||||
guest_arch: x86_64
|
||||
runs-on: ${{ matrix.runner }}
|
||||
timeout-minutes: 30
|
||||
container:
|
||||
image: ghcr.io/nvidia/openshell/ci:latest
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
options: --privileged
|
||||
env:
|
||||
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SCCACHE_MEMCACHED_ENDPOINT: ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
|
||||
OPENSHELL_IMAGE_TAG: dev
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Mark workspace safe for git
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags --force
|
||||
|
||||
- name: Install tools
|
||||
run: mise install
|
||||
|
||||
- name: Cache Rust target and registry
|
||||
uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2
|
||||
with:
|
||||
shared-key: vm-linux-${{ matrix.arch }}
|
||||
cache-directories: .cache/sccache
|
||||
cache-targets: "true"
|
||||
|
||||
- name: Download kernel runtime tarball
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: kernel-runtime-tarballs
|
||||
path: runtime-download/
|
||||
|
||||
- name: Download rootfs tarball
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: rootfs-${{ matrix.arch }}
|
||||
path: rootfs-download/
|
||||
|
||||
- name: Stage compressed runtime for embedding
|
||||
run: |
|
||||
set -euo pipefail
|
||||
COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed"
|
||||
mkdir -p "$COMPRESSED_DIR"
|
||||
|
||||
# Extract kernel runtime tarball and re-compress individual files
|
||||
EXTRACT_DIR=$(mktemp -d)
|
||||
zstd -d "runtime-download/vm-runtime-${{ matrix.platform }}.tar.zst" --stdout \
|
||||
| tar -xf - -C "$EXTRACT_DIR"
|
||||
|
||||
echo "Extracted runtime files:"
|
||||
ls -lah "$EXTRACT_DIR"
|
||||
|
||||
for file in "$EXTRACT_DIR"/*; do
|
||||
[ -f "$file" ] || continue
|
||||
name=$(basename "$file")
|
||||
[ "$name" = "provenance.json" ] && continue
|
||||
zstd -19 -f -q -T0 -o "${COMPRESSED_DIR}/${name}.zst" "$file"
|
||||
done
|
||||
|
||||
# Copy rootfs tarball (already zstd-compressed)
|
||||
cp rootfs-download/rootfs.tar.zst "${COMPRESSED_DIR}/rootfs.tar.zst"
|
||||
|
||||
echo "Staged compressed artifacts:"
|
||||
ls -lah "$COMPRESSED_DIR"
|
||||
|
||||
- name: Scope workspace to VM crates
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sed -i 's|members = \["crates/\*"\]|members = ["crates/openshell-vm", "crates/openshell-core", "crates/openshell-bootstrap", "crates/openshell-policy"]|' Cargo.toml
|
||||
|
||||
- name: Patch workspace version
|
||||
if: needs.compute-versions.outputs.cargo_version != ''
|
||||
run: |
|
||||
set -euo pipefail
|
||||
sed -i -E '/^\[workspace\.package\]/,/^\[/{s/^version[[:space:]]*=[[:space:]]*".*"/version = "'"${{ needs.compute-versions.outputs.cargo_version }}"'"/}' Cargo.toml
|
||||
|
||||
- name: Build openshell-vm
|
||||
run: |
|
||||
set -euo pipefail
|
||||
OPENSHELL_VM_RUNTIME_COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed" \
|
||||
mise x -- cargo build --release -p openshell-vm
|
||||
|
||||
- name: sccache stats
|
||||
if: always()
|
||||
run: mise x -- sccache --show-stats
|
||||
|
||||
- name: Package binary
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p artifacts
|
||||
tar -czf "artifacts/openshell-vm-${{ matrix.target }}.tar.gz" \
|
||||
-C target/release openshell-vm
|
||||
ls -lh artifacts/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vm-linux-${{ matrix.arch }}
|
||||
path: artifacts/*.tar.gz
|
||||
retention-days: 5
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Build openshell-vm binary (macOS ARM64 via osxcross)
|
||||
# ---------------------------------------------------------------------------
|
||||
build-vm-macos:
|
||||
name: Build VM (macOS)
|
||||
needs: [compute-versions, download-kernel-runtime, build-rootfs]
|
||||
runs-on: build-amd64
|
||||
timeout-minutes: 60
|
||||
container:
|
||||
image: ghcr.io/nvidia/openshell/ci:latest
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
options: --privileged
|
||||
volumes:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
env:
|
||||
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SCCACHE_MEMCACHED_ENDPOINT: ${{ vars.SCCACHE_MEMCACHED_ENDPOINT }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Mark workspace safe for git
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Fetch tags
|
||||
run: git fetch --tags --force
|
||||
|
||||
- name: Log in to GHCR
|
||||
run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.actor }}" --password-stdin
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: ./.github/actions/setup-buildx
|
||||
|
||||
- name: Download kernel runtime tarball
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: kernel-runtime-tarballs
|
||||
path: runtime-download/
|
||||
|
||||
- name: Download rootfs tarball (arm64)
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: rootfs-arm64
|
||||
path: rootfs-download/
|
||||
|
||||
- name: Prepare compressed runtime directory
|
||||
run: |
|
||||
set -euo pipefail
|
||||
COMPRESSED_DIR="${PWD}/target/vm-runtime-compressed-macos"
|
||||
mkdir -p "$COMPRESSED_DIR"
|
||||
|
||||
# Extract the darwin runtime tarball and re-compress for embedding.
|
||||
# The macOS embedded.rs expects: libkrun.dylib.zst, libkrunfw.5.dylib.zst, gvproxy.zst
|
||||
EXTRACT_DIR=$(mktemp -d)
|
||||
zstd -d "runtime-download/vm-runtime-darwin-aarch64.tar.zst" --stdout \
|
||||
| tar -xf - -C "$EXTRACT_DIR"
|
||||
|
||||
echo "Extracted darwin runtime files:"
|
||||
ls -lah "$EXTRACT_DIR"
|
||||
|
||||
for file in "$EXTRACT_DIR"/*; do
|
||||
[ -f "$file" ] || continue
|
||||
name=$(basename "$file")
|
||||
[ "$name" = "provenance.json" ] && continue
|
||||
zstd -19 -f -q -T0 -o "${COMPRESSED_DIR}/${name}.zst" "$file"
|
||||
done
|
||||
|
||||
# The macOS VM guest is always Linux ARM64, so use the arm64 rootfs
|
||||
cp rootfs-download/rootfs.tar.zst "${COMPRESSED_DIR}/rootfs.tar.zst"
|
||||
|
||||
echo "Staged macOS compressed artifacts:"
|
||||
ls -lah "$COMPRESSED_DIR"
|
||||
|
||||
- name: Build macOS binary via Docker (osxcross)
|
||||
run: |
|
||||
set -euo pipefail
|
||||
docker buildx build \
|
||||
--file deploy/docker/Dockerfile.vm-macos \
|
||||
--build-arg OPENSHELL_CARGO_VERSION="${{ needs.compute-versions.outputs.cargo_version }}" \
|
||||
--build-arg OPENSHELL_IMAGE_TAG=dev \
|
||||
--build-arg CARGO_TARGET_CACHE_SCOPE="${{ github.sha }}" \
|
||||
--build-context vm-runtime-compressed="${PWD}/target/vm-runtime-compressed-macos" \
|
||||
--target binary \
|
||||
--output type=local,dest=out/ \
|
||||
.
|
||||
|
||||
- name: Package binary
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p artifacts
|
||||
tar -czf artifacts/openshell-vm-aarch64-apple-darwin.tar.gz \
|
||||
-C out openshell-vm
|
||||
ls -lh artifacts/
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vm-macos
|
||||
path: artifacts/*.tar.gz
|
||||
retention-days: 5
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Upload all VM binaries to the vm-dev rolling release
|
||||
# ---------------------------------------------------------------------------
|
||||
release-vm-dev:
|
||||
name: Release VM Dev
|
||||
needs: [build-vm-linux, build-vm-macos]
|
||||
runs-on: build-amd64
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download all VM binary artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: vm-*
|
||||
path: release/
|
||||
merge-multiple: true
|
||||
|
||||
- name: Filter to only binary tarballs
|
||||
run: |
|
||||
set -euo pipefail
|
||||
mkdir -p release-final
|
||||
# Only include the openshell-vm binary tarballs, not kernel runtime
|
||||
cp release/openshell-vm-*.tar.gz release-final/
|
||||
count=$(ls release-final/openshell-vm-*.tar.gz 2>/dev/null | wc -l)
|
||||
if [ "$count" -eq 0 ]; then
|
||||
echo "ERROR: No VM binary tarballs found in release/" >&2
|
||||
exit 1
|
||||
fi
|
||||
echo "Release artifacts (${count} binaries):"
|
||||
ls -lh release-final/
|
||||
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd release-final
|
||||
sha256sum openshell-vm-*.tar.gz > vm-binary-checksums-sha256.txt
|
||||
cat vm-binary-checksums-sha256.txt
|
||||
|
||||
- name: Ensure vm-dev tag exists
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag -fa vm-dev -m "VM Development Build" "${GITHUB_SHA}"
|
||||
git push --force origin vm-dev
|
||||
|
||||
- name: Prune stale VM binary assets from vm-dev release
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
|
||||
let release;
|
||||
try {
|
||||
release = await github.rest.repos.getReleaseByTag({ owner, repo, tag: 'vm-dev' });
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
core.info('No existing vm-dev release; will create fresh.');
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
// Delete old VM binary assets (keep kernel runtime assets)
|
||||
for (const asset of release.data.assets) {
|
||||
if (asset.name.startsWith('openshell-vm-') || asset.name === 'vm-binary-checksums-sha256.txt') {
|
||||
core.info(`Deleting stale asset: ${asset.name}`);
|
||||
await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: asset.id });
|
||||
}
|
||||
}
|
||||
|
||||
- name: Upload to vm-dev GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: OpenShell VM Development Build
|
||||
prerelease: true
|
||||
tag_name: vm-dev
|
||||
target_commitish: ${{ github.sha }}
|
||||
body: |
|
||||
Rolling development build of **openshell-vm** — the MicroVM runtime for OpenShell.
|
||||
|
||||
> **NOTE**: This is a development build, not a tagged release, and may be unstable.
|
||||
|
||||
### Kernel Runtime Artifacts
|
||||
|
||||
Pre-built kernel runtime (libkrunfw + libkrun + gvproxy) for embedding into
|
||||
the openshell-vm binary. These are rebuilt when the kernel config or pinned
|
||||
dependency versions change.
|
||||
|
||||
| Platform | Artifact |
|
||||
|----------|----------|
|
||||
| Linux ARM64 | `vm-runtime-linux-aarch64.tar.zst` |
|
||||
| Linux x86_64 | `vm-runtime-linux-x86_64.tar.zst` |
|
||||
| macOS ARM64 | `vm-runtime-darwin-aarch64.tar.zst` |
|
||||
|
||||
### VM Binaries
|
||||
|
||||
Self-extracting openshell-vm binaries with embedded kernel runtime and base
|
||||
rootfs. These are rebuilt on every push to main.
|
||||
|
||||
| Platform | Artifact |
|
||||
|----------|----------|
|
||||
| Linux ARM64 | `openshell-vm-aarch64-unknown-linux-gnu.tar.gz` |
|
||||
| Linux x86_64 | `openshell-vm-x86_64-unknown-linux-gnu.tar.gz` |
|
||||
| macOS ARM64 | `openshell-vm-aarch64-apple-darwin.tar.gz` |
|
||||
|
||||
**macOS users:** The binary must be codesigned with the Hypervisor entitlement:
|
||||
```bash
|
||||
codesign --entitlements crates/openshell-vm/entitlements.plist --force -s - ./openshell-vm
|
||||
```
|
||||
|
||||
files: |
|
||||
release-final/openshell-vm-aarch64-unknown-linux-gnu.tar.gz
|
||||
release-final/openshell-vm-x86_64-unknown-linux-gnu.tar.gz
|
||||
release-final/openshell-vm-aarch64-apple-darwin.tar.gz
|
||||
release-final/vm-binary-checksums-sha256.txt
|
||||
@@ -0,0 +1,247 @@
|
||||
name: Release VM Kernel
|
||||
|
||||
# Build custom libkrunfw (kernel firmware) + libkrun (VMM) + gvproxy for all
|
||||
# supported openshell-vm platforms. Artifacts are uploaded to the rolling
|
||||
# "vm-dev" GitHub Release and consumed by release-vm-dev.yml when building the
|
||||
# openshell-vm binary.
|
||||
#
|
||||
# This workflow runs on-demand (or when kernel config / pins change). It is
|
||||
# intentionally decoupled from the per-commit VM binary build because the
|
||||
# kernel rarely changes and takes 15-45 minutes to compile.
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
|
||||
# Serialize with release-vm-dev.yml — both update the vm-dev release.
|
||||
concurrency:
|
||||
group: vm-dev-release
|
||||
cancel-in-progress: false
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: bash
|
||||
|
||||
jobs:
|
||||
# ---------------------------------------------------------------------------
|
||||
# Linux ARM64 — native kernel + libkrun build
|
||||
# ---------------------------------------------------------------------------
|
||||
build-runtime-linux-arm64:
|
||||
name: Build Runtime (Linux ARM64)
|
||||
runs-on: build-arm64
|
||||
timeout-minutes: 60
|
||||
container:
|
||||
image: ghcr.io/nvidia/openshell/ci:latest
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
options: --privileged
|
||||
env:
|
||||
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Mark workspace safe for git
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Build libkrunfw + libkrun from source
|
||||
run: tasks/scripts/vm/build-libkrun.sh
|
||||
|
||||
- name: Package runtime tarball
|
||||
run: |
|
||||
tasks/scripts/vm/package-vm-runtime.sh \
|
||||
--platform linux-aarch64 \
|
||||
--build-dir target/libkrun-build \
|
||||
--output artifacts/vm-runtime-linux-aarch64.tar.zst
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vm-runtime-linux-arm64
|
||||
path: artifacts/vm-runtime-linux-aarch64.tar.zst
|
||||
retention-days: 5
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Linux AMD64 — native kernel + libkrun build
|
||||
# ---------------------------------------------------------------------------
|
||||
build-runtime-linux-amd64:
|
||||
name: Build Runtime (Linux AMD64)
|
||||
runs-on: build-amd64
|
||||
timeout-minutes: 60
|
||||
container:
|
||||
image: ghcr.io/nvidia/openshell/ci:latest
|
||||
credentials:
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
options: --privileged
|
||||
env:
|
||||
MISE_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Mark workspace safe for git
|
||||
run: git config --global --add safe.directory "$GITHUB_WORKSPACE"
|
||||
|
||||
- name: Build libkrunfw + libkrun from source
|
||||
run: tasks/scripts/vm/build-libkrun.sh
|
||||
|
||||
- name: Package runtime tarball
|
||||
run: |
|
||||
tasks/scripts/vm/package-vm-runtime.sh \
|
||||
--platform linux-x86_64 \
|
||||
--build-dir target/libkrun-build \
|
||||
--output artifacts/vm-runtime-linux-x86_64.tar.zst
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vm-runtime-linux-amd64
|
||||
path: artifacts/vm-runtime-linux-x86_64.tar.zst
|
||||
retention-days: 5
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# macOS ARM64 — kernel built via krunvm, libkrun built natively
|
||||
# ---------------------------------------------------------------------------
|
||||
build-runtime-macos-arm64:
|
||||
name: Build Runtime (macOS ARM64)
|
||||
runs-on: macos-latest-xlarge
|
||||
timeout-minutes: 90
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
set -euo pipefail
|
||||
brew install rust lld dtc xz
|
||||
# libkrunfw from Homebrew (used as a fallback/reference by build scripts)
|
||||
brew install libkrunfw
|
||||
# krunvm is needed to build the Linux kernel inside a Fedora VM
|
||||
brew tap slp/krun
|
||||
brew install krunvm
|
||||
|
||||
- name: Build custom libkrunfw (kernel)
|
||||
run: crates/openshell-vm/runtime/build-custom-libkrunfw.sh
|
||||
|
||||
- name: Build portable libkrun
|
||||
run: tasks/scripts/vm/build-libkrun-macos.sh
|
||||
|
||||
- name: Package runtime tarball
|
||||
env:
|
||||
CUSTOM_PROVENANCE_DIR: target/custom-runtime
|
||||
run: |
|
||||
tasks/scripts/vm/package-vm-runtime.sh \
|
||||
--platform darwin-aarch64 \
|
||||
--build-dir target/libkrun-build \
|
||||
--output artifacts/vm-runtime-darwin-aarch64.tar.zst
|
||||
|
||||
- name: Upload artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: vm-runtime-macos-arm64
|
||||
path: artifacts/vm-runtime-darwin-aarch64.tar.zst
|
||||
retention-days: 5
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Upload all runtime tarballs to the vm-dev rolling release
|
||||
# ---------------------------------------------------------------------------
|
||||
release-kernel:
|
||||
name: Release Kernel Runtime
|
||||
needs: [build-runtime-linux-arm64, build-runtime-linux-amd64, build-runtime-macos-arm64]
|
||||
runs-on: build-amd64
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Download all runtime artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
pattern: vm-runtime-*
|
||||
path: release/
|
||||
merge-multiple: true
|
||||
|
||||
- name: Generate checksums
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd release
|
||||
sha256sum vm-runtime-*.tar.zst > vm-runtime-checksums-sha256.txt
|
||||
cat vm-runtime-checksums-sha256.txt
|
||||
|
||||
- name: Ensure vm-dev tag exists
|
||||
run: |
|
||||
git config user.name "github-actions[bot]"
|
||||
git config user.email "github-actions[bot]@users.noreply.github.com"
|
||||
git tag -fa vm-dev -m "VM Development Build" "${GITHUB_SHA}"
|
||||
git push --force origin vm-dev
|
||||
|
||||
- name: Prune stale runtime assets from vm-dev release
|
||||
uses: actions/github-script@v7
|
||||
with:
|
||||
script: |
|
||||
const [owner, repo] = process.env.GITHUB_REPOSITORY.split('/');
|
||||
let release;
|
||||
try {
|
||||
release = await github.rest.repos.getReleaseByTag({ owner, repo, tag: 'vm-dev' });
|
||||
} catch (err) {
|
||||
if (err.status === 404) {
|
||||
core.info('No existing vm-dev release; will create fresh.');
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
// Delete old runtime tarballs and checksums (keep vm binary assets)
|
||||
for (const asset of release.data.assets) {
|
||||
if (asset.name.startsWith('vm-runtime-')) {
|
||||
core.info(`Deleting stale asset: ${asset.name}`);
|
||||
await github.rest.repos.deleteReleaseAsset({ owner, repo, asset_id: asset.id });
|
||||
}
|
||||
}
|
||||
|
||||
- name: Create / update vm-dev GitHub Release
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: OpenShell VM Development Build
|
||||
prerelease: true
|
||||
tag_name: vm-dev
|
||||
target_commitish: ${{ github.sha }}
|
||||
body: |
|
||||
Rolling development build of **openshell-vm** — the MicroVM runtime for OpenShell.
|
||||
|
||||
> **NOTE**: This is a development build, not a tagged release, and may be unstable.
|
||||
> The VM implementation itself is also experimental and may change or break without
|
||||
> notice.
|
||||
|
||||
### Kernel Runtime Artifacts
|
||||
|
||||
Pre-built kernel runtime (libkrunfw + libkrun + gvproxy) for embedding into
|
||||
the openshell-vm binary. These are rebuilt when the kernel config or pinned
|
||||
dependency versions change.
|
||||
|
||||
| Platform | Artifact |
|
||||
|----------|----------|
|
||||
| Linux ARM64 | `vm-runtime-linux-aarch64.tar.zst` |
|
||||
| Linux x86_64 | `vm-runtime-linux-x86_64.tar.zst` |
|
||||
| macOS ARM64 | `vm-runtime-darwin-aarch64.tar.zst` |
|
||||
|
||||
### VM Binaries
|
||||
|
||||
Self-extracting openshell-vm binaries with embedded kernel runtime and base
|
||||
rootfs. These are rebuilt on every push to main.
|
||||
|
||||
| Platform | Artifact |
|
||||
|----------|----------|
|
||||
| Linux ARM64 | `openshell-vm-aarch64-unknown-linux-gnu.tar.gz` |
|
||||
| Linux x86_64 | `openshell-vm-x86_64-unknown-linux-gnu.tar.gz` |
|
||||
| macOS ARM64 | `openshell-vm-aarch64-apple-darwin.tar.gz` |
|
||||
|
||||
**macOS users:** The binary must be codesigned with the Hypervisor entitlement:
|
||||
```bash
|
||||
codesign --entitlements crates/openshell-vm/entitlements.plist --force -s - ./openshell-vm
|
||||
```
|
||||
|
||||
files: |
|
||||
release/vm-runtime-linux-aarch64.tar.zst
|
||||
release/vm-runtime-linux-x86_64.tar.zst
|
||||
release/vm-runtime-darwin-aarch64.tar.zst
|
||||
release/vm-runtime-checksums-sha256.txt
|
||||
Reference in New Issue
Block a user