virtual_box 0.0.1 → 0.1.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 (47) hide show
  1. data/.autotest +9 -0
  2. data/.document +5 -0
  3. data/.project +12 -0
  4. data/.rspec +1 -0
  5. data/Gemfile +14 -0
  6. data/Gemfile.lock +44 -0
  7. data/LICENSE.txt +20 -0
  8. data/README.markdown +67 -0
  9. data/Rakefile +35 -22
  10. data/VERSION +1 -0
  11. data/lib/virtual_box/board.rb +287 -0
  12. data/lib/virtual_box/cli.rb +20 -0
  13. data/lib/virtual_box/dhcp.rb +149 -0
  14. data/lib/virtual_box/disk.rb +138 -0
  15. data/lib/virtual_box/io_bus.rb +261 -0
  16. data/lib/virtual_box/net.rb +144 -0
  17. data/lib/virtual_box/nic.rb +213 -0
  18. data/lib/virtual_box/version.rb +37 -24
  19. data/lib/virtual_box/vm.rb +289 -24
  20. data/lib/virtual_box.rb +14 -9
  21. data/test/helper.rb +24 -0
  22. data/test/tasks/tinycore.rake +378 -0
  23. data/test/virtual_box/board_test.rb +39 -0
  24. data/test/virtual_box/cli_test.rb +33 -0
  25. data/test/virtual_box/dhcp_test.rb +52 -0
  26. data/test/virtual_box/disk_test.rb +116 -0
  27. data/test/virtual_box/integration_test.rb +53 -0
  28. data/test/virtual_box/io_bus_test.rb +54 -0
  29. data/test/virtual_box/net_test.rb +80 -0
  30. data/test/virtual_box/nic_test.rb +50 -0
  31. data/test/virtual_box/version_test.rb +71 -0
  32. data/test/virtual_box/vm_test.rb +55 -0
  33. data/virtual_box.gemspec +81 -22
  34. metadata +208 -89
  35. data/CHANGELOG +0 -1
  36. data/LICENSE +0 -21
  37. data/Manifest +0 -17
  38. data/README.textile +0 -19
  39. data/lib/virtual_box/command_line.rb +0 -27
  40. data/lib/virtual_box/vm/general_settings.rb +0 -136
  41. data/lib/virtual_box/vm/identity.rb +0 -43
  42. data/lib/virtual_box/vm/lifecycle.rb +0 -42
  43. data/test/command_line_test.rb +0 -19
  44. data/test/general_settings_test.rb +0 -20
  45. data/test/lifecycle_test.rb +0 -64
  46. data/test/version_test.rb +0 -56
  47. data/testdata/golden_general_params.txt +0 -1
