photoncloud-monorepo/plasmavmc/crates/plasmavmc-firecracker/src/env.rs
centra a7ec7e2158 Add T026 practical test + k8shost to flake + workspace files
- Created T026-practical-test task.yaml for MVP smoke testing
- Added k8shost-server to flake.nix (packages, apps, overlays)
- Staged all workspace directories for nix flake build
- Updated flake.nix shellHook to include k8shost

Resolves: T026.S1 blocker (R8 - nix submodule visibility)
2025-12-09 06:07:50 +09:00

107 lines
3.9 KiB
Rust

use std::path::PathBuf;
/// Environment variable names used by the FireCracker backend.
pub const ENV_FIRECRACKER_PATH: &str = "PLASMAVMC_FIRECRACKER_PATH";
pub const ENV_FIRECRACKER_JAILER_PATH: &str = "PLASMAVMC_FIRECRACKER_JAILER_PATH";
pub const ENV_FIRECRACKER_RUNTIME_DIR: &str = "PLASMAVMC_FIRECRACKER_RUNTIME_DIR";
pub const ENV_FIRECRACKER_SOCKET_BASE_PATH: &str = "PLASMAVMC_FIRECRACKER_SOCKET_BASE_PATH";
pub const ENV_FIRECRACKER_KERNEL_PATH: &str = "PLASMAVMC_FIRECRACKER_KERNEL_PATH";
pub const ENV_FIRECRACKER_ROOTFS_PATH: &str = "PLASMAVMC_FIRECRACKER_ROOTFS_PATH";
pub const ENV_FIRECRACKER_INITRD_PATH: &str = "PLASMAVMC_FIRECRACKER_INITRD_PATH";
pub const ENV_FIRECRACKER_BOOT_ARGS: &str = "PLASMAVMC_FIRECRACKER_BOOT_ARGS";
pub const ENV_FIRECRACKER_USE_JAILER: &str = "PLASMAVMC_FIRECRACKER_USE_JAILER";
/// Resolve FireCracker binary path, falling back to default.
pub fn resolve_firecracker_path() -> PathBuf {
std::env::var_os(ENV_FIRECRACKER_PATH)
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("/usr/bin/firecracker"))
}
/// Resolve optional Jailer binary path from env.
pub fn resolve_jailer_path() -> Option<PathBuf> {
std::env::var_os(ENV_FIRECRACKER_JAILER_PATH).map(PathBuf::from)
}
/// Resolve runtime directory, falling back to default.
pub fn resolve_runtime_dir() -> PathBuf {
std::env::var_os(ENV_FIRECRACKER_RUNTIME_DIR)
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("/var/run/plasmavmc/firecracker"))
}
/// Resolve socket base path, falling back to default.
pub fn resolve_socket_base_path() -> PathBuf {
std::env::var_os(ENV_FIRECRACKER_SOCKET_BASE_PATH)
.map(PathBuf::from)
.unwrap_or_else(|| PathBuf::from("/tmp/firecracker"))
}
/// Resolve kernel image path from env (required).
pub fn resolve_kernel_path() -> Option<PathBuf> {
std::env::var_os(ENV_FIRECRACKER_KERNEL_PATH).map(PathBuf::from)
}
/// Resolve rootfs image path from env (required).
pub fn resolve_rootfs_path() -> Option<PathBuf> {
std::env::var_os(ENV_FIRECRACKER_ROOTFS_PATH).map(PathBuf::from)
}
/// Resolve optional initrd image path from env.
pub fn resolve_initrd_path() -> Option<PathBuf> {
std::env::var_os(ENV_FIRECRACKER_INITRD_PATH).map(PathBuf::from)
}
/// Resolve boot arguments, falling back to default.
pub fn resolve_boot_args() -> String {
std::env::var(ENV_FIRECRACKER_BOOT_ARGS)
.unwrap_or_else(|_| "console=ttyS0".to_string())
}
/// Resolve whether to use jailer, falling back to checking if jailer exists.
pub fn resolve_use_jailer() -> bool {
match std::env::var(ENV_FIRECRACKER_USE_JAILER) {
Ok(val) => val == "1" || val.to_lowercase() == "true",
Err(_) => {
// Default to true if jailer binary exists
resolve_jailer_path()
.map(|p| p.exists())
.unwrap_or(false)
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn resolve_firecracker_default_when_unset() {
std::env::remove_var(ENV_FIRECRACKER_PATH);
let path = resolve_firecracker_path();
assert_eq!(path, PathBuf::from("/usr/bin/firecracker"));
}
#[test]
fn resolve_firecracker_from_env() {
std::env::set_var(ENV_FIRECRACKER_PATH, "/tmp/firecracker");
let path = resolve_firecracker_path();
assert_eq!(path, PathBuf::from("/tmp/firecracker"));
std::env::remove_var(ENV_FIRECRACKER_PATH);
}
#[test]
fn resolve_boot_args_default() {
std::env::remove_var(ENV_FIRECRACKER_BOOT_ARGS);
let args = resolve_boot_args();
assert_eq!(args, "console=ttyS0");
}
#[test]
fn resolve_boot_args_from_env() {
std::env::set_var(ENV_FIRECRACKER_BOOT_ARGS, "console=ttyS0 reboot=k");
let args = resolve_boot_args();
assert_eq!(args, "console=ttyS0 reboot=k");
std::env::remove_var(ENV_FIRECRACKER_BOOT_ARGS);
}
}