mirror of
https://github.com/NVIDIA/OpenShell.git
synced 2026-10-30 07:33:59 +08:00
* feat(isolation): publish backend protocol contracts independently of runtime Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(isolation): expose trusted launch and registry data contracts Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(isolation): name the required capability sandbox Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(sandbox): align protocol and compute capability names Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(sandbox): finalize public protocol contract names Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(isolation)!: activate backend contracts in sandbox runtime and driver selection Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(sandbox): simplify runtime and fix backend example Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(examples): organize WASI backend in Rust Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(sandbox): defer protocol conformance fixtures Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(examples): add supervised V8 backend demo Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(examples): stream V8 guest output with default policy Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(examples): handle V8 rejections and roll back failed launches Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(examples): align V8 crypto dependencies with CI AWS-LC Signed-off-by: Drew Newberry <anewberry@nvidia.com> * feat(sandbox): represent Sandbox Protocol operations in protobuf Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(isolation): replace backend traits with RPC clients Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(proto): remove legacy isolation protocol reservations Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(proto): clarify Sandbox Protocol names Signed-off-by: Drew Newberry <anewberry@nvidia.com> * docs(isolation): clarify authentication bootstrap and supervisor APIs Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(isolation): simplify policy enforcement confirmation Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(sandbox): rotate launch generations and stabilize retry sessions Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(sandbox): remove redundant backend adapters and TCP flags Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(sandbox): repair Docker restarts and macOS lint Signed-off-by: Drew Newberry <anewberry@nvidia.com> * refactor(isolation): simplify RPC contracts and backend registration Signed-off-by: Drew Newberry <anewberry@nvidia.com> * fix(sandbox): deliver TCP denials before closing the RPC Signed-off-by: Drew Newberry <anewberry@nvidia.com> --------- Signed-off-by: Drew Newberry <anewberry@nvidia.com>
145 lines
5.6 KiB
Rust
145 lines
5.6 KiB
Rust
// SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
use std::env;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
mod build_version;
|
|
|
|
const PROTO_REL: &str = "../../proto";
|
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
|
// A caller-supplied PROTOC (for example a distro package's system
|
|
// compiler) is used as-is and prost resolves its own includes. Without it,
|
|
// use the vendored compiler and include tree.
|
|
println!("cargo:rerun-if-env-changed=PROTOC");
|
|
println!("cargo:rerun-if-env-changed=PROTOC_INCLUDE");
|
|
let use_vendored_protoc = env::var_os("PROTOC").is_none();
|
|
|
|
// In vendored mode, preserve the vendored include-tree guarantee even when
|
|
// the caller has PROTOC_INCLUDE set: prost validates that ambient path
|
|
// independently of explicit includes. Re-enter with a child-only
|
|
// environment override.
|
|
if use_vendored_protoc && env::var_os("PROTOC_INCLUDE").is_some() {
|
|
let status = std::process::Command::new(env::current_exe()?)
|
|
.env_remove("PROTOC_INCLUDE")
|
|
.status()?;
|
|
if !status.success() {
|
|
return Err(format!("vendored protobuf build failed: {status}").into());
|
|
}
|
|
return Ok(());
|
|
}
|
|
|
|
// --- Git-derived version ---
|
|
// Compute a version from tags and commit metadata for local builds. In
|
|
// Docker/CI builds where .git is absent, this silently does nothing and
|
|
// the binary falls back to CARGO_PKG_VERSION (which is already sed-patched
|
|
// by the build pipeline).
|
|
println!("cargo:rerun-if-changed=../../.git/HEAD");
|
|
println!("cargo:rerun-if-changed=../../.git/logs/HEAD");
|
|
println!("cargo:rerun-if-changed=../../.git/refs/tags");
|
|
println!("cargo:rerun-if-changed=../../.git/packed-refs");
|
|
|
|
if let Some(version) = git_version() {
|
|
println!("cargo:rustc-env=OPENSHELL_GIT_VERSION={version}");
|
|
}
|
|
|
|
// --- Protobuf compilation ---
|
|
// Re-run when anything under proto/ changes (including newly added .proto files).
|
|
println!("cargo:rerun-if-changed={PROTO_REL}");
|
|
// Configure the vendored compiler and well-known includes without changing
|
|
// the build process environment. With a caller-supplied PROTOC, leave both
|
|
// to prost.
|
|
let mut proto_config = tonic_prost_build::Config::new();
|
|
// Keep optional grant evidence off sandbox lifecycle futures' stacks.
|
|
proto_config.boxed(".openshell.v1.SandboxStatus.last_token_grant_failure");
|
|
let proto_include = if use_vendored_protoc {
|
|
proto_config.protoc_executable(protoc_bin_vendored::protoc_bin_path()?);
|
|
Some(protoc_bin_vendored::include_path()?)
|
|
} else {
|
|
None
|
|
};
|
|
|
|
let manifest_dir = PathBuf::from(env::var("CARGO_MANIFEST_DIR")?);
|
|
let proto_root = manifest_dir.join(PROTO_REL);
|
|
let mut proto_files = Vec::new();
|
|
collect_proto_files(&proto_root, &mut proto_files)?;
|
|
proto_files.sort();
|
|
|
|
let out_dir = PathBuf::from(env::var("OUT_DIR")?);
|
|
let descriptor_path = out_dir.join("openshell_descriptor.bin");
|
|
let mut include_dirs = vec![proto_root];
|
|
include_dirs.extend(proto_include);
|
|
|
|
// Configure tonic/prost protobuf code generation.
|
|
tonic_prost_build::configure()
|
|
.btree_map(".openshell.sandbox.protocol.v1")
|
|
.build_server(true)
|
|
.build_client(true)
|
|
.include_file("openshell.rs")
|
|
// Emit a binary FileDescriptorSet so the server can enumerate every
|
|
// RPC at runtime (used by the per-handler auth exhaustiveness test).
|
|
.file_descriptor_set_path(&descriptor_path)
|
|
.compile_with_config(proto_config, &proto_files, &include_dirs)?;
|
|
|
|
println!(
|
|
"cargo:rustc-env=OPENSHELL_DESCRIPTOR_PATH={}",
|
|
descriptor_path.display()
|
|
);
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn collect_proto_files(dir: &Path, out: &mut Vec<PathBuf>) -> std::io::Result<()> {
|
|
for entry in std::fs::read_dir(dir)? {
|
|
let path = entry?.path();
|
|
if path.is_dir() {
|
|
collect_proto_files(&path, out)?;
|
|
} else if path.extension().is_some_and(|ext| ext == "proto") {
|
|
out.push(path);
|
|
}
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
/// Derive the release or development version from git metadata.
|
|
///
|
|
/// Implements the "guess-next-dev" convention used by the release pipeline
|
|
/// (`tasks/scripts/release.py`): exact stable and prerelease tags retain their
|
|
/// version. Otherwise, the latest merged stable release gets a patch bump and
|
|
/// `-dev.<N>+g<sha>` is appended.
|
|
///
|
|
/// Examples:
|
|
/// on tag v0.1.0-pre.1 → "0.1.0-pre.1"
|
|
/// 3 commits past v0.0.3 → "0.0.4-dev.3+g2bf9969ab"
|
|
///
|
|
/// Returns `None` when git metadata cannot be read.
|
|
fn git_version() -> Option<String> {
|
|
let exact_tags = git_output(&["tag", "--points-at", "HEAD"])?;
|
|
if let Some(version) = build_version::exact_release_version(exact_tags.lines()) {
|
|
return Some(version);
|
|
}
|
|
|
|
let merged_tags = git_output(&["tag", "--merged", "HEAD", "--list", "v*.*.*"])?;
|
|
let latest_tag = build_version::latest_stable_tag(merged_tags.lines());
|
|
let revision_range = latest_tag
|
|
.as_deref()
|
|
.map_or_else(|| "HEAD".to_string(), |tag| format!("{tag}..HEAD"));
|
|
let distance = git_output(&["rev-list", "--count", &revision_range])?
|
|
.parse()
|
|
.ok()?;
|
|
let sha = git_output(&["rev-parse", "--short=9", "HEAD"])?;
|
|
|
|
build_version::next_dev_version(latest_tag.as_deref(), distance, &sha)
|
|
}
|
|
|
|
fn git_output(args: &[&str]) -> Option<String> {
|
|
let output = std::process::Command::new("git").args(args).output().ok()?;
|
|
if !output.status.success() {
|
|
return None;
|
|
}
|
|
String::from_utf8(output.stdout)
|
|
.ok()
|
|
.map(|output| output.trim().to_string())
|
|
}
|