@@ -0,0 +1,213 @@
1
+ require 'securerandom'
2
+
3
+ module VirtualBox
4
+
5
+ # Configuration for a network card.
6
+ class Nic
7
+ # The kind of network emulation implemented on this card.
8
+ #
9
+ # Can be one of the following values:
10
+ # :nat:: uses VirtualBox internal NAT engine to hide under host OS
11
+ # :bridged:: bypasses host OS, connects directly to a network interface
12
+ # :host:: virtual network connecting guest to host
13
+ # :virtual:: virtual network connecting multiple guests
14
+ # @return [Symbol]
15
+ attr_accessor :mode
16
+
17
+ # The NIC controller chip.
18
+ #
19
+ # Can be one of the following values:
20
+ # :amd:: AMD PCNet FAST III (good default)
21
+ # :intel:: Intel PRO/1000 MT Server (for newer Windows systems)
22
+ # :intel_xp:: Intel PRO/1000 MT Server (for Windows XP)
23
+ # :virtio:: fake card optimized for virtualization (custom drivers needed)
24
+ # @return [Symbol]
25
+ attr_accessor :chip
26
+
27
+ # Name of the virtual network that the NIC is connected to.
28
+ #
29
+ # The identifier differs depending on the networking mode:
30
+ # :nat:: not applicable
31
+ # :bridged:: name of the bridge network interface on the host
32
+ # :host:: name of the host-only network interface
33
+ # :virtual:: virtual network name
34
+ # @return [Symbol]
35
+ attr_accessor :net_name
36
+
37
+ # MAC address for the network card, as a hexadecimal string.
38
+ #
39
+ # The format for specifying MACs is '0123456789AB'. A random MAC will be
40
+ # generated if one is not assigned.
41
+ # @return [String]
42
+ attr_accessor :mac
43
+
44
+ # Path to a file that logs a network trace for the VM.
45
+ #
46
+ # Can be null to disable tracing.
47
+ # @return [String]
48
+ attr_accessor :trace_file
49
+
50
+ undef :mode
51
+ def mode
52
+ @mode ||= :nat
53
+ end
54
+
55
+ undef :chip
56
+ def chip
57
+ @chip ||= (:mode == :virtual) ? :virtual : :amd
58
+ end
59
+
60
+ undef :mac
61
+ def mac
62
+ return @mac if @mac
63
+ @mac = SecureRandom.hex(6).upcase
64
+ @mac[1] = 'A' # Set the OUI bits to unicast and globally unique
65
+ @mac
66
+ end
67
+ undef :mac=
68
+ def mac=(new_mac)
69
+ @mac = new_mac && new_mac.upcase.gsub(/[^0-9A-F]/, '')
70
+ end
71
+
72
+ # Creates a NIC with the given attributes.
73
+ #
74
+ # @param [Hash<Symbol, Object>] options ActiveRecord-style initial values for
75
+ # attributes; can be used together with Nic#to_hash to save and restore
76
+ def initialize(options = {})
77
+ options.each { |k, v| self.send :"#{k}=", v }
78
+ end
79
+
80
+ # Arguments to "VBoxManage modifyvm" describing the NIC.
81
+ #
82
+ # @param [Number] nic_id the number of the card (1-4) connected to the host
83
+ # @return [Array<String>] arguments that can be concatenated to a "VBoxManage
84
+ # modifyvm" command to express this NIC specification
85
+ def to_params(nic_id)
86
+ params = []
87
+
88
+ params.push "--nic#{nic_id}"
89
+ case mode
90
+ when :nat
91
+ params.push 'nat'
92
+ when :bridged
93
+ params.push 'bridged', "--bridgeadapter#{nic_id}", net_name
94
+ when :virtual
95
+ params.push 'intnet', "--intnet#{nic_id}", net_name
96
+ when :host
97
+ params.push 'hostonly', "--hostonlyadapter#{nic_id}", net_name
98
+ else
99
+ params.push 'null'
100
+ end
101
+
102
+ params.push "--nictype#{nic_id}", case chip
103
+ when :amd
104
+ 'Am79C973'
105
+ when :intel
106
+ '82545EM'
107
+ when :intel_xp
108
+ '82543GC'
109
+ when :virtual
110
+ 'virtio'
111
+ end
112
+
113
+ params.push "--cableconnected#{nic_id}", 'on'
114
+ params.push "--macaddress#{nic_id}", mac if mac
115
+
116
+ params.push "--nictrace#{nic_id}"
117
+ if trace_file
118
+ params.push 'on', "--nictracefile#{nic_id}", trace_file
119
+ else
120
+ params.push 'off'
121
+ end
122
+
123
+ params
124
+ end
125
+
126
+ # Parses "VBoxManage showvminfo --machinereadable" output into this instance.
127
+ #
128
+ # @param [Hash<String, String>] params the "VBoxManage showvminfo" output,
129
+ # parsed by Vm.parse_machine_readble
130
+ # @param [Integer] nic_id the NIC's number in the VM
131
+ # @return [VirtualBox::Nic] self, for easy call chaining
132
+ def from_params(params, nic_id)
133
+ case params["nic#{nic_id}"]
134
+ when 'nat'
135
+ self.mode = :nat
136
+ when 'bridged'
137
+ self.mode = :bridged
138
+ self.net_name = params["bridgeadapter#{nic_id}"]
139
+ when 'intnet'
140
+ self.mode = :virtual
141
+ self.net_name = params["intnet#{nic_id}"]
142
+ when 'hostonly'
143
+ self.mode = :host
144
+ self.net_name = params["hostonlyadapter#{nic_id}"]
145
+ end
146
+
147
+ self.chip = case params["nictype#{nic_id}"]
148
+ when 'Am79C970A', 'Am79C973',
149
+ :amd
150
+ when '82543GC'
151
+ :intel_xp
152
+ when '82540OEM', '82545EM'
153
+ :intel
154
+ when 'virtio'
155
+ :virtual
156
+ else
157
+ (self.mode == :virtual) ? :virtual : :amd
158
+ end
159
+
160
+ self.mac = params["macaddress#{nic_id}"]
161
+ if params["nictrace#{nic_id}"] == 'on'
162
+ self.trace_file = params["nictracefile#{nic_id}"]
163
+ else
164
+ self.trace_file = nil
165
+ end
166
+
167
+ self
168
+ end
169
+
170
+ # Hash capturing this specification. Can be passed to Nic#new.
171
+ #
172
+ # @return [Hash<Symbol, Object>] Ruby-friendly Hash that can be used to
173
+ # re-create this NIC specification
174
+ def to_hash
175
+ { :mode => mode, :chip => chip, :net_name => net_name, :mac => mac,
176
+ :trace_file => trace_file }
177
+ end
178
+
179
+ # Information about the NICs attached to the computer.
180
+ #
181
+ # @return [Array<Hash<Symbol, Object>>] an array with one hash per NIC; hashes
182
+ # have the following keys:
183
+ # :id:: the inteface id (use when setting a Nic's net_id)
184
+ # :ip:: the IP address (check for 0.0.0.0 to see if it's live)
185
+ # :mask:: the netmask
186
+ # :mac:: the NICs MAC address
187
+ def self.host_nics
188
+ @host_nics ||= get_host_nics
189
+ end
190
+
191
+ # Queries VirtualBox for the network interfaces on the computer.
192
+ #
193
+ # @return (see .host_nics)
194
+ def self.get_host_nics
195
+ result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list',
196
+ '--long', 'hostifs']
197
+ if result.status != 0
198
+ raise 'Unexpected error code returned by VirtualBox'
199
+ end
200
+
201
+ result.output.split("\n\n").map do |nic_info|
202
+ i = Hash[nic_info.split("\n").map { |line|
203
+ line.split(':', 2).map(&:strip)
204
+ }]
205
+ {
206
+ :id => i['Name'], :ip => i['IPAddress'], :mask => i['NetworkMask'],
207
+ :mac => i['HardwareAddress'].upcase.gsub(/[^0-9A-F]/, '')
208
+ }
209
+ end
210
+ end
211
+ end # class VirtualBox::Nic
212
+
213
+ end # namespace VirtualBox
@@ -1,46 +1,59 @@
1
1
  # VirtualBox version detection.
