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.
- data/.gitignore +8 -0
- data/.yardopts +3 -0
- data/Gemfile +16 -0
- data/LICENSE +19 -0
- data/Rakefile +33 -0
- data/Readme.md +70 -0
- data/docs/GettingStarted.md +196 -0
- data/docs/WhatsNew.md +12 -0
- data/features/README.md +33 -0
- data/features/global.feature +19 -0
- data/features/global_extra_data.feature +27 -0
- data/features/step_definitions/abstract_model_steps.rb +39 -0
- data/features/step_definitions/extra_data_steps.rb +36 -0
- data/features/step_definitions/global_steps.rb +29 -0
- data/features/step_definitions/nat_engine_steps.rb +76 -0
- data/features/step_definitions/network_adapter_steps.rb +38 -0
- data/features/step_definitions/shared_folder_steps.rb +76 -0
- data/features/step_definitions/snapshot_steps.rb +74 -0
- data/features/step_definitions/storage_controller_steps.rb +16 -0
- data/features/step_definitions/virtualbox_steps.rb +17 -0
- data/features/step_definitions/vm_steps.rb +50 -0
- data/features/support/env.rb +61 -0
- data/features/support/helpers.rb +38 -0
- data/features/support/hooks.rb +30 -0
- data/features/support/ordered_hash.rb +49 -0
- data/features/support/vboxmanage.rb +191 -0
- data/features/version.feature +16 -0
- data/features/vm.feature +13 -0
- data/features/vm_bios.feature +29 -0
- data/features/vm_cpu.feature +29 -0
- data/features/vm_extra_data.feature +35 -0
- data/features/vm_hw_virt.feature +29 -0
- data/features/vm_nat_engine.feature +57 -0
- data/features/vm_network_adapters.feature +27 -0
- data/features/vm_shared_folders.feature +42 -0
- data/features/vm_snapshots.feature +29 -0
- data/features/vm_storage_controllers.feature +11 -0
- data/lib/virtualbox.rb +11 -0
- data/lib/virtualbox/abstract_model.rb +281 -0
- data/lib/virtualbox/abstract_model/attributable.rb +290 -0
- data/lib/virtualbox/abstract_model/dirty.rb +177 -0
- data/lib/virtualbox/abstract_model/interface_attributes.rb +98 -0
- data/lib/virtualbox/abstract_model/relatable.rb +332 -0
- data/lib/virtualbox/abstract_model/validatable.rb +167 -0
- data/lib/virtualbox/abstract_model/version_matcher.rb +35 -0
- data/lib/virtualbox/appliance.rb +62 -0
- data/lib/virtualbox/audio_adapter.rb +52 -0
- data/lib/virtualbox/bios.rb +50 -0
- data/lib/virtualbox/com.rb +23 -0
- data/lib/virtualbox/com/abstract_enum.rb +43 -0
- data/lib/virtualbox/com/abstract_implementer.rb +45 -0
- data/lib/virtualbox/com/abstract_interface.rb +167 -0
- data/lib/virtualbox/com/base_interface.rb +38 -0
- data/lib/virtualbox/com/ffi/interface.rb +150 -0
- data/lib/virtualbox/com/ffi/interfaces.rb +54 -0
- data/lib/virtualbox/com/ffi/util.rb +119 -0
- data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
- data/lib/virtualbox/com/ffi_interface.rb +96 -0
- data/lib/virtualbox/com/implementer/base.rb +59 -0
- data/lib/virtualbox/com/implementer/ffi.rb +361 -0
- data/lib/virtualbox/com/implementer/mscom.rb +175 -0
- data/lib/virtualbox/com/implementer/nil.rb +10 -0
- data/lib/virtualbox/com/interface/3.1.x/access_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/appliance.rb +22 -0
- data/lib/virtualbox/com/interface/3.1.x/audio_adapter.rb +15 -0
- data/lib/virtualbox/com/interface/3.1.x/audio_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/audio_driver_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/bios_boot_menu_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/bios_settings.rb +21 -0
- data/lib/virtualbox/com/interface/3.1.x/clipboard_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/console.rb +50 -0
- data/lib/virtualbox/com/interface/3.1.x/cpu_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/device_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/dhcp_server.rb +22 -0
- data/lib/virtualbox/com/interface/3.1.x/firmware_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/guest_os_type.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/host.rb +42 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface.rb +30 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface_medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface_status.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/host_network_interface_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/host_usb_device.rb +13 -0
- data/lib/virtualbox/com/interface/3.1.x/host_usb_device_filter.rb +13 -0
- data/lib/virtualbox/com/interface/3.1.x/hw_virt_ex_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/machine.rb +105 -0
- data/lib/virtualbox/com/interface/3.1.x/machine_state.rb +14 -0
- data/lib/virtualbox/com/interface/3.1.x/medium.rb +50 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_attachment.rb +18 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_format.rb +18 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/medium_variant.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/network_adapter.rb +30 -0
- data/lib/virtualbox/com/interface/3.1.x/network_adapter_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/network_attachment_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/nsiexception.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/nsisupports.rb +15 -0
- data/lib/virtualbox/com/interface/3.1.x/parallel_port.rb +17 -0
- data/lib/virtualbox/com/interface/3.1.x/port_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/progress.rb +63 -0
- data/lib/virtualbox/com/interface/3.1.x/serial_port.rb +19 -0
- data/lib/virtualbox/com/interface/3.1.x/session.rb +18 -0
- data/lib/virtualbox/com/interface/3.1.x/session_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/session_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/shared_folder.rb +17 -0
- data/lib/virtualbox/com/interface/3.1.x/snapshot.rb +20 -0
- data/lib/virtualbox/com/interface/3.1.x/storage_bus.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/storage_controller.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/storage_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/system_properties.rb +37 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_controller.rb +20 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device.rb +24 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device_filter.rb +23 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device_filter_action.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/usb_device_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_box_error_info.rb +17 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_system_description.rb +19 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_type.rb +14 -0
- data/lib/virtualbox/com/interface/3.1.x/virtual_system_description_value_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/virtualbox.rb +67 -0
- data/lib/virtualbox/com/interface/3.1.x/vrdp_auth_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.1.x/vrdp_server.rb +19 -0
- data/lib/virtualbox/com/interface/3.2.x/access_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/appliance.rb +22 -0
- data/lib/virtualbox/com/interface/3.2.x/audio_adapter.rb +15 -0
- data/lib/virtualbox/com/interface/3.2.x/audio_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/audio_driver_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/bios_boot_menu_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/bios_settings.rb +21 -0
- data/lib/virtualbox/com/interface/3.2.x/clipboard_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/console.rb +50 -0
- data/lib/virtualbox/com/interface/3.2.x/cpu_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/device_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/dhcp_server.rb +22 -0
- data/lib/virtualbox/com/interface/3.2.x/firmware_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/guest.rb +13 -0
- data/lib/virtualbox/com/interface/3.2.x/guest_os_type.rb +33 -0
- data/lib/virtualbox/com/interface/3.2.x/host.rb +43 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface.rb +30 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface_medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface_status.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/host_network_interface_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/host_usb_device.rb +13 -0
- data/lib/virtualbox/com/interface/3.2.x/host_usb_device_filter.rb +13 -0
- data/lib/virtualbox/com/interface/3.2.x/hw_virt_ex_property_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/keyboard_hid_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/machine.rb +118 -0
- data/lib/virtualbox/com/interface/3.2.x/machine_state.rb +14 -0
- data/lib/virtualbox/com/interface/3.2.x/medium.rb +51 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_attachment.rb +18 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_format.rb +18 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/medium_variant.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/nat_alias_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/nat_engine.rb +27 -0
- data/lib/virtualbox/com/interface/3.2.x/nat_protocol.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/network_adapter.rb +34 -0
- data/lib/virtualbox/com/interface/3.2.x/network_adapter_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/network_attachment_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/nsiexception.rb +23 -0
- data/lib/virtualbox/com/interface/3.2.x/nsisupports.rb +15 -0
- data/lib/virtualbox/com/interface/3.2.x/parallel_port.rb +17 -0
- data/lib/virtualbox/com/interface/3.2.x/pointing_hid_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/port_mode.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/progress.rb +63 -0
- data/lib/virtualbox/com/interface/3.2.x/serial_port.rb +19 -0
- data/lib/virtualbox/com/interface/3.2.x/session.rb +18 -0
- data/lib/virtualbox/com/interface/3.2.x/session_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/session_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/shared_folder.rb +17 -0
- data/lib/virtualbox/com/interface/3.2.x/snapshot.rb +20 -0
- data/lib/virtualbox/com/interface/3.2.x/storage_bus.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/storage_controller.rb +24 -0
- data/lib/virtualbox/com/interface/3.2.x/storage_controller_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/system_properties.rb +42 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_controller.rb +21 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device.rb +24 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device_filter.rb +23 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device_filter_action.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/usb_device_state.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_box_error_info.rb +17 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_system_description.rb +19 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_type.rb +14 -0
- data/lib/virtualbox/com/interface/3.2.x/virtual_system_description_value_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/virtualbox.rb +67 -0
- data/lib/virtualbox/com/interface/3.2.x/vrdp_auth_type.rb +11 -0
- data/lib/virtualbox/com/interface/3.2.x/vrdp_server.rb +21 -0
- data/lib/virtualbox/com/mscom_interface.rb +44 -0
- data/lib/virtualbox/com/nil_interface.rb +7 -0
- data/lib/virtualbox/com/util.rb +32 -0
- data/lib/virtualbox/cpu.rb +61 -0
- data/lib/virtualbox/dhcp_server.rb +89 -0
- data/lib/virtualbox/dvd.rb +27 -0
- data/lib/virtualbox/exceptions.rb +39 -0
- data/lib/virtualbox/ext/byte_normalizer.rb +17 -0
- data/lib/virtualbox/ext/glob_loader.rb +22 -0
- data/lib/virtualbox/ext/logger.rb +38 -0
- data/lib/virtualbox/ext/platform.rb +27 -0
- data/lib/virtualbox/ext/subclass_listing.rb +24 -0
- data/lib/virtualbox/extra_data.rb +127 -0
- data/lib/virtualbox/forwarded_port.rb +222 -0
- data/lib/virtualbox/global.rb +102 -0
- data/lib/virtualbox/guest_property.rb +116 -0
- data/lib/virtualbox/hard_drive.rb +246 -0
- data/lib/virtualbox/host.rb +71 -0
- data/lib/virtualbox/host_network_interface.rb +137 -0
- data/lib/virtualbox/hw_virtualization.rb +63 -0
- data/lib/virtualbox/lib.rb +84 -0
- data/lib/virtualbox/media.rb +20 -0
- data/lib/virtualbox/medium.rb +145 -0
- data/lib/virtualbox/medium_attachment.rb +61 -0
- data/lib/virtualbox/nat_engine.rb +71 -0
- data/lib/virtualbox/nat_forwarded_port.rb +171 -0
- data/lib/virtualbox/network_adapter.rb +166 -0
- data/lib/virtualbox/proxies/collection.rb +57 -0
- data/lib/virtualbox/shared_folder.rb +220 -0
- data/lib/virtualbox/snapshot.rb +185 -0
- data/lib/virtualbox/storage_controller.rb +160 -0
- data/lib/virtualbox/system_properties.rb +74 -0
- data/lib/virtualbox/usb_controller.rb +59 -0
- data/lib/virtualbox/usb_device_filter.rb +74 -0
- data/lib/virtualbox/version.rb +36 -0
- data/lib/virtualbox/virtual_system_description.rb +47 -0
- data/lib/virtualbox/vm.rb +684 -0
- data/lib/virtualbox/vrdp_server.rb +59 -0
- data/test/test_helper.rb +18 -0
- data/test/virtualbox/abstract_model/attributable_test.rb +269 -0
- data/test/virtualbox/abstract_model/dirty_test.rb +83 -0
- data/test/virtualbox/abstract_model/interface_attributes_test.rb +194 -0
- data/test/virtualbox/abstract_model/relatable_test.rb +348 -0
- data/test/virtualbox/abstract_model/validatable_test.rb +308 -0
- data/test/virtualbox/abstract_model/version_matcher_test.rb +41 -0
- data/test/virtualbox/abstract_model_test.rb +462 -0
- data/test/virtualbox/appliance_test.rb +159 -0
- data/test/virtualbox/audio_adapter_test.rb +83 -0
- data/test/virtualbox/bios_test.rb +83 -0
- data/test/virtualbox/com/abstract_enum_test.rb +49 -0
- data/test/virtualbox/com/abstract_implementer_test.rb +40 -0
- data/test/virtualbox/com/abstract_interface_test.rb +140 -0
- data/test/virtualbox/com/ffi/interface_test.rb +249 -0
- data/test/virtualbox/com/ffi/util_test.rb +108 -0
- data/test/virtualbox/com/ffi_interface_test.rb +42 -0
- data/test/virtualbox/com/implementer/base_test.rb +38 -0
- data/test/virtualbox/com/implementer/ffi_test.rb +527 -0
- data/test/virtualbox/com/implementer/mscom_test.rb +247 -0
- data/test/virtualbox/com/mscom_interface_test.rb +17 -0
- data/test/virtualbox/com/util_test.rb +17 -0
- data/test/virtualbox/cpu_test.rb +103 -0
- data/test/virtualbox/dhcp_server_test.rb +165 -0
- data/test/virtualbox/dvd_test.rb +28 -0
- data/test/virtualbox/ext/byte_normalizer_test.rb +34 -0
- data/test/virtualbox/ext/platform_test.rb +50 -0
- data/test/virtualbox/ext/subclass_listing_test.rb +25 -0
- data/test/virtualbox/extra_data_test.rb +155 -0
- data/test/virtualbox/forwarded_port_test.rb +286 -0
- data/test/virtualbox/global_test.rb +46 -0
- data/test/virtualbox/hard_drive_test.rb +141 -0
- data/test/virtualbox/host_network_interface_test.rb +254 -0
- data/test/virtualbox/host_test.rb +94 -0
- data/test/virtualbox/hw_virtualization_test.rb +103 -0
- data/test/virtualbox/lib_test.rb +93 -0
- data/test/virtualbox/medium_attachment_test.rb +147 -0
- data/test/virtualbox/medium_test.rb +192 -0
- data/test/virtualbox/nat_engine_test.rb +106 -0
- data/test/virtualbox/nat_forwarded_port_test.rb +222 -0
- data/test/virtualbox/network_adapter_test.rb +191 -0
- data/test/virtualbox/proxies/collection_test.rb +102 -0
- data/test/virtualbox/shared_folder_test.rb +219 -0
- data/test/virtualbox/snapshot_test.rb +231 -0
- data/test/virtualbox/storage_controller_test.rb +197 -0
- data/test/virtualbox/system_properties_test.rb +87 -0
- data/test/virtualbox/usb_controller_test.rb +112 -0
- data/test/virtualbox/usb_device_filter_test.rb +93 -0
- data/test/virtualbox/version_test.rb +59 -0
- data/test/virtualbox/virtual_system_description_test.rb +61 -0
- data/test/virtualbox/vm_test.rb +637 -0
- data/test/virtualbox/vrdp_server_test.rb +83 -0
- data/test/virtualbox_test.rb +11 -0
- data/virtualbox.gemspec +25 -0
- 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
|