Struct MicroVmBuilder

Source
pub struct MicroVmBuilder<R, E> { /* private fields */ }
Expand description

The builder for a MicroVm.

This struct provides a fluent interface for configuring and creating a MicroVm instance. It allows you to set various parameters such as the log level, root path, number of vCPUs, memory size, virtio-fs mounts, port mappings, resource limits, working directory, executable path, arguments, environment variables, and console output.

§Required Fields

  • rootfs: The root filesystem to use for the MicroVm.
  • exec_path: The path to the executable to run in the MicroVm.

§Optional Fields

  • num_vcpus: The number of virtual CPUs to use for the MicroVm.
  • memory_mib: The amount of memory in MiB to use for the MicroVm.
  • mapped_dirs: The directories to mount in the MicroVm.
  • port_map: The ports to map in the MicroVm.
  • scope: The network scope to use for the MicroVm.
  • ip: The IP address to use for the MicroVm.
  • subnet: The subnet to use for the MicroVm.
  • rlimits: The resource limits to use for the MicroVm.
  • workdir_path: The working directory to use for the MicroVm.
  • args: The arguments to pass to the executable.
  • env: The environment variables to use for the MicroVm.
  • console_output: The path to the file to write the console output to.

§Examples

use microsandbox_core::vm::{MicroVmBuilder, LogLevel, Rootfs};
use microsandbox_core::config::NetworkScope;
use std::path::PathBuf;

let vm = MicroVmBuilder::default()
    .log_level(LogLevel::Debug)
    .rootfs(Rootfs::Native(PathBuf::from("/tmp")))
    .num_vcpus(2)
    .memory_mib(1024)
    .mapped_dirs(["/home:/guest/mount".parse()?])
    .port_map(["8080:80".parse()?])
    .scope(NetworkScope::Public)
    .ip("192.168.1.100".parse()?)
    .subnet("192.168.1.0/24".parse()?)
    .rlimits(["RLIMIT_NOFILE=1024:1024".parse()?])
    .workdir_path("/workdir")
    .exec_path("/bin/example")
    .args(["arg1", "arg2"])
    .env(["KEY1=VALUE1".parse()?, "KEY2=VALUE2".parse()?])
    .console_output("/tmp/console.log")
    .build()?;

Implementations§

Source§

impl<R, M> MicroVmBuilder<R, M>

Source

pub fn log_level(self, log_level: LogLevel) -> Self

Sets the log level for the MicroVm.

The log level controls the verbosity of the MicroVm’s logging output.

§Examples
use microsandbox_core::vm::{LogLevel, MicroVmBuilder, Rootfs};
use tempfile::TempDir;

let temp_dir = TempDir::new()?;
let vm = MicroVmBuilder::default()
    .log_level(LogLevel::Debug)  // Enable debug logging
    .rootfs(Rootfs::Native(temp_dir.path().to_path_buf()))
    .memory_mib(1024)
    .exec_path("/bin/echo")
    .build()?;
§Log Levels
  • Off - No logging (default)
  • Error - Only error messages
  • Warn - Warnings and errors
  • Info - Informational messages, warnings, and errors
  • Debug - Debug information and all above
  • Trace - Detailed trace information and all above
Source

pub fn rootfs(self, rootfs: Rootfs) -> MicroVmBuilder<Rootfs, M>

Sets the root filesystem sharing mode for the MicroVm.

This determines how the root filesystem is shared with the guest system, with two options:

  • Rootfs::Native: Direct passthrough of a directory as the root filesystem
  • Rootfs::Overlayfs: Use overlayfs with multiple layers as the root filesystem
§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use std::path::PathBuf;

// Option 1: Direct passthrough
let vm = MicroVmBuilder::default()
    .rootfs(Rootfs::Native(PathBuf::from("/path/to/rootfs")));

// Option 2: Overlayfs with layers
let vm = MicroVmBuilder::default()
    .rootfs(Rootfs::Overlayfs(vec![
        PathBuf::from("/path/to/layer1"),
        PathBuf::from("/path/to/layer2")
    ]));
§Notes
  • For Passthrough: The directory must exist and contain a valid root filesystem structure
  • For Overlayfs: The layers are stacked in order, with later layers taking precedence
  • Common choices include Alpine Linux or Ubuntu root filesystems
  • This is a required field - the build will fail if not set
Source

pub fn num_vcpus(self, num_vcpus: u8) -> Self

Sets the number of virtual CPUs (vCPUs) for the MicroVm.

This determines how many CPU cores are available to the guest system.

§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use tempfile::TempDir;

let temp_dir = TempDir::new()?;
let vm = MicroVmBuilder::default()
    .rootfs(Rootfs::Native(temp_dir.path().to_path_buf()))
    .memory_mib(1024)
    .num_vcpus(2)  // Allocate 2 virtual CPU cores
    .exec_path("/bin/echo")
    .build()?;