2
- #
3
- # Author:: Victor Costan
4
- # Copyright:: Copyright (C) 2009 Zergling.Net
5
- # License:: MIT
6
2
 
7
- # :nodoc: namespace
8
3
  module VirtualBox
9
4
  @version_info = nil
10
5
 
11
6
  # True if the installed VirtualBox is the open-source edition.
12
7
  #
13
- # The open-source edition of VirtualBox has some limitations, such as no support
14
- # for RDP and USB devices.
8
+ # The open-source edition of VirtualBox has some limitations, such as no
9
+ # support for RDP and USB devices.
15
10
  def self.ose?
16
- version_info ? (version_info[:edition] == 'OSE') : nil
11
+ unless version.edition
12
+ raise 'VirtualBox is not installed on this machine.'
13
+ end
14
+ version.edition == 'OSE'
17
15
  end
18
16
 
19
- # Version information about the installed VirtualBox.
17
+ # Version information about the VirtualBox package installed on this machine.
20
18
  #
21
- # Returns:
22
- # false if VirtualBox is not installed; otherwise, a hash with the keys:
23
- # revision:: (number) the SVN revision that VirtualBox is built off of
24
- # edition:: the VirtualBox edition (nil for the personal edition, 'OSE'
25
- # for the open-source edition)
26
- # version:: the VirtualBox version (e.g. '3.0.4')
27
- def self.version_info
19
+ # @return [Hash<Symbol, Object>, Boolean] false if VirtualBox is not
20
+ # installed; otherwise, a hash with the following keys:
21
+ # :svn:: (number) the SVN revision that VirtualBox is built off of
22
+ # :edition:: the VirtualBox edition ('' for the personal edition, 'OSE'
23
+ # for the open-source edition)
24
+ # :release:: the public release number (e.g. '3.0.4')
25
+ def self.version
28
26
  return @version_info unless @version_info.nil?
