use serde::{Deserialize, Serialize};
use crate::error::{fail, Result};
#[derive(Debug, Clone, PartialEq, Eq, Deserialize, Serialize)]
#[serde(rename_all = "camelCase", deny_unknown_fields)]
pub struct BoxTarget {
pub platform: String,
pub arch: String,
pub accelerator: String,
#[serde(default, skip_serializing_if = "Option::is_none")]
pub cuda_version: Option<String>,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct PythonLayout {
pub payload_root: &'static str,
pub entry_point: &'static str,
pub scripts_directory: &'static str,
pub executable_suffix: &'static str,
pub launcher_kind: &'static str,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct BoxTargetAdapter {
pub id: &'static str,
pub platform: &'static str,
pub arch: &'static str,
pub host_os: &'static str,
pub host_arch: &'static str,
pub python: PythonLayout,
pub execution_affecting_environment_variables: &'static [&'static str],
pub self_test_python: &'static str,
}
const PYTHON_EXECUTION_ENVIRONMENT: &[&str] = &[
"PYTHONPATH",
"PYTHONHOME",
"PYTHONSTARTUP",
"PYTHONBREAKPOINT",
];
const MACOS_EXECUTION_ENVIRONMENT: &[&str] = &[
"PYTHONPATH",
"PYTHONHOME",
"PYTHONSTARTUP",
"PYTHONBREAKPOINT",
"DYLD_INSERT_LIBRARIES",
];
const LINUX_EXECUTION_ENVIRONMENT: &[&str] = &[
"PYTHONPATH",
"PYTHONHOME",
"PYTHONSTARTUP",
"PYTHONBREAKPOINT",
"LD_PRELOAD",
];
const POSIX_PYTHON: PythonLayout = PythonLayout {
payload_root: "venv",
entry_point: "venv/bin/python",
scripts_directory: "venv/bin",
executable_suffix: "",
launcher_kind: "posix-polyglot",
};
const TARGET_ADAPTERS: &[BoxTargetAdapter] = &[
BoxTargetAdapter {
id: "macos-aarch64",
platform: "macos",
arch: "aarch64",
host_os: "macos",
host_arch: "aarch64",
python: POSIX_PYTHON,
execution_affecting_environment_variables: MACOS_EXECUTION_ENVIRONMENT,
self_test_python: "import sys; assert sys.platform == 'darwin'",
},
BoxTargetAdapter {
id: "linux-x86_64",
platform: "linux",
arch: "x86_64",
host_os: "linux",
host_arch: "x86_64",
python: POSIX_PYTHON,
execution_affecting_environment_variables: LINUX_EXECUTION_ENVIRONMENT,
self_test_python: "import sys; assert sys.platform.startswith('linux')",
},
BoxTargetAdapter {
id: "windows-x86_64",
platform: "windows",
arch: "x86_64",
host_os: "windows",
host_arch: "x86_64",
python: PythonLayout {
payload_root: "venv",
entry_point: "venv/python.exe",
scripts_directory: "venv/Scripts",
executable_suffix: ".exe",
launcher_kind: "uv-windows-pe",
},
execution_affecting_environment_variables: PYTHON_EXECUTION_ENVIRONMENT,
self_test_python: "import sys; assert sys.platform == 'win32'",
},
];
fn supported_accelerators(platform: &str, arch: &str) -> Option<&'static [&'static str]> {
match (platform, arch) {
("macos", "aarch64") => Some(&["metal", "cpu"]),
("linux" | "windows", "x86_64") => Some(&["cpu", "cuda"]),
_ => None,
}
}
fn is_cuda_version(value: &str) -> bool {
let Some((major, minor)) = value.split_once('.') else {
return false;
};
let major_valid = !major.is_empty()
&& !major.starts_with('0')
&& major.bytes().all(|byte| byte.is_ascii_digit());
let minor_valid = !minor.is_empty() && minor.bytes().all(|byte| byte.is_ascii_digit());
major_valid && minor_valid
}
pub fn box_target_id(target: &BoxTarget) -> Result<String> {
let accelerators = supported_accelerators(&target.platform, &target.arch);
if !accelerators.is_some_and(|values| values.contains(&target.accelerator.as_str())) {
fail!(
"Unsupported box target: {}/{}/{}",
target.platform,
target.arch,
target.accelerator
);
}
if target.accelerator == "cuda" {
let Some(version) = target.cuda_version.as_deref().filter(|v| is_cuda_version(v)) else {
fail!("A CUDA box target requires a numeric major.minor CUDA version");
};
return Ok(format!(
"{}-{}-cuda{version}",
target.platform, target.arch
));
}
if target.cuda_version.is_some() {
fail!("Only CUDA box targets may declare a CUDA version");
}
Ok(format!(
"{}-{}-{}",
target.platform, target.arch, target.accelerator
))
}
pub fn box_target_adapter(target: &BoxTarget) -> Result<&'static BoxTargetAdapter> {
box_target_id(target)?;
let Some(adapter) = TARGET_ADAPTERS
.iter()
.find(|candidate| candidate.platform == target.platform && candidate.arch == target.arch)
else {
fail!(
"No box target adapter exists for {}/{}",
target.platform,
target.arch
);
};
Ok(adapter)
}
#[must_use]
pub fn box_target_adapters() -> &'static [BoxTargetAdapter] {
TARGET_ADAPTERS
}
pub fn assert_native_host(adapter: &BoxTargetAdapter) -> Result<()> {
assert_host(adapter, std::env::consts::OS, std::env::consts::ARCH)
}
pub fn assert_host(adapter: &BoxTargetAdapter, os: &str, arch: &str) -> Result<()> {
if os != adapter.host_os || arch != adapter.host_arch {
fail!(
"{} boxes cannot run on {os}/{arch}; they require {}/{}",
adapter.id,
adapter.host_os,
adapter.host_arch
);
}
Ok(())
}
pub fn assert_python_entry_point(adapter: &BoxTargetAdapter, entry_point: &str) -> Result<()> {
if entry_point != adapter.python.entry_point {
fail!(
"{} boxes must use Python entry point {}",
adapter.id,
adapter.python.entry_point
);
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::{
assert_host, assert_python_entry_point, box_target_adapter, box_target_adapters,
box_target_id, is_cuda_version, BoxTarget,
};
fn target(platform: &str, arch: &str, accelerator: &str, cuda: Option<&str>) -> BoxTarget {
BoxTarget {
platform: platform.to_string(),
arch: arch.to_string(),
accelerator: accelerator.to_string(),
cuda_version: cuda.map(str::to_string),
}
}
#[test]
fn cuda_versions_follow_the_major_minor_rule() {
assert!(is_cuda_version("12.4"));
assert!(is_cuda_version("9.0"));
for invalid in ["", "12", "12.", ".4", "0.1", "01.2", "12.4.1", "12.x", " 12.4"] {
assert!(!is_cuda_version(invalid), "{invalid} was accepted");
}
}
#[test]
fn every_adapter_is_reachable_from_a_target() {
for adapter in box_target_adapters() {
let accelerator = if adapter.platform == "macos" {
"metal"
} else {
"cpu"
};
let resolved =
box_target_adapter(&target(adapter.platform, adapter.arch, accelerator, None))
.unwrap();
assert_eq!(resolved.id, adapter.id);
}
}
#[test]
fn a_foreign_host_is_refused_with_the_shared_wording() {
let adapter = box_target_adapter(&target("linux", "x86_64", "cpu", None)).unwrap();
assert!(assert_host(adapter, "linux", "x86_64").is_ok());
let error = assert_host(adapter, "macos", "aarch64").unwrap_err();
assert!(error.message().contains("cannot run on"), "{error}");
}
#[test]
fn an_entry_point_from_another_platform_is_refused() {
let windows = box_target_adapter(&target("windows", "x86_64", "cpu", None)).unwrap();
assert!(assert_python_entry_point(windows, "venv/python.exe").is_ok());
assert!(assert_python_entry_point(windows, "venv/bin/python").is_err());
}
#[test]
fn a_target_id_is_never_produced_for_an_unsupported_triple() {
assert!(box_target_id(&target("macos", "x86_64", "cpu", None)).is_err());
assert!(box_target_id(&target("linux", "x86_64", "metal", None)).is_err());
}
}