§Notes
  • The default is 1 vCPU if not specified
  • More vCPUs aren’t always better - consider the workload’s needs
Source

pub fn memory_mib(self, memory_mib: u32) -> Self

Sets the amount of memory in MiB for the MicroVm.

This determines how much memory is available to the guest system.

§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use tempfile::TempDir;

let temp_dir = TempDir::new()?;
let vm = MicroVmBuilder::default()
    .rootfs(Rootfs::Native(temp_dir.path().to_path_buf()))
    .memory_mib(1024)  // Allocate 1 GiB of memory
    .exec_path("/bin/echo")
    .build()?;
§Notes
  • The value is in MiB (1 GiB = 1024 MiB)
  • Consider the host’s available memory when setting this value
  • This is a required field - the build will fail if not set
Source

pub fn mapped_dirs( self, mapped_dirs: impl IntoIterator<Item = PathPair>, ) -> Self

Sets the directory mappings for the MicroVm using virtio-fs.

Each mapping follows Docker’s volume mapping convention using the format host:guest.

§Examples
use microsandbox_core::vm::MicroVmConfigBuilder;

let config = MicroVmConfigBuilder::default()
    .mapped_dirs([
        // Share host's /data directory as /mnt/data in guest
        "/data:/mnt/data".parse()?,
        // Share current directory as /app in guest
        "./:/app".parse()?,
        // Use same path in both host and guest
        "/shared".parse()?
    ]);
Source

pub fn port_map(self, port_map: impl IntoIterator<Item = PortPair>) -> Self

Sets the port mappings between host and guest for the MicroVm.

Port mappings follow Docker’s convention using the format host:guest, where:

  • host is the port number on the host machine
  • guest is the port number inside the MicroVm
§Examples
use microsandbox_core::vm::MicroVmBuilder;
use microsandbox_core::config::PortPair;

let vm = MicroVmBuilder::default()
    .port_map([
        // Map host port 8080 to guest port 80 (for web server)
        "8080:80".parse()?,
        // Map host port 2222 to guest port 22 (for SSH)
        "2222:22".parse()?,
        // Use same port (3000) on both host and guest
        "3000".parse()?
    ]);
§Notes
  • If you don’t call this method, no ports will be mapped between host and guest
  • The guest application will need to use the guest port number to listen for connections
  • External connections should use the host port number to connect to the service
  • Port mapping is not supported when using passt networking mode
Source

pub fn scope(self, scope: NetworkScope) -> Self

Sets the network scope for the MicroVm.

The network scope controls the MicroVm’s level of network isolation and connectivity.

§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use microsandbox_core::config::NetworkScope;
use std::path::PathBuf;

let vm = MicroVmBuilder::default()
    .scope(NetworkScope::Public)  // Allow access to public networks
    .rootfs(Rootfs::Native(PathBuf::from("/path/to/rootfs")))
    .exec_path("/bin/echo");
§Network Scope Options
  • None - Sandboxes cannot communicate with any other sandboxes
  • Group - Sandboxes can only communicate within their subnet (default)
  • Public - Sandboxes can communicate with any other non-private address
  • Any - Sandboxes can communicate with any address
Source

pub fn ip(self, ip: Ipv4Addr) -> Self

Sets the IP address for the MicroVm.

This sets a specific IPv4 address for the guest system’s network interface.

§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use std::path::PathBuf;
use std::net::Ipv4Addr;

let vm = MicroVmBuilder::default()
    .ip(Ipv4Addr::new(192, 168, 1, 100))  // Assign IP 192.168.1.100 to the MicroVm
    .rootfs(Rootfs::Native(PathBuf::from("/path/to/rootfs")))
    .exec_path("/bin/echo");
§Notes
  • The IP address should be within the subnet assigned to the MicroVm
  • If not specified, an IP address may be assigned automatically
Source

pub fn subnet(self, subnet: Ipv4Network) -> Self

Sets the subnet for the MicroVm.

This defines the IPv4 network and mask for the guest system’s network interface.

§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use std::path::PathBuf;
use ipnetwork::Ipv4Network;

let vm = MicroVmBuilder::default()
    .subnet("192.168.1.0/24".parse()?)  // Set subnet to 192.168.1.0/24
    .rootfs(Rootfs::Native(PathBuf::from("/path/to/rootfs")))
    .exec_path("/bin/echo");
§Notes
  • The subnet defines the range of IP addresses available to the MicroVm
  • Used for networking between multiple MicroVms in the same group
Source

pub fn rlimits(self, rlimits: impl IntoIterator<Item = LinuxRlimit>) -> Self

Sets the resource limits for the MicroVm.

§Examples
use microsandbox_core::vm::MicroVmBuilder;

