velir_virtualbox 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (350) hide show
  1. data/.gitignore +8 -0
  2. data/.yardopts +3 -0
  3. data/Gemfile +16 -0
  4. data/LICENSE +19 -0
  5. data/Rakefile +37 -0
  6. data/Readme.md +70 -0
  7. data/docs/GettingStarted.md +196 -0
  8. data/docs/WhatsNew.md +12 -0
  9. data/features/README.md +33 -0
  10. data/features/global.feature +19 -0
  11. data/features/global_extra_data.feature +27 -0
  12. data/features/step_definitions/abstract_model_steps.rb +39 -0
  13. data/features/step_definitions/extra_data_steps.rb +36 -0
  14. data/features/step_definitions/global_steps.rb +29 -0
  15. data/features/step_definitions/nat_engine_steps.rb +76 -0
  16. data/features/step_definitions/network_adapter_steps.rb +38 -0
  17. data/features/step_definitions/shared_folder_steps.rb +76 -0
  18. data/features/step_definitions/snapshot_steps.rb +74 -0
  19. data/features/step_definitions/storage_controller_steps.rb +16 -0
  20. data/features/step_definitions/virtualbox_steps.rb +17 -0
  21. data/features/step_definitions/vm_steps.rb +50 -0
  22. data/features/support/env.rb +61 -0
  23. data/features/support/helpers.rb +38 -0
  24. data/features/support/hooks.rb +30 -0
  25. data/features/support/ordered_hash.rb +49 -0
  26. data/features/support/vboxmanage.rb +191 -0
  27. data/features/version.feature +16 -0
  28. data/features/vm.feature +13 -0
  29. data/features/vm_bios.feature +29 -0
  30. data/features/vm_cpu.feature +29 -0
  31. data/features/vm_extra_data.feature +35 -0
  32. data/features/vm_hw_virt.feature +29 -0
  33. data/features/vm_nat_engine.feature +57 -0
  34. data/features/vm_network_adapters.feature +27 -0
  35. data/features/vm_shared_folders.feature +42 -0
  36. data/features/vm_snapshots.feature +29 -0
  37. data/features/vm_storage_controllers.feature +11 -0
  38. data/lib/virtualbox.rb +11 -0
  39. data/lib/virtualbox/abstract_model.rb +281 -0
  40. data/lib/virtualbox/abstract_model/attributable.rb +290 -0
  41. data/lib/virtualbox/abstract_model/dirty.rb +177 -0
  42. data/lib/virtualbox/abstract_model/interface_attributes.rb +98 -0
  43. data/lib/virtualbox/abstract_model/relatable.rb +332 -0
  44. data/lib/virtualbox/abstract_model/validatable.rb +167 -0
  45. data/lib/virtualbox/abstract_model/version_matcher.rb +35 -0
  46. data/lib/virtualbox/appliance.rb +62 -0
  47. data/lib/virtualbox/audio_adapter.rb +52 -0
  48. data/lib/virtualbox/bios.rb +50 -0
  49. data/lib/virtualbox/com.rb +23 -0
  50. data/lib/virtualbox/com/abstract_enum.rb +43 -0
  51. data/lib/virtualbox/com/abstract_implementer.rb +45 -0
  52. data/lib/virtualbox/com/abstract_interface.rb +167 -0
  53. data/lib/virtualbox/com/base_interface.rb +38 -0
  54. data/lib/virtualbox/com/ffi/interface.rb +150 -0
  55. data/lib/virtualbox/com/ffi/interfaces.rb +63 -0
  56. data/lib/virtualbox/com/ffi/util.rb +121 -0
  57. data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
  58. data/lib/virtualbox/com/ffi_interface.rb +96 -0
  59. data/lib/virtualbox/com/implementer/base.rb +59 -0
  60. data/lib/virtualbox/com/implementer/ffi.rb +381 -0
  61. data/lib/virtualbox/com/implementer/mscom.rb +189 -0
  62. data/lib/virtualbox/com/implementer/nil.rb +10 -0
  63. data/lib/virtualbox/com/interface/3.1.x/access_mode.rb +11 -0
  64. data/lib/virtualbox/com/interface/3.1.x/appliance.rb +22 -0
  65. data/lib/virtualbox/com/interface/3.1.x/audio_adapter.rb +15 -0
  66. data/lib/virtualbox/com/interface/3.1.x/audio_controller_type.rb +11 -0
  67. data/lib/virtualbox/com/interface/3.1.x/audio_driver_type.rb +11 -0
  68. data/lib/virtualbox/com/interface/3.1.x/bios_boot_menu_mode.rb +11 -0
  69. data/lib/virtualbox/com/interface/3.1.x/bios_settings.rb +21 -0
  70. data/lib/virtualbox/com/interface/3.1.x/clipboard_mode.rb +11 -0
  71. data/lib/virtualbox/com/interface/3.1.x/console.rb +50 -0
  72. data/lib/virtualbox/com/interface/3.1.x/cpu_property_type.rb +11 -0
  73. data/lib/virtualbox/com/interface/3.1.x/device_type.rb +11 -0
  74. data/lib/virtualbox/com/interface/3.1.x/dhcp_server.rb +22 -0
  75. data/lib/virtualbox/com/interface/3.1.x/firmware_type.rb +11 -0
  76. data/lib/virtualbox/com/interface/3.1.x/guest_os_type.rb +23 -0
  77. data/lib/virtualbox/com/interface/3.1.x/host.rb +42 -0
  78. data/lib/virtualbox/com/interface/3.1.x/host_network_interface.rb +30 -0
  79. data/lib/virtualbox/com/interface/3.1.x/host_network_interface_medium_type.rb +11 -0
  80. data/lib/virtualbox/com/interface/3.1.x/host_network_interface_status.rb +11 -0
  81. data/lib/virtualbox/com/interface/3.1.x/host_network_interface_type.rb +11 -0
  82. data/lib/virtualbox/com/interface/3.1.x/host_usb_device.rb +13 -0
  83. data/lib/virtualbox/com/interface/3.1.x/host_usb_device_filter.rb +13 -0
  84. data/lib/virtualbox/com/interface/3.1.x/hw_virt_ex_property_type.rb +11 -0
  85. data/lib/virtualbox/com/interface/3.1.x/machine.rb +105 -0
  86. data/lib/virtualbox/com/interface/3.1.x/machine_state.rb +14 -0
  87. data/lib/virtualbox/com/interface/3.1.x/medium.rb +50 -0
  88. data/lib/virtualbox/com/interface/3.1.x/medium_attachment.rb +18 -0
  89. data/lib/virtualbox/com/interface/3.1.x/medium_format.rb +18 -0
  90. data/lib/virtualbox/com/interface/3.1.x/medium_state.rb +11 -0
  91. data/lib/virtualbox/com/interface/3.1.x/medium_type.rb +11 -0
  92. data/lib/virtualbox/com/interface/3.1.x/medium_variant.rb +11 -0
  93. data/lib/virtualbox/com/interface/3.1.x/network_adapter.rb +30 -0
  94. data/lib/virtualbox/com/interface/3.1.x/network_adapter_type.rb +11 -0
  95. data/lib/virtualbox/com/interface/3.1.x/network_attachment_type.rb +11 -0
  96. data/lib/virtualbox/com/interface/3.1.x/nsiexception.rb +23 -0
  97. data/lib/virtualbox/com/interface/3.1.x/nsisupports.rb +15 -0
  98. data/lib/virtualbox/com/interface/3.1.x/parallel_port.rb +17 -0
  99. data/lib/virtualbox/com/interface/3.1.x/port_mode.rb +11 -0
  100. data/lib/virtualbox/com/interface/3.1.x/progress.rb +63 -0
  101. data/lib/virtualbox/com/interface/3.1.x/serial_port.rb +19 -0
  102. data/lib/virtualbox/com/interface/3.1.x/session.rb +18 -0
  103. data/lib/virtualbox/com/interface/3.1.x/session_state.rb +11 -0
  104. data/lib/virtualbox/com/interface/3.1.x/session_type.rb +11 -0
  105. data/lib/virtualbox/com/interface/3.1.x/shared_folder.rb +17 -0
  106. data/lib/virtualbox/com/interface/3.1.x/snapshot.rb +20 -0
  107. data/lib/virtualbox/com/interface/3.1.x/storage_bus.rb +11 -0
  108. data/lib/virtualbox/com/interface/3.1.x/storage_controller.rb +23 -0
  109. data/lib/virtualbox/com/interface/3.1.x/storage_controller_type.rb +11 -0
  110. data/lib/virtualbox/com/interface/3.1.x/system_properties.rb +37 -0
  111. data/lib/virtualbox/com/interface/3.1.x/usb_controller.rb +20 -0
  112. data/lib/virtualbox/com/interface/3.1.x/usb_device.rb +24 -0
  113. data/lib/virtualbox/com/interface/3.1.x/usb_device_filter.rb +23 -0
  114. data/lib/virtualbox/com/interface/3.1.x/usb_device_filter_action.rb +11 -0
  115. data/lib/virtualbox/com/interface/3.1.x/usb_device_state.rb +11 -0
  116. data/lib/virtualbox/com/interface/3.1.x/virtual_box_error_info.rb +17 -0
  117. data/lib/virtualbox/com/interface/3.1.x/virtual_system_description.rb +19 -0
  118. data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_type.rb +14 -0
  119. data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_value_type.rb +11 -0
  120. data/lib/virtualbox/com/interface/3.1.x/virtualbox.rb +67 -0
  121. data/lib/virtualbox/com/interface/3.1.x/vrdp_auth_type.rb +11 -0
  122. data/lib/virtualbox/com/interface/3.1.x/vrdp_server.rb +19 -0
  123. data/lib/virtualbox/com/interface/3.2.x/access_mode.rb +11 -0
  124. data/lib/virtualbox/com/interface/3.2.x/appliance.rb +22 -0
  125. data/lib/virtualbox/com/interface/3.2.x/audio_adapter.rb +15 -0
  126. data/lib/virtualbox/com/interface/3.2.x/audio_controller_type.rb +11 -0
  127. data/lib/virtualbox/com/interface/3.2.x/audio_driver_type.rb +11 -0
  128. data/lib/virtualbox/com/interface/3.2.x/bios_boot_menu_mode.rb +11 -0
  129. data/lib/virtualbox/com/interface/3.2.x/bios_settings.rb +21 -0
  130. data/lib/virtualbox/com/interface/3.2.x/clipboard_mode.rb +11 -0
  131. data/lib/virtualbox/com/interface/3.2.x/console.rb +50 -0
  132. data/lib/virtualbox/com/interface/3.2.x/cpu_property_type.rb +11 -0
  133. data/lib/virtualbox/com/interface/3.2.x/device_type.rb +11 -0
  134. data/lib/virtualbox/com/interface/3.2.x/dhcp_server.rb +22 -0
  135. data/lib/virtualbox/com/interface/3.2.x/firmware_type.rb +11 -0
  136. data/lib/virtualbox/com/interface/3.2.x/guest.rb +13 -0
  137. data/lib/virtualbox/com/interface/3.2.x/guest_os_type.rb +33 -0
  138. data/lib/virtualbox/com/interface/3.2.x/host.rb +43 -0
  139. data/lib/virtualbox/com/interface/3.2.x/host_network_interface.rb +30 -0
  140. data/lib/virtualbox/com/interface/3.2.x/host_network_interface_medium_type.rb +11 -0
  141. data/lib/virtualbox/com/interface/3.2.x/host_network_interface_status.rb +11 -0
  142. data/lib/virtualbox/com/interface/3.2.x/host_network_interface_type.rb +11 -0
  143. data/lib/virtualbox/com/interface/3.2.x/host_usb_device.rb +13 -0
  144. data/lib/virtualbox/com/interface/3.2.x/host_usb_device_filter.rb +13 -0
  145. data/lib/virtualbox/com/interface/3.2.x/hw_virt_ex_property_type.rb +11 -0
  146. data/lib/virtualbox/com/interface/3.2.x/keyboard_hid_type.rb +11 -0
  147. data/lib/virtualbox/com/interface/3.2.x/machine.rb +118 -0
  148. data/lib/virtualbox/com/interface/3.2.x/machine_state.rb +14 -0
  149. data/lib/virtualbox/com/interface/3.2.x/medium.rb +51 -0
  150. data/lib/virtualbox/com/interface/3.2.x/medium_attachment.rb +18 -0
  151. data/lib/virtualbox/com/interface/3.2.x/medium_format.rb +18 -0
  152. data/lib/virtualbox/com/interface/3.2.x/medium_state.rb +11 -0
  153. data/lib/virtualbox/com/interface/3.2.x/medium_type.rb +11 -0
  154. data/lib/virtualbox/com/interface/3.2.x/medium_variant.rb +11 -0
  155. data/lib/virtualbox/com/interface/3.2.x/nat_alias_mode.rb +11 -0
  156. data/lib/virtualbox/com/interface/3.2.x/nat_engine.rb +27 -0
  157. data/lib/virtualbox/com/interface/3.2.x/nat_protocol.rb +11 -0
  158. data/lib/virtualbox/com/interface/3.2.x/network_adapter.rb +34 -0
  159. data/lib/virtualbox/com/interface/3.2.x/network_adapter_type.rb +11 -0
  160. data/lib/virtualbox/com/interface/3.2.x/network_attachment_type.rb +11 -0
  161. data/lib/virtualbox/com/interface/3.2.x/nsiexception.rb +23 -0
  162. data/lib/virtualbox/com/interface/3.2.x/nsisupports.rb +15 -0
  163. data/lib/virtualbox/com/interface/3.2.x/parallel_port.rb +17 -0
  164. data/lib/virtualbox/com/interface/3.2.x/pointing_hid_type.rb +11 -0
  165. data/lib/virtualbox/com/interface/3.2.x/port_mode.rb +11 -0
  166. data/lib/virtualbox/com/interface/3.2.x/progress.rb +63 -0
  167. data/lib/virtualbox/com/interface/3.2.x/serial_port.rb +19 -0
  168. data/lib/virtualbox/com/interface/3.2.x/session.rb +18 -0
  169. data/lib/virtualbox/com/interface/3.2.x/session_state.rb +11 -0
  170. data/lib/virtualbox/com/interface/3.2.x/session_type.rb +11 -0
  171. data/lib/virtualbox/com/interface/3.2.x/shared_folder.rb +17 -0
  172. data/lib/virtualbox/com/interface/3.2.x/snapshot.rb +20 -0
  173. data/lib/virtualbox/com/interface/3.2.x/storage_bus.rb +11 -0
  174. data/lib/virtualbox/com/interface/3.2.x/storage_controller.rb +24 -0
  175. data/lib/virtualbox/com/interface/3.2.x/storage_controller_type.rb +11 -0
  176. data/lib/virtualbox/com/interface/3.2.x/system_properties.rb +42 -0
  177. data/lib/virtualbox/com/interface/3.2.x/usb_controller.rb +21 -0
  178. data/lib/virtualbox/com/interface/3.2.x/usb_device.rb +24 -0
  179. data/lib/virtualbox/com/interface/3.2.x/usb_device_filter.rb +23 -0
  180. data/lib/virtualbox/com/interface/3.2.x/usb_device_filter_action.rb +11 -0
  181. data/lib/virtualbox/com/interface/3.2.x/usb_device_state.rb +11 -0
  182. data/lib/virtualbox/com/interface/3.2.x/virtual_box_error_info.rb +17 -0
  183. data/lib/virtualbox/com/interface/3.2.x/virtual_system_description.rb +19 -0
  184. data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_type.rb +14 -0
  185. data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_value_type.rb +11 -0
  186. data/lib/virtualbox/com/interface/3.2.x/virtualbox.rb +67 -0
  187. data/lib/virtualbox/com/interface/3.2.x/vrdp_auth_type.rb +11 -0
  188. data/lib/virtualbox/com/interface/3.2.x/vrdp_server.rb +21 -0
  189. data/lib/virtualbox/com/interface/4.0.x/access_mode.rb +11 -0
  190. data/lib/virtualbox/com/interface/4.0.x/appliance.rb +23 -0
  191. data/lib/virtualbox/com/interface/4.0.x/audio_adapter.rb +15 -0
  192. data/lib/virtualbox/com/interface/4.0.x/audio_controller_type.rb +11 -0
  193. data/lib/virtualbox/com/interface/4.0.x/audio_driver_type.rb +11 -0
  194. data/lib/virtualbox/com/interface/4.0.x/auth_type.rb +11 -0
  195. data/lib/virtualbox/com/interface/4.0.x/bios_boot_menu_mode.rb +11 -0
  196. data/lib/virtualbox/com/interface/4.0.x/bios_settings.rb +21 -0
  197. data/lib/virtualbox/com/interface/4.0.x/cleanup_mode.rb +12 -0
  198. data/lib/virtualbox/com/interface/4.0.x/clipboard_mode.rb +11 -0
  199. data/lib/virtualbox/com/interface/4.0.x/console.rb +50 -0
  200. data/lib/virtualbox/com/interface/4.0.x/cpu_property_type.rb +11 -0
  201. data/lib/virtualbox/com/interface/4.0.x/device_type.rb +11 -0
  202. data/lib/virtualbox/com/interface/4.0.x/dhcp_server.rb +22 -0
  203. data/lib/virtualbox/com/interface/4.0.x/event_source.rb +13 -0
  204. data/lib/virtualbox/com/interface/4.0.x/fault_tolerance_state.rb +11 -0
  205. data/lib/virtualbox/com/interface/4.0.x/firmware_type.rb +11 -0
  206. data/lib/virtualbox/com/interface/4.0.x/guest.rb +13 -0
  207. data/lib/virtualbox/com/interface/4.0.x/guest_os_type.rb +33 -0
  208. data/lib/virtualbox/com/interface/4.0.x/host.rb +43 -0
  209. data/lib/virtualbox/com/interface/4.0.x/host_network_interface.rb +30 -0
  210. data/lib/virtualbox/com/interface/4.0.x/host_network_interface_medium_type.rb +11 -0
  211. data/lib/virtualbox/com/interface/4.0.x/host_network_interface_status.rb +11 -0
  212. data/lib/virtualbox/com/interface/4.0.x/host_network_interface_type.rb +11 -0
  213. data/lib/virtualbox/com/interface/4.0.x/host_usb_device.rb +13 -0
  214. data/lib/virtualbox/com/interface/4.0.x/host_usb_device_filter.rb +13 -0
  215. data/lib/virtualbox/com/interface/4.0.x/hw_virt_ex_property_type.rb +12 -0
  216. data/lib/virtualbox/com/interface/4.0.x/keyboard_hid_type.rb +11 -0
  217. data/lib/virtualbox/com/interface/4.0.x/lock_type.rb +11 -0
  218. data/lib/virtualbox/com/interface/4.0.x/machine.rb +132 -0
  219. data/lib/virtualbox/com/interface/4.0.x/machine_state.rb +14 -0
  220. data/lib/virtualbox/com/interface/4.0.x/medium.rb +53 -0
  221. data/lib/virtualbox/com/interface/4.0.x/medium_attachment.rb +18 -0
  222. data/lib/virtualbox/com/interface/4.0.x/medium_format.rb +18 -0
  223. data/lib/virtualbox/com/interface/4.0.x/medium_state.rb +11 -0
  224. data/lib/virtualbox/com/interface/4.0.x/medium_type.rb +11 -0
  225. data/lib/virtualbox/com/interface/4.0.x/medium_variant.rb +11 -0
  226. data/lib/virtualbox/com/interface/4.0.x/nat_alias_mode.rb +11 -0
  227. data/lib/virtualbox/com/interface/4.0.x/nat_engine.rb +27 -0
  228. data/lib/virtualbox/com/interface/4.0.x/nat_protocol.rb +11 -0
  229. data/lib/virtualbox/com/interface/4.0.x/network_adapter.rb +35 -0
  230. data/lib/virtualbox/com/interface/4.0.x/network_adapter_type.rb +11 -0
  231. data/lib/virtualbox/com/interface/4.0.x/network_attachment_type.rb +11 -0
  232. data/lib/virtualbox/com/interface/4.0.x/nsiexception.rb +23 -0
  233. data/lib/virtualbox/com/interface/4.0.x/nsisupports.rb +15 -0
  234. data/lib/virtualbox/com/interface/4.0.x/parallel_port.rb +17 -0
  235. data/lib/virtualbox/com/interface/4.0.x/pointing_hid_type.rb +11 -0
  236. data/lib/virtualbox/com/interface/4.0.x/port_mode.rb +11 -0
  237. data/lib/virtualbox/com/interface/4.0.x/progress.rb +64 -0
  238. data/lib/virtualbox/com/interface/4.0.x/serial_port.rb +19 -0
  239. data/lib/virtualbox/com/interface/4.0.x/session.rb +18 -0
  240. data/lib/virtualbox/com/interface/4.0.x/session_state.rb +11 -0
  241. data/lib/virtualbox/com/interface/4.0.x/session_type.rb +11 -0
  242. data/lib/virtualbox/com/interface/4.0.x/shared_folder.rb +17 -0
  243. data/lib/virtualbox/com/interface/4.0.x/snapshot.rb +20 -0
  244. data/lib/virtualbox/com/interface/4.0.x/storage_bus.rb +11 -0
  245. data/lib/virtualbox/com/interface/4.0.x/storage_controller.rb +24 -0
  246. data/lib/virtualbox/com/interface/4.0.x/storage_controller_type.rb +11 -0
  247. data/lib/virtualbox/com/interface/4.0.x/system_properties.rb +42 -0
  248. data/lib/virtualbox/com/interface/4.0.x/usb_controller.rb +21 -0
  249. data/lib/virtualbox/com/interface/4.0.x/usb_device.rb +24 -0
  250. data/lib/virtualbox/com/interface/4.0.x/usb_device_filter.rb +23 -0
  251. data/lib/virtualbox/com/interface/4.0.x/usb_device_filter_action.rb +11 -0
  252. data/lib/virtualbox/com/interface/4.0.x/usb_device_state.rb +11 -0
  253. data/lib/virtualbox/com/interface/4.0.x/virtual_box_error_info.rb +17 -0
  254. data/lib/virtualbox/com/interface/4.0.x/virtual_system_description.rb +19 -0
  255. data/lib/virtualbox/com/interface/4.0.x/virtual_system_description_type.rb +14 -0
  256. data/lib/virtualbox/com/interface/4.0.x/virtual_system_description_value_type.rb +11 -0
  257. data/lib/virtualbox/com/interface/4.0.x/virtualbox.rb +50 -0
  258. data/lib/virtualbox/com/interface/4.0.x/vrde_server.rb +23 -0
  259. data/lib/virtualbox/com/mscom_interface.rb +44 -0
  260. data/lib/virtualbox/com/nil_interface.rb +7 -0
  261. data/lib/virtualbox/com/util.rb +32 -0
  262. data/lib/virtualbox/cpu.rb +61 -0
  263. data/lib/virtualbox/dhcp_server.rb +89 -0
  264. data/lib/virtualbox/dvd.rb +27 -0
  265. data/lib/virtualbox/exceptions.rb +39 -0
  266. data/lib/virtualbox/ext/byte_normalizer.rb +17 -0
  267. data/lib/virtualbox/ext/glob_loader.rb +35 -0
  268. data/lib/virtualbox/ext/logger.rb +38 -0
  269. data/lib/virtualbox/ext/platform.rb +31 -0
  270. data/lib/virtualbox/ext/subclass_listing.rb +24 -0
  271. data/lib/virtualbox/extra_data.rb +127 -0
  272. data/lib/virtualbox/forwarded_port.rb +222 -0
  273. data/lib/virtualbox/global.rb +96 -0
  274. data/lib/virtualbox/hard_drive.rb +246 -0
  275. data/lib/virtualbox/host.rb +71 -0
  276. data/lib/virtualbox/host_network_interface.rb +137 -0
  277. data/lib/virtualbox/hw_virtualization.rb +64 -0
  278. data/lib/virtualbox/lib.rb +84 -0
  279. data/lib/virtualbox/media.rb +20 -0
  280. data/lib/virtualbox/medium.rb +145 -0
  281. data/lib/virtualbox/medium_attachment.rb +61 -0
  282. data/lib/virtualbox/nat_engine.rb +71 -0
  283. data/lib/virtualbox/nat_forwarded_port.rb +171 -0
  284. data/lib/virtualbox/network_adapter.rb +166 -0
  285. data/lib/virtualbox/proxies/collection.rb +57 -0
  286. data/lib/virtualbox/shared_folder.rb +220 -0
  287. data/lib/virtualbox/snapshot.rb +185 -0
  288. data/lib/virtualbox/storage_controller.rb +160 -0
  289. data/lib/virtualbox/system_properties.rb +73 -0
  290. data/lib/virtualbox/usb_controller.rb +59 -0
  291. data/lib/virtualbox/usb_device_filter.rb +74 -0
  292. data/lib/virtualbox/version.rb +36 -0
  293. data/lib/virtualbox/virtual_system_description.rb +47 -0
  294. data/lib/virtualbox/vm.rb +649 -0
  295. data/lib/virtualbox/vrde_server.rb +57 -0
  296. data/test/test_helper.rb +18 -0
  297. data/test/virtualbox/abstract_model/attributable_test.rb +269 -0
  298. data/test/virtualbox/abstract_model/dirty_test.rb +83 -0
  299. data/test/virtualbox/abstract_model/interface_attributes_test.rb +194 -0
  300. data/test/virtualbox/abstract_model/relatable_test.rb +348 -0
  301. data/test/virtualbox/abstract_model/validatable_test.rb +308 -0
  302. data/test/virtualbox/abstract_model/version_matcher_test.rb +41 -0
  303. data/test/virtualbox/abstract_model_test.rb +462 -0
  304. data/test/virtualbox/appliance_test.rb +159 -0
  305. data/test/virtualbox/audio_adapter_test.rb +83 -0
  306. data/test/virtualbox/bios_test.rb +83 -0
  307. data/test/virtualbox/com/abstract_enum_test.rb +49 -0
  308. data/test/virtualbox/com/abstract_implementer_test.rb +40 -0
  309. data/test/virtualbox/com/abstract_interface_test.rb +140 -0
  310. data/test/virtualbox/com/ffi/interface_test.rb +249 -0
  311. data/test/virtualbox/com/ffi/util_test.rb +108 -0
  312. data/test/virtualbox/com/ffi_interface_test.rb +42 -0
  313. data/test/virtualbox/com/implementer/base_test.rb +38 -0
  314. data/test/virtualbox/com/implementer/ffi_test.rb +527 -0
  315. data/test/virtualbox/com/implementer/mscom_test.rb +247 -0
  316. data/test/virtualbox/com/mscom_interface_test.rb +17 -0
  317. data/test/virtualbox/com/util_test.rb +17 -0
  318. data/test/virtualbox/cpu_test.rb +103 -0
  319. data/test/virtualbox/dhcp_server_test.rb +165 -0
  320. data/test/virtualbox/dvd_test.rb +28 -0
  321. data/test/virtualbox/ext/byte_normalizer_test.rb +34 -0
  322. data/test/virtualbox/ext/platform_test.rb +50 -0
  323. data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
  324. data/test/virtualbox/extra_data_test.rb +155 -0
  325. data/test/virtualbox/forwarded_port_test.rb +286 -0
  326. data/test/virtualbox/global_test.rb +46 -0
  327. data/test/virtualbox/hard_drive_test.rb +141 -0
  328. data/test/virtualbox/host_network_interface_test.rb +255 -0
  329. data/test/virtualbox/host_test.rb +94 -0
  330. data/test/virtualbox/hw_virtualization_test.rb +103 -0
  331. data/test/virtualbox/lib_test.rb +93 -0
  332. data/test/virtualbox/medium_attachment_test.rb +147 -0
  333. data/test/virtualbox/medium_test.rb +192 -0
  334. data/test/virtualbox/nat_engine_test.rb +106 -0
  335. data/test/virtualbox/nat_forwarded_port_test.rb +222 -0
  336. data/test/virtualbox/network_adapter_test.rb +191 -0
  337. data/test/virtualbox/proxies/collection_test.rb +102 -0
  338. data/test/virtualbox/shared_folder_test.rb +219 -0
  339. data/test/virtualbox/snapshot_test.rb +231 -0
  340. data/test/virtualbox/storage_controller_test.rb +197 -0
  341. data/test/virtualbox/system_properties_test.rb +87 -0
  342. data/test/virtualbox/usb_controller_test.rb +112 -0
  343. data/test/virtualbox/usb_device_filter_test.rb +93 -0
  344. data/test/virtualbox/version_test.rb +59 -0
  345. data/test/virtualbox/virtual_system_description_test.rb +61 -0
  346. data/test/virtualbox/vm_test.rb +633 -0
  347. data/test/virtualbox/vrde_server_test.rb +83 -0
  348. data/test/virtualbox_test.rb +11 -0
  349. data/virtualbox.gemspec +24 -0
  350. metadata +464 -0
