virtualbox 0.5.4 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (162) hide show
  1. data/.gitignore +2 -1
  2. data/Gemfile +1 -1
  3. data/Rakefile +1 -1
  4. data/Readme.md +5 -21
  5. data/VERSION +1 -1
  6. data/docs/WhatsNew.md +9 -47
  7. data/lib/virtualbox.rb +7 -30
  8. data/lib/virtualbox/abstract_model.rb +25 -5
  9. data/lib/virtualbox/abstract_model/attributable.rb +5 -1
  10. data/lib/virtualbox/abstract_model/dirty.rb +2 -0
  11. data/lib/virtualbox/abstract_model/interface_attributes.rb +96 -0
  12. data/lib/virtualbox/abstract_model/relatable.rb +19 -8
  13. data/lib/virtualbox/appliance.rb +59 -0
  14. data/lib/virtualbox/audio_adapter.rb +44 -0
  15. data/lib/virtualbox/bios.rb +44 -0
  16. data/lib/virtualbox/com.rb +23 -0
  17. data/lib/virtualbox/com/abstract_enum.rb +42 -0
  18. data/lib/virtualbox/com/abstract_implementer.rb +43 -0
  19. data/lib/virtualbox/com/abstract_interface.rb +165 -0
  20. data/lib/virtualbox/com/ffi/interface.rb +141 -0
  21. data/lib/virtualbox/com/ffi/interfaces.rb +42 -0
  22. data/lib/virtualbox/com/ffi/util.rb +101 -0
  23. data/lib/virtualbox/com/ffi/vboxxpcomc.rb +31 -0
  24. data/lib/virtualbox/com/ffi_interface.rb +65 -0
  25. data/lib/virtualbox/com/implementer/base.rb +52 -0
  26. data/lib/virtualbox/com/implementer/ffi.rb +350 -0
  27. data/lib/virtualbox/com/implementer/mscom.rb +165 -0
  28. data/lib/virtualbox/com/implementer/nil.rb +10 -0
  29. data/lib/virtualbox/com/interface/appliance.rb +20 -0
  30. data/lib/virtualbox/com/interface/audio_adapter.rb +13 -0
  31. data/lib/virtualbox/com/interface/audio_controller_type.rb +9 -0
  32. data/lib/virtualbox/com/interface/audio_driver_type.rb +9 -0
  33. data/lib/virtualbox/com/interface/bios_boot_menu_mode.rb +9 -0
  34. data/lib/virtualbox/com/interface/bios_settings.rb +19 -0
  35. data/lib/virtualbox/com/interface/clipboard_mode.rb +9 -0
  36. data/lib/virtualbox/com/interface/console.rb +48 -0
  37. data/lib/virtualbox/com/interface/cpu_property_type.rb +9 -0
  38. data/lib/virtualbox/com/interface/device_type.rb +9 -0
  39. data/lib/virtualbox/com/interface/dhcp_server.rb +20 -0
  40. data/lib/virtualbox/com/interface/firmware_type.rb +9 -0
  41. data/lib/virtualbox/com/interface/guest_os_type.rb +21 -0
  42. data/lib/virtualbox/com/interface/host.rb +40 -0
  43. data/lib/virtualbox/com/interface/host_network_interface.rb +28 -0
  44. data/lib/virtualbox/com/interface/host_network_interface_medium_type.rb +9 -0
  45. data/lib/virtualbox/com/interface/host_network_interface_status.rb +9 -0
  46. data/lib/virtualbox/com/interface/host_network_interface_type.rb +9 -0
  47. data/lib/virtualbox/com/interface/host_usb_device.rb +11 -0
  48. data/lib/virtualbox/com/interface/host_usb_device_filter.rb +11 -0
  49. data/lib/virtualbox/com/interface/hw_virt_ex_property_type.rb +9 -0
  50. data/lib/virtualbox/com/interface/machine.rb +103 -0
  51. data/lib/virtualbox/com/interface/machine_state.rb +12 -0
  52. data/lib/virtualbox/com/interface/medium.rb +48 -0
  53. data/lib/virtualbox/com/interface/medium_attachment.rb +16 -0
  54. data/lib/virtualbox/com/interface/medium_format.rb +16 -0
  55. data/lib/virtualbox/com/interface/medium_state.rb +9 -0
  56. data/lib/virtualbox/com/interface/medium_type.rb +9 -0
  57. data/lib/virtualbox/com/interface/medium_variant.rb +9 -0
  58. data/lib/virtualbox/com/interface/network_adapter.rb +28 -0
  59. data/lib/virtualbox/com/interface/network_adapter_type.rb +9 -0
  60. data/lib/virtualbox/com/interface/network_attachment_type.rb +9 -0
  61. data/lib/virtualbox/com/interface/nsiexception.rb +21 -0
  62. data/lib/virtualbox/com/interface/nsisupports.rb +13 -0
  63. data/lib/virtualbox/com/interface/parallel_port.rb +15 -0
  64. data/lib/virtualbox/com/interface/port_mode.rb +9 -0
  65. data/lib/virtualbox/com/interface/progress.rb +58 -0
  66. data/lib/virtualbox/com/interface/serial_port.rb +17 -0
  67. data/lib/virtualbox/com/interface/session.rb +16 -0
  68. data/lib/virtualbox/com/interface/session_state.rb +9 -0
  69. data/lib/virtualbox/com/interface/session_type.rb +9 -0
  70. data/lib/virtualbox/com/interface/shared_folder.rb +15 -0
  71. data/lib/virtualbox/com/interface/snapshot.rb +18 -0
  72. data/lib/virtualbox/com/interface/storage_bus.rb +9 -0
  73. data/lib/virtualbox/com/interface/storage_controller.rb +21 -0
  74. data/lib/virtualbox/com/interface/storage_controller_type.rb +9 -0
  75. data/lib/virtualbox/com/interface/system_properties.rb +35 -0
  76. data/lib/virtualbox/com/interface/usb_controller.rb +18 -0
  77. data/lib/virtualbox/com/interface/usb_device.rb +22 -0
  78. data/lib/virtualbox/com/interface/usb_device_filter.rb +21 -0
  79. data/lib/virtualbox/com/interface/usb_device_filter_action.rb +9 -0
  80. data/lib/virtualbox/com/interface/usb_device_state.rb +9 -0
  81. data/lib/virtualbox/com/interface/virtual_box_error_info.rb +15 -0
  82. data/lib/virtualbox/com/interface/virtual_system_description.rb +17 -0
  83. data/lib/virtualbox/com/interface/virtual_system_description_type.rb +12 -0
  84. data/lib/virtualbox/com/interface/virtual_system_description_value_type.rb +9 -0
  85. data/lib/virtualbox/com/interface/virtualbox.rb +54 -0
  86. data/lib/virtualbox/com/interface/vrdp_auth_type.rb +9 -0
  87. data/lib/virtualbox/com/interface/vrdp_server.rb +17 -0
  88. data/lib/virtualbox/com/mscom_interface.rb +22 -0
  89. data/lib/virtualbox/com/util.rb +18 -0
  90. data/lib/virtualbox/dvd.rb +7 -94
  91. data/lib/virtualbox/exceptions.rb +24 -0
  92. data/lib/virtualbox/ext/glob_loader.rb +22 -0
  93. data/lib/virtualbox/ext/logger.rb +38 -0
  94. data/lib/virtualbox/ext/platform.rb +1 -1
  95. data/lib/virtualbox/extra_data.rb +25 -37
  96. data/lib/virtualbox/forwarded_port.rb +35 -13
  97. data/lib/virtualbox/global.rb +22 -80
  98. data/lib/virtualbox/hard_drive.rb +30 -97
  99. data/lib/virtualbox/lib.rb +82 -0
  100. data/lib/virtualbox/media.rb +7 -6
  101. data/lib/virtualbox/medium.rb +138 -0
  102. data/lib/virtualbox/medium_attachment.rb +61 -0
  103. data/lib/virtualbox/network_adapter.rb +134 -0
  104. data/lib/virtualbox/shared_folder.rb +53 -78
  105. data/lib/virtualbox/storage_controller.rb +76 -20
  106. data/lib/virtualbox/system_properties.rb +74 -0
  107. data/lib/virtualbox/usb_controller.rb +55 -0
  108. data/lib/virtualbox/version.rb +15 -0
  109. data/lib/virtualbox/virtual_system_description.rb +47 -0
  110. data/lib/virtualbox/vm.rb +160 -272
  111. data/test/test_helper.rb +0 -108
  112. data/test/virtualbox/abstract_model/attributable_test.rb +7 -1
  113. data/test/virtualbox/abstract_model/dirty_test.rb +1 -1
  114. data/test/virtualbox/abstract_model/interface_attributes_test.rb +169 -0
  115. data/test/virtualbox/abstract_model/relatable_test.rb +20 -0
  116. data/test/virtualbox/abstract_model_test.rb +40 -5
  117. data/test/virtualbox/appliance_test.rb +152 -0
  118. data/test/virtualbox/audio_adapter_test.rb +83 -0
  119. data/test/virtualbox/bios_test.rb +83 -0
  120. data/test/virtualbox/com/abstract_enum_test.rb +48 -0
  121. data/test/virtualbox/com/abstract_implementer_test.rb +39 -0
  122. data/test/virtualbox/com/abstract_interface_test.rb +139 -0
  123. data/test/virtualbox/com/ffi/interface_test.rb +249 -0
  124. data/test/virtualbox/com/ffi/util_test.rb +86 -0
  125. data/test/virtualbox/com/ffi_interface_test.rb +42 -0
  126. data/test/virtualbox/com/implementer/base_test.rb +37 -0
  127. data/test/virtualbox/com/implementer/ffi_test.rb +519 -0
  128. data/test/virtualbox/com/implementer/mscom_test.rb +208 -0
  129. data/test/virtualbox/com/mscom_interface_test.rb +17 -0
  130. data/test/virtualbox/com/util_test.rb +17 -0
  131. data/test/virtualbox/dvd_test.rb +4 -95
  132. data/test/virtualbox/ext/platform_test.rb +8 -0
  133. data/test/virtualbox/extra_data_test.rb +78 -102
  134. data/test/virtualbox/forwarded_port_test.rb +57 -7
  135. data/test/virtualbox/global_test.rb +25 -115
  136. data/test/virtualbox/hard_drive_test.rb +49 -212
  137. data/test/virtualbox/lib_test.rb +93 -0
  138. data/test/virtualbox/medium_attachment_test.rb +147 -0
  139. data/test/virtualbox/medium_test.rb +192 -0
  140. data/test/virtualbox/network_adapter_test.rb +160 -0
  141. data/test/virtualbox/shared_folder_test.rb +144 -160
  142. data/test/virtualbox/storage_controller_test.rb +166 -45
  143. data/test/virtualbox/system_properties_test.rb +87 -0
  144. data/test/virtualbox/usb_controller_test.rb +104 -0
  145. data/test/virtualbox/version_test.rb +34 -0
  146. data/test/virtualbox/virtual_system_description_test.rb +61 -0
  147. data/test/virtualbox/vm_test.rb +288 -322
  148. data/test/virtualbox_test.rb +1 -9
  149. data/virtualbox.gemspec +139 -23
  150. metadata +143 -27
  151. data/lib/virtualbox/attached_device.rb +0 -249
  152. data/lib/virtualbox/command.rb +0 -109
  153. data/lib/virtualbox/image.rb +0 -137
  154. data/lib/virtualbox/nic.rb +0 -111
  155. data/lib/virtualbox/system_property.rb +0 -55
  156. data/lib/virtualbox/usb.rb +0 -72
  157. data/test/virtualbox/attached_device_test.rb +0 -303
  158. data/test/virtualbox/command_test.rb +0 -152
  159. data/test/virtualbox/image_test.rb +0 -190
  160. data/test/virtualbox/nic_test.rb +0 -76
  161. data/test/virtualbox/system_property_test.rb +0 -71
  162. 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
@@ -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
@@ -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