MicroVmBuilder::default().rlimits(["RLIMIT_NOFILE=1024:1024".parse()?]);
Source

pub fn workdir_path(self, workdir_path: impl Into<Utf8UnixPathBuf>) -> Self

Sets the working directory path for the MicroVm.

§Examples
use microsandbox_core::vm::MicroVmBuilder;

MicroVmBuilder::default().workdir_path("/path/to/workdir");
Source

pub fn exec_path( self, exec_path: impl Into<Utf8UnixPathBuf>, ) -> MicroVmBuilder<R, Utf8UnixPathBuf>

Sets the executable path for the MicroVm.

§Examples
use microsandbox_core::vm::MicroVmBuilder;

MicroVmBuilder::default().exec_path("/path/to/exec");
Source

pub fn args<'a>(self, args: impl IntoIterator<Item = &'a str>) -> Self

Sets the command-line arguments for the executable.

These arguments will be passed to the program specified by exec_path.

§Examples
use microsandbox_core::vm::MicroVmBuilder;

let vm = MicroVmBuilder::default()
    .args([
        "-m", "http.server",  // Run Python's HTTP server module
        "8080",               // Listen on port 8080
        "--directory", "/data" // Serve files from /data
    ]);
§Notes
  • Arguments are passed in the order they appear in the iterator
  • The program name (argv[0]) is automatically set from exec_path
  • Each argument should be a separate string
Source

pub fn env(self, env: impl IntoIterator<Item = EnvPair>) -> Self

Sets environment variables for processes in the MicroVm.

Environment variables follow the standard format KEY=VALUE and are available to all processes in the guest system.

§Examples
use microsandbox_core::vm::MicroVmBuilder;

let vm = MicroVmBuilder::default()
    .env([
        // Set application environment
        "APP_ENV=production".parse()?,
        // Configure logging
        "LOG_LEVEL=info".parse()?,
        // Set timezone
        "TZ=UTC".parse()?,
        // Multiple values are OK
        "ALLOWED_HOSTS=localhost,127.0.0.1".parse()?
    ]);
§Notes
  • Variables are available to all processes in the guest
  • Values should be properly escaped if they contain special characters
  • Common uses include configuration and runtime settings
  • Some programs expect specific environment variables to function
Source

pub fn console_output(self, console_output: impl Into<Utf8UnixPathBuf>) -> Self

Sets the path for capturing console output from the MicroVm.

This allows redirecting and saving all console output (stdout/stderr) from the guest system to a file on the host.

§Examples
use microsandbox_core::vm::MicroVmBuilder;

let vm = MicroVmBuilder::default()
    .console_output("/var/log/microvm.log")  // Save output to log file
    .exec_path("/usr/local/bin/myapp");      // Run application
§Notes
  • The path must be writable on the host system
  • The file will be created if it doesn’t exist
  • Useful for debugging and logging
  • Captures both stdout and stderr
Source§

impl MicroVmBuilder<Rootfs, Utf8UnixPathBuf>

Source

pub fn build(self) -> MicrosandboxResult<MicroVm>

Builds the MicroVm.

This method creates a MicroVm instance based on the configuration set in the builder. The MicroVm will be ready to start but won’t be running until you call start().

§Examples
use microsandbox_core::vm::{MicroVmBuilder, Rootfs};
use tempfile::TempDir;

let temp_dir = TempDir::new()?;
let vm = MicroVmBuilder::default()
    .rootfs(Rootfs::Native(temp_dir.path().to_path_buf()))
    .memory_mib(1024)
    .exec_path("/usr/bin/python3")
    .args(["-c", "print('Hello from MicroVm!')"])
    .build()?;

// Start the MicroVm
vm.start()?;  // This would actually run the VM
§Notes
  • The build will fail if required configuration is missing
  • The build will fail if the root path doesn’t exist
  • The build will fail if memory value is invalid
  • After building, use start() to run the MicroVm

Trait Implementations§

Source§

impl<R: Debug, E: Debug> Debug for MicroVmBuilder<R, E>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Default for MicroVmBuilder<(), ()>

Source§

fn default() -> Self

Returns the “default value” for a type. Read more

Auto Trait Implementations§

§

impl<R, E> Freeze for MicroVmBuilder<R, E>
where R: Freeze, E: Freeze,

§

impl<R, E> RefUnwindSafe for MicroVmBuilder<R, E>

§

impl<R, E> Send for MicroVmBuilder<R, E>
where R: Send, E: Send,

§

impl<R, E> Sync for MicroVmBuilder<R, E>
where R: Sync, E: Sync,

§

impl<R, E> Unpin for MicroVmBuilder<R, E>
where R: Unpin, E: Unpin,

§

impl<R, E> UnwindSafe for MicroVmBuilder<R, E>
where R: UnwindSafe, E: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,