[model-gateway] Add version command support to SMG (#12558)
This commit is contained in:
@@ -106,6 +106,8 @@ deadpool-postgres = "0.14.1"
|
||||
[build-dependencies]
|
||||
tonic-prost-build = "0.14.2"
|
||||
prost-build = "0.14.1"
|
||||
chrono = { version = "0.4", features = ["clock"] }
|
||||
toml = "0.9"
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = { version = "0.5", features = ["html_reports"] }
|
||||
|
||||
@@ -88,6 +88,20 @@ pip install --force-reinstall dist/*.whl
|
||||
```
|
||||
> **Note:** Python bindings are located in `bindings/python/` with their own Cargo.toml. Use `maturin develop` for fast iteration during development (builds in debug mode and installs directly). Use `maturin build --release --features vendored-openssl` for production wheels with full optimizations (opt-level="z", lto="fat") and cross-platform compatibility. The package uses abi3 support for Python 3.8+ compatibility.
|
||||
|
||||
## Checking Version
|
||||
|
||||
After installation, verify the installation and check version information:
|
||||
|
||||
```bash
|
||||
# Short version info (Rust binary)
|
||||
./target/release/sglang-router -v
|
||||
|
||||
# Full version info with build details (Rust binary)
|
||||
./target/release/sglang-router --version
|
||||
```
|
||||
|
||||
The `-v` flag displays a concise version string, while `--version` (or `-V`) shows comprehensive build information including Git commit, build time, compiler versions, and platform details.
|
||||
|
||||
## Quick Start
|
||||
### Regular HTTP Routing
|
||||
- **Rust binary**
|
||||
|
||||
@@ -1,7 +1,14 @@
|
||||
use std::process::Command;
|
||||
|
||||
// Default values for version and project name when pyproject.toml is unavailable
|
||||
const DEFAULT_VERSION: &str = "0.0.0";
|
||||
const DEFAULT_PROJECT_NAME: &str = "sgl-router";
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Only regenerate if proto files change
|
||||
println!("cargo:rerun-if-changed=src/proto/sglang_scheduler.proto");
|
||||
println!("cargo:rerun-if-changed=src/proto/vllm_engine.proto");
|
||||
println!("cargo:rerun-if-changed=pyproject.toml");
|
||||
|
||||
// Configure tonic-prost-build for gRPC code generation
|
||||
tonic_prost_build::configure()
|
||||
@@ -23,5 +30,129 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
|
||||
println!("cargo:info=Protobuf compilation completed successfully");
|
||||
|
||||
// Read version and project name from pyproject.toml with fallback
|
||||
let version =
|
||||
read_field_from_pyproject("version").unwrap_or_else(|_| DEFAULT_VERSION.to_string());
|
||||
let project_name =
|
||||
read_field_from_pyproject("name").unwrap_or_else(|_| DEFAULT_PROJECT_NAME.to_string());
|
||||
println!("cargo:rustc-env=SGL_ROUTER_VERSION={}", version);
|
||||
println!("cargo:rustc-env=SGL_ROUTER_PROJECT_NAME={}", project_name);
|
||||
|
||||
// Generate build time (UTC)
|
||||
let build_time = chrono::Utc::now()
|
||||
.format("%Y-%m-%d %H:%M:%S UTC")
|
||||
.to_string();
|
||||
println!("cargo:rustc-env=SGL_ROUTER_BUILD_TIME={}", build_time);
|
||||
|
||||
// Try to get Git branch
|
||||
let git_branch = get_git_branch().unwrap_or_else(|| "unknown".to_string());
|
||||
println!("cargo:rustc-env=SGL_ROUTER_GIT_BRANCH={}", git_branch);
|
||||
|
||||
// Try to get Git commit hash
|
||||
let git_commit = get_git_commit().unwrap_or_else(|| "unknown".to_string());
|
||||
println!("cargo:rustc-env=SGL_ROUTER_GIT_COMMIT={}", git_commit);
|
||||
|
||||
// Try to get Git status (clean/dirty)
|
||||
let git_status = get_git_status().unwrap_or_else(|| "unknown".to_string());
|
||||
println!("cargo:rustc-env=SGL_ROUTER_GIT_STATUS={}", git_status);
|
||||
|
||||
// Get Rustc version
|
||||
let rustc_version = get_rustc_version().unwrap_or_else(|| "unknown".to_string());
|
||||
println!("cargo:rustc-env=SGL_ROUTER_RUSTC_VERSION={}", rustc_version);
|
||||
|
||||
// Get Cargo version
|
||||
let cargo_version = get_cargo_version().unwrap_or_else(|| "unknown".to_string());
|
||||
println!("cargo:rustc-env=SGL_ROUTER_CARGO_VERSION={}", cargo_version);
|
||||
|
||||
// Get target triple (platform)
|
||||
let target_triple = std::env::var("TARGET").unwrap_or_else(|_| {
|
||||
// Try to get from rustc if not set
|
||||
get_target_from_rustc().unwrap_or_else(|| "unknown".to_string())
|
||||
});
|
||||
println!("cargo:rustc-env=SGL_ROUTER_TARGET_TRIPLE={}", target_triple);
|
||||
|
||||
// Get build mode (debug/release)
|
||||
let build_mode = if std::env::var("PROFILE").unwrap_or_default() == "release" {
|
||||
"release"
|
||||
} else {
|
||||
"debug"
|
||||
};
|
||||
println!("cargo:rustc-env=SGL_ROUTER_BUILD_MODE={}", build_mode);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn read_field_from_pyproject(field: &str) -> Result<String, Box<dyn std::error::Error>> {
|
||||
let content = std::fs::read_to_string("pyproject.toml")?;
|
||||
let toml: toml::Value = toml::from_str(&content)?;
|
||||
|
||||
// Navigate to [project] section
|
||||
let project = toml
|
||||
.get("project")
|
||||
.ok_or("Missing [project] section in pyproject.toml")?;
|
||||
|
||||
// Get the field value
|
||||
let value = project
|
||||
.get(field)
|
||||
.ok_or_else(|| format!("Missing '{}' field in [project] section", field))?;
|
||||
|
||||
// Convert to string
|
||||
match value {
|
||||
toml::Value::String(s) => Ok(s.clone()),
|
||||
toml::Value::Integer(i) => Ok(i.to_string()),
|
||||
toml::Value::Float(f) => Ok(f.to_string()),
|
||||
toml::Value::Boolean(b) => Ok(b.to_string()),
|
||||
_ => Err(format!("Field '{}' is not a string value", field).into()),
|
||||
}
|
||||
}
|
||||
|
||||
/// Execute a command and return its output as a trimmed string
|
||||
fn run_command(command: &str, args: &[&str]) -> Option<String> {
|
||||
let output = Command::new(command).args(args).output().ok()?;
|
||||
|
||||
if output.status.success() {
|
||||
String::from_utf8(output.stdout)
|
||||
.ok()
|
||||
.map(|s| s.trim().to_string())
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_git_branch() -> Option<String> {
|
||||
run_command("git", &["rev-parse", "--abbrev-ref", "HEAD"])
|
||||
}
|
||||
|
||||
fn get_git_commit() -> Option<String> {
|
||||
run_command("git", &["rev-parse", "--short", "HEAD"])
|
||||
}
|
||||
|
||||
fn get_git_status() -> Option<String> {
|
||||
// Check if there are uncommitted changes
|
||||
let output = run_command("git", &["status", "--porcelain"])?;
|
||||
if output.is_empty() {
|
||||
Some("clean".to_string())
|
||||
} else {
|
||||
Some("dirty".to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn get_rustc_version() -> Option<String> {
|
||||
run_command("rustc", &["--version"])
|
||||
}
|
||||
|
||||
fn get_cargo_version() -> Option<String> {
|
||||
run_command("cargo", &["--version"])
|
||||
}
|
||||
|
||||
fn get_target_from_rustc() -> Option<String> {
|
||||
let output_str = run_command("rustc", &["-vV"])?;
|
||||
for line in output_str.lines() {
|
||||
if line.starts_with("host: ") {
|
||||
if let Some(host) = line.strip_prefix("host: ") {
|
||||
return Some(host.trim().to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
@@ -16,3 +16,4 @@ pub mod server;
|
||||
pub mod service_discovery;
|
||||
pub mod tokenizer;
|
||||
pub mod tool_parser;
|
||||
pub mod version;
|
||||
|
||||
@@ -11,6 +11,7 @@ use sglang_router_rs::{
|
||||
metrics::PrometheusConfig,
|
||||
server::{self, ServerConfig},
|
||||
service_discovery::ServiceDiscoveryConfig,
|
||||
version,
|
||||
};
|
||||
fn parse_prefill_args() -> Vec<(String, Option<u16>)> {
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
@@ -683,6 +684,19 @@ impl CliArgs {
|
||||
}
|
||||
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
// Check for version flags before parsing other args to avoid errors
|
||||
let args: Vec<String> = std::env::args().collect();
|
||||
for arg in &args {
|
||||
if arg == "--version" || arg == "-V" {
|
||||
println!("{}", version::get_version_string());
|
||||
return Ok(());
|
||||
}
|
||||
if arg == "-v" {
|
||||
println!("{}", version::get_short_version_string());
|
||||
return Ok(());
|
||||
}
|
||||
}
|
||||
|
||||
let prefill_urls = parse_prefill_args();
|
||||
|
||||
let mut filtered_args: Vec<String> = Vec::new();
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
//! Version information module
|
||||
//!
|
||||
//! Provides version information including version number, build time, and Git metadata.
|
||||
|
||||
/// Project name from pyproject.toml (set at compile time)
|
||||
pub const PROJECT_NAME: &str = env!("SGL_ROUTER_PROJECT_NAME");
|
||||
|
||||
/// Version string from pyproject.toml (set at compile time)
|
||||
pub const VERSION: &str = env!("SGL_ROUTER_VERSION");
|
||||
|
||||
/// Build time in UTC format (set at compile time)
|
||||
pub const BUILD_TIME: &str = env!("SGL_ROUTER_BUILD_TIME");
|
||||
|
||||
/// Git branch name (set at compile time, "unknown" if not available)
|
||||
pub const GIT_BRANCH: &str = env!("SGL_ROUTER_GIT_BRANCH");
|
||||
|
||||
/// Git commit hash (short) (set at compile time, "unknown" if not available)
|
||||
pub const GIT_COMMIT: &str = env!("SGL_ROUTER_GIT_COMMIT");
|
||||
|
||||
/// Git repository status (clean/dirty) (set at compile time)
|
||||
pub const GIT_STATUS: &str = env!("SGL_ROUTER_GIT_STATUS");
|
||||
|
||||
/// Rustc version (set at compile time)
|
||||
pub const RUSTC_VERSION: &str = env!("SGL_ROUTER_RUSTC_VERSION");
|
||||
|
||||
/// Cargo version (set at compile time)
|
||||
pub const CARGO_VERSION: &str = env!("SGL_ROUTER_CARGO_VERSION");
|
||||
|
||||
/// Target triple (platform) (set at compile time)
|
||||
pub const TARGET_TRIPLE: &str = env!("SGL_ROUTER_TARGET_TRIPLE");
|
||||
|
||||
/// Build mode (debug/release) (set at compile time)
|
||||
pub const BUILD_MODE: &str = env!("SGL_ROUTER_BUILD_MODE");
|
||||
|
||||
/// Get formatted version information string with structured format
|
||||
pub fn get_version_string() -> String {
|
||||
format!(
|
||||
"{}\n\n\
|
||||
Build Information:\n\
|
||||
Build Time: {}\n\
|
||||
Build Mode: {}\n\
|
||||
Platform: {}\n\n\
|
||||
Version Control:\n\
|
||||
Git Branch: {}\n\
|
||||
Git Commit: {}\n\
|
||||
Git Status: {}\n\n\
|
||||
Compiler:\n\
|
||||
{}\n\
|
||||
{}",
|
||||
get_title(),
|
||||
BUILD_TIME,
|
||||
BUILD_MODE,
|
||||
TARGET_TRIPLE,
|
||||
GIT_BRANCH,
|
||||
GIT_COMMIT,
|
||||
GIT_STATUS,
|
||||
RUSTC_VERSION,
|
||||
CARGO_VERSION
|
||||
)
|
||||
}
|
||||
|
||||
/// Get version title line
|
||||
pub fn get_title() -> String {
|
||||
format!("{} version {}", PROJECT_NAME, VERSION)
|
||||
}
|
||||
|
||||
/// Get version number only
|
||||
pub fn get_version() -> &'static str {
|
||||
VERSION
|
||||
}
|
||||
|
||||
/// Get short version information string
|
||||
pub fn get_short_version_string() -> String {
|
||||
format!("{} version {}, build {}", PROJECT_NAME, VERSION, GIT_COMMIT)
|
||||
}
|
||||
Reference in New Issue
Block a user