29
27
 
30
- cmd_result = shell_command 'VBoxManage --version'
31
- return @version_info = false if cmd_result[:status] != 0
28
+ cmd_result = run_command ['VBoxManage', '--version']
29
+ if cmd_result.status != 0
30
+ @version_info = Hashie::Mash.new
31
+ return @version_info
32
+ end
32
33
 
33
- output = cmd_result[:output].strip
34
- @version_info = {}
34
+ output = cmd_result.output.strip
35
+
35
36
  if revision_offset = output.rindex('r')
36
- @version_info[:revision] = output[revision_offset + 1, output.length].to_i
37
+ revision = output[revision_offset + 1, output.length].to_i
37
38
  output.slice! revision_offset..-1
39
+ else
40
+ revision = nil
38
41
  end
42
+
39
43
  if edition_offset = output.rindex('_')
40
- @version_info[:edition] = output[edition_offset + 1, output.length]
44
+ edition = output[edition_offset + 1, output.length]
41
45
  output.slice! edition_offset..-1
46
+ else
47
+ edition = ''
42
48
  end
43
- @version_info[:version] = output
44
- @version_info
49
+
50
+ @version_info = Hashie::Mash.new :release => output, :svn => revision,
51
+ :edition => edition
52
+ end
53
+
54
+ # Removes the cached information on the VirtualBox package version.
55
+ # @return <NilObject> nil
56
+ def self.reset_version_info!
57
+ @version_info = nil
45
58
  end
46
59
  end # namespace VirtualBox
@@ -1,35 +1,300 @@
1
- # Definition for the main VM class.
2
- #
3
- # Author:: Victor Costan
4
- # Copyright:: Copyright (C) 2009 Zergling.Net
5
- # License:: MIT
6
-
7
- # :nodoc: namespace
8
1
  module VirtualBox
2
+
3
+ # VirtualBox virtual machine.
4
+ class Vm
5
+ # The UUID used to register this virtual machine with VirtualBox.
6
+ #
7
+ # The UUID is used to identify the VM in many VirtualBox commands. It should
8
+ # not be changed once the VM is registered. In fact, the UUID should not
9
+ # be manually assigned under normal use.
10
+ # @return [String]
11
+ attr_accessor :uid
12
+
13
+ # A user-friendly name for this virtual machine.
14
+ #
15
+ # If not assigned, a unique name will be generated based on the VM's UUID.
16
+ #
17
+ # @return [String]
18
+ attr_accessor :name
19
+
20
+ # The general VM configuration.
21
+ # @return [VirtualBox::Board]
22
+ attr_accessor :board
9
23
 
10
- # A VirtualBox virtual machine.
11
- class VM
12
- include GeneralSettings
13
- include Identity
14
- include Lifecycle
24
+ # The IO controllers (and disks) connected to the VM.
25
+ # @return [Array<VirtualBox::IoBus>]
26
+ attr_accessor :io_buses
15
27
 
