virtualization_rs/virtualization/
virtual_machine.rs1use crate::{
4 base::{Id, NSArray, NSError},
5 virtualization::boot_loader::VZBootLoader,
6 virtualization::entropy_device::VZEntropyDeviceConfiguration,
7 virtualization::memory_device::VZMemoryBalloonDeviceConfiguration,
8 virtualization::network_device::VZNetworkDeviceConfiguration,
9 virtualization::serial_port::VZSerialPortConfiguration,
10 virtualization::socket_device::VZSocketDeviceConfiguration,
11 virtualization::storage_device::VZStorageDeviceConfiguration,
12};
13
14use block::Block;
15use objc::runtime::BOOL;
16use objc::{class, msg_send, sel, sel_impl};
17use objc::{rc::StrongPtr, runtime::YES};
18
19pub struct VZVirtualMachineConfigurationBuilder {
34 conf: VZVirtualMachineConfiguration,
35}
36
37impl VZVirtualMachineConfigurationBuilder {
38 pub fn new() -> Self {
39 VZVirtualMachineConfigurationBuilder {
40 conf: VZVirtualMachineConfiguration::new(),
41 }
42 }
43
44 pub fn boot_loader<T: VZBootLoader>(mut self, boot_loader: T) -> Self {
45 self.conf.set_boot_loader(boot_loader);
46 self
47 }
48
49 pub fn cpu_count(mut self, cpu_count: usize) -> Self {
50 self.conf.set_cpu_count(cpu_count);
51 self
52 }
53
54 pub fn memory_size(mut self, memory_size: usize) -> Self {
55 self.conf.set_memory_size(memory_size);
56 self
57 }
58
59 pub fn entropy_devices<T: VZEntropyDeviceConfiguration>(
60 mut self,
61 entropy_devices: Vec<T>,
62 ) -> Self {
63 self.conf.set_entropy_devices(entropy_devices);
64 self
65 }
66
67 pub fn memory_balloon_devices<T: VZMemoryBalloonDeviceConfiguration>(
68 mut self,
69 memory_balloon_devices: Vec<T>,
70 ) -> Self {
71 self.conf.set_memory_balloon_devices(memory_balloon_devices);
72 self
73 }
74
75 pub fn network_devices<T: VZNetworkDeviceConfiguration>(
76 mut self,
77 network_devices: Vec<T>,
78 ) -> Self {
79 self.conf.set_network_devices(network_devices);
80 self
81 }
82
83 pub fn serial_ports<T: VZSerialPortConfiguration>(mut self, serial_ports: Vec<T>) -> Self {
84 self.conf.set_serial_ports(serial_ports);
85 self
86 }
87
88 pub fn socket_devices<T: VZSocketDeviceConfiguration>(
89 mut self,
90 socket_devices: Vec<T>,
91 ) -> Self {
92 self.conf.set_socket_devices(socket_devices);
93 self
94 }
95
96 pub fn storage_devices<T: VZStorageDeviceConfiguration>(
97 mut self,
98 storage_devices: Vec<T>,
99 ) -> Self {
100 self.conf.set_storage_devices(storage_devices);
101 self
102 }
103
104 pub fn build(self) -> VZVirtualMachineConfiguration {
105 self.conf
106 }
107}
108
109pub struct VZVirtualMachineConfiguration(StrongPtr);
111
112impl VZVirtualMachineConfiguration {
113 fn new() -> VZVirtualMachineConfiguration {
114 unsafe {
115 let obj = StrongPtr::new(msg_send![class!(VZVirtualMachineConfiguration), new]);
116 VZVirtualMachineConfiguration(obj)
117 }
118 }
119
120 fn set_boot_loader<T: VZBootLoader>(&mut self, boot_loader: T) {
121 unsafe {
122 let _: () = msg_send![*self.0, setBootLoader: boot_loader.id()];
123 }
124 }
125
126 fn set_cpu_count(&mut self, cnt: usize) {
127 unsafe {
128 let _: () = msg_send![*self.0, setCPUCount: cnt];
129 }
130 }
131
132 fn set_memory_size(&mut self, size: usize) {
133 unsafe {
134 let _: () = msg_send![*self.0, setMemorySize: size];
135 }
136 }
137
138 fn set_entropy_devices<T: VZEntropyDeviceConfiguration>(&mut self, devices: Vec<T>) {
139 let device_ids = devices.iter().map(|x| x.id()).collect();
140 let arr: NSArray<T> = NSArray::array_with_objects(device_ids);
141 unsafe {
142 let _: () = msg_send![*self.0, setEntropyDevices:*arr.p];
143 }
144 }
145
146 fn set_memory_balloon_devices<T: VZMemoryBalloonDeviceConfiguration>(
147 &mut self,
148 devices: Vec<T>,
149 ) {
150 let device_ids = devices.iter().map(|x| x.id()).collect();
151 let arr: NSArray<T> = NSArray::array_with_objects(device_ids);
152 unsafe {
153 let _: () = msg_send![*self.0, setMemoryBalloonDevices:*arr.p];
154 }
155 }
156
157 fn set_network_devices<T: VZNetworkDeviceConfiguration>(&mut self, devices: Vec<T>) {
158 let device_ids = devices.iter().map(|x| x.id()).collect();
159 let arr: NSArray<T> = NSArray::array_with_objects(device_ids);
160 unsafe {
161 let _: () = msg_send![*self.0, setNetworkDevices:*arr.p];
162 }
163 }
164
165 fn set_serial_ports<T: VZSerialPortConfiguration>(&mut self, devices: Vec<T>) {
166 let device_ids = devices.iter().map(|x| x.id()).collect();
167 let arr: NSArray<T> = NSArray::array_with_objects(device_ids);
168 unsafe {
169 let _: () = msg_send![*self.0, setSerialPorts:*arr.p];
170 }
171 }
172
173 fn set_socket_devices<T: VZSocketDeviceConfiguration>(&mut self, devices: Vec<T>) {
174 let device_ids = devices.iter().map(|x| x.id()).collect();
175 let arr: NSArray<T> = NSArray::array_with_objects(device_ids);
176 unsafe {
177 let _: () = msg_send![*self.0, setSocketDevices:*arr.p];
178 }
179 }
180
181 fn set_storage_devices<T: VZStorageDeviceConfiguration>(&mut self, devices: Vec<T>) {
182 let device_ids = devices.iter().map(|x| x.id()).collect();
183 let arr: NSArray<T> = NSArray::array_with_objects(device_ids);
184 unsafe {
185 let _: () = msg_send![*self.0, setStorageDevices:*arr.p];
186 }
187 }
188
189 pub fn validate_with_error(&self) -> Result<BOOL, NSError> {
190 unsafe {
191 let error = NSError(StrongPtr::new(0 as Id));
192 let obj: Id = msg_send![*self.0, validateWithError: &(*error.0)];
193 if error.code() != 0 {
194 Err(error)
195 } else {
196 Ok(obj as BOOL)
197 }
198 }
199 }
200}
201
202#[derive(Clone)]
204pub struct VZVirtualMachine(StrongPtr);
205
206#[derive(Debug)]
208pub enum VZVirtualMachineState {
209 VZVirtualMachineStateStopped,
211
212 VZVirtualMachineStateRunning,
214
215 VZVirtualMachineStatePaused,
217
218 VZVirtualMachineStateError,
220
221 VZVirtualMachineStateStarting,
223
224 VZVirtualMachineStatePausing,
226
227 VZVirtualMachineStateResuming,
229
230 Other,
232}
233
234impl VZVirtualMachine {
235 pub fn new(conf: VZVirtualMachineConfiguration, queue: Id) -> VZVirtualMachine {
236 unsafe {
237 let i: Id = msg_send![class!(VZVirtualMachine), alloc];
238 let p = StrongPtr::new(msg_send![i, initWithConfiguration:*conf.0 queue:queue]);
239 VZVirtualMachine(p)
240 }
241 }
242
243 pub fn start_with_completion_handler(&self, completion_handler: &Block<(Id,), ()>) {
244 unsafe {
245 let _: Id = msg_send![*self.0, startWithCompletionHandler: completion_handler];
246 }
247 }
248
249 pub unsafe fn request_stop_with_error(&mut self) -> Result<bool, NSError> {
250 let error = NSError(StrongPtr::new(0 as Id));
251 let ret: BOOL = msg_send![*self.0, requestStopWithError:*error.0];
252 if error.code() != 0 {
253 Err(error)
254 } else {
255 Ok(ret == 1i8)
256 }
257 }
258
259 pub fn supported() -> bool {
260 unsafe {
261 let b: BOOL = msg_send![class!(VZVirtualMachine), isSupported];
262 b == YES
263 }
264 }
265
266 pub unsafe fn state(&self) -> VZVirtualMachineState {
267 let n: isize = msg_send![*self.0, state];
268 match n {
269 0 => VZVirtualMachineState::VZVirtualMachineStateStopped,
270 1 => VZVirtualMachineState::VZVirtualMachineStateRunning,
271 2 => VZVirtualMachineState::VZVirtualMachineStatePaused,
272 3 => VZVirtualMachineState::VZVirtualMachineStateError,
273 4 => VZVirtualMachineState::VZVirtualMachineStateStarting,
274 5 => VZVirtualMachineState::VZVirtualMachineStatePausing,
275 6 => VZVirtualMachineState::VZVirtualMachineStateResuming,
276 _ => VZVirtualMachineState::Other,
277 }
278 }
279}