Skip to main content

arcbox_hypervisor/
config.rs

1//! VM configuration types.
2
3use crate::types::{CpuArch, default_vm_cpu_count, default_vm_memory_size};
4
5/// Virtual machine configuration.
6#[derive(Debug, Clone)]
7pub struct VmConfig {
8    /// Number of virtual CPUs.
9    pub vcpu_count: u32,
10    /// Memory size in bytes.
11    pub memory_size: u64,
12    /// CPU architecture (defaults to native).
13    pub arch: CpuArch,
14    /// Path to the kernel image.
15    pub kernel_path: Option<String>,
16    /// Kernel command line arguments.
17    pub kernel_cmdline: Option<String>,
18    /// Path to the initial ramdisk.
19    pub initrd_path: Option<String>,
20    /// Enable Rosetta 2 translation (macOS ARM only).
21    pub enable_rosetta: bool,
22    /// Let the guest run its own hypervisor (macOS ARM only).
23    ///
24    /// Each nested-capable VM pins a hypervisor address space that plain
25    /// VMs share among themselves, and Hypervisor.framework asserts inside
26    /// `hv_vm_create` once they run out (about a dozen per host). Only a
27    /// VM that will host sandboxes should ask for it.
28    pub nested_virt: bool,
29}
30
31impl Default for VmConfig {
32    fn default() -> Self {
33        Self {
34            vcpu_count: default_vm_cpu_count(),
35            memory_size: default_vm_memory_size(),
36            arch: CpuArch::native(),
37            kernel_path: None,
38            kernel_cmdline: None,
39            initrd_path: None,
40            enable_rosetta: false,
41            nested_virt: false,
42        }
43    }
44}
45
46impl VmConfig {
47    /// Creates a new builder for VM configuration.
48    #[must_use]
49    pub fn builder() -> VmConfigBuilder {
50        VmConfigBuilder::default()
51    }
52}
53
54/// Builder for [`VmConfig`].
55#[derive(Debug, Default)]
56pub struct VmConfigBuilder {
57    config: VmConfig,
58}
59
60impl VmConfigBuilder {
61    /// Sets the number of vCPUs.
62    #[must_use]
63    pub const fn vcpu_count(mut self, count: u32) -> Self {
64        self.config.vcpu_count = count;
65        self
66    }
67
68    /// Sets the memory size in bytes.
69    #[must_use]
70    pub const fn memory_size(mut self, size: u64) -> Self {
71        self.config.memory_size = size;
72        self
73    }
74
75    /// Sets the CPU architecture.
76    #[must_use]
77    pub const fn arch(mut self, arch: CpuArch) -> Self {
78        self.config.arch = arch;
79        self
80    }
81
82    /// Sets the kernel path.
83    #[must_use]
84    pub fn kernel_path(mut self, path: impl Into<String>) -> Self {
85        self.config.kernel_path = Some(path.into());
86        self
87    }
88
89    /// Sets the kernel command line.
90    #[must_use]
91    pub fn kernel_cmdline(mut self, cmdline: impl Into<String>) -> Self {
92        self.config.kernel_cmdline = Some(cmdline.into());
93        self
94    }
95
96    /// Sets the initrd path.
97    #[must_use]
98    pub fn initrd_path(mut self, path: impl Into<String>) -> Self {
99        self.config.initrd_path = Some(path.into());
100        self
101    }
102
103    /// Enables Rosetta 2 translation.
104    #[must_use]
105    pub const fn enable_rosetta(mut self, enable: bool) -> Self {
106        self.config.enable_rosetta = enable;
107        self
108    }
109
110    /// Lets the guest run its own hypervisor.
111    #[must_use]
112    pub const fn nested_virt(mut self, enable: bool) -> Self {
113        self.config.nested_virt = enable;
114        self
115    }
116
117    /// Builds the configuration.
118    #[must_use]
119    pub fn build(self) -> VmConfig {
120        self.config
121    }
122}