bbrowning-virtualbox 0.7.6.dev

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 (281) 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 +33 -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 +54 -0
  56. data/lib/virtualbox/com/ffi/util.rb +119 -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 +361 -0
  61. data/lib/virtualbox/com/implementer/mscom.rb +175 -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/mscom_interface.rb +44 -0
  190. data/lib/virtualbox/com/nil_interface.rb +7 -0
  191. data/lib/virtualbox/com/util.rb +32 -0
  192. data/lib/virtualbox/cpu.rb +61 -0
  193. data/lib/virtualbox/dhcp_server.rb +89 -0
  194. data/lib/virtualbox/dvd.rb +27 -0
  195. data/lib/virtualbox/exceptions.rb +39 -0
  196. data/lib/virtualbox/ext/byte_normalizer.rb +17 -0
  197. data/lib/virtualbox/ext/glob_loader.rb +22 -0
  198. data/lib/virtualbox/ext/logger.rb +38 -0
  199. data/lib/virtualbox/ext/platform.rb +27 -0
  200. data/lib/virtualbox/ext/subclass_listing.rb +24 -0
  201. data/lib/virtualbox/extra_data.rb +127 -0
  202. data/lib/virtualbox/forwarded_port.rb +222 -0
  203. data/lib/virtualbox/global.rb +102 -0
  204. data/lib/virtualbox/guest_property.rb +116 -0
  205. data/lib/virtualbox/hard_drive.rb +246 -0
  206. data/lib/virtualbox/host.rb +71 -0
  207. data/lib/virtualbox/host_network_interface.rb +137 -0
  208. data/lib/virtualbox/hw_virtualization.rb +63 -0
  209. data/lib/virtualbox/lib.rb +84 -0
  210. data/lib/virtualbox/media.rb +20 -0
  211. data/lib/virtualbox/medium.rb +145 -0
  212. data/lib/virtualbox/medium_attachment.rb +61 -0
  213. data/lib/virtualbox/nat_engine.rb +71 -0
  214. data/lib/virtualbox/nat_forwarded_port.rb +171 -0
  215. data/lib/virtualbox/network_adapter.rb +166 -0
  216. data/lib/virtualbox/proxies/collection.rb +57 -0
  217. data/lib/virtualbox/shared_folder.rb +220 -0
  218. data/lib/virtualbox/snapshot.rb +185 -0
  219. data/lib/virtualbox/storage_controller.rb +160 -0
  220. data/lib/virtualbox/system_properties.rb +74 -0
  221. data/lib/virtualbox/usb_controller.rb +59 -0
  222. data/lib/virtualbox/usb_device_filter.rb +74 -0
  223. data/lib/virtualbox/version.rb +36 -0
  224. data/lib/virtualbox/virtual_system_description.rb +47 -0
  225. data/lib/virtualbox/vm.rb +684 -0
  226. data/lib/virtualbox/vrdp_server.rb +59 -0
  227. data/test/test_helper.rb +18 -0
  228. data/test/virtualbox/abstract_model/attributable_test.rb +269 -0
  229. data/test/virtualbox/abstract_model/dirty_test.rb +83 -0
  230. data/test/virtualbox/abstract_model/interface_attributes_test.rb +194 -0
  231. data/test/virtualbox/abstract_model/relatable_test.rb +348 -0
  232. data/test/virtualbox/abstract_model/validatable_test.rb +308 -0
  233. data/test/virtualbox/abstract_model/version_matcher_test.rb +41 -0
  234. data/test/virtualbox/abstract_model_test.rb +462 -0
  235. data/test/virtualbox/appliance_test.rb +159 -0
  236. data/test/virtualbox/audio_adapter_test.rb +83 -0
  237. data/test/virtualbox/bios_test.rb +83 -0
  238. data/test/virtualbox/com/abstract_enum_test.rb +49 -0
  239. data/test/virtualbox/com/abstract_implementer_test.rb +40 -0
  240. data/test/virtualbox/com/abstract_interface_test.rb +140 -0
  241. data/test/virtualbox/com/ffi/interface_test.rb +249 -0
  242. data/test/virtualbox/com/ffi/util_test.rb +108 -0
  243. data/test/virtualbox/com/ffi_interface_test.rb +42 -0
  244. data/test/virtualbox/com/implementer/base_test.rb +38 -0
  245. data/test/virtualbox/com/implementer/ffi_test.rb +527 -0
  246. data/test/virtualbox/com/implementer/mscom_test.rb +247 -0
  247. data/test/virtualbox/com/mscom_interface_test.rb +17 -0
  248. data/test/virtualbox/com/util_test.rb +17 -0
  249. data/test/virtualbox/cpu_test.rb +103 -0
  250. data/test/virtualbox/dhcp_server_test.rb +165 -0
  251. data/test/virtualbox/dvd_test.rb +28 -0
  252. data/test/virtualbox/ext/byte_normalizer_test.rb +34 -0
  253. data/test/virtualbox/ext/platform_test.rb +50 -0
  254. data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
  255. data/test/virtualbox/extra_data_test.rb +155 -0
  256. data/test/virtualbox/forwarded_port_test.rb +286 -0
  257. data/test/virtualbox/global_test.rb +46 -0
  258. data/test/virtualbox/hard_drive_test.rb +141 -0
  259. data/test/virtualbox/host_network_interface_test.rb +254 -0
  260. data/test/virtualbox/host_test.rb +94 -0
  261. data/test/virtualbox/hw_virtualization_test.rb +103 -0
  262. data/test/virtualbox/lib_test.rb +93 -0
  263. data/test/virtualbox/medium_attachment_test.rb +147 -0
  264. data/test/virtualbox/medium_test.rb +192 -0
  265. data/test/virtualbox/nat_engine_test.rb +106 -0
  266. data/test/virtualbox/nat_forwarded_port_test.rb +222 -0
  267. data/test/virtualbox/network_adapter_test.rb +191 -0
  268. data/test/virtualbox/proxies/collection_test.rb +102 -0
  269. data/test/virtualbox/shared_folder_test.rb +219 -0
  270. data/test/virtualbox/snapshot_test.rb +231 -0
  271. data/test/virtualbox/storage_controller_test.rb +197 -0
  272. data/test/virtualbox/system_properties_test.rb +87 -0
  273. data/test/virtualbox/usb_controller_test.rb +112 -0
  274. data/test/virtualbox/usb_device_filter_test.rb +93 -0
  275. data/test/virtualbox/version_test.rb +59 -0
  276. data/test/virtualbox/virtual_system_description_test.rb +61 -0
  277. data/test/virtualbox/vm_test.rb +637 -0
  278. data/test/virtualbox/vrdp_server_test.rb +83 -0
  279. data/test/virtualbox_test.rb +11 -0
  280. data/virtualbox.gemspec +25 -0
  281. metadata +397 -0
