velir_virtualbox 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
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