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