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