16
- def initialize
17
- reset_identity
18
- reset_settings
28
+ # The network cards connected to this virtual machine.
29
+ # @return [Array<VirtualBox::Nic>]
30
+ attr_accessor :nics
31
+
32
+ # If true, the VM's screen will be displayed in a GUI.
33
+ #
34
+ # This is only intended for manual testing. Many continuous integration
35
+ # servers cannot display the VirtualBox GUI, so this attribute should not be
36
+ # set to true in test suites.
37
+ # @return [Boolean]
38
+ attr_accessor :gui
39
+
40
+ undef :uid
41
+ def uid
42
+ @uid ||= UUID.generate
43
+ end
44
+
45
+ undef :name
46
+ def name
47
+ @name ||= 'rbx_' + uid.gsub('-', '')
19
48
  end
20
49
 
21
- # Resets the VM's settings to their defaults.
50
+ undef :board=
51
+ def board=(new_board)
52
+ @board = if new_board.kind_of?(VirtualBox::Board)
53
+ new_board
54
+ else
55
+ VirtualBox::Board.new new_board
56
+ end
57
+ end
58
+
59
+ undef :io_buses=
60
+ def io_buses=(new_io_buses)
61
+ @io_buses = new_io_buses.map do |io_bus|
62
+ if io_bus.kind_of?(VirtualBox::IoBus)
63
+ io_bus
64
+ else
65
+ VirtualBox::IoBus.new io_bus
66
+ end
67
+ end
68
+ end
69
+
70
+ undef :nics=
71
+ def nics=(new_nics)
72
+ @nics = []
73
+ new_nics.each do |nic|
74
+ if nic.kind_of?(VirtualBox::Nic) || nic.nil?
75
+ @nics << nic
76
+ else
77
+ options = nic.dup
78
+ port = options.delete(:port) || @nics.length
79
+ @nics[port] = VirtualBox::Nic.new options
80
+ end
81
+ end
82
+ new_nics
83
+ end
84
+
85
+ # Creates a new virtual machine specification based on the given attributes.
22
86
  #