@@ -0,0 +1,222 @@
1
+ module VirtualBox
2
+ # When a VM uses NAT as its NIC type, VirtualBox acts like its
3
+ # own private router for all virtual machines. Because of this,
4
+ # the host machine can't access services within the guest machine.
5
+ # To get around this, NAT supports port forwarding, which allows the
6
+ # guest machine services to be forwarded to some port on the host
7
+ # machine. Port forwarding is done completely through {ExtraData}, but
8
+ # is a complicated enough procedure that this class was made to
9
+ # faciliate it.
10
+ #
11
+ # **Note:** After changing any forwarded ports, the entire VirtualBox
12
+ # process must be restarted completely for them to take effect. When
13
+ # working with the ruby library, this isn't so much of an issue, but
14
+ # if you have any VMs running, they must all be shut down and restarted.
15
+ #
16
+ # # Adding a new Forwarded Port
17
+ #
18
+ # Since forwarded ports rely on being part of a {VM}, we're going to
19
+ # assume that `vm` points to a {VM} which has already been found.
20
+ #
21
+ # port = VirtualBox::ForwardedPort.new
22
+ # port.name = "apache" # This can be anything
23
+ # port.guestport = 80
24
+ # port.hostport = 8080
25
+ # vm.forwarded_ports << port
26
+ # port.save # Or vm.save
27
+ #
28
+ # # Modifying an Existing Forwarded Port
29
+ #
30
+ # This is assuming that `vm` is a local variable storing a {VM} object
31
+ # which has already been found.
32
+ #
33
+ # vm.forwarded_ports.first.hostport = 1919
34
+ # vm.save
35
+ #
36
+ # # Deleting a Forwarded Port
37
+ #
38
+ # To delete a forwarded port, you simply destroy it like any other model:
39
+ #
40
+ # vm.forwarded_ports.first.destroy
41
+ #
42
+ # # Attributes and Relationships
43
+ #
44
+ # Properties of the model are exposed using standard ruby instance
45
+ # methods which are generated on the fly. Because of this, they are not listed
46
+ # below as available instance methods.
47
+ #
48
+ # These attributes can be accessed and modified via standard ruby-style
49
+ # `instance.attribute` and `instance.attribute=` methods. The attributes are
50
+ # listed below.
51
+ #
52
+ # Relationships are also accessed like attributes but can't be set. Instead,
53
+ # they are typically references to other objects such as an {AttachedDevice} which
54
+ # in turn have their own attributes which can be modified.
55
+ #
56
+ # ## Attributes
57
+ #
58
+ # This is copied directly from the class header, but lists all available
59
+ # attributes. If you don't understand what this means, read {Attributable}.
60
+ #
61
+ # attribute :parent, :readonly => true
62
+ # attribute :name
63
+ # attribute :instance, :default => "0"
64
+ # attribute :device, :default => "pcnet"
65
+ # attribute :protocol, :default => "TCP"
66
+ # attribute :guestport
67
+ # attribute :hostport
68
+ #
69
+ class ForwardedPort < AbstractModel
70
+ attribute :parent, :readonly => true, :property => false
71
+ attribute :parent_collection, :readonly => true, :property => false
72
+ attribute :name
73
+ attribute :instance, :default => "0"
74
+ attribute :device, :default => "pcnet"
75
+ attribute :protocol, :default => "TCP"
76
+ attribute :guestport
77
+ attribute :hostport
78
+
79
+ class << self
80
+ # Populates a relationship with another model.
81
+ #
82
+ # **This method typically won't be used except internally.**
83
+ #
84
+ # @return [Array<ForwardedPort>]
85
+ def populate_relationship(caller, data)
86
+ relation = Proxies::Collection.new(caller)
87
+
88
+ caller.extra_data.each do |key, value|
89
+ next unless key =~ /^(VBoxInternal\/Devices\/(.+?)\/(.+?)\/LUN#0\/Config\/(.+?)\/)Protocol$/i
90
+
91
+ port = new({
92
+ :parent => caller,
93
+ :parent_collection => relation,
94
+ :name => $4.to_s,
95
+ :instance => $3.to_s,
96
+ :device => $2.to_s,
97
+ :protocol => value,
98
+ :guestport => caller.extra_data["#{$1.to_s}GuestPort"],
99
+ :hostport => caller.extra_data["#{$1.to_s}HostPort"]
100
+ })
101
+
102
+ port.existing_record!
103
+
104
+ relation.push(port)
105
+ end
106
+
107
+ relation
108
+ end
109
+
110
+ # Saves the relationship. This simply calls {#save} on every
111
+ # member of the relationship.
112
+ #
113
+ # **This method typically won't be used except internally.**
114
+ def save_relationship(caller, data)
115
+ data.dup.each do |fp|
116
+ fp.save
117
+ end
118
+ end
119
+ end
120
+
121
+ # @param [Hash] data The initial attributes to populate.
122
+ def initialize(data={})
123
+ super()
124
+ populate_attributes(data) if !data.empty?
125
+ end
126
+
127
+ # Validates a forwarded port.
128
+ def validate
129
+ super
130
+
131
+ validates_presence_of :parent
132
+ validates_presence_of :name
133
+ validates_presence_of :guestport
134
+ validates_presence_of :hostport
135
+ end
136
+
137
+ # Retrieves the device for the forwarded port. This tries to "do the
138
+ # right thing" depending on the first NIC of the VM parent by either
139
+ # setting the forwarded port type to "pcnet" or "e1000." If the device
140
+ # was already set manually, this method will simply return that value
141
+ # instead.
142
+ #
143
+ # @return [String] Device type for the forwarded port
144
+ def device
145
+ # Return the current or default value if it is:
146
+ # * an existing record, since it was already mucked with, no need to
147
+ # modify it again
148
+ # * device setting changed, since we should return what the user set
149
+ # it to
150
+ # * If the parent is nil, since we can't infer the type without a parent
151
+ return read_attribute(:device) if !new_record? || device_changed? || parent.nil?
152
+
153
+ device_map = {
154
+ :Am79C970A => "pcnet",
155
+ :Am79C973 => "pcnet",
156
+ :I82540EM => "e1000",
157
+ :I82543GC => "e1000",
158
+ :I82545EM => "e1000"
159
+ }
160
+
161
+ return device_map[parent.network_adapters[0].adapter_type]
162
+ end
163
+
164
+ # Saves the forwarded port.
165
+ #
166
+ # @return [Boolean] True if command was successful, false otherwise.
167
+ def save
168
+ return true if !new_record? && !changed?
169
+ raise Exceptions::ValidationFailedException.new(errors) if !valid?
170
+
171
+ destroy if !new_record? && name_changed?
172
+
173
+ parent.extra_data["#{key_prefix}Protocol"] = protocol
174
+ parent.extra_data["#{key_prefix}GuestPort"] = guestport
175
+ parent.extra_data["#{key_prefix}HostPort"] = hostport
176
+ result = parent.extra_data.save
177
+
178
+ clear_dirty!
179
+ existing_record!
180
+
181
+ result
182
+ end
183
+
184
+ # Destroys the port forwarding mapping.
185
+ #
186
+ # @return [Boolean] True if command was successful, false otherwise.
187
+ def destroy
188
+ results = []
189
+
190
+ if !new_record?
191
+ results << parent.extra_data.delete("#{key_prefix(true)}Protocol")
192
+ results << parent.extra_data.delete("#{key_prefix(true)}GuestPort")
193
+ results << parent.extra_data.delete("#{key_prefix(true)}HostPort")
194
+
195
+ # Remove it from any collection
196
+ parent_collection.delete(self, true) if parent_collection
197
+
198
+ new_record!
199
+ end
200
+
201
+ results.empty? || results.all? { |o| o == true }
202
+ end
203
+
204
+ # Relationship callback when added to a collection. This is automatically
205
+ # called by any relationship collection when this object is added.
206
+ def added_to_relationship(proxy)
207
+ write_attribute(:parent, proxy.parent)
208
+ write_attribute(:parent_collection, proxy)
209
+ end
210
+
211
+ # Returns the prefix to be used for the extra data key. Forwarded ports
212
+ # are created by simply setting {ExtraData} on a {VM}. This class hides most
213
+ # of the inner workings of it, but it requires a common prefix. This method
214
+ # generates that.
215
+ #
216
+ # @return [String]
217
+ def key_prefix(old_name=false)
218
+ name_value = old_name && name_changed? ? name_was : name
219
+ "VBoxInternal\/Devices\/#{device}\/#{instance}\/LUN#0\/Config\/#{name_value}\/"
220
+ end
221
+ end
222
+ end
@@ -0,0 +1,102 @@
1
+ module VirtualBox
2
+ # Represents the VirtualBox main configuration file (VirtualBox.xml)
3
+ # which VirtualBox uses to keep track of all known virtual machines
4
+ # and images. This "global" configuration has many relationships which
5
+ # allow the user to retrieve a list of all VMs, media, global extra data,
6
+ # etc. Indeed, even methods like {VM.all} are implemented using this class.
7
+ #
8
+ # # Getting Global Data
9
+ #
10
+ # To retrieve the global data, use `Global.global`. This value is _cached_
11
+ # between calls, so subsequent calls will not go through the entire parsing
12
+ # process. To force a reload, set the `reload` parameter to true. Besides
13
+ # setting the parameter explicitly, some actions will implicitly force the
14
+ # global data to reload on the next call, such as saving a VM or destroying
15
+ # an image, for example.
16
+ #
17
+ # # Retrieve global data for the first time. This will parse all the
18
+ # # data.
19
+ # global_object = VirtualBox::Global.global
20
+ #
21
+ # # Subsequent calls are near-instant:
22
+ # VirtualBox::Global.global
23
+ #
24
+ # # Or we can choose to reload the data...
25
+ # reloaded_object = VirtualBox::Global.global(true)
26
+ #
27
+ # # Relationships
28
+ #
29
+ # While a global object doesn't have attributes, it does have many
30
+ # relationships. The relationships are listed below. If you don't
31
+ # understand this, read {Relatable}.
32
+ #
33
+ # relationship :vms, VM
34
+ # relationship :media, Media
35
+ # relationship :extra_data, ExtraData
36
+ # relationship :system_properties, :SystemProperties, :lazy => true
37
+ #
38
+ class Global < AbstractModel
39
+ attribute :lib, :readonly => true
40
+
41
+ relationship :vms, :VM, :lazy => true
42
+ relationship :media, :Media, :lazy => true
43
+ relationship :extra_data, :ExtraData, :lazy => true
44
+ relationship :system_properties, :SystemProperties, :lazy => true
45
+ relationship :host, :Host, :lazy => true
46
+ relationship :dhcp_servers, :DHCPServer, :lazy => true
47
+
48
+ @@global_data = nil
49
+
50
+ class << self
51
+ # Retrieves the global data. The return value of this call is cached,
52
+ # and can be reloaded by setting the `reload` parameter to true. Besides
53
+ # explicitly setting the parameter, some actions within the library
54
+ # force global to reload itself on the next call, such as saving a VM,
55
+ # or destroying an image.
56
+ #
57
+ # @param [Boolean] reload True if you want to force a reload of the data.
58
+ # @return [Global]
59
+ def global(reload=false)
60
+ if !@@global_data || reload
61
+ @@global_data = new(Lib.lib)
62
+ end
63
+
64
+ @@global_data
65
+ end
66
+
67
+ # Resets the global data singleton. This is used for testing purposes.
68
+ def reset!
69
+ @@global_data = nil
70
+ end
71
+ end
72
+
73
+ def initialize(lib)
74
+ write_attribute(:lib, lib)
75
+
76
+ # Required to load lazy relationships
77
+ existing_record!
78
+ end
79
+
80
+ def create_machine(name, type)
81
+ imachine = lib.virtualbox.create_machine(name, type)
82
+ lib.virtualbox.register_machine(imachine)
83
+ VirtualBox::VM.find(imachine.id)
84
+ end
85
+
86
+ def load_relationship(name)
87
+ # "Lazy loaded" associations table. These associate the relationship
88
+ # with the data it needs to load. The data is wrapped in lambdas so
89
+ # that the evaluation doesn't occur unless necessary.
90
+ relationships = {
91
+ :vms => lambda { lib.virtualbox.machines },
92
+ :media => lambda { lib },
93
+ :extra_data => lambda { lib.virtualbox },
94
+ :system_properties => lambda { lib.virtualbox.system_properties },
95
+ :host => lambda { lib.virtualbox.host },
96
+ :dhcp_servers => lambda { lib.virtualbox.dhcp_servers }
97
+ }
98
+
99
+ populate_relationship(name, relationships[name].call)
100
+ end
101
+ end
102
+ end
@@ -0,0 +1,116 @@
1
+ module VirtualBox
2
+ # Represents guest properties which can be read and set per virtual
3
+ # machine as long as the guest additions are running in the VM.
4
+ #
5
+ # A number of properties are predefined by VirtualBox for retrieving
6
+ # information about the VM such as operating system, guest additions
7
+ # version, users currently logged in, network statistics (including ip
8
+ # addresses), and more. For more information, read the Guest Properties
9
+ # section under the Guest Additions chapter (currently chapter 4) in
10
+ # the VirtualBox manual.
11
+ #
12
+ # Guest Properties on a Virtual Machine
13
+ #
14
+ # Setting a guest property on a virtual machine is easy. All {VM} objects
15
+ # have a `guest_property` relationship which is just a simple ruby hash,
16
+ # so you can treat it like one! Once the data is set, simply saving the VM
17
+ # will save the guest property. An example below:
18
+ #
19
+ # vm = VirtualBox::VM.find("FooVM")
20
+ # vm.guest_property["/Foo/Bar"] = "yes"
21
+ # vm.save
22
+ #
23
+ # Now, let's say you open up the VM again some other time:
24
+ #
25
+ # vm = VirtualBox::VM.find("FooVM")
26
+ # puts vm.guest_property["/Foo/Bar"]
27
+ #
28
+ # It acts just like a hash!
29
+ #
30
+ class GuestProperty < Hash
31
+ include AbstractModel::Dirty
32
+
33
+ attr_accessor :parent
34
+ attr_reader :interface
35
+
36
+ class << self
37
+ # Populates a relationship with another model.
38
+ #
39
+ # **This method typically won't be used except internally.**
40
+ #
41
+ # @return [Array<GuestProperty>]
42
+ def populate_relationship(caller, interface)
43
+ data = new(caller, interface)
44
+
45
+ keys, values, timestamps, flags = interface.enumerate_guest_properties
46
+ keys.each_with_index do |key, index|
47
+ data[key] = values[index]
48
+ end
49
+
50
+ data.clear_dirty!
51
+ data
52
+ end
53
+
54
+ # Saves the relationship. This simply calls {#save} on every
55
+ # member of the relationship.
56
+ #
57
+ # **This method typically won't be used except internally.**
58
+ def save_relationship(caller, data)
59
+ data.save
60
+ end
61
+ end
62
+
63
+ # Initializes a guest property object.
64
+ #
65
+ # @param [Hash] data Initial attributes to populate.
66
+ def initialize(parent, interface)
67
+ @parent = parent
68
+ @interface = interface
69
+ end
70
+
71
+ # Set a guest property key-value pair. Overrides ruby hash implementation
72
+ # to set dirty state. Otherwise, behaves the same way.
73
+ def []=(key,value)
74
+ set_dirty!(key, self[key], value)
75
+ super
76
+ end
77
+
78
+ # Saves guest properties. This method does the same thing for both new
79
+ # and existing guest properties, since virtualbox will overwrite old data or
80
+ # create it if it doesn't exist.
81
+ def save
82
+ changes.each do |key, value|
83
+ unless virtualbox_key?(key)
84
+ interface.set_guest_property_value(key.to_s, value[1].to_s)
85
+
86
+ clear_dirty!(key)
87
+
88
+ if value[1].nil?
89
+ # Remove the key from the hash altogether
90
+ hash_delete(key.to_s)
91
+ end
92
+ end
93
+ end
94
+ end
95
+
96
+ # Alias away the old delete method so its still accessible somehow
97
+ alias :hash_delete :delete
98
+
99
+ # Deletes the specified extra data.
100
+ #
101
+ # @param [String] key The extra data key to delete
102
+ def delete(key)
103
+ unless virtualbox_key?(key)
104
+ interface.set_guest_property_value(key.to_s, nil)
105
+ hash_delete(key.to_s)
106
+ end
107
+ end
108
+
109
+ # Determine if a key is one set by VirtualBox
110
+ #
111
+ # **This method typically won't be used except internally.**
112
+ def virtualbox_key?(key)
113
+ key =~ /^\/VirtualBox/
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,246 @@
1
+ module VirtualBox
2
+ # Represents a hard disk which is registered with VirtualBox.
3
+ #
4
+ # # Finding a Hard Drive
5
+ #
6
+ # Hard drives can be found use {HardDrive.all} and {HardDrive.find}, which
7
+ # find all or a specific hard drive, respectively. Example below:
8
+ #
9
+ # VirtualBox::HardDrive.all
10
+ #
11
+ # Or use find with the UUID of the HardDrive:
12
+ #
13
+ # VirtualBox::HardDrive.find("4a896f0b-b3a3-4dec-8c26-8406c6fccd6e")
14
+ #
15
+ # # Creating a Hard Drive
16
+ #
17
+ # Hard Drives can be created by intilizing an empty hard drive, assigning
18
+ # values to the necessary attributes, and calling save on the object.
19
+ # Below is a simple example of how this works:
20
+ #
21
+ # hd = VirtualBox::HardDrive.new
22
+ # hd.format = "VDI" # Or any format list with `VBoxManage list hddbackends`
23
+ # hd.location = "foo.vdi"
24
+ # hd.size = 2400 # in megabytes
25
+ # hd.save
26
+ #
27
+ # # You can now access other attributes, since its saved:
28
+ # hd.uuid
29
+ # hd.location # will return a full path now
30
+ #
31
+ # # Destroying Hard Drives
32
+ #
33
+ # Hard drives can also be deleted. **This operation is not reversable**.
34
+ #
35
+ # hd = VirtualBox::HardDrive.find("...")
36
+ # hd.destroy
37
+ #
38
+ # This will only unregister the Hard Drive from VirtualBox and will not destroy
39
+ # the storage space on the disk. To destroy the storage space, pass `true` to
40
+ # the destroy method, example:
41
+ #
42
+ # hd.destroy(true)
43
+ #
44
+ # # Cloning Hard Drives
45
+ #
46
+ # Hard Drives can just as easily be cloned as they can be created or destroyed.
47
+ #
48
+ # hd = VirtualBox::HardDrive.find("...")
49
+ # cloned_hd = hd.clone("bar.vdi")
50
+ #
51
+ # In addition to simply cloning hard drives, this command can be used to
52
+ # clone to a different format. If the format is not passed in (as with the
53
+ # the above example, the system default format will be used). example:
54
+ #
55
+ # hd = VirtualBox::HardDrive.find("...")
56
+ # hd.clone("bar.vmdk", "VMDK") # Will clone and convert to VMDK format
57
+ #
58
+ # # Attributes
59
+ #
60
+ # Properties of the model are exposed using standard ruby instance
61
+ # methods which are generated on the fly. Because of this, they are not listed
62
+ # below as available instance methods.
63
+ #
64
+ # These attributes can be accessed and modified via standard ruby-style
65
+ # `instance.attribute` and `instance.attribute=` methods. The attributes are
66
+ # listed below. If you aren't sure what this means or you can't understand
67
+ # why the below is listed, please read {Attributable}.
68
+ #
69
+ # attribute :format, :default => "VDI"
70
+ # attribute :location
71
+ # attribute :logical_size
72
+ # attribute :physical_size, :readonly => true, :property => :size
73
+ #
74
+ # There are more attributes on the {Medium} model, which {HardDrive} inherits
75
+ # from.
76
+ #
77
+ class HardDrive < Medium
78
+ include ByteNormalizer
79
+
80
+ attribute :format, :default => "VDI"
81
+ attribute :location
82
+ attribute :logical_size
83
+ attribute :physical_size, :readonly => true, :property => :size
84
+
85
+ class << self
86
+ # Returns an array of all available hard drives as HardDrive
87
+ # objects.
88
+ #
89
+ # @return [Array<HardDrive>]
90
+ def all
91
+ Global.global(true).media.hard_drives
92
+ end
93
+
94
+ # Finds one specific hard drive by UUID. If the hard drive
95
+ # can not be found, will return `nil`.
96
+ #
97
+ # @param [String] id The UUID of the hard drive
98
+ # @return [HardDrive]
99
+ def find(id)
100
+ all.detect { |hd| hd.uuid == id }
101
+ end
102
+
103
+ # Override of {Medium.device_type}.
104
+ def device_type
105
+ :hard_disk
106
+ end
107
+ end
108
+
109
+ # Overwrite the AbstractModel initialize to make the imedium parameter
110
+ # optional so that new Hard Drives can be created
111
+ def initialize(imedium = nil)
112
+ super if imedium
113
+ end
114
+
115
+ # Custom getter to convert the physical size from bytes to megabytes.
116
+ def physical_size
117
+ bytes_to_megabytes(read_attribute(:physical_size))
118
+ end
119
+
120
+ # Get an array of machines attached to this Virtual Machine
121
+ def machines
122
+ interface.machine_ids.collect { |id| VirtualBox::VM.find(id) }
123
+ end
124
+
125
+ # Validates a hard drive for the minimum attributes required to
126
+ # create or save.
127
+ def validate
128
+ super
129
+
130
+ medium_formats = Global.global.system_properties.medium_formats.collect { |mf| mf.id }
131
+ validates_inclusion_of :format, :in => medium_formats, :message => "must be one of the following: #{medium_formats.join(', ')}."
132
+
133
+ validates_presence_of :location
134
+
135
+ max_vdi_size = Global.global.system_properties.max_vdi_size
136
+ validates_inclusion_of :logical_size, :in => (0..max_vdi_size), :message => "must be between 0 and #{max_vdi_size}."
137
+ end
138
+
139
+ # Creates a new {COM::Interface::Medium} instance. This simply creates
140
+ # the new {COM::Interface::Medium} structure. It does not (and shouldn't)
141
+ # create the storage space on the host system. See the create method for
142
+ # an example on to create the storage space.
143
+ #
144
+ # @param [String] outputfile The output file. This can be a full path
145
+ # or just a filename. If its just a filename, it will be placed in
146
+ # the default hard drives directory. Should not be present already.
147
+ # @param [String] format The format to convert to. If not present, the
148
+ # systems default will be used.
149
+ # @return [COM::Interface::Medium] The new {COM::Interface::Medium} instance
150
+ # or will raise a {Exceptions::MediumCreationFailedException} on failure.
151
+ def create_hard_disk_medium(outputfile, format = nil)
152
+ # Get main VirtualBox object
153
+ virtualbox = Lib.lib.virtualbox
154
+
155
+ # Assign the default format if it isn't set yet
156
+ format ||= virtualbox.system_properties.default_hard_disk_format
157
+
158
+ # Expand path relative to the default hard disk folder. This allows
159
+ # filenames to exist in the default folder while full paths will use
160
+ # the paths specified.
161
+ outputfile = File.expand_path(outputfile, virtualbox.system_properties.default_hard_disk_folder)
162
+
163
+ # If the outputfile path is in use by another Hard Drive, lets fail
164
+ # now with a meaningful exception rather than simply return a nil
165
+ raise Exceptions::MediumLocationInUseException.new(outputfile) if File.exist?(outputfile)
166
+
167
+ # Create the new {COM::Interface::Medium} instance.
168
+ new_medium = virtualbox.create_hard_disk(format, outputfile)
169
+
170
+ # Raise an error if the creation of the {COM::Interface::Medium}
171
+ # instance failed
172
+ raise Exceptions::MediumCreationFailedException.new unless new_medium
173
+
174
+ # Return the new {COM::Interface::Medium} instance.
175
+ new_medium
176
+ end
177
+
178
+ # Clone hard drive, possibly also converting formats. All formats
179
+ # supported by your local VirtualBox installation are supported
180
+ # here. If no format is specified, the systems default will be used.
181
+ #
182
+ # @param [String] outputfile The output file. This can be a full path
183
+ # or just a filename. If its just a filename, it will be placed in
184
+ # the default hard drives directory. Should not be present already.
185
+ # @param [String] format The format to convert to. If not present, the
186
+ # systems default will be used.
187
+ # @return [HardDrive] The new, cloned hard drive, or nil on failure.
188
+ def clone(outputfile, format = nil)
189
+ # Create the new Hard Disk medium
190
+ new_medium = create_hard_disk_medium(outputfile, format)
191
+
192
+ # Clone the current drive onto the new Hard Disk medium
193
+ interface.clone_to(new_medium, :standard, nil).wait_for_completion(-1)
194
+
195
+ # Locate the newly cloned hard drive
196
+ self.class.find(new_medium.id) if new_medium.respond_to?(:id)
197
+ end
198
+
199
+ # Creates a new hard drive.
200
+ #
201
+ # **This method should NEVER be called. Call {#save} instead.**
202
+ #
203
+ # @return [Boolean] True if command was successful, false otherwise.
204
+ def create
205
+ return false unless new_record?
206
+ raise Exceptions::ValidationFailedException.new(errors) if !valid?
207
+
208
+ # Create the new Hard Disk medium
209
+ new_medium = create_hard_disk_medium(location, format)
210
+
211
+ # Create the storage on the host system
212
+ new_medium.create_base_storage(logical_size, :standard).wait_for_completion(-1)
213
+
214
+ # Update the current Hard Drive instance with the uuid and
215
+ # other attributes assigned after storage was written
216
+ write_attribute(:interface, new_medium)
217
+ initialize_attributes(new_medium)
218
+
219
+ # If the uuid is present, then everything worked
220
+ uuid && !uuid.to_s.empty?
221
+ end
222
+
223
+ # Saves the hard drive object. If the hard drive is new,
224
+ # this will create a new hard drive. Otherwise, it will
225
+ # save any other details about the existing hard drive.
226
+ #
227
+ # Currently, **saving existing hard drives does nothing**.
228
+ # This is a limitation of VirtualBox, rather than the library itself.
229
+ #
230
+ # @return [Boolean] True if command was successful, false otherwise.
231
+ def save
232
+ return true if !new_record? && !changed?
233
+ raise Exceptions::ValidationFailedException.new(errors) if !valid?
234
+
235
+ if new_record?
236
+ create # Create a new hard drive
237
+ else
238
+ # Mediums like Hard Drives are not updatable, they need to be recreated
239
+ # Because Hard Drives contain info and paritions, it's easier to error
240
+ # out now than try and do some complicated logic
241
+ msg = "Hard Drives cannot be updated. You need to create one from scratch."
242
+ raise Exceptions::MediumNotUpdatableException.new(msg)
243
+ end
244
+ end
245
+ end
246
+ end