From 5e96e31061f1c4e111fb55941c74876ef91efdb0 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:38:52 -0600 Subject: [PATCH 01/18] feat(config): add optional port range for sandbox configuration --- microsandbox-server/lib/config.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/microsandbox-server/lib/config.rs b/microsandbox-server/lib/config.rs index c3a83e40..600c0cc3 100644 --- a/microsandbox-server/lib/config.rs +++ b/microsandbox-server/lib/config.rs @@ -56,6 +56,12 @@ pub struct Config { /// Address to listen on addr: SocketAddr, + + /// Minimum port for sandbox port range (if set) + port_range_min: Option, + + /// Maximum port for sandbox port range (if set) + port_range_max: Option, } //-------------------------------------------------------------------------------------------------- @@ -91,6 +97,13 @@ impl Config { let namespace_dir = namespace_dir .unwrap_or_else(|| env::get_microsandbox_home_path().join(NAMESPACES_SUBDIR)); + // Load sandbox port range from environment variables + let port_range = env::get_sandbox_port_range(); + let (port_range_min, port_range_max) = match port_range { + Some((min, max)) => (Some(min), Some(max)), + None => (None, None), + }; + Ok(Self { key, namespace_dir, @@ -98,6 +111,8 @@ impl Config { host: host_ip, port, addr, + port_range_min, + port_range_max, }) } } From d0d4f1b29ef39ef62ac04e62ccfd968e58d0fb20 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:39:12 -0600 Subject: [PATCH 02/18] feat(env): add environment variables for sandbox port range --- microsandbox-utils/lib/env.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/microsandbox-utils/lib/env.rs b/microsandbox-utils/lib/env.rs index 1796f53d..bccdf1af 100644 --- a/microsandbox-utils/lib/env.rs +++ b/microsandbox-utils/lib/env.rs @@ -20,6 +20,12 @@ pub const MSBRUN_EXE_ENV_VAR: &str = "MSBRUN_EXE"; /// Environment variable for the msbserver binary path pub const MSBSERVER_EXE_ENV_VAR: &str = "MSBSERVER_EXE"; +/// Environment variable for the minimum port in the sandbox port range +pub const MICROSANDBOX_PORT_MIN_ENV_VAR: &str = "MICROSANDBOX_PORT_MIN"; + +/// Environment variable for the maximum port in the sandbox port range +pub const MICROSANDBOX_PORT_MAX_ENV_VAR: &str = "MICROSANDBOX_PORT_MAX"; + //-------------------------------------------------------------------------------------------------- // Functions //-------------------------------------------------------------------------------------------------- @@ -45,3 +51,21 @@ pub fn get_oci_registry() -> String { DEFAULT_OCI_REGISTRY.to_string() } } + +/// Returns the port range for sandbox port allocation. +/// If both MICROSANDBOX_PORT_MIN and MICROSANDBOX_PORT_MAX are set, +/// returns Some((min, max)). Otherwise, returns None for dynamic allocation. +pub fn get_sandbox_port_range() -> Option<(u16, u16)> { + let min = std::env::var(MICROSANDBOX_PORT_MIN_ENV_VAR) + .ok() + .and_then(|v| v.parse::().ok()); + let max = std::env::var(MICROSANDBOX_PORT_MAX_ENV_VAR) + .ok() + .and_then(|v| v.parse::().ok()); + + match (min, max) { + (Some(min_val), Some(max_val)) if min_val <= max_val => Some((min_val, max_val)), + _ => None, + } +} + From f77a66b630bb5367eeb29b1401f795ee840595da Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:39:20 -0600 Subject: [PATCH 03/18] feat(handler): add missing line for sandbox configuration mapping --- microsandbox-server/lib/handler.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/microsandbox-server/lib/handler.rs b/microsandbox-server/lib/handler.rs index 125d0a37..fd0dcfdc 100644 --- a/microsandbox-server/lib/handler.rs +++ b/microsandbox-server/lib/handler.rs @@ -475,6 +475,7 @@ pub async fn sandbox_start_impl( *sandboxes_value = serde_yaml::Value::Mapping(serde_yaml::Mapping::new()); } + let sandboxes_map = sandboxes_value.as_mapping_mut().unwrap(); // If config is provided and we have an image, update the sandbox configuration From 3b6c91f4b34aac1ce52f2fc65837fc68724e4f83 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:39:27 -0600 Subject: [PATCH 04/18] feat(port): initialize port manager with configurable port range --- microsandbox-cli/bin/msbserver.rs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/microsandbox-cli/bin/msbserver.rs b/microsandbox-cli/bin/msbserver.rs index 62afd843..6232d58a 100644 --- a/microsandbox-cli/bin/msbserver.rs +++ b/microsandbox-cli/bin/msbserver.rs @@ -41,11 +41,21 @@ pub async fn main() -> MicrosandboxCliResult<()> { args.dev_mode, )?); - // Get namespace directory from config + // Get namespace directory and port range from config let namespace_dir = config.get_namespace_dir().clone(); + let port_range = ( + config.get_port_range_min().as_ref().copied(), + config.get_port_range_max().as_ref().copied(), + ); - // Initialize the port manager - let port_manager = PortManager::new(namespace_dir).await.map_err(|e| { + // Initialize the port manager with the configured port range + let port_manager = if let (Some(min), Some(max)) = port_range { + PortManager::new_with_range(namespace_dir, Some((min, max))) + .await + } else { + PortManager::new(namespace_dir).await + } + .map_err(|e| { eprintln!("Error initializing port manager: {}", e); e })?; From 68ad8eeb61eeec2a3fc19ea6866b1dc42724809f Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:39:35 -0600 Subject: [PATCH 05/18] feat(port): add optional port range for sandbox port allocation --- microsandbox-server/lib/port.rs | 51 +++++++++++++++++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/microsandbox-server/lib/port.rs b/microsandbox-server/lib/port.rs index 631dd0b4..682d4198 100644 --- a/microsandbox-server/lib/port.rs +++ b/microsandbox-server/lib/port.rs @@ -64,6 +64,9 @@ pub struct PortManager { /// Path to the port mappings file file_path: PathBuf, + + /// Optional port range (min, max) for sandbox port allocation + port_range: Option<(u16, u16)>, } //-------------------------------------------------------------------------------------------------- @@ -158,12 +161,30 @@ impl BiPortMapping { impl PortManager { /// Create a new port manager pub async fn new(namespace_dir: impl AsRef) -> MicrosandboxServerResult { + Self::new_with_range(namespace_dir, None).await + } + + /// Create a new port manager with an optional port range + pub async fn new_with_range( + namespace_dir: impl AsRef, + port_range: Option<(u16, u16)>, + ) -> MicrosandboxServerResult { let file_path = namespace_dir.as_ref().join(PORTAL_PORTS_FILE); let mappings = Self::load_mappings(&file_path).await?; + if let Some((min, max)) = port_range { + info!( + "Port manager initialized with port range: {}-{}", + min, max + ); + } else { + debug!("Port manager initialized with dynamic port allocation"); + } + Ok(Self { mappings, file_path, + port_range, }) } @@ -240,8 +261,8 @@ impl PortManager { // Get a lock to ensure only one thread gets a port at a time let _lock = PORT_ASSIGNMENT_LOCK.lock().await; - // Get a truly available port from the OS - let port = self.get_available_port_from_os()?; + // Get an available port (from range or from OS) + let port = self.get_available_port()?; // Save the mapping self.mappings.insert(key.to_string(), port); @@ -272,7 +293,31 @@ impl PortManager { TcpListener::bind(addr).is_ok() } - /// Get an available port from the OS + /// Get an available port from the OS or from the configured port range + fn get_available_port(&self) -> MicrosandboxServerResult { + // If a port range is configured, try to find an available port within it + if let Some((min, max)) = self.port_range { + debug!("Attempting to find an available port in range {}-{}", min, max); + + for port in min..=max { + if self.verify_port_availability(port) { + debug!("Found available port {} in configured range", port); + return Ok(port); + } + } + + // If no port is available in the range, log a warning and try dynamic allocation + warn!( + "No available ports found in configured range {}-{}, falling back to OS allocation", + min, max + ); + } + + // Fall back to dynamic port allocation from the OS + self.get_available_port_from_os() + } + + /// Get a truly available port from the OS by binding to port 0 fn get_available_port_from_os(&self) -> MicrosandboxServerResult { // Bind to port 0 to let the OS assign an available port let addr = SocketAddr::new(LOCALHOST_IP, 0); From 37335bd92d0ae096038ecc42fe17a47f212e2980 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:46:46 -0600 Subject: [PATCH 06/18] feat(build): update Makefile to use bash for building libkrun --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 616bab1a..9f700e5b 100644 --- a/Makefile +++ b/Makefile @@ -161,7 +161,7 @@ uninstall: fi build_libkrun: - ./scripts/build_libkrun.sh --no-clean --build-dir "$(BUILD_DIR)" + bash ./scripts/build_libkrun.sh --no-clean --build-dir "$(BUILD_DIR)" # Catch-all target to allow example names and arguments %: From f96282a6fed90f5b2ed64103f186149a4a9f2005 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:46:55 -0600 Subject: [PATCH 07/18] feat(build): switch build script to use bash for improved compatibility --- scripts/build_libkrun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_libkrun.sh b/scripts/build_libkrun.sh index 1b08cf3d..bbc6a72f 100755 --- a/scripts/build_libkrun.sh +++ b/scripts/build_libkrun.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # build_libkrun.sh # --------------- From d4aedaacc0dc811437fc94e48bf02fc26ff51e2c Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:47:55 -0600 Subject: [PATCH 08/18] feat(dependencies): update multiple crate versions in Cargo.lock --- Cargo.lock | 154 ++++++++++++++++++++++++++--------------------------- 1 file changed, 77 insertions(+), 77 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1b890090..ccf775be 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -106,13 +106,12 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.36" +version = "0.4.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "98ec5f6c2f8bc326c994cb9e241cc257ddaba9afa8555a43cffbb5dd86efaa37" +checksum = "d10e4f991a553474232bc0a31799f6d24b034a84c0971d80d2e2f78b2e576e40" dependencies = [ "compression-codecs", "compression-core", - "futures-core", "pin-project-lite", "tokio", ] @@ -151,9 +150,9 @@ checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" [[package]] name = "aws-lc-rs" -version = "1.15.2" +version = "1.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6a88aab2464f1f25453baa7a07c84c5b7684e274054ba06817f382357f77a288" +checksum = "e84ce723ab67259cfeb9877c6a639ee9eb7a27b28123abd71db7f0d5d0cc9d86" dependencies = [ "aws-lc-sys", "zeroize", @@ -161,9 +160,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.35.0" +version = "0.36.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b45afffdee1e7c9126814751f88dddc747f41d91da16c9551a0f1e8a11e788a1" +checksum = "43a442ece363113bd4bd4c8b18977a7798dd4d3c3383f34fb61936960e8f4ad8" dependencies = [ "cc", "cmake", @@ -243,9 +242,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.8.2" +version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d809780667f4410e7c41b07f52439b94d2bdf8528eeedc287fa38d3b7f95d82" +checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] name = "bitflags" @@ -301,9 +300,9 @@ checksum = "b35204fbdc0b3f4446b89fc1ac2cf84a8a68971995d0bf2e925ec7cd960f9cb3" [[package]] name = "cc" -version = "1.2.51" +version = "1.2.53" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0aeaff4ff1a90589618835a598e545176939b97874f7abc7851caa0618f203" +checksum = "755d2fce177175ffca841e9a06afdb2c4ab0f593d53b4dee48147dfaade85932" dependencies = [ "find-msvc-tools", "jobserver", @@ -331,9 +330,9 @@ checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" [[package]] name = "chrono" -version = "0.4.42" +version = "0.4.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145052bdd345b87320e369255277e3fb5152762ad123a901ef5c262dd38fe8d2" +checksum = "fac4744fb15ae8337dc853fee7fb3f4e48c0fbaa23d0afe49c447b4fab126118" dependencies = [ "iana-time-zone", "js-sys", @@ -379,9 +378,9 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.7.6" +version = "0.7.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1d728cc89cf3aee9ff92b05e62b19ee65a02b5702cff7d5a377e32c6ae29d8d" +checksum = "c3e64b0cc0439b12df2fa678eae89a1c56a529fd067a9115f7827f1fffd22b32" [[package]] name = "cmake" @@ -410,9 +409,9 @@ dependencies = [ [[package]] name = "compression-codecs" -version = "0.4.35" +version = "0.4.36" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0f7ac3e5b97fdce45e8922fb05cae2c37f7bbd63d30dd94821dacfd8f3f2bf2" +checksum = "00828ba6fd27b45a448e57dbfe84f1029d4c9f26b368157e9a448a5f49a2ec2a" dependencies = [ "compression-core", "flate2", @@ -818,15 +817,15 @@ dependencies = [ [[package]] name = "find-msvc-tools" -version = "0.1.6" +version = "0.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "645cbb3a84e60b7531617d5ae4e57f7e27308f6445f5abf653209ea76dec8dff" +checksum = "8591b0bcc8a98a64310a2fae1bb3e9b8564dd10e381e6e28010fde8e8e8568db" [[package]] name = "flate2" -version = "1.1.5" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfe33edd8e85a12a67454e37f8c75e730830d83e313556ab9ebf9ee7fbeb3bfb" +checksum = "b375d6465b98090a5f25b1c7703f3859783755aa9a80433b36e0379a3ec2f369" dependencies = [ "crc32fast", "miniz_oxide", @@ -997,9 +996,9 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.2.16" +version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "335ff9f135e4384c8150d6f27c6daed433577f86b4750418338c01a1a2528592" +checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ "cfg-if", "js-sys", @@ -1399,9 +1398,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.12.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0ad4bb2b565bca0645f4d68c5c9af97fba094e9791da685bf83cb5f3ce74acf2" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -1491,9 +1490,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "464a3709c7f55f1f721e5389aa6ea4e3bc6aba669353300af094b29ffbdde1d8" +checksum = "8c942ebf8e95485ca0d52d97da7c5a2c387d0e7f0ba4c35e93bfcaee045955b3" dependencies = [ "once_cell", "wasm-bindgen", @@ -1561,9 +1560,9 @@ checksum = "2604dd126bb14f13fb5d1bd6a66155079cb9fa655b37f875b3a742c705dbed17" [[package]] name = "libc" -version = "0.2.179" +version = "0.2.180" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5a2d376baa530d1238d133232d15e239abad80d05838b4b59354e5268af431f" +checksum = "bcc35a38544a891a5f7c865aca548a982ccb3b8650a5b06d0fd33a10283c56fc" [[package]] name = "libm" @@ -1979,7 +1978,7 @@ dependencies = [ [[package]] name = "oci-client" version = "0.15.0" -source = "git+https://github.com/toksdotdev/rust-oci-client.git?branch=toks%2Fstring-impl-for-enums#e165654aecf842b3dd57d8b31268378e8d1884c0" +source = "git+https://github.com/toksdotdev/rust-oci-client.git?branch=toks%2Fstring-impl-for-enums#0c0e352487c407a662de1b645bbc7ab2b87c1191" dependencies = [ "bytes", "chrono", @@ -2385,7 +2384,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" dependencies = [ "rand_chacha 0.9.0", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2405,7 +2404,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" dependencies = [ "ppv-lite86", - "rand_core 0.9.3", + "rand_core 0.9.5", ] [[package]] @@ -2414,14 +2413,14 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", ] [[package]] name = "rand_core" -version = "0.9.3" +version = "0.9.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +checksum = "76afc826de14238e6e8c374ddcc1fa19e374fd8dd986b0d2af0d02377261d83c" dependencies = [ "getrandom 0.3.4", ] @@ -2450,7 +2449,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ - "getrandom 0.2.16", + "getrandom 0.2.17", "libredox", "thiserror 2.0.17", ] @@ -2605,7 +2604,7 @@ dependencies = [ "anyhow", "async-trait", "futures", - "getrandom 0.2.16", + "getrandom 0.2.17", "http", "hyper", "reqwest 0.12.28", @@ -2634,7 +2633,7 @@ checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.16", + "getrandom 0.2.17", "libc", "untrusted", "windows-sys 0.52.0", @@ -2708,9 +2707,9 @@ dependencies = [ [[package]] name = "rustls-pki-types" -version = "1.13.2" +version = "1.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "21e6f2ab2928ca4291b86736a8bd920a277a399bba1589409d72154ff87c1282" +checksum = "be040f8b0a225e40375822a563fa9524378b9d63112f53e19ffff34df5d33fdd" dependencies = [ "web-time", "zeroize", @@ -2745,9 +2744,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.8" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ffdfa2f5286e2247234e03f680868ac2815974dc39e00ea15adc445d0aafe52" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "aws-lc-rs", "ring", @@ -3330,9 +3329,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.113" +version = "2.0.114" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678faa00651c9eb72dd2020cbdf275d92eccb2400d568e419efdd64838145cb4" +checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a" dependencies = [ "proc-macro2", "quote", @@ -3455,30 +3454,30 @@ dependencies = [ [[package]] name = "time" -version = "0.3.44" +version = "0.3.45" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e7d9e3bb61134e77bde20dd4825b97c010155709965fedf0f49bb138e52a9d" +checksum = "f9e442fc33d7fdb45aa9bfeb312c095964abdf596f7567261062b2a7107aaabd" dependencies = [ "deranged", "itoa", "num-conv", "powerfmt", - "serde", + "serde_core", "time-core", "time-macros", ] [[package]] name = "time-core" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40868e7c1d2f0b8d73e4a8c7f0ff63af4f6d19be117e90bd73eb1d62cf831c6b" +checksum = "8b36ee98fd31ec7426d599183e8fe26932a8dc1fb76ddb6214d05493377d34ca" [[package]] name = "time-macros" -version = "0.2.24" +version = "0.2.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30cfb0125f12d9c277f35663a0a33f8c30190f4e4574868a330595412d34ebf3" +checksum = "71e552d1249bf61ac2a52db88179fd0673def1e1ad8243a00d9ec9ed71fee3dd" dependencies = [ "num-conv", "time-core", @@ -3583,9 +3582,9 @@ dependencies = [ [[package]] name = "toml" -version = "0.9.10+spec-1.1.0" +version = "0.9.11+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0825052159284a1a8b4d6c0c86cbc801f2da5afd2b225fa548c72f2e74002f48" +checksum = "f3afc9a848309fe1aaffaed6e1546a7a14de1f935dc9d89d32afd9a44bab7c46" dependencies = [ "indexmap", "serde_core", @@ -3622,9 +3621,9 @@ checksum = "ab16f14aed21ee8bfd8ec22513f7287cd4a91aa92e44edfe2c17ddd004e92607" [[package]] name = "tower" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d039ad9159c98b70ecfd540b2573b97f7f52c3e8d9f8ad57a24b916a536975f9" +checksum = "ebe5ef63511595f1344e2d5cfa636d973292adc0eec1f0ad45fae9f0851ab1d4" dependencies = [ "futures-core", "futures-util", @@ -3926,9 +3925,9 @@ checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b" [[package]] name = "wasip2" -version = "1.0.1+wasi-0.2.4" +version = "1.0.2+wasi-0.2.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0562428422c63773dad2c345a1882263bbf4d65cf3f42e90921f787ef5ad58e7" +checksum = "9517f9239f02c069db75e65f174b3da828fe5f5b945c4dd26bd25d89c03ebcf5" dependencies = [ "wit-bindgen", ] @@ -3941,9 +3940,9 @@ checksum = "b8dad83b4f25e74f184f64c43b150b91efe7647395b42289f38e50566d82855b" [[package]] name = "wasm-bindgen" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d759f433fa64a2d763d1340820e46e111a7a5ab75f993d1852d70b03dbb80fd" +checksum = "64024a30ec1e37399cf85a7ffefebdb72205ca1c972291c51512360d90bd8566" dependencies = [ "cfg-if", "once_cell", @@ -3954,11 +3953,12 @@ dependencies = [ [[package]] name = "wasm-bindgen-futures" -version = "0.4.56" +version = "0.4.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "836d9622d604feee9e5de25ac10e3ea5f2d65b41eac0d9ce72eb5deae707ce7c" +checksum = "70a6e77fd0ae8029c9ea0063f87c46fde723e7d887703d74ad2616d792e51e6f" dependencies = [ "cfg-if", + "futures-util", "js-sys", "once_cell", "wasm-bindgen", @@ -3967,9 +3967,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48cb0d2638f8baedbc542ed444afc0644a29166f1595371af4fecf8ce1e7eeb3" +checksum = "008b239d9c740232e71bd39e8ef6429d27097518b6b30bdf9086833bd5b6d608" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3977,9 +3977,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cefb59d5cd5f92d9dcf80e4683949f15ca4b511f4ac0a6e14d4e1ac60c6ecd40" +checksum = "5256bae2d58f54820e6490f9839c49780dff84c65aeab9e772f15d5f0e913a55" dependencies = [ "bumpalo", "proc-macro2", @@ -3990,9 +3990,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.106" +version = "0.2.108" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cbc538057e648b67f72a982e708d485b2efa771e1ac05fec311f9f63e5800db4" +checksum = "1f01b580c9ac74c8d8f0c0e4afb04eeef2acf145458e52c03845ee9cd23e3d12" dependencies = [ "unicode-ident", ] @@ -4026,9 +4026,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.83" +version = "0.3.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b32828d774c412041098d182a8b38b16ea816958e07cf40eec2bc080ae137ac" +checksum = "312e32e551d92129218ea9a2452120f4aabc03529ef03e4d0d82fb2780608598" dependencies = [ "js-sys", "wasm-bindgen", @@ -4473,9 +4473,9 @@ checksum = "d135d17ab770252ad95e9a872d365cf3090e3be864a34ab46f48555993efc904" [[package]] name = "wit-bindgen" -version = "0.46.0" +version = "0.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f17a85883d4e6d00e8a97c586de764dabcc06133f7f1d55dce5cdc070ad7fe59" +checksum = "d7249219f66ced02969388cf2bb044a09756a083d0fab1e566056b04d9fbcaa5" [[package]] name = "writeable" @@ -4518,18 +4518,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fabae64378cb18147bb18bca364e63bdbe72a0ffe4adf0addfec8aa166b2c56" +checksum = "668f5168d10b9ee831de31933dc111a459c97ec93225beb307aed970d1372dfd" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.32" +version = "0.8.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c9c2d862265a8bb4471d87e033e730f536e2a285cc7cb05dbce09a2a97075f90" +checksum = "2c7962b26b0a8685668b671ee4b54d007a67d4eaf05fda79ac0ecf41e32270f1" dependencies = [ "proc-macro2", "quote", @@ -4598,6 +4598,6 @@ dependencies = [ [[package]] name = "zmij" -version = "1.0.12" +version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2fc5a66a20078bf1251bde995aa2fdcc4b800c70b5d92dd2c62abc5c60f679f8" +checksum = "94f63c051f4fe3c1509da62131a678643c5b6fbdc9273b2b79d4378ebda003d2" From 93cb92327d293a006ed8a6f1d8f1b03a6f908301 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 18 Jan 2026 11:48:10 -0600 Subject: [PATCH 09/18] feat(dependencies): update multiple crate versions in Cargo.lock --- scripts/install_microsandbox.sh | 2 +- scripts/package_microsandbox.sh | 2 +- scripts/setup_env.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/install_microsandbox.sh b/scripts/install_microsandbox.sh index 658a8fdd..e9a2d930 100755 --- a/scripts/install_microsandbox.sh +++ b/scripts/install_microsandbox.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # install_microsandbox.sh # ------------------ diff --git a/scripts/package_microsandbox.sh b/scripts/package_microsandbox.sh index eb0536bb..8523e252 100755 --- a/scripts/package_microsandbox.sh +++ b/scripts/package_microsandbox.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # package_microsandbox.sh # ------------------ diff --git a/scripts/setup_env.sh b/scripts/setup_env.sh index 8572f99c..8ac4f7a4 100755 --- a/scripts/setup_env.sh +++ b/scripts/setup_env.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/usr/bin/env bash # setup_env.sh # ----------- From e679d95141602d2fc5d43f1f817348f1609c3147 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sat, 14 Feb 2026 08:40:37 -0600 Subject: [PATCH 10/18] Revert "feat(build): update Makefile to use bash for building libkrun" This reverts commit 37335bd92d0ae096038ecc42fe17a47f212e2980. --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 9f700e5b..616bab1a 100644 --- a/Makefile +++ b/Makefile @@ -161,7 +161,7 @@ uninstall: fi build_libkrun: - bash ./scripts/build_libkrun.sh --no-clean --build-dir "$(BUILD_DIR)" + ./scripts/build_libkrun.sh --no-clean --build-dir "$(BUILD_DIR)" # Catch-all target to allow example names and arguments %: From e2264112e5be17cdcac2a5cbcdb1cc4a14366b3c Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sat, 14 Feb 2026 08:40:41 -0600 Subject: [PATCH 11/18] Revert "feat(build): switch build script to use bash for improved compatibility" This reverts commit f96282a6fed90f5b2ed64103f186149a4a9f2005. --- scripts/build_libkrun.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/build_libkrun.sh b/scripts/build_libkrun.sh index bbc6a72f..1b08cf3d 100755 --- a/scripts/build_libkrun.sh +++ b/scripts/build_libkrun.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # build_libkrun.sh # --------------- From 0a0c23a3890905f6e66338cbb433e71f4b77254a Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sat, 14 Feb 2026 09:04:27 -0600 Subject: [PATCH 12/18] enhance(env): update sandbox port range handling to use inclusive syntax --- microsandbox-server/lib/config.rs | 2 +- microsandbox-utils/lib/env.rs | 71 ++++++++++++++++++++++--------- 2 files changed, 52 insertions(+), 21 deletions(-) diff --git a/microsandbox-server/lib/config.rs b/microsandbox-server/lib/config.rs index 600c0cc3..1387581e 100644 --- a/microsandbox-server/lib/config.rs +++ b/microsandbox-server/lib/config.rs @@ -100,7 +100,7 @@ impl Config { // Load sandbox port range from environment variables let port_range = env::get_sandbox_port_range(); let (port_range_min, port_range_max) = match port_range { - Some((min, max)) => (Some(min), Some(max)), + Some(range) => (Some(*range.start()), Some(*range.end())), None => (None, None), }; diff --git a/microsandbox-utils/lib/env.rs b/microsandbox-utils/lib/env.rs index bccdf1af..0bc53b93 100644 --- a/microsandbox-utils/lib/env.rs +++ b/microsandbox-utils/lib/env.rs @@ -1,6 +1,6 @@ //! Utility functions for working with environment variables. -use std::path::PathBuf; +use std::{ops::RangeInclusive, path::PathBuf}; use crate::{DEFAULT_MICROSANDBOX_HOME, DEFAULT_OCI_REGISTRY}; @@ -20,11 +20,8 @@ pub const MSBRUN_EXE_ENV_VAR: &str = "MSBRUN_EXE"; /// Environment variable for the msbserver binary path pub const MSBSERVER_EXE_ENV_VAR: &str = "MSBSERVER_EXE"; -/// Environment variable for the minimum port in the sandbox port range -pub const MICROSANDBOX_PORT_MIN_ENV_VAR: &str = "MICROSANDBOX_PORT_MIN"; - -/// Environment variable for the maximum port in the sandbox port range -pub const MICROSANDBOX_PORT_MAX_ENV_VAR: &str = "MICROSANDBOX_PORT_MAX"; +/// Environment variable for the sandbox port range (`..[=]`) +pub const MSB_PORT_RANGE_ENV_VAR: &str = "MSB_PORT_RANGE"; //-------------------------------------------------------------------------------------------------- // Functions @@ -53,19 +50,53 @@ pub fn get_oci_registry() -> String { } /// Returns the port range for sandbox port allocation. -/// If both MICROSANDBOX_PORT_MIN and MICROSANDBOX_PORT_MAX are set, -/// returns Some((min, max)). Otherwise, returns None for dynamic allocation. -pub fn get_sandbox_port_range() -> Option<(u16, u16)> { - let min = std::env::var(MICROSANDBOX_PORT_MIN_ENV_VAR) - .ok() - .and_then(|v| v.parse::().ok()); - let max = std::env::var(MICROSANDBOX_PORT_MAX_ENV_VAR) - .ok() - .and_then(|v| v.parse::().ok()); - - match (min, max) { - (Some(min_val), Some(max_val)) if min_val <= max_val => Some((min_val, max_val)), - _ => None, - } +/// If MSB_PORT_RANGE is set and matches `..[=]`, +/// returns `Some(lower..=upper)`. Otherwise, returns None for dynamic allocation. +pub fn get_sandbox_port_range() -> Option> { + let range = std::env::var(MSB_PORT_RANGE_ENV_VAR).ok()?; + parse_sandbox_port_range(&range) +} + +fn parse_sandbox_port_range(range: &str) -> Option> { + let (lower_raw, upper_raw) = range.split_once("..")?; + let lower = lower_raw.parse::().ok()?; + let upper_part = upper_raw.strip_prefix('=').unwrap_or(upper_raw); + let upper = upper_part.parse::().ok()?; + + (lower <= upper).then_some(lower..=upper) } +#[cfg(test)] +mod tests { + use super::parse_sandbox_port_range; + + #[test] + fn test_parse_sandbox_port_range_with_exclusive_syntax() { + assert_eq!(parse_sandbox_port_range("3000..4000"), Some(3000..=4000)); + } + + #[test] + fn test_parse_sandbox_port_range_with_inclusive_syntax() { + assert_eq!(parse_sandbox_port_range("3000..=4000"), Some(3000..=4000)); + } + + #[test] + fn test_parse_sandbox_port_range_with_missing_lower_is_invalid() { + assert_eq!(parse_sandbox_port_range("..=4000"), None); + } + + #[test] + fn test_parse_sandbox_port_range_with_invalid_order_is_invalid() { + assert_eq!(parse_sandbox_port_range("4000..3000"), None); + } + + #[test] + fn test_parse_sandbox_port_range_requested_cases() { + // Includes '=' and lower < upper + assert_eq!(parse_sandbox_port_range("1000..=2000"), Some(1000..=2000)); + // Only upper exists (missing lower) should be invalid + assert_eq!(parse_sandbox_port_range("..2000"), None); + // Does not include '=' and lower < upper + assert_eq!(parse_sandbox_port_range("1000..2000"), Some(1000..=2000)); + } +} From ec2d0c0c0415f3f990dcecded5b53354fcb5d366 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sat, 14 Feb 2026 09:06:56 -0600 Subject: [PATCH 13/18] enhance(config): refactor sandbox port range to use inclusive range type --- microsandbox-server/lib/config.rs | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/microsandbox-server/lib/config.rs b/microsandbox-server/lib/config.rs index 1387581e..58f1d73f 100644 --- a/microsandbox-server/lib/config.rs +++ b/microsandbox-server/lib/config.rs @@ -14,6 +14,7 @@ use std::{ net::{IpAddr, SocketAddr}, + ops::RangeInclusive, path::PathBuf, }; @@ -57,11 +58,8 @@ pub struct Config { /// Address to listen on addr: SocketAddr, - /// Minimum port for sandbox port range (if set) - port_range_min: Option, - - /// Maximum port for sandbox port range (if set) - port_range_max: Option, + /// Port range for sandbox allocation (if set) + port_range: Option>, } //-------------------------------------------------------------------------------------------------- @@ -99,11 +97,6 @@ impl Config { // Load sandbox port range from environment variables let port_range = env::get_sandbox_port_range(); - let (port_range_min, port_range_max) = match port_range { - Some(range) => (Some(*range.start()), Some(*range.end())), - None => (None, None), - }; - Ok(Self { key, namespace_dir, @@ -111,8 +104,7 @@ impl Config { host: host_ip, port, addr, - port_range_min, - port_range_max, + port_range, }) } } From d8a96fc36f7a77ea17c4ffae5f8fa4065798a2f3 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sat, 14 Feb 2026 09:10:28 -0600 Subject: [PATCH 14/18] enhance(port): refactor port range handling to use inclusive range type --- microsandbox-cli/bin/msbserver.rs | 10 +++------- microsandbox-server/lib/port.rs | 25 ++++++++++++++++--------- 2 files changed, 19 insertions(+), 16 deletions(-) diff --git a/microsandbox-cli/bin/msbserver.rs b/microsandbox-cli/bin/msbserver.rs index 6232d58a..f1bee6fd 100644 --- a/microsandbox-cli/bin/msbserver.rs +++ b/microsandbox-cli/bin/msbserver.rs @@ -43,15 +43,11 @@ pub async fn main() -> MicrosandboxCliResult<()> { // Get namespace directory and port range from config let namespace_dir = config.get_namespace_dir().clone(); - let port_range = ( - config.get_port_range_min().as_ref().copied(), - config.get_port_range_max().as_ref().copied(), - ); + let port_range = config.get_port_range().clone(); // Initialize the port manager with the configured port range - let port_manager = if let (Some(min), Some(max)) = port_range { - PortManager::new_with_range(namespace_dir, Some((min, max))) - .await + let port_manager = if let Some(range) = port_range { + PortManager::new_with_range(namespace_dir, Some(range)).await } else { PortManager::new(namespace_dir).await } diff --git a/microsandbox-server/lib/port.rs b/microsandbox-server/lib/port.rs index 682d4198..e8f76093 100644 --- a/microsandbox-server/lib/port.rs +++ b/microsandbox-server/lib/port.rs @@ -18,6 +18,7 @@ use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, + ops::RangeInclusive, path::{Path, PathBuf}, }; use tokio::{fs, sync::Mutex}; @@ -65,8 +66,8 @@ pub struct PortManager { /// Path to the port mappings file file_path: PathBuf, - /// Optional port range (min, max) for sandbox port allocation - port_range: Option<(u16, u16)>, + /// Optional inclusive port range for sandbox port allocation + port_range: Option>, } //-------------------------------------------------------------------------------------------------- @@ -167,15 +168,16 @@ impl PortManager { /// Create a new port manager with an optional port range pub async fn new_with_range( namespace_dir: impl AsRef, - port_range: Option<(u16, u16)>, + port_range: Option>, ) -> MicrosandboxServerResult { let file_path = namespace_dir.as_ref().join(PORTAL_PORTS_FILE); let mappings = Self::load_mappings(&file_path).await?; - if let Some((min, max)) = port_range { + if let Some(range) = port_range.as_ref() { info!( "Port manager initialized with port range: {}-{}", - min, max + range.start(), + range.end() ); } else { debug!("Port manager initialized with dynamic port allocation"); @@ -296,10 +298,14 @@ impl PortManager { /// Get an available port from the OS or from the configured port range fn get_available_port(&self) -> MicrosandboxServerResult { // If a port range is configured, try to find an available port within it - if let Some((min, max)) = self.port_range { - debug!("Attempting to find an available port in range {}-{}", min, max); + if let Some(range) = self.port_range.as_ref() { + debug!( + "Attempting to find an available port in range {}-{}", + range.start(), + range.end() + ); - for port in min..=max { + for port in range.clone() { if self.verify_port_availability(port) { debug!("Found available port {} in configured range", port); return Ok(port); @@ -309,7 +315,8 @@ impl PortManager { // If no port is available in the range, log a warning and try dynamic allocation warn!( "No available ports found in configured range {}-{}, falling back to OS allocation", - min, max + range.start(), + range.end() ); } From 7f487a9f28b96aad58c1215b03313b0122454404 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sat, 14 Feb 2026 09:11:01 -0600 Subject: [PATCH 15/18] chore(handler): remove unnecessary blank line in handler.rs --- microsandbox-server/lib/handler.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/microsandbox-server/lib/handler.rs b/microsandbox-server/lib/handler.rs index fd0dcfdc..125d0a37 100644 --- a/microsandbox-server/lib/handler.rs +++ b/microsandbox-server/lib/handler.rs @@ -475,7 +475,6 @@ pub async fn sandbox_start_impl( *sandboxes_value = serde_yaml::Value::Mapping(serde_yaml::Mapping::new()); } - let sandboxes_map = sandboxes_value.as_mapping_mut().unwrap(); // If config is provided and we have an image, update the sandbox configuration From 0e57b4e552f689d5a18f2dd4e9f245cd85f80407 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 15 Feb 2026 12:51:24 -0600 Subject: [PATCH 16/18] Revert "feat(dependencies): update multiple crate versions in Cargo.lock" This reverts commit 93cb92327d293a006ed8a6f1d8f1b03a6f908301. --- scripts/install_microsandbox.sh | 2 +- scripts/package_microsandbox.sh | 2 +- scripts/setup_env.sh | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/install_microsandbox.sh b/scripts/install_microsandbox.sh index e9a2d930..658a8fdd 100755 --- a/scripts/install_microsandbox.sh +++ b/scripts/install_microsandbox.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # install_microsandbox.sh # ------------------ diff --git a/scripts/package_microsandbox.sh b/scripts/package_microsandbox.sh index 8523e252..eb0536bb 100755 --- a/scripts/package_microsandbox.sh +++ b/scripts/package_microsandbox.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # package_microsandbox.sh # ------------------ diff --git a/scripts/setup_env.sh b/scripts/setup_env.sh index 8ac4f7a4..8572f99c 100755 --- a/scripts/setup_env.sh +++ b/scripts/setup_env.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # setup_env.sh # ----------- From babced219f155a8a69fd3ac9c12f5d23ff9ba1f4 Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 15 Feb 2026 12:55:14 -0600 Subject: [PATCH 17/18] enhance(config, port): refactor port range handling to use exclusive range type --- microsandbox-server/lib/config.rs | 4 ++-- microsandbox-server/lib/port.rs | 26 +++++++++++++------------- microsandbox-utils/lib/env.rs | 18 +++++++++--------- 3 files changed, 24 insertions(+), 24 deletions(-) diff --git a/microsandbox-server/lib/config.rs b/microsandbox-server/lib/config.rs index 40958603..da106860 100644 --- a/microsandbox-server/lib/config.rs +++ b/microsandbox-server/lib/config.rs @@ -14,7 +14,7 @@ use std::{ net::{IpAddr, SocketAddr}, - ops::RangeInclusive, + ops::Range, path::PathBuf, }; @@ -59,7 +59,7 @@ pub struct Config { addr: SocketAddr, /// Port range for sandbox allocation (if set) - port_range: Option>, + port_range: Option>, } //-------------------------------------------------------------------------------------------------- diff --git a/microsandbox-server/lib/port.rs b/microsandbox-server/lib/port.rs index db2bba5c..9ffcbb0f 100644 --- a/microsandbox-server/lib/port.rs +++ b/microsandbox-server/lib/port.rs @@ -18,7 +18,7 @@ use serde::{Deserialize, Serialize}; use std::{ collections::HashMap, net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, - ops::RangeInclusive, + ops::Range, path::{Path, PathBuf}, }; use tokio::{fs, sync::Mutex}; @@ -66,8 +66,8 @@ pub struct PortManager { /// Path to the port mappings file file_path: PathBuf, - /// Optional inclusive port range for sandbox port allocation - port_range: Option>, + /// Optional port range for sandbox port allocation (upper bound exclusive) + port_range: Option>, } //-------------------------------------------------------------------------------------------------- @@ -168,16 +168,16 @@ impl PortManager { /// Create a new port manager with an optional port range pub async fn new_with_range( project_dir: impl AsRef, - port_range: Option>, + port_range: Option>, ) -> MicrosandboxServerResult { let file_path = project_dir.as_ref().join(PORTAL_PORTS_FILE); let mappings = Self::load_mappings(&file_path).await?; if let Some(range) = port_range.as_ref() { info!( - "Port manager initialized with port range: {}-{}", - range.start(), - range.end() + "Port manager initialized with port range: {}..{} (upper exclusive)", + range.start, + range.end ); } else { debug!("Port manager initialized with dynamic port allocation"); @@ -300,9 +300,9 @@ impl PortManager { // If a port range is configured, try to find an available port within it if let Some(range) = self.port_range.as_ref() { debug!( - "Attempting to find an available port in range {}-{}", - range.start(), - range.end() + "Attempting to find an available port in range {}..{} (upper exclusive)", + range.start, + range.end ); for port in range.clone() { @@ -314,9 +314,9 @@ impl PortManager { // If no port is available in the range, log a warning and try dynamic allocation warn!( - "No available ports found in configured range {}-{}, falling back to OS allocation", - range.start(), - range.end() + "No available ports found in configured range {}..{} (upper exclusive), falling back to OS allocation", + range.start, + range.end ); } diff --git a/microsandbox-utils/lib/env.rs b/microsandbox-utils/lib/env.rs index 0bc53b93..fb01dc2f 100644 --- a/microsandbox-utils/lib/env.rs +++ b/microsandbox-utils/lib/env.rs @@ -1,6 +1,6 @@ //! Utility functions for working with environment variables. -use std::{ops::RangeInclusive, path::PathBuf}; +use std::{ops::Range, path::PathBuf}; use crate::{DEFAULT_MICROSANDBOX_HOME, DEFAULT_OCI_REGISTRY}; @@ -51,19 +51,19 @@ pub fn get_oci_registry() -> String { /// Returns the port range for sandbox port allocation. /// If MSB_PORT_RANGE is set and matches `..[=]`, -/// returns `Some(lower..=upper)`. Otherwise, returns None for dynamic allocation. -pub fn get_sandbox_port_range() -> Option> { +/// returns `Some(lower..upper)` (upper exclusive). Otherwise, returns None for dynamic allocation. +pub fn get_sandbox_port_range() -> Option> { let range = std::env::var(MSB_PORT_RANGE_ENV_VAR).ok()?; parse_sandbox_port_range(&range) } -fn parse_sandbox_port_range(range: &str) -> Option> { +fn parse_sandbox_port_range(range: &str) -> Option> { let (lower_raw, upper_raw) = range.split_once("..")?; let lower = lower_raw.parse::().ok()?; let upper_part = upper_raw.strip_prefix('=').unwrap_or(upper_raw); let upper = upper_part.parse::().ok()?; - (lower <= upper).then_some(lower..=upper) + (lower < upper).then_some(lower..upper) } #[cfg(test)] @@ -72,12 +72,12 @@ mod tests { #[test] fn test_parse_sandbox_port_range_with_exclusive_syntax() { - assert_eq!(parse_sandbox_port_range("3000..4000"), Some(3000..=4000)); + assert_eq!(parse_sandbox_port_range("3000..4000"), Some(3000..4000)); } #[test] fn test_parse_sandbox_port_range_with_inclusive_syntax() { - assert_eq!(parse_sandbox_port_range("3000..=4000"), Some(3000..=4000)); + assert_eq!(parse_sandbox_port_range("3000..=4000"), Some(3000..4000)); } #[test] @@ -93,10 +93,10 @@ mod tests { #[test] fn test_parse_sandbox_port_range_requested_cases() { // Includes '=' and lower < upper - assert_eq!(parse_sandbox_port_range("1000..=2000"), Some(1000..=2000)); + assert_eq!(parse_sandbox_port_range("1000..=2000"), Some(1000..2000)); // Only upper exists (missing lower) should be invalid assert_eq!(parse_sandbox_port_range("..2000"), None); // Does not include '=' and lower < upper - assert_eq!(parse_sandbox_port_range("1000..2000"), Some(1000..=2000)); + assert_eq!(parse_sandbox_port_range("1000..2000"), Some(1000..2000)); } } From bf05b3076e48668227d523f23d756e4555a5321a Mon Sep 17 00:00:00 2001 From: Ivan Yael Garcia Perez Date: Sun, 15 Feb 2026 12:55:54 -0600 Subject: [PATCH 18/18] chore(port): applies fmt lint --- microsandbox-server/lib/port.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/microsandbox-server/lib/port.rs b/microsandbox-server/lib/port.rs index 9ffcbb0f..da266ac6 100644 --- a/microsandbox-server/lib/port.rs +++ b/microsandbox-server/lib/port.rs @@ -176,8 +176,7 @@ impl PortManager { if let Some(range) = port_range.as_ref() { info!( "Port manager initialized with port range: {}..{} (upper exclusive)", - range.start, - range.end + range.start, range.end ); } else { debug!("Port manager initialized with dynamic port allocation"); @@ -301,8 +300,7 @@ impl PortManager { if let Some(range) = self.port_range.as_ref() { debug!( "Attempting to find an available port in range {}..{} (upper exclusive)", - range.start, - range.end + range.start, range.end ); for port in range.clone() { @@ -315,8 +313,7 @@ impl PortManager { // If no port is available in the range, log a warning and try dynamic allocation warn!( "No available ports found in configured range {}..{} (upper exclusive), falling back to OS allocation", - range.start, - range.end + range.start, range.end ); }