23
- # The defaults are chosen somewhat arbitrarily by the gem's author.
24
- def reset_settings
25
- reset_general_settings
87
+ # @param [Hash<Symbol, Object>] options ActiveRecord-style initial values for
88
+ # attributes; can be used together with Vm#to_hash to save and restore
89
+ def initialize(options = {})
90
+ self.board = {}
91
+ self.io_buses = []
92
+ self.nics = []
93
+ self.gui = false
94
+ options.each { |k, v| self.send :"#{k}=", v }
95
+ end
96
+
97
+ # Hash capturing this specification. Can be passed to Vm#new.
98
+ #
99
+ # @return [Hash<Symbol, Object>] Ruby-friendly Hash that can be used to
100
+ # re-create this virtual machine specification
101
+ def to_hash
102
+ {
103
+ :name => name, :uid => uid, :gui => gui,
104
+ :board => board.to_hash, :io_buses => io_buses.map(&:to_hash),
105
+ :nics => nics.map.
106
+ with_index { |nic, i| nic && nic.to_hash.merge!(:port => i) }.
107
+ reject!(&:nil?)
108
+ }
109
+ end
110
+
111
+ # True if this VM has been registered with VirtualBox.
112
+ #
113
+ # @return [Boolean] true for VMs that are already registered with VirtualBox
114
+ def registered?
115
+ self.class.registered_uids.include? uid
116
+ end
117
+
118
+ # Registers this VM with VirtualBox.
119
+ #
120
+ # @return [VirtualBox::Vm] self, for easy call chaining
121
+ def register
122
+ unregister if registered?
123
+
124
+ result = VirtualBox.run_command ['VBoxManage', 'createvm',
125
+ '--name', name, '--uuid', uid, '--register']
126
+ if result.status != 0
127
+ raise 'Unexpected error code returned by VirtualBox'
128
+ end
129
+
130
+ begin
131
+ push_config
132
+ rescue
133
+ unregister
134
+ raise
135
+ end
136
+
137
+ self
138
+ end
139
+
140
+ # De-registers this VM from VirtualBox's database.
141
+ #
142
+ # @return [VirtualBox::Vm] self, for easy call chaining
143
+ def unregister
144
+ VirtualBox.run_command ['VBoxManage', 'unregistervm', uid, '--delete']
145
+ self
146
+ end
147
+
148
+ # Starts the virtual machine.
149
+ #
150
+ # @return [VirtualBox::Vm] self, for easy call chaining
151
+ def start
152
+ register unless registered?
153
+
154
+ result = VirtualBox.run_command ['VBoxManage', '--nologo', 'startvm', uid,
155
+ '--type', gui ? 'gui' : 'headless']
156
+ if result.status != 0
157
+ raise 'Unexpected error code returned by VirtualBox'
158
+ end
159
+ self
160
+ end
161
+
162
+ # Stops the virtual machine simulation.
163
+ #
164
+ # This is equivalent to pulling the power cord from a physical machine.
165
+ # @return [VirtualBox::Vm] self, for easy call chaining
166
+ def stop
167
+ control :kill
168
+ self
169
+ end
170
+
171
+ # Controls a started virtual machine.
172
+ #
173
+ # @param [Symbol] action the following actions are supported:
174
+ # :kill:: hard power-off (pulling the power cord from the machine)
175
+ # :power_button:: Power button press
176
+ # :nmi:: NMI (non-maskable interrupt)
177
+ # @return [VirtualBox::Vm] self, for easy call chaining
178
+ def control(action)
179
+ action = case action
180
+ when :kill
181
+ 'poweroff'
182
+ when :power_button
183
+ 'acpipowerbutton'
184
+ when :nmi
185
+ 'injectnmi'
186
+ end
187
+
188
+ result = VirtualBox.run_command ['VBoxManage', '--nologo', 'controlvm', uid,
189
+ action]
190
+ if result.status != 0
191
+ raise 'Unexpected error code returned by VirtualBox'
192
+ end
193
+ self
194
+ end
195
+
196
+ # The UUIDs of all VMs that are registered with VirtualBox.
197
+ #
198
+ # @return [Array<String>] UUIDs for VMs that VirtualBox is aware of
199
+ def self.registered_uids
200
+ result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list', 'vms']
201
+ if result.status != 0
202
+ raise 'Unexpected error code returned by VirtualBox'
203
+ end
204
+ result.output.split("\n").map do |id_info|
205
+ uid_offset = id_info.rindex(?{) + 1
206
+ uid = id_info[uid_offset...-1] # Exclude the closing }
207
+ end
26
208
  end
27
209
 
28
- # Arguments to "VBoxManage modifyvm" describing the VM's settings.
29
- def modifyvm_params
30
- params = ''
31
- params << modifyvm_general_params
210
+ # The UUIDs of all VirtualBox VMs that are started.
211
+ #
212
+ # @return [Array<String>] UUIDs for VMs that are running in VirtualBox
213
+ def self.started_uids
214
+ result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list',
215
+ 'runningvms']
216
+ if result.status != 0
217
+ raise 'Unexpected error code returned by VirtualBox'
218
+ end
219
+ result.output.split("\n").map do |id_info|
220
+ uid_offset = id_info.rindex(?{) + 1
221
+ uid = id_info[uid_offset...-1] # Exclude the closing }
222
+ end
32
223
  end
33
- end # class VM
34
224
 
225
+ # Updates the configuration in VirtualBox to reflect this VM's configuration.
226
+ #
227
+ # @return [VirtualBox::Vm] self, for easy call chaining
228
+ def push_config
229
+ command = ['VBoxManage', 'modifyvm', uid]
230
+ command.concat board.to_params
231
+ nics.each_with_index do |nic, index|
232
+ if nic.nil?
233
+ command.push "--nic#{index + 1}", 'none'
234
+ else
235
+ command.concat nic.to_params(index + 1)
236
+ end
237
+ end
238
+ if VirtualBox.run_command(command).status != 0
239
+ raise 'Unexpected error code returned by VirtualBox'
240
+ end
241
+
242
+ io_buses.each { |bus| bus.add_to self }
243
+
244
+ self
245
+ end
246
+
247
+ # Updates this VM's configuration to reflect the VirtualBox configuration.
248
+ #
249
+ # @return [VirtualBox::Vm] self, for easy call chaining
250
+ def pull_config
251
+ result = VirtualBox.run_command ['VBoxManage', '--nologo', 'showvminfo',
252
+ '--machinereadable', uid]
253
+ if result.status != 0
254
+ raise 'Unexpected error code returned by VirtualBox'
255
+ end
256
+
257
+ config = self.class.parse_machine_readable result.output
258
+
259
+ self.name = config['name']
260
+ self.uid = config['UUID']
261
+ board.from_params config
262
+
263
+ nic_count = config.keys.select { |key| /^nic\d+$/ =~ key }.max[3..-1].to_i
264
+ 1.upto nic_count do |index|
265
+ if config["nic#{index}"] == 'none'
266
+ nics[index - 1] = nil
267
+ else
268
+ nics[index - 1] ||= VirtualBox::Nic.new
269
+ nics[index - 1].from_params config, index
270
+ end
271
+ end
272
+
273
+ bus_count = 1 + (config.keys.select { |key|
274
+ /^storagecontrollername\d+$/ =~ key
275
+ }.max || "storagecontrollername-1")[21..-1].to_i
276
+ 0.upto bus_count - 1 do |index|
277
+ io_buses[index] ||= VirtualBox::IoBus.new
278
+ io_buses[index].from_params config, index
279
+ end
280
+
281
+ self
282
+ end
283
+
284
+ # Parses the output of the 'VBoxManage showvminfo --machinereadable' command.
285
+ #
286
+ # @param [String] output the command output
287
+ # @return [Hash<String, Object>] a Hash whose keys are the strings on the left
288
+ # side of "=" on each line, and whose values are the strings on the right
289
+ # side
290
+ def self.parse_machine_readable(output)
291
+ Hash[output.split("\n").map { |line|
292
+ key, value = *line.split('=', 2)
293
+ key = key[1...-1] if key[0] == ?" # Remove string quotes ("").
294
+ value = value[1...-1] if value[0] == ?" # Remove string quotes ("").
295
+ [key, value]
296
+ }]
297
+ end
298
+ end # class VirtualBox::Vm
299
+
35
300
  end # namespace VirtualBox
data/lib/virtual_box.rb CHANGED
@@ -1,12 +1,17 @@
1
- # Main include file for the virtual_box gem.
2
- #
3
- # Author:: Victor Costan
4
- # Copyright:: Copyright (C) 2009 Zergling.Net
5
- # License:: MIT
1
+ # TODO(pwnall): documentation for the top-level VirtualBox module
2
+ module VirtualBox
3
+
4
+ end
6
5
 
7
- require 'virtual_box/command_line.rb'
6
+ require 'hashie/mash'
7
+ require 'uuid'
8
+
9
+ require 'virtual_box/board.rb'
10
+ require 'virtual_box/cli.rb'
11
+ require 'virtual_box/dhcp.rb'
12
+ require 'virtual_box/disk.rb'
13
+ require 'virtual_box/io_bus.rb'
14
+ require 'virtual_box/net.rb'
15
+ require 'virtual_box/nic.rb'
8
16
  require 'virtual_box/version.rb'
9
- require 'virtual_box/vm/general_settings.rb'
10
- require 'virtual_box/vm/identity.rb'
11
- require 'virtual_box/vm/lifecycle.rb'
12
17
  require 'virtual_box/vm.rb'
data/test/helper.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'minitest/unit'
11
+ require 'minitest/spec'
12
+ require 'mocha'
13
+
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
16
+ require 'virtual_box'
17
+
18
+ class MiniTest::Unit::TestCase
19
+ end
20
+
21
+ Dir[File.expand_path('helpers/**/*.rb', File.dirname(__FILE__))].
22
+ each { |h| require h }
23
+
24
+ MiniTest::Unit.autorun