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.
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