virtualbox 0.5.4 → 0.6.0
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 +2 -1
- data/Gemfile +1 -1
- data/Rakefile +1 -1
- data/Readme.md +5 -21
- data/VERSION +1 -1
- data/docs/WhatsNew.md +9 -47
- data/lib/virtualbox.rb +7 -30
- data/lib/virtualbox/abstract_model.rb +25 -5
- data/lib/virtualbox/abstract_model/attributable.rb +5 -1
- data/lib/virtualbox/abstract_model/dirty.rb +2 -0
- data/lib/virtualbox/abstract_model/interface_attributes.rb +96 -0
- data/lib/virtualbox/abstract_model/relatable.rb +19 -8
- data/lib/virtualbox/appliance.rb +59 -0
- data/lib/virtualbox/audio_adapter.rb +44 -0
- data/lib/virtualbox/bios.rb +44 -0
- data/lib/virtualbox/com.rb +23 -0
- data/lib/virtualbox/com/abstract_enum.rb +42 -0
- data/lib/virtualbox/com/abstract_implementer.rb +43 -0
- data/lib/virtualbox/com/abstract_interface.rb +165 -0
- data/lib/virtualbox/com/ffi/interface.rb +141 -0
- data/lib/virtualbox/com/ffi/interfaces.rb +42 -0
- data/lib/virtualbox/com/ffi/util.rb +101 -0
- data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
- data/lib/virtualbox/com/ffi_interface.rb +65 -0
- data/lib/virtualbox/com/implementer/base.rb +52 -0
- data/lib/virtualbox/com/implementer/ffi.rb +350 -0
- data/lib/virtualbox/com/implementer/mscom.rb +165 -0
- data/lib/virtualbox/com/implementer/nil.rb +10 -0
- data/lib/virtualbox/com/interface/appliance.rb +20 -0
- data/lib/virtualbox/com/interface/audio_adapter.rb +13 -0
- data/lib/virtualbox/com/interface/audio_controller_type.rb +9 -0
- data/lib/virtualbox/com/interface/audio_driver_type.rb +9 -0
- data/lib/virtualbox/com/interface/bios_boot_menu_mode.rb +9 -0
- data/lib/virtualbox/com/interface/bios_settings.rb +19 -0
- data/lib/virtualbox/com/interface/clipboard_mode.rb +9 -0
- data/lib/virtualbox/com/interface/console.rb +48 -0
- data/lib/virtualbox/com/interface/cpu_property_type.rb +9 -0
- data/lib/virtualbox/com/interface/device_type.rb +9 -0
- data/lib/virtualbox/com/interface/dhcp_server.rb +20 -0
- data/lib/virtualbox/com/interface/firmware_type.rb +9 -0
- data/lib/virtualbox/com/interface/guest_os_type.rb +21 -0
- data/lib/virtualbox/com/interface/host.rb +40 -0
- data/lib/virtualbox/com/interface/host_network_interface.rb +28 -0
- data/lib/virtualbox/com/interface/host_network_interface_medium_type.rb +9 -0
- data/lib/virtualbox/com/interface/host_network_interface_status.rb +9 -0
- data/lib/virtualbox/com/interface/host_network_interface_type.rb +9 -0
- data/lib/virtualbox/com/interface/host_usb_device.rb +11 -0
- data/lib/virtualbox/com/interface/host_usb_device_filter.rb +11 -0
- data/lib/virtualbox/com/interface/hw_virt_ex_property_type.rb +9 -0
- data/lib/virtualbox/com/interface/machine.rb +103 -0
- data/lib/virtualbox/com/interface/machine_state.rb +12 -0
- data/lib/virtualbox/com/interface/medium.rb +48 -0
- data/lib/virtualbox/com/interface/medium_attachment.rb +16 -0
- data/lib/virtualbox/com/interface/medium_format.rb +16 -0
- data/lib/virtualbox/com/interface/medium_state.rb +9 -0
- data/lib/virtualbox/com/interface/medium_type.rb +9 -0
- data/lib/virtualbox/com/interface/medium_variant.rb +9 -0
- data/lib/virtualbox/com/interface/network_adapter.rb +28 -0
- data/lib/virtualbox/com/interface/network_adapter_type.rb +9 -0
- data/lib/virtualbox/com/interface/network_attachment_type.rb +9 -0
- data/lib/virtualbox/com/interface/nsiexception.rb +21 -0
- data/lib/virtualbox/com/interface/nsisupports.rb +13 -0
- data/lib/virtualbox/com/interface/parallel_port.rb +15 -0
- data/lib/virtualbox/com/interface/port_mode.rb +9 -0
- data/lib/virtualbox/com/interface/progress.rb +58 -0
- data/lib/virtualbox/com/interface/serial_port.rb +17 -0
- data/lib/virtualbox/com/interface/session.rb +16 -0
- data/lib/virtualbox/com/interface/session_state.rb +9 -0
- data/lib/virtualbox/com/interface/session_type.rb +9 -0
- data/lib/virtualbox/com/interface/shared_folder.rb +15 -0
- data/lib/virtualbox/com/interface/snapshot.rb +18 -0
- data/lib/virtualbox/com/interface/storage_bus.rb +9 -0
- data/lib/virtualbox/com/interface/storage_controller.rb +21 -0
- data/lib/virtualbox/com/interface/storage_controller_type.rb +9 -0
- data/lib/virtualbox/com/interface/system_properties.rb +35 -0
- data/lib/virtualbox/com/interface/usb_controller.rb +18 -0
- data/lib/virtualbox/com/interface/usb_device.rb +22 -0
- data/lib/virtualbox/com/interface/usb_device_filter.rb +21 -0
- data/lib/virtualbox/com/interface/usb_device_filter_action.rb +9 -0
- data/lib/virtualbox/com/interface/usb_device_state.rb +9 -0
- data/lib/virtualbox/com/interface/virtual_box_error_info.rb +15 -0
- data/lib/virtualbox/com/interface/virtual_system_description.rb +17 -0
- data/lib/virtualbox/com/interface/virtual_system_description_type.rb +12 -0
- data/lib/virtualbox/com/interface/virtual_system_description_value_type.rb +9 -0
- data/lib/virtualbox/com/interface/virtualbox.rb +54 -0
- data/lib/virtualbox/com/interface/vrdp_auth_type.rb +9 -0
- data/lib/virtualbox/com/interface/vrdp_server.rb +17 -0
- data/lib/virtualbox/com/mscom_interface.rb +22 -0
- data/lib/virtualbox/com/util.rb +18 -0
- data/lib/virtualbox/dvd.rb +7 -94
- data/lib/virtualbox/exceptions.rb +24 -0
- data/lib/virtualbox/ext/glob_loader.rb +22 -0
- data/lib/virtualbox/ext/logger.rb +38 -0
- data/lib/virtualbox/ext/platform.rb +1 -1
- data/lib/virtualbox/extra_data.rb +25 -37
- data/lib/virtualbox/forwarded_port.rb +35 -13
- data/lib/virtualbox/global.rb +22 -80
- data/lib/virtualbox/hard_drive.rb +30 -97
- data/lib/virtualbox/lib.rb +82 -0
- data/lib/virtualbox/media.rb +7 -6
- data/lib/virtualbox/medium.rb +138 -0
- data/lib/virtualbox/medium_attachment.rb +61 -0
- data/lib/virtualbox/network_adapter.rb +134 -0
- data/lib/virtualbox/shared_folder.rb +53 -78
- data/lib/virtualbox/storage_controller.rb +76 -20
- data/lib/virtualbox/system_properties.rb +74 -0
- data/lib/virtualbox/usb_controller.rb +55 -0
- data/lib/virtualbox/version.rb +15 -0
- data/lib/virtualbox/virtual_system_description.rb +47 -0
- data/lib/virtualbox/vm.rb +160 -272
- data/test/test_helper.rb +0 -108
- data/test/virtualbox/abstract_model/attributable_test.rb +7 -1
- data/test/virtualbox/abstract_model/dirty_test.rb +1 -1
- data/test/virtualbox/abstract_model/interface_attributes_test.rb +169 -0
- data/test/virtualbox/abstract_model/relatable_test.rb +20 -0
- data/test/virtualbox/abstract_model_test.rb +40 -5
- data/test/virtualbox/appliance_test.rb +152 -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 +48 -0
- data/test/virtualbox/com/abstract_implementer_test.rb +39 -0
- data/test/virtualbox/com/abstract_interface_test.rb +139 -0
- data/test/virtualbox/com/ffi/interface_test.rb +249 -0
- data/test/virtualbox/com/ffi/util_test.rb +86 -0
- data/test/virtualbox/com/ffi_interface_test.rb +42 -0
- data/test/virtualbox/com/implementer/base_test.rb +37 -0
- data/test/virtualbox/com/implementer/ffi_test.rb +519 -0
- data/test/virtualbox/com/implementer/mscom_test.rb +208 -0
- data/test/virtualbox/com/mscom_interface_test.rb +17 -0
- data/test/virtualbox/com/util_test.rb +17 -0
- data/test/virtualbox/dvd_test.rb +4 -95
- data/test/virtualbox/ext/platform_test.rb +8 -0
- data/test/virtualbox/extra_data_test.rb +78 -102
- data/test/virtualbox/forwarded_port_test.rb +57 -7
- data/test/virtualbox/global_test.rb +25 -115
- data/test/virtualbox/hard_drive_test.rb +49 -212
- 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/network_adapter_test.rb +160 -0
- data/test/virtualbox/shared_folder_test.rb +144 -160
- data/test/virtualbox/storage_controller_test.rb +166 -45
- data/test/virtualbox/system_properties_test.rb +87 -0
- data/test/virtualbox/usb_controller_test.rb +104 -0
- data/test/virtualbox/version_test.rb +34 -0
- data/test/virtualbox/virtual_system_description_test.rb +61 -0
- data/test/virtualbox/vm_test.rb +288 -322
- data/test/virtualbox_test.rb +1 -9
- data/virtualbox.gemspec +139 -23
- metadata +143 -27
- data/lib/virtualbox/attached_device.rb +0 -249
- data/lib/virtualbox/command.rb +0 -109
- data/lib/virtualbox/image.rb +0 -137
- data/lib/virtualbox/nic.rb +0 -111
- data/lib/virtualbox/system_property.rb +0 -55
- data/lib/virtualbox/usb.rb +0 -72
- data/test/virtualbox/attached_device_test.rb +0 -303
- data/test/virtualbox/command_test.rb +0 -152
- data/test/virtualbox/image_test.rb +0 -190
- data/test/virtualbox/nic_test.rb +0 -76
- data/test/virtualbox/system_property_test.rb +0 -71
- data/test/virtualbox/usb_test.rb +0 -35
|
@@ -1,249 +0,0 @@
|
|
|
1
|
-
module VirtualBox
|
|
2
|
-
# Represents an device which is attached to a storage controller. An example
|
|
3
|
-
# of such a device would be a CD or hard drive attached to an IDE controller.
|
|
4
|
-
#
|
|
5
|
-
# # Creating a New Attached Device
|
|
6
|
-
#
|
|
7
|
-
# Creating a new attached device is simple. The following is a simple example
|
|
8
|
-
# of creating a DVD with an empty drive:
|
|
9
|
-
#
|
|
10
|
-
# ad = VirtualBox::AttachedDevice.new
|
|
11
|
-
# ad.port = 0
|
|
12
|
-
# ad.image = VirtualBox::DVD.empty_drive
|
|
13
|
-
# storage_controller.devices << ad
|
|
14
|
-
# ad.save
|
|
15
|
-
#
|
|
16
|
-
# The only quirk is that the attached device **must** be attached to a
|
|
17
|
-
# storage controller. The above assumes that `storage_controller` exists,
|
|
18
|
-
# which adds the device.
|
|
19
|
-
#
|
|
20
|
-
# Any {Image} subclass can be set to the `image` relationship.
|
|
21
|
-
#
|
|
22
|
-
# The following is an example using {VM.find}:
|
|
23
|
-
#
|
|
24
|
-
# # First creating the new device...
|
|
25
|
-
# ad = VirtualBox::AttachedDevice.new
|
|
26
|
-
# ad.port = 0
|
|
27
|
-
# ad.image = VirtualBox::DVD.empty_drive
|
|
28
|
-
#
|
|
29
|
-
# # Now attaching to existing VM
|
|
30
|
-
# vm = VirtualBox::VM.find("FooVM")
|
|
31
|
-
# vm.storage_controllers[0].devices << ad
|
|
32
|
-
# vm.save
|
|
33
|
-
#
|
|
34
|
-
# The interesting thing in this example is that the `save` method is called on
|
|
35
|
-
# the virtual machine rather than the AttachedDevice. This will actually work
|
|
36
|
-
# as expected! Saving a virtual machine automatically saves all it's relationships
|
|
37
|
-
# as well.
|
|
38
|
-
#
|
|
39
|
-
# # Attributes and Relationships
|
|
40
|
-
#
|
|
41
|
-
# Properties of the model are exposed using standard ruby instance
|
|
42
|
-
# methods which are generated on the fly. Because of this, they are not listed
|
|
43
|
-
# below as available instance methods.
|
|
44
|
-
#
|
|
45
|
-
# These attributes can be accessed and modified via standard ruby-style
|
|
46
|
-
# `instance.attribute` and `instance.attribute=` methods. The attributes are
|
|
47
|
-
# listed below.
|
|
48
|
-
#
|
|
49
|
-
# Relationships are also accessed like attributes but can't be set. Instead,
|
|
50
|
-
# they are typically references to other objects such as an {AttachedDevice} which
|
|
51
|
-
# in turn have their own attributes which can be modified.
|
|
52
|
-
#
|
|
53
|
-
# ## Attributes
|
|
54
|
-
#
|
|
55
|
-
# This is copied directly from the class header, but lists all available
|
|
56
|
-
# attributes. If you don't understand what this means, read {Attributable}.
|
|
57
|
-
#
|
|
58
|
-
# attribute :parent, :readonly => true
|
|
59
|
-
# attribute :uuid
|
|
60
|
-
# attribute :medium
|
|
61
|
-
# attribute :port
|
|
62
|
-
#
|
|
63
|
-
# ## Relationships
|
|
64
|
-
#
|
|
65
|
-
# In addition to the basic attributes, a virtual machine is related
|
|
66
|
-
# to other things. The relationships are listed below. If you don't
|
|
67
|
-
# understand this, read {Relatable}.
|
|
68
|
-
#
|
|
69
|
-
# relationship :image, Image
|
|
70
|
-
#
|
|
71
|
-
class AttachedDevice < AbstractModel
|
|
72
|
-
attribute :parent, :readonly => true
|
|
73
|
-
attribute :uuid, :readonly => true
|
|
74
|
-
attribute :port
|
|
75
|
-
attribute :type, :readonly => true
|
|
76
|
-
relationship :image, Image
|
|
77
|
-
|
|
78
|
-
class <<self
|
|
79
|
-
# Populate relationship with another model.
|
|
80
|
-
#
|
|
81
|
-
# **This method typically won't be used except internally.**
|
|
82
|
-
#
|
|
83
|
-
# @return [Array<AttachedDevice>]
|
|
84
|
-
def populate_relationship(caller, data)
|
|
85
|
-
relation = Proxies::Collection.new(caller)
|
|
86
|
-
|
|
87
|
-
counter = 0
|
|
88
|
-
data.css("AttachedDevice").each do |ad|
|
|
89
|
-
relation << new(counter, caller, ad)
|
|
90
|
-
counter += 1
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
relation
|
|
94
|
-
end
|
|
95
|
-
|
|
96
|
-
# Destroy attached devices associated with another model.
|
|
97
|
-
#
|
|
98
|
-
# **This method typically won't be used except internally.**
|
|
99
|
-
def destroy_relationship(caller, data, *args)
|
|
100
|
-
data.each { |v| v.destroy(*args) }
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
# Saves the relationship. This simply calls {#save} on every
|
|
104
|
-
# member of the relationship.
|
|
105
|
-
#
|
|
106
|
-
# **This method typically won't be used except internally.**
|
|
107
|
-
def save_relationship(caller, data)
|
|
108
|
-
# Just call save on each nic with the VM
|
|
109
|
-
data.each do |ad|
|
|
110
|
-
ad.save
|
|
111
|
-
end
|
|
112
|
-
end
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# @overload initialize(data={})
|
|
116
|
-
# Creates a new AttachedDevice which is a new record. This
|
|
117
|
-
# should be attached to a storage controller and saved.
|
|
118
|
-
# @param [Hash] data (optional) A hash which contains initial attribute
|
|
119
|
-
# values for the AttachedDevice.
|
|
120
|
-
# @overload initialize(index, caller, data)
|
|
121
|
-
# Creates an AttachedDevice for a relationship. **This should
|
|
122
|
-
# never be called except internally.**
|
|
123
|
-
# @param [Integer] index Index of the port
|
|
124
|
-
# @param [Object] caller The parent
|
|
125
|
-
# @param [Hash] data A hash of data which must be used
|
|
126
|
-
# to extract the relationship data.
|
|
127
|
-
def initialize(*args)
|
|
128
|
-
super()
|
|
129
|
-
|
|
130
|
-
if args.length == 3
|
|
131
|
-
populate_from_data(*args)
|
|
132
|
-
elsif args.length == 1
|
|
133
|
-
populate_attributes(*args)
|
|
134
|
-
new_record!
|
|
135
|
-
elsif args.empty?
|
|
136
|
-
return
|
|
137
|
-
else
|
|
138
|
-
raise NoMethodError.new
|
|
139
|
-
end
|
|
140
|
-
end
|
|
141
|
-
|
|
142
|
-
# Validates an attached device.
|
|
143
|
-
def validate
|
|
144
|
-
super
|
|
145
|
-
|
|
146
|
-
validates_presence_of :parent
|
|
147
|
-
validates_presence_of :image
|
|
148
|
-
validates_presence_of :port
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
# Saves or creates an attached device.
|
|
152
|
-
#
|
|
153
|
-
# @param [Boolean] raise_errors If true, {Exceptions::CommandFailedException}
|
|
154
|
-
# will be raised if the command failed.
|
|
155
|
-
# @return [Boolean] True if command was successful, false otherwise.
|
|
156
|
-
def save(raise_errors=false)
|
|
157
|
-
return true unless changed?
|
|
158
|
-
|
|
159
|
-
if !valid?
|
|
160
|
-
raise Exceptions::ValidationFailedException.new(errors) if raise_errors
|
|
161
|
-
return false
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
# If the port changed, we have to destroy the old one, then create
|
|
165
|
-
# a new one
|
|
166
|
-
destroy({:port => port_was}, raise_errors) if port_changed? && !port_was.nil?
|
|
167
|
-
|
|
168
|
-
Command.vboxmanage("storageattach", parent.parent.name, "--storagectl", parent.name, "--port", port, "--device", "0", "--type", image.image_type, "--medium", medium)
|
|
169
|
-
existing_record!
|
|
170
|
-
clear_dirty!
|
|
171
|
-
|
|
172
|
-
true
|
|
173
|
-
rescue Exceptions::CommandFailedException
|
|
174
|
-
raise if raise_errors
|
|
175
|
-
false
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
# Medium of the attached image. This attribute will be dependent
|
|
179
|
-
# on the attached image and will return one of the following values:
|
|
180
|
-
#
|
|
181
|
-
# * **none** - There is no attached image
|
|
182
|
-
# * **emptydrive** - An image with an empty drive is attached (see
|
|
183
|
-
# {DVD.empty_drive})
|
|
184
|
-
# * **image uuid** - The image's UUID
|
|
185
|
-
#
|
|
186
|
-
# @return [String]
|
|
187
|
-
def medium
|
|
188
|
-
if image.nil?
|
|
189
|
-
"none"
|
|
190
|
-
elsif image.empty_drive?
|
|
191
|
-
"emptydrive"
|
|
192
|
-
else
|
|
193
|
-
image.uuid
|
|
194
|
-
end
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
# Destroys the attached device. By default, this only removes any
|
|
198
|
-
# media inserted within the device, but does not destroy it. This
|
|
199
|
-
# option can be specified, however, through the `destroy_image`
|
|
200
|
-
# option.
|
|
201
|
-
#
|
|
202
|
-
# @option options [Boolean] :destroy_image (false) If true, will also
|
|
203
|
-
# destroy the image associated with device.
|
|
204
|
-
# @param [Boolean] raise_errors If true, {Exceptions::CommandFailedException}
|
|
205
|
-
# will be raised if the command failed.
|
|
206
|
-
# @return [Boolean] True if command was successful, false otherwise.
|
|
207
|
-
def destroy(options={}, raise_errors=false)
|
|
208
|
-
# parent = storagecontroller
|
|
209
|
-
# parent.parent = vm
|
|
210
|
-
destroy_port = options[:port] || port
|
|
211
|
-
Command.vboxmanage("storageattach", parent.parent.name, "--storagectl", parent.name, "--port", destroy_port, "--device", "0", "--medium", "none")
|
|
212
|
-
image.destroy(raise_errors) if options[:destroy_image] && image
|
|
213
|
-
rescue Exceptions::CommandFailedException
|
|
214
|
-
raise if raise_errors
|
|
215
|
-
false
|
|
216
|
-
end
|
|
217
|
-
|
|
218
|
-
# Relationship callback when added to a collection. This is automatically
|
|
219
|
-
# called by any relationship collection when this object is added.
|
|
220
|
-
def added_to_relationship(parent)
|
|
221
|
-
write_attribute(:parent, parent)
|
|
222
|
-
end
|
|
223
|
-
|
|
224
|
-
protected
|
|
225
|
-
|
|
226
|
-
# Populates the model based on data from a parsed vminfo. This
|
|
227
|
-
# method is used to create a model which already exists and is
|
|
228
|
-
# part of a relationship.
|
|
229
|
-
#
|
|
230
|
-
# **This method should never be called except internally.**
|
|
231
|
-
def populate_from_data(index, caller, data)
|
|
232
|
-
# Get the regular attributes
|
|
233
|
-
attrs = {}
|
|
234
|
-
data.attributes.each do |key, value|
|
|
235
|
-
attrs[key.downcase.to_sym] = value.to_s
|
|
236
|
-
end
|
|
237
|
-
|
|
238
|
-
# Get the Image UUID
|
|
239
|
-
image = data.css("Image")
|
|
240
|
-
if image.empty?
|
|
241
|
-
attrs[:uuid] = nil
|
|
242
|
-
else
|
|
243
|
-
attrs[:uuid] = image[0]["uuid"][1..-2]
|
|
244
|
-
end
|
|
245
|
-
|
|
246
|
-
populate_attributes(attrs.merge({ :parent => caller }))
|
|
247
|
-
end
|
|
248
|
-
end
|
|
249
|
-
end
|
data/lib/virtualbox/command.rb
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
module VirtualBox
|
|
2
|
-
def self.version
|
|
3
|
-
Command.version
|
|
4
|
-
end
|
|
5
|
-
|
|
6
|
-
# Used by the rest of the virtualbox library to call shell commands.
|
|
7
|
-
# It also can be used to change the path for your VBoxManage program.
|
|
8
|
-
#
|
|
9
|
-
# # Changing VBoxManage Path
|
|
10
|
-
#
|
|
11
|
-
# The rest of the library won't work without a proper path to VBoxManage,
|
|
12
|
-
# so it is crucial to set this properly right away. By default its set
|
|
13
|
-
# to `VBoxManage` which assumes that it is in your `PATH`.
|
|
14
|
-
#
|
|
15
|
-
# VirtualBox::Command.vboxmanage = "/opt/local/bin/VBoxManage"
|
|
16
|
-
#
|
|
17
|
-
class Command
|
|
18
|
-
@@vboxmanage = "VBoxManage"
|
|
19
|
-
|
|
20
|
-
class <<self
|
|
21
|
-
# Returns a string of the version of VirtualBox installed, or nil if
|
|
22
|
-
# it can't detect VirtualBox.
|
|
23
|
-
#
|
|
24
|
-
# @return [String]
|
|
25
|
-
def version
|
|
26
|
-
result = execute("#{@@vboxmanage} --version")
|
|
27
|
-
return nil unless Command.success?
|
|
28
|
-
result.chomp
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
# Reads the XML file and returns a Nokogiri document. Reads the XML data
|
|
32
|
-
# from the specified file and returns a Nokogiri document.
|
|
33
|
-
#
|
|
34
|
-
# @param [String] File name.
|
|
35
|
-
# @return [Nokogiri::XML::Document]
|
|
36
|
-
def parse_xml(filename)
|
|
37
|
-
f = File.open(filename, "r")
|
|
38
|
-
result = Nokogiri::XML(f)
|
|
39
|
-
f.close
|
|
40
|
-
|
|
41
|
-
result
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
# Returns true if the last run command was a success. Obviously this
|
|
45
|
-
# will introduce all sorts of thread-safe problems. Those will have to
|
|
46
|
-
# be addressed another time.
|
|
47
|
-
def success?
|
|
48
|
-
$?.to_i == 0
|
|
49
|
-
end
|
|
50
|
-
|
|
51
|
-
# Sets the path to VBoxManage, which is required for this gem to
|
|
52
|
-
# work.
|
|
53
|
-
#
|
|
54
|
-
# @param [String] Full path to `VBoxManage`.
|
|
55
|
-
def vboxmanage=(path)
|
|
56
|
-
@@vboxmanage = path
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# Runs a VBoxManage command and returns the output. This method will automatically
|
|
60
|
-
# shell escape all args passed to it. There is no way to avoid this at the moment
|
|
61
|
-
# (since it hasn't been necessary to). This will raise an {Exceptions::CommandFailedException}
|
|
62
|
-
# if the exit status of the command is nonzero. It is up to the caller to figure
|
|
63
|
-
# out how to handle this; there is no way to suppress it via a parameter to this
|
|
64
|
-
# call.
|
|
65
|
-
#
|
|
66
|
-
# Upon success, {vboxmanage} returns the stdout output from the command.
|
|
67
|
-
#
|
|
68
|
-
# @return [String] The data from stdout of the command.
|
|
69
|
-
def vboxmanage(*args)
|
|
70
|
-
args.collect! { |arg| shell_escape(arg.to_s) }
|
|
71
|
-
result = execute("#{@@vboxmanage} -q #{args.join(" ")}")
|
|
72
|
-
raise Exceptions::CommandFailedException.new(result) if !Command.success?
|
|
73
|
-
result
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
# Runs a command and returns a boolean result showing
|
|
77
|
-
# if the command ran successfully or not based on the
|
|
78
|
-
# exit code.
|
|
79
|
-
def test(command)
|
|
80
|
-
execute(command)
|
|
81
|
-
success?
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# Runs a command and returns the STDOUT result. The reason this is
|
|
85
|
-
# a method at the moment is because in the future we may want to
|
|
86
|
-
# change the way commands are run (replace the backticks), plus it
|
|
87
|
-
# makes testing easier.
|
|
88
|
-
def execute(command)
|
|
89
|
-
`#{command}`
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
# Shell escapes a string. This is almost a direct copy/paste from
|
|
93
|
-
# the ruby mailing list. I'm not sure how well it works but so far
|
|
94
|
-
# it hasn't failed!
|
|
95
|
-
def shell_escape(str)
|
|
96
|
-
if Platform.windows?
|
|
97
|
-
# Special case for windows. This is probably not 100% bullet proof
|
|
98
|
-
# but it gets the job done until we find trouble
|
|
99
|
-
str = "\"#{str}\"" if str =~ /\s/
|
|
100
|
-
return str
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
str.to_s.gsub(/(?=[^a-zA-Z0-9_.\/\-\x7F-\xFF\n])/n, '\\').
|
|
104
|
-
gsub(/\n/, "'\n'").
|
|
105
|
-
sub(/^$/, "''")
|
|
106
|
-
end
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
data/lib/virtualbox/image.rb
DELETED
|
@@ -1,137 +0,0 @@
|
|
|
1
|
-
require 'virtualbox/ext/subclass_listing'
|
|
2
|
-
|
|
3
|
-
module VirtualBox
|
|
4
|
-
# An abstract class which encapsulates the shared behaviour of
|
|
5
|
-
# images such as {HardDrive} and {DVD}.
|
|
6
|
-
#
|
|
7
|
-
# ## Attributes
|
|
8
|
-
#
|
|
9
|
-
# All images expose the following attributes. If you don't know how to read
|
|
10
|
-
# this than read {Attributable}.
|
|
11
|
-
#
|
|
12
|
-
# attribute :uuid, :readonly => true
|
|
13
|
-
# attribute :location
|
|
14
|
-
# attribute :accessible, :readonly => true
|
|
15
|
-
#
|
|
16
|
-
# @abstract
|
|
17
|
-
class Image < AbstractModel
|
|
18
|
-
include SubclassListing
|
|
19
|
-
|
|
20
|
-
attribute :uuid, :readonly => true
|
|
21
|
-
attribute :location
|
|
22
|
-
attribute :accessible, :readonly => true, :lazy => true
|
|
23
|
-
|
|
24
|
-
class <<self
|
|
25
|
-
# Parses the raw output of virtualbox into image objects. Used by
|
|
26
|
-
# subclasses to parse the output of their respective listing functions.
|
|
27
|
-
#
|
|
28
|
-
# **This method typically won't be used except internally.**
|
|
29
|
-
#
|
|
30
|
-
# @return [Array<Image>]
|
|
31
|
-
def parse_raw(raw)
|
|
32
|
-
parse_blocks(raw).collect { |v| new(v) }
|
|
33
|
-
end
|
|
34
|
-
|
|
35
|
-
# Parses the blocks of the output from virtualbox. VirtualBox outputs
|
|
36
|
-
# image listing in "blocks" which are then parsed down to their attributes.
|
|
37
|
-
#
|
|
38
|
-
# **This method typically won't be used except internally.**
|
|
39
|
-
#
|
|
40
|
-
# @return [Array<Hash>]
|
|
41
|
-
def parse_blocks(raw)
|
|
42
|
-
raw.split(/\n\n/).collect { |v| parse_block(v.chomp) }.compact
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# Parses a single block from VirtualBox output.
|
|
46
|
-
#
|
|
47
|
-
# **This method typically won't be used except internally.**
|
|
48
|
-
#
|
|
49
|
-
# @return [Hash]
|
|
50
|
-
def parse_block(block)
|
|
51
|
-
return nil unless block =~ /^UUID:/i
|
|
52
|
-
hd = {}
|
|
53
|
-
|
|
54
|
-
# Parses each line which should be in the format:
|
|
55
|
-
# KEY: VALUE
|
|
56
|
-
block.split("\n").each do |line|
|
|
57
|
-
next unless line =~ /^(.+?):\s+(.+?)$/
|
|
58
|
-
hd[$1.downcase.to_sym] = $2.to_s
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
# If we don't have a location but have a path, use that, as they
|
|
62
|
-
# are equivalent but not consistent.
|
|
63
|
-
hd[:location] = hd[:path] if hd.has_key?(:path)
|
|
64
|
-
|
|
65
|
-
hd
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
# Searches the subclasses which implement all method, searching for
|
|
69
|
-
# a matching UUID and returning that as the relationship.
|
|
70
|
-
#
|
|
71
|
-
# **This method typically won't be used except internally.**
|
|
72
|
-
#
|
|
73
|
-
# @return [Array<Image>]
|
|
74
|
-
def populate_relationship(caller, data)
|
|
75
|
-
return DVD.empty_drive if data[:uuid].nil?
|
|
76
|
-
|
|
77
|
-
subclasses.each do |subclass|
|
|
78
|
-
next unless subclass.respond_to?(:all)
|
|
79
|
-
|
|
80
|
-
matching = subclass.all.find { |obj| obj.uuid == data[:uuid] }
|
|
81
|
-
return matching unless matching.nil?
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
nil
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# Sets an image onto a relationship and/or removes it from a
|
|
88
|
-
# relationship. This method is automatically called by {Relatable}.
|
|
89
|
-
#
|
|
90
|
-
# **This method typically won't be used except internally.**
|
|
91
|
-
#
|
|
92
|
-
# @return [Image]
|
|
93
|
-
def set_relationship(caller, old_value, new_value)
|
|
94
|
-
# We don't actually destroy any images using this method,
|
|
95
|
-
# so just return the new value as long as its a valid object
|
|
96
|
-
raise Exceptions::InvalidRelationshipObjectException.new if new_value && !new_value.is_a?(Image)
|
|
97
|
-
|
|
98
|
-
return new_value
|
|
99
|
-
end
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
# **This should never be called directly on {Image}.** Instead, initialize
|
|
103
|
-
# one of the subclasses.
|
|
104
|
-
def initialize(info=nil)
|
|
105
|
-
super()
|
|
106
|
-
|
|
107
|
-
populate_attributes(info) if info
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
# The image type as a string for the virtualbox command line. This
|
|
111
|
-
# method should be overridden by any subclass and is expected to
|
|
112
|
-
# return the type which is used in command line parameters for
|
|
113
|
-
# attaching to storage controllers.
|
|
114
|
-
#
|
|
115
|
-
# @return [String]
|
|
116
|
-
def image_type
|
|
117
|
-
raise "This must be implemented by any subclasses"
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
# Returns boolean showing if empty drive or not. This method should be
|
|
121
|
-
# overriden by any subclass and is expected to return true of false
|
|
122
|
-
# showing if this image represents an empty drive of whatever type
|
|
123
|
-
# the subclass is.
|
|
124
|
-
#
|
|
125
|
-
# @return [Boolean]
|
|
126
|
-
def empty_drive?
|
|
127
|
-
false
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
# Returns the basename of the images location (the file name +extension)
|
|
131
|
-
#
|
|
132
|
-
# @return [String]
|
|
133
|
-
def filename
|
|
134
|
-
File.basename(location.to_s)
|
|
135
|
-
end
|
|
136
|
-
end
|
|
137
|
-
end
|