@@ -0,0 +1,74 @@
1
+ module VirtualBox
2
+ # Represents a USB device filter within VirtualBox. This class
3
+ # is a relationship to {USBController} objects.
4
+ class USBDeviceFilter < AbstractModel
5
+ attribute :parent, :readonly => true, :property => false
6
+ attribute :parent_collection, :readonly => true, :property => false
7
+ attribute :interface, :readonly => true, :property => false
8
+ attribute :name
9
+ attribute :active, :boolean => true
10
+ attribute :vendor_id
11
+ attribute :product_id
12
+ attribute :revision
13
+ attribute :manufacturer
14
+ attribute :product
15
+ attribute :serial_number
16
+ attribute :port
17
+ attribute :remote
18
+ attribute :masked_interfaces
19
+
20
+ class << self
21
+ # Populates the USB controller relationship for anything
22
+ # which is related to it.
23
+ #
24
+ # **This method typically won't be used except internally.**
25
+ #
26
+ # @return [USBDeviceFilter]
27
+ def populate_relationship(caller, usbcontroller)
28
+ result = Proxies::Collection.new(caller)
29
+
30
+ usbcontroller.device_filters.each do |filter|
31
+ result << new(filter)
32
+ end
33
+
34
+ result
35
+ end
36
+
37
+ # Saves the relationship. This simply calls {#save} on the
38
+ # relationship object.
39
+ #
40
+ # **This method typically won't be used except internally.**
41
+ def save_relationship(caller, item)
42
+ item.save
43
+ end
44
+ end
45
+
46
+ def initialize(iusb)
47
+ initialize_attributes(iusb)
48
+ end
49
+
50
+ def initialize_attributes(iusb)
51
+ # Write the parent and interface attributes
52
+ write_attribute(:interface, iusb)
53
+
54
+ # Load the interface attributes
55
+ load_interface_attributes(interface)
56
+
57
+ # Clear dirty and mark as existing
58
+ clear_dirty!
59
+ existing_record!
60
+ end
61
+
62
+ def added_to_relationship(proxy)
63
+ write_attribute(:parent, proxy.parent)
64
+ write_attribute(:parent_collection, proxy)
65
+ end
66
+
67
+ # Saves the USB device.
68
+ def save
69
+ parent.with_open_session do |session|
70
+ # TODO: save_changed_interface_attributes(session.machine.usb_controller)
71
+ end
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,36 @@
1
+ module VirtualBox
2
+ VERSION = "0.8.4"
3
+
4
+ module Version
5
+ # Returns a boolean denoting whether the current VirtualBox
6
+ # version is supported or not. This will return `false` if the
7
+ # version is invalid, the version is not detected, etc. That means
8
+ # that even if VirtualBox is not installed, this will simply
9
+ # return `false`.
10
+ #
11
+ # @return [Boolean]
12
+ def supported?
13
+ !version.nil?
14
+ end
15
+
16
+ # Returns the version string of the VirtualBox installed, ex. "3.1.6"
17
+ # This string is cached since the version typically doesn't change
18
+ # during runtime. If you must refresh the version, send the boolean
19
+ # `true` as the first parameter.
20
+ def version(refresh=false)
21
+ @_version = Lib.lib.virtualbox.version if @_version.nil? || refresh
22
+ @_version
23
+ rescue Exception
24
+ nil
25
+ end
26
+
27
+ # Returns the revision string of the VirtualBox installed, ex. "51742"
28
+ # This string is cached since the revision doesn't typically change during
29
+ # runtime. If you must refresh the version, send the boolean `true` as the
30
+ # first parameter.
31
+ def revision(refresh=false)
32
+ @_revision = Lib.lib.virtualbox.revision.to_s if @_revision.nil? || refresh
33
+ @_revision
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,47 @@
1
+ module VirtualBox
2
+ # Represents a description of a virtual system in an {Appliance}. This contains
3
+ # the values that are in the OVF files as well as recommend values from VirtualBox.
4
+ class VirtualSystemDescription < AbstractModel
5
+ attribute :interface, :readonly => true
6
+ attribute :descriptions, :readonly => true, :default => {}
7
+
8
+ class << self
9
+ def populate_relationship(caller, data)
10
+ result = Proxies::Collection.new(caller)
11
+
12
+ data.each do |vsd|
13
+ result << new(vsd)
14
+ end
15
+
16
+ result
17
+ end
18
+ end
19
+
20
+ def initialize(ivsd)
21
+ write_attribute(:interface, ivsd)
22
+ initialize_attributes(ivsd)
23
+ end
24
+
25
+ def initialize_attributes(ivsd)
26
+ # Grab all the descriptions, iterate over each, and add to the hash of
27
+ # descriptions. This multiple loop method is used instead of `get_description` since
28
+ # that method doesn't work well with MSCOM.
29
+ COM::Util.versioned_interface(:VirtualSystemDescriptionType).each_with_index do |type, index|
30
+ COM::Util.versioned_interface(:VirtualSystemDescriptionValueType).each_with_index do |value_type, value_index|
31
+ value = ivsd.get_values_by_type(type, value_type)
32
+ if value && value != [] && value != [nil]
33
+ descriptions[type] ||= {}
34
+ descriptions[type][value_type] = value.first
35
+ end
36
+ end
37
+ end
38
+
39
+ # Clear dirtiness, since this should only be called initially and
40
+ # therefore shouldn't affect dirtiness
41
+ clear_dirty!
42
+
43
+ # But this is an existing record
44
+ existing_record!
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,649 @@
1
+ require 'pathname'
2
+ require 'virtualbox/ext/platform'
3
+
4
+ module VirtualBox
5
+ # Represents a single VirtualBox virtual machine. All attributes which are
6
+ # not read-only can be modified and saved.
7
+ #
8
+ # # Finding Virtual Machines
9
+ #
10
+ # Two methods are used to find virtual machines: {VM.all} and {VM.find}. Each
11
+ # return a {VM} object. An example is shown below:
12
+ #
13
+ # vm = VirtualBox::VM.find("MyWindowsXP")
14
+ # puts vm.name # => "MyWindowsXP"
15
+ #
16
+ # # Modifying Virtual Machines
17
+ #
18
+ # Virtual machines can be modified a lot like [ActiveRecord](http://ar.rubyonrails.org/)
19
+ # objects. This is best shown through example:
20
+ #
21
+ # vm = VirtualBox::VM.find("MyWindowsXP")
22
+ # vm.memory_size = 256
23
+ # vm.name = "WindowsXP"
24
+ # vm.save
25
+ #
26
+ # # Controlling Virtual Machines
27
+ #
28
+ # Virtual machines can be controlled using the basic {#start}, {#stop}, etc.
29
+ # methods. The current state of the VM can also be retrieved via the {#state}
30
+ # method. An example of this use is shown below:
31
+ #
32
+ # if vm.powered_off?
33
+ # vm.start
34
+ # end
35
+ #
36
+ # # Taking a Snapshot
37
+ #
38
+ # Snapshots allow virtual machine states to be saved at a given point in time
39
+ # without having to stop the machine. This state can then be restored later.
40
+ # VirtualBox handles this by creating a differencing image which allows the hard
41
+ # drive to even retain its exact state. Taking a snapshot is extremely simple:
42
+ #
43
+ # vm = VirtualBox::VM.find("MyWindowsXP")
44
+ # vm.take_snapshot("My Snapshot", "A description of my snapshot")
45
+ #
46
+ # # Traversing Snapshots
47
+ #
48
+ # Snapshots are represented by a tree-like structure. There is a root snapshot
49
+ # and that snapshot has many children which may in turn have their own children.
50
+ # The easiest way to traverse this structure is to use the {#root_snapshot}
51
+ # VM method and traverse the structure like any tree structure:
52
+ #
53
+ # vm = VirtualBox::VM.find("MyWindowsXP")
54
+ # p vm.root_snapshot.children.length
55
+ #
56
+ # # Finding Snapshots
57
+ #
58
+ # While traversing the entire snapshot tree can be useful, it is often more
59
+ # useful to be able to simply find a snapshot by name. For this, use the
60
+ # {#find_snapshot} method:
61
+ #
62
+ # vm = VirtualBox::VM.find("MyWindowsXP")
63
+ # p vm.find_snapshot("PreSP3")
64
+ #
65
+ # # Attributes and Relationships
66
+ #
67
+ # Properties of the virtual machine are exposed using standard ruby instance
68
+ # methods which are generated on the fly. Because of this, they are not listed
69
+ # below as available instance methods.
70
+ #
71
+ # These attributes can be accessed and modified via standard ruby-style
72
+ # `instance.attribute` and `instance.attribute=` methods. The attributes are
73
+ # listed below.
74
+ #
75
+ # Relationships are also accessed like attributes but can't be set. Instead,
76
+ # they are typically references to other objects such as a {HardDrive} which
77
+ # in turn have their own attributes which can be modified.
78
+ #
79
+ # ## Attributes
80
+ #
81
+ # This is copied directly from the class header, but lists all available
82
+ # attributes. If you don't understand what this means, read {Attributable}.
83
+ #
84
+ # attribute :uuid, :readonly => true, :property => :id
85
+ # attribute :name
86
+ # attribute :os_type_id
87
+ # attribute :description
88
+ # attribute :memory_size
89
+ # attribute :memory_balloon_size
90
+ # attribute :vram_size
91
+ # attribute :cpu_count
92
+ # attribute :accelerate_3d_enabled, :boolean => true
93
+ # attribute :accelerate_2d_video_enabled, :boolean => true
94
+ # attribute :clipboard_mode
95
+ # attribute :monitor_count
96
+ # attribute :state, :readonly => true
97
+ # attribute :accessible, :readonly => true, :boolean => true
98
+ # attribute :hardware_version
99
+ # attribute :hardware_uuid
100
+ # attribute :firmware_type
101
+ # attribute :snapshot_folder
102
+ # attribute :settings_file_path, :readonly => true
103
+ # attribute :last_state_change, :readonly => true
104
+ # attribute :state_file_path, :readonly => true
105
+ # attribute :log_folder, :readonly => true
106
+ # attribute :snapshot_count, :readonly => true
107
+ # attribute :current_state_modified, :readonly => true
108
+ # attribute :guest_property_notification_patterns
109
+ # attribute :teleporter_enabled, :boolean => true
110
+ # attribute :teleporter_port
111
+ # attribute :teleporter_address
112
+ # attribute :teleporter_password
113
+ # attribute :interface, :readonly => true, :property => false
114
+ #
115
+ # ## Relationships
116
+ #
117
+ # In addition to the basic attributes, a virtual machine is related
118
+ # to other things. The relationships are listed below. If you don't
119
+ # understand this, read {Relatable}.
120
+ #
121
+ # relationship :audio_adapter, :AudioAdapter
122
+ # relationship :bios, :BIOS
123
+ # relationship :hw_virt, :HWVirtualization
124
+ # relationship :cpu, :CPU
125
+ # relationship :vrdp_server, :VRDPServer
126
+ # relationship :storage_controllers, :StorageController, :dependent => :destroy
127
+ # relationship :medium_attachments, :MediumAttachment
128
+ # relationship :shared_folders, :SharedFolder
129
+ # relationship :extra_data, :ExtraData
130
+ # relationship :forwarded_ports, :ForwardedPort
131
+ # relationship :network_adapters, :NetworkAdapter
132
+ # relationship :usb_controller, :USBController
133
+ # relationship :current_snapshot, :Snapshot
134
+ #
135
+ class VM < AbstractModel
136
+ attribute :uuid, :readonly => true, :property => :id
137
+ attribute :name
138
+ attribute :os_type_id
139
+ attribute :description
140
+ attribute :memory_size
141
+ attribute :memory_balloon_size
142
+ attribute :vram_size
143
+ attribute :cpu_count
144
+ attribute :accelerate_3d_enabled, :boolean => true
145
+ attribute :accelerate_2d_video_enabled, :boolean => true
146
+ attribute :clipboard_mode
147
+ attribute :monitor_count
148
+ attribute :state, :readonly => true
149
+ attribute :accessible, :readonly => true, :boolean => true
150
+ attribute :hardware_version
151
+ attribute :hardware_uuid
152
+ attribute :firmware_type
153
+ attribute :snapshot_folder
154
+ attribute :settings_file_path, :readonly => true
155
+ attribute :last_state_change, :readonly => true
156
+ attribute :state_file_path, :readonly => true
157
+ attribute :log_folder, :readonly => true
158
+ attribute :snapshot_count, :readonly => true
159
+ attribute :current_state_modified, :readonly => true
160
+ attribute :guest_property_notification_patterns
161
+ attribute :teleporter_enabled, :boolean => true
162
+ attribute :teleporter_port
163
+ attribute :teleporter_address
164
+ attribute :teleporter_password
165
+ attribute :boot_order,
166
+ :property_getter => Proc.new { |instance, *args| instance.get_boot_order(*args) },
167
+ :property_setter => Proc.new { |instance, *args| instance.set_boot_order(*args) }
168
+ attribute :interface, :readonly => true, :property => false
169
+ relationship :audio_adapter, :AudioAdapter
170
+ relationship :bios, :BIOS
171
+ relationship :hw_virt, :HWVirtualization
172
+ relationship :cpu, :CPU
173
+ relationship :vrde_server, :VRDEServer
174
+ relationship :storage_controllers, :StorageController, :dependent => :destroy
175
+ relationship :medium_attachments, :MediumAttachment
176
+ relationship :shared_folders, :SharedFolder
177
+ relationship :extra_data, :ExtraData
178
+ relationship :forwarded_ports, :ForwardedPort, :version => "3.1"
179
+ relationship :network_adapters, :NetworkAdapter
180
+ relationship :usb_controller, :USBController
181
+ relationship :current_snapshot, :Snapshot
182
+
183
+ class << self
184
+ # Returns an array of all available VMs.
185
+ #
186
+ # @return [Array<VM>]
187
+ def all
188
+ Global.global(true).vms
189
+ end
190
+
191
+ # Finds a VM by UUID or registered name and returns a
192
+ # new VM object. If the VM doesn't exist, will return `nil`.
193
+ #
194
+ # @return [VM]
195
+ def find(name)
196
+ all.detect { |o| o.name == name || o.uuid == name }
197
+ end
198
+
199
+ # Imports a VM, blocking the entire thread during this time.
200
+ # When finished, on success, will return the VM object. This
201
+ # VM object can be used to make any modifications necessary
202
+ # (RAM, cpus, etc.).
203
+ #
204
+ # If there are multiple VMs in the OVF file being imported,
205
+ # the first virtual machine will be returned, although all will
206
+ # be imported.
207
+ #
208
+ # If a block is given, it will be yielded with the progress of the
209
+ # import operation, so that the progress of the import can be
210
+ # tracked.
211
+ #
212
+ # @return [VM] The newly imported virtual machine
213
+ def import(source_path, &block)
214
+ appliance = Appliance.new(source_path)
215
+ appliance.import(&block)
216
+
217
+ find(appliance.virtual_systems.first.descriptions[:name][:auto])
218
+ end
219
+
220
+ def populate_relationship(caller, machines)
221
+ machines.is_a?(Array) ? populate_array_relationship(caller, machines) : populate_single_relationship(caller, machines)
222
+ end
223
+
224
+ def populate_single_relationship(caller, machine)
225
+ new(machine)
226
+ end
227
+
228
+ def populate_array_relationship(caller, machines)
229
+ result = Proxies::Collection.new(caller)
230
+
231
+ machines.each do |machine|
232
+ result << new(machine)
233
+ end
234
+
235
+ result
236
+ end
237
+ end
238
+
239
+ # Creates a new instance of a virtual machine.
240
+ #
241
+ # **Currently can NOT be used to create a NEW virtual machine**.
242
+ # Support for creating new virtual machines will be added shortly.
243
+ # For now, this is only used by {VM.find} and {VM.all} to
244
+ # initialize the VMs.
245
+ def initialize(imachine)
246
+ super()
247
+
248
+ write_attribute(:interface, imachine)
249
+ initialize_attributes(imachine)
250
+ end
251
+
252
+ def initialize_attributes(machine)
253
+ # Load the interface attributes
254
+ load_interface_attributes(machine)
255
+
256
+ # Setup the relationships
257
+ populate_relationships(machine)
258
+
259
+ # Clear dirtiness, since this should only be called initially and
260
+ # therefore shouldn't affect dirtiness
261
+ clear_dirty!
262
+
263
+ # But this is an existing record
264
+ existing_record!
265
+ end
266
+
267
+ # Reload the model so that all the attributes and relationships are
268
+ # up to date. This method will automatically discard any changes to
269
+ # the VM and any of its relationships.
270
+ def reload
271
+ initialize_attributes(interface)
272
+ self
273
+ end
274
+
275
+ # State of the virtual machine. Returns the state of the virtual
276
+ # machine. This state will represent the state that was assigned
277
+ # when the VM was found unless `reload` is set to `true`.
278
+ #
279
+ # @param [Boolean] reload If true, will reload the state to current
280
+ # value.
281
+ # @return [String] Virtual machine state.
282
+ def state(suppress_state_reload=false)
283
+ if !suppress_state_reload
284
+ load_interface_attribute(:state, interface)
285
+ clear_dirty!(:state)
286
+ end
287
+
288
+ read_attribute(:state)
289
+ end
290
+
291
+ # Validates the virtual machine
292
+ def validate
293
+ super
294
+
295
+ validates_presence_of :name, :os_type_id, :memory_size, :vram_size, :cpu_count
296
+ validates_numericality_of :memory_balloon_size, :monitor_count
297
+ validates_inclusion_of :accelerate_3d_enabled, :accelerate_2d_video_enabled, :teleporter_enabled, :in => [true, false]
298
+
299
+ if !errors_on(:name)
300
+ # Only validate the name if the name has no errors already
301
+ vms_of_same_name = self.class.find(name)
302
+ add_error(:name, 'must not be used by another virtual machine.') if vms_of_same_name && vms_of_same_name.uuid != uuid
303
+ end
304
+
305
+ validates_inclusion_of :os_type_id, :in => VirtualBox::Global.global.lib.virtualbox.guest_os_types.collect { |os| os.id }
306
+
307
+ min_guest_ram, max_guest_ram = Global.global.system_properties.min_guest_ram, Global.global.system_properties.max_guest_ram
308
+ validates_inclusion_of :memory_size, :in => (min_guest_ram..max_guest_ram), :message => "must be between #{min_guest_ram} and #{max_guest_ram}."
309
+ validates_inclusion_of :memory_balloon_size, :in => (0..max_guest_ram), :message => "must be between 0 and #{max_guest_ram}."
310
+
311
+ min_guest_vram, max_guest_vram = Global.global.system_properties.min_guest_vram, Global.global.system_properties.max_guest_vram
312
+ validates_inclusion_of :vram_size, :in => (min_guest_vram..max_guest_vram), :message => "must be between #{min_guest_vram} and #{max_guest_vram}."
313
+
314
+ min_guest_cpu_count, max_guest_cpu_count = Global.global.system_properties.min_guest_cpu_count, Global.global.system_properties.max_guest_cpu_count
315
+ validates_inclusion_of :cpu_count, :in => (min_guest_cpu_count..max_guest_cpu_count), :message => "must be between #{min_guest_cpu_count} and #{max_guest_cpu_count}."
316
+
317
+ validates_inclusion_of :clipboard_mode, :in => COM::Util.versioned_interface(:ClipboardMode).map
318
+ validates_inclusion_of :firmware_type, :in => COM::Util.versioned_interface(:FirmwareType).map
319
+ end
320
+
321
+ # Saves the virtual machine if modified. This method saves any modified
322
+ # attributes of the virtual machine. If any related attributes were saved
323
+ # as well (such as storage controllers), those will be saved, too.
324
+ def save
325
+ return false unless valid?
326
+ raise Exceptions::ReadonlyVMStateException.new("VM must not be in saved state to modify.") if saved?
327
+
328
+ with_open_session do |session|
329
+ # Use setters to save the attributes on the locked machine and persist
330
+ # the settings
331
+ machine = session.machine
332
+
333
+ # Save the boot order
334
+ save_interface_attribute(:boot_order, machine)
335
+
336
+ # Save all the attributes and relationships
337
+ save_changed_interface_attributes(machine)
338
+
339
+ # Save relationships, which may open their own sessions if necessary
340
+ save_relationships
341
+ end
342
+
343
+ true
344
+ end
345
+
346
+ # Returns the root snapshot of this virtual machine. This root snapshot
347
+ # can be used to traverse the tree of snapshots.
348
+ #
349
+ # @return [Snapshot]
350
+ def root_snapshot
351
+ return nil if current_snapshot.nil?
352
+
353
+ current = current_snapshot
354
+ current = current.parent while current.parent != nil
355
+ current
356
+ end
357
+
358
+ # Find a snapshot by name or UUID. This allows you to find a snapshot by a given
359
+ # name, rather than having to resort to traversing the entire tree structure
360
+ # manually.
361
+ def find_snapshot(name)
362
+ find_helper = lambda do |name, root|
363
+ return nil if root.nil?
364
+ return root if root.name == name || root.uuid == name
365
+
366
+ root.children.each do |child|
367
+ result = find_helper.call(name, child)
368
+ return result unless result.nil?
369
+ end
370
+
371
+ nil
372
+ end
373
+
374
+ find_helper.call(name, root_snapshot)
375
+ end
376
+
377
+ # Opens a direct session with the machine this VM represents and yields
378
+ # the session object to a block. Many of the VirtualBox's settings can only
379
+ # be modified with an open session on a machine. An open session is similar
380
+ # to a write-lock. Once the session is completed, it must be closed, which
381
+ # this method does as well.
382
+ def with_open_session(mode=:write)
383
+ # Set the session up
384
+ session = Lib.lib.session
385
+
386
+ close_session = false
387
+
388
+ if session.state != :open
389
+ # Open up a session for this virtual machine
390
+ interface.lock_machine(session, mode)
391
+
392
+ # Mark the session to be closed
393
+ close_session = true
394
+ end
395
+
396
+ # Yield the block with the session
397
+ yield session if block_given?
398
+
399
+ # Close the session
400
+ if close_session
401
+ # Save these settings only if we're closing and only if the state
402
+ # is not saved, since that doesn't allow the machine to be saved.
403
+ session.machine.save_settings if mode == :write && session.machine.state != :saved
404
+
405
+ # Close the session
406
+ session.unlock_machine
407
+ end
408
+ rescue Exception
409
+ # Close the session so we don't get locked out. We use a rescue block
410
+ # here instead of an "ensure" since we ONLY want this to occur if an
411
+ # exception is raised. Otherwise, we may or may not close the session,
412
+ # depending how deeply nested this call to `with_open_session` is.
413
+ # (see close_session boolean above)
414
+ session.unlock_machine if session.state == :open
415
+
416
+ # Reraise the exception, we're not actually catching it to handle it
417
+ raise
418
+ end
419
+
420
+ # Exports a virtual machine. The virtual machine will be exported
421
+ # to the specified OVF file name. This directory will also have the
422
+ # `mf` file which contains the file checksums and also the virtual
423
+ # drives of the machine.
424
+ #
425
+ # Export also supports an additional options hash which can contain
426
+ # information that will be embedded with the virtual machine. View
427
+ # below for more information on the available options.
428
+ #
429
+ # This method will block until the export is complete, which takes about
430
+ # 60 to 90 seconds on my 2.2 GHz 2009 model MacBook Pro.
431
+ #
432
+ # If a block is given to the method, then it will be yielded with the
433
+ # progress of the operation.
434
+ #
435
+ # @param [String] filename The file (not directory) to save the exported
436
+ # OVF file. This directory will also receive the checksum file and
437
+ # virtual disks.
438
+ def export(filename, options = {}, &block)
439
+ app = Appliance.new
440
+ app.path = filename
441
+ app.add_machine(self, options)
442
+ app.export(&block)
443
+ end
444
+
445
+ # Take a snapshot of the current state of the machine. This method can be
446
+ # called while the VM is running and also while it is powered off. This
447
+ # method will block while the snapshot is being taken.
448
+ #
449
+ # If a block is given to this method, it will yield with a progress
450
+ # object which can be used to get the progress of the operation.
451
+ #
452
+ # @param [String] name Name of the snapshot.
453
+ # @param [String] description Description of the snapshot.
454
+ def take_snapshot(name, description="", &block)
455
+ with_open_session do |session|
456
+ session.console.take_snapshot(name, description).wait(&block)
457
+ end
458
+ end
459
+
460
+ # Starts the virtual machine. The virtual machine can be started in a
461
+ # variety of modes:
462
+ #
463
+ # * **gui** -- The VirtualBox GUI will open with the screen of the VM.
464
+ # * **vrdp** -- The VM will run in the background. No GUI will be
465
+ # present at all.
466
+ #
467
+ # This method blocks while the external processes are starting.
468
+ #
469
+ # @param [Symbol] mode Described above.
470
+ # @return [Boolean] True if command was successful, false otherwise.
471
+ def start(mode="gui")
472
+ return false if running?
473
+
474
+ # Open a new remote session, this will automatically start the machine
475
+ # as well
476
+ session = Lib.lib.session
477
+ interface.launch_vm_process(session, mode.to_s, "").wait
478
+ session.unlock_machine if session.state == :open
479
+ true
480
+ end
481
+
482
+ # Shuts down the VM by directly calling "acpipowerbutton". Depending on the
483
+ # settings of the Virtual Machine, this may not work. For example, some linux
484
+ # installations don't respond to the ACPI power button at all. In such cases,
485
+ # {#stop} or {#save_state} may be used instead.
486
+ #
487
+ # @return [Boolean] True if command was successful, false otherwise.
488
+ def shutdown
489
+ control(:power_button)
490
+ end
491
+
492
+ # Stops the VM by directly calling "poweroff." Immediately halts the
493
+ # virtual machine without saving state. This could result in a loss
494
+ # of data. To prevent data loss, see {#shutdown}
495
+ #
496
+ # @return [Boolean] True if command was successful, false otherwise.
497
+ def stop
498
+ control(:power_down)
499
+ end
500
+
501
+ # Pauses the VM, putting it on hold temporarily. The VM can be resumed
502
+ # again by calling {#resume}
503
+ #
504
+ # @return [Boolean] True if command was successful, false otherwise.
505
+ def pause
506
+ control(:pause)
507
+ end
508
+
509
+ # Resume a paused VM.
510
+ #
511
+ # @return [Boolean] True if command was successful, false otherwise.
512
+ def resume
513
+ control(:resume)
514
+ end
515
+
516
+ # Saves the state of a VM and stops it. The VM can be resumed
517
+ # again by calling "{#start}" again.
518
+ #
519
+ # @return [Boolean] True if command was successful, false otherwise.
520
+ def save_state
521
+ control(:save_state)
522
+ end
523
+
524
+ # Discards any saved state on the current VM. The VM is not destroyed though
525
+ # and can still be started by calling {#start}.
526
+ #
527
+ # @return [Boolean] True if command was successful, false otherwise.
528
+ def discard_state
529
+ control(:discard_saved_state, true)
530
+ end
531
+
532
+ # Controls the virtual machine. This method is used by {#stop},
533
+ # {#pause}, {#resume}, and {#save_state} to control the virtual machine.
534
+ # Typically, you won't ever have to call this method and should
535
+ # instead call those.
536
+ #
537
+ # @param [String] command The command to run on controlvm
538
+ # @return [Boolean] True if command was successful, false otherwise.
539
+ def control(command, *args)
540
+ with_open_session(:shared) do |session|
541
+ result = session.console.send(command, *args)
542
+ result.wait if result.is_a?(COM::Util.versioned_interface(:Progress))
543
+ end
544
+ end
545
+
546
+ # Destroys the virtual machine. This method also removes all attached
547
+ # media (required by VirtualBox to destroy a VM). By default,
548
+ # this **will not** destroy attached hard drives, but will if given
549
+ # the `destroy_image` option.
550
+ #
551
+ # @overload destroy(opts = {})
552
+ # Passes options to the destroy method.
553
+ # @option opts [Boolean] :destroy_medium (false) If true, will
554
+ # also unregister attached media. If set to `:delete`, it will
555
+ # not only unregister attached media, but will also physically
556
+ # remove their respective data.
557
+ def destroy(*args)
558
+ # Do a full cleanup on the machine, then delete all the media attached
559
+ media = interface.unregister(:full)
560
+
561
+ if !media.empty?
562
+ if Platform.windows? && !Platform.jruby?
563
+ # The MSCOM interface in CRuby to delete media is broken,
564
+ # so we do this ghettoness.
565
+ path = interface.settings_file_path
566
+
567
+ # A simple sanity check to make sure we don't attempt to delete
568
+ # the root or something
569
+ if path.length > 10
570
+ Pathname.new(path).parent.rmtree
571
+ end
572
+ else
573
+ interface.delete(media)
574
+
575
+ # TODO: This sleep is silly. The progress object returned by the media
576
+ # delete always fails to "wait" for some reason, so I do this. I hope
577
+ # to solve this issue soon.
578
+ sleep 1
579
+ end
580
+ end
581
+ end
582
+
583
+ # Returns true if the virtual machine state is starting
584
+ #
585
+ # @return [Boolean] True if virtual machine state is starting
586
+ def starting?
587
+ state == :starting
588
+ end
589
+
590
+ # Returns true if the virtual machine state is running
591
+ #
592
+ # @return [Boolean] True if virtual machine state is running
593
+ def running?
594
+ state == :running
595
+ end
596
+
597
+ # Returns true if the virtual machine state is powered off
598
+ #
599
+ # @return [Boolean] True if virtual machine state is powered off
600
+ def powered_off?
601
+ state == :powered_off
602
+ end
603
+
604
+ # Returns true if the virtual machine state is paused
605
+ #
606
+ # @return [Boolean] True if virtual machine state is paused
607
+ def paused?
608
+ state == :paused
609
+ end
610
+
611
+ # Returns true if the virtual machine state is saved
612
+ #
613
+ # @return [Boolean] True if virtual machine state is saved
614
+ def saved?
615
+ state == :saved
616
+ end
617
+
618
+ # Returns true if the virtual machine state is aborted
619
+ #
620
+ # @return [Boolean] True if virtual machine state is aborted
621
+ def aborted?
622
+ state == :aborted
623
+ end
624
+
625
+ # Loads the boot order for this virtual machine. This method should
626
+ # never be called directly. Instead, use the `boot_order` attribute
627
+ # to read and modify the boot order.
628
+ def get_boot_order(interface, key)
629
+ max_boot = Global.global.system_properties.max_boot_position
630
+
631
+ (1..max_boot).inject([]) do |order, position|
632
+ order << interface.get_boot_order(position)
633
+ order
634
+ end
635
+ end
636
+
637
+ # Sets the boot order for this virtual machine. This method should
638
+ # never be called directly. Instead, modify the `boot_order` array.
639
+ def set_boot_order(interface, key, value)
640
+ max_boot = Global.global.system_properties.max_boot_position
641
+ value = value.dup
642
+ value.concat(Array.new(max_boot - value.size)) if value.size < max_boot
643
+
644
+ (1..max_boot).each do |position|
645
+ interface.set_boot_order(position, value[position - 1])
646
+ end
647
+ end
648
+ end
649
+ end