virtual_box 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.project CHANGED
@@ -5,8 +5,14 @@
5
5
  <projects>
6
6
  </projects>
7
7
  <buildSpec>
8
+ <buildCommand>
9
+ <name>com.aptana.ide.core.unifiedBuilder</name>
10
+ <arguments>
11
+ </arguments>
12
+ </buildCommand>
8
13
  </buildSpec>
9
14
  <natures>
10
15
  <nature>org.radrails.rails.core.railsnature</nature>
16
+ <nature>com.aptana.ruby.core.rubynature</nature>
11
17
  </natures>
12
18
  </projectDescription>
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source :rubygems
2
2
 
3
- gem 'hashie', '>= 0.4.0'
3
+ gem 'posix-spawn', '>= 0.3.6'
4
4
  gem 'uuid', '>= 2.3.5'
5
5
 
6
6
  group :development do
@@ -9,6 +9,7 @@ group :development do
9
9
  gem 'minitest', '>= 2.12.1'
10
10
  gem 'mocha', '>= 0.11.0', :require => false
11
11
  gem 'net-ssh', '>= 2.3.0', :require => 'net/ssh'
12
+ gem 'redcarpet', '>= 2.1.1' # Yard needs this to parse Markdown.
12
13
  gem 'simplecov', '>= 0.6.1'
13
- gem 'yard', '>= 0.7.5'
14
+ gem 'yard', '>= 0.8.1'
14
15
  end
data/Gemfile.lock CHANGED
@@ -2,7 +2,6 @@ GEM
2
2
  remote: http://rubygems.org/
3
3
  specs:
4
4
  git (1.2.5)
5
- hashie (1.2.0)
6
5
  jeweler (1.8.3)
7
6
  bundler (~> 1.0)
8
7
  git (>= 1.2.5)
@@ -17,9 +16,11 @@ GEM
17
16
  metaclass (~> 0.0.1)
18
17
  multi_json (1.3.4)
19
18
  net-ssh (2.3.0)
19
+ posix-spawn (0.3.6)
20
20
  rake (0.9.2.2)
21
21
  rdoc (3.12)
22
22
  json (~> 1.4)
23
+ redcarpet (2.1.1)
23
24
  simplecov (0.6.2)
24
25
  multi_json (~> 1.3)
25
26
  simplecov-html (~> 0.5.3)
@@ -27,18 +28,19 @@ GEM
27
28
  systemu (2.5.0)
28
29
  uuid (2.3.5)
29
30
  macaddr (~> 1.0)
30
- yard (0.8.0)
31
+ yard (0.8.1)
31
32
 
32
33
  PLATFORMS
33
34
  ruby
34
35
 
35
36
  DEPENDENCIES
36
37
  bundler (>= 1.1.3)
37
- hashie (>= 0.4.0)
38
38
  jeweler (>= 1.8.3)
39
39
  minitest (>= 2.12.1)
40
40
  mocha (>= 0.11.0)
41
41
  net-ssh (>= 2.3.0)
42
+ posix-spawn (>= 0.3.6)
43
+ redcarpet (>= 2.1.1)
42
44
  simplecov (>= 0.6.1)
43
45
  uuid (>= 2.3.5)
44
- yard (>= 0.7.5)
46
+ yard (>= 0.8.1)
data/README.markdown CHANGED
@@ -28,7 +28,7 @@ Running tests relies on a few command-line tools.
28
28
  On Fedora, use the following command to install the packages.
29
29
 
30
30
  ```bash
31
- sudo yum install advancecomp curl mkisofs p7zip squashfs-tools
31
+ sudo yum install -y advancecomp curl mkisofs p7zip p7zip-plugins squashfs-tools
32
32
  ```
33
33
 
34
34
  On OSX, run the following command.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.1
1
+ 0.1.2
@@ -8,13 +8,31 @@ module VirtualBox
8
8
  # Runs a command in a sub-shell, waiting until the command completes.
9
9
  #
10
10
  # @param [Array<String>] args the name and arguments for the command to be run
11
- #
12
- # @return [Hashie::Mash<Symbol, String>] hash with the following keys / methods:
11
+ # @return [Hash<Symbol, String>] hash with the following keys:
13
12
  # :status:: the command's exit status
14
13
  # :output:: a string with the command's output
15
14
  def self.run_command(args)
16
- output = Kernel.`(Shellwords.shelljoin(args))
17
- Hashie::Mash.new :status => $CHILD_STATUS.exitstatus, :output => output
15
+ begin
16
+ output = Kernel.`(Shellwords.shelljoin(args) + ' 2>&1')
17
+ { :status => $CHILD_STATUS.exitstatus, :output => output }
18
+
19
+ # TODO(pwnall): this should work, but it makes VirtualBox slow as hell
20
+ # child = POSIX::Spawn::Child.new(*args)
21
+ # Hashie::Mash.new :status => child.status.exitstatus, :output => child.out
22
+ rescue SystemCallError
23
+ { :status => -1, :output => '' }
24
+ end
25
+ end
26
+
27
+ # Runs a command in a sub-shell, waiting until the command completes.
28
+ #
29
+ # @param [Array<String>] args the name and arguments for the command to be run
30
+ # @return [String] the command's output
31
+ # @raise [VirtualBox::Error] if the command exits with a non-zero code
32
+ def self.run_command!(args)
33
+ result = run_command args
34
+ raise VirtualBox::Error, result unless result[:status] == 0
35
+ result[:output]
18
36
  end
19
37
 
20
38
  end # namespace VirtualBox
@@ -0,0 +1,25 @@
1
+ module VirtualBox
2
+
3
+ # Raised when the VirtualBox CLI returns a non-zero error code.
4
+ class Error < StandardError
5
+ # The exit code of the failed VirtualBox command.
6
+ # @return [Integer]
7
+ attr_reader :exit_code
8
+
9
+ # The combined stdout and stderr of the failed VirtualBox command.
10
+ # @return [String]
11
+ attr_reader :output
12
+
13
+ # Called by raise.
14
+ #
15
+ # @param [Hash<Symbol, Object>] cli_result the return value of a
16
+ # VirtualBox.run call.
17
+ def initialize(cli_result)
18
+ @exit_code = cli_result[:status]
19
+ @output = output
20
+
21
+ super "VirtualBox CLI exited with code #{@exit_code}:\n#{@output}\n"
22
+ end
23
+ end # class VirtualBox::Error
24
+
25
+ end # namespace VirtualBox
@@ -1,14 +1,9 @@
1
1
  module VirtualBox
2
2
 
3
+ class Net
4
+
3
5
  # Specification for a virtual DHCP server.
4
6
  class Dhcp
5
- # The name of the VirtualBox network served by this DHCP server.
6
- #
7
- # This name must match the name of a host-only or internal network that is
8
- # registered with VirtualBox.
9
- # @return [String]
10
- attr_accessor :net_name
11
-
12
7
  # This DHCP server's IP address on the virtual network that it serves.
13
8
  # @return [String]
14
9
  attr_accessor :ip
@@ -66,48 +61,54 @@ class Dhcp
66
61
  :start_ip => start_ip, :end_ip => end_ip }
67
62
  end
68
63
 
69
- # True if this DHCP rule has been registered with VirtualBox.
70
- def live?
71
- servers = self.class.all
72
- dhcp = servers.find { |server| server.net_name == net_name }
73
- dhcp ? true : false
74
- end
75
-
76
64
  # Adds this DHCP server to VirtualBox.
77
65
  #
78
- # @return [VirtualBox::Dhcp] self, for easy call chaining
79
- def add
80
- remove if live?
81
-
82
- result = VirtualBox.run_command ['VBoxManage', 'dhcpserver', 'add',
83
- '--netname', net_name, '--ip', ip, '--netmask', netmask,
84
- '--lowerip', start_ip, '--upperip', end_ip, '--enable']
85
- if result.status != 0
86
- raise 'Unexpected error code returned by VirtualBox'
66
+ # @param [String, VirtualBox::Net] net_or_name the name of the VirtualBox
67
+ # virtual network that this server will be connected to
68
+ # @return [VirtualBox::Net::Dhcp] self, for easy call chaining
69
+ def add(net_or_name)
70
+ command = ['VBoxManage', 'dhcpserver', 'add', '--ip', ip,
71
+ '--netmask', netmask, '--lowerip', start_ip, '--upperip', end_ip,
72
+ '--enable']
73
+ if net_or_name.kind_of? VirtualBox::Net
74
+ command.push '--ifname', net_or_name.if_name
75
+ else
76
+ command.push '--netname', net_or_name
87
77
  end
78
+
79
+ VirtualBox.run_command! command
88
80
  self
89
81
  end
90
82
 
91
83
  # Removes this DHCP server from VirtualBox.
92
84
  #
93
- # @return [VirtualBox::Dhcp] self, for easy call chaining
94
- def remove
95
- VirtualBox.run_command ['VBoxManage', 'dhcpserver', 'remove', '--netname',
96
- net_name]
85
+ # @param [String, VirtualBox::Net] net_or_name the name of the VirtualBox
86
+ # virtual network that this server was connected to
87
+ # @return [VirtualBox::Net::Dhcp] self, for easy call chaining
88
+ def remove(net_or_name)
89
+ command = ['VBoxManage', 'dhcpserver', 'remove']
90
+ if net_or_name.kind_of? VirtualBox::Net
91
+ command.push '--ifname', net_or_name.if_name
92
+ else
93
+ command.push '--netname', net_or_name
94
+ end
95
+
96
+ VirtualBox.run_command command
97
97
  self
98
98
  end
99
99
 
100
100
  # The DHCP servers added to with VirtualBox.
101
101
  #
102
- # @return [Array<VirtualBox::Dhcp>] all the DHCP servers added to VirtualBox
102
+ # @return [Hash<String, VirtualBox::Dhcp>] all the DHCP servers added to
103
+ # VirtualBox, indexed by the name of the virtual network that they serve
103
104
  def self.all
104
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list', '--long',
105
- 'dhcpservers']
106
- if result.status != 0
107
- raise 'Unexpected error code returned by VirtualBox'
108
- end
109
- result.output.split("\n\n").
110
- map { |dhcp_info| new.from_dhcp_info(dhcp_info) }
105
+ output = VirtualBox.run_command! ['VBoxManage', '--nologo', 'list',
106
+ '--long', 'dhcpservers']
107
+ Hash[output.split("\n\n").map { |dhcp_info|
108
+ dhcp = new
109
+ if_name = dhcp.from_dhcp_info(dhcp_info)
110
+ [if_name, dhcp]
111
+ }]
111
112
  end
112
113
 
113
114
  # Parses information about a DHCP server returned by VirtualBox.
@@ -115,18 +116,18 @@ class Dhcp
115
116
  # The parsed information is used to replace this network's specification.
116
117
  # @param [String] dhcp_info output from "VBoxManage list --long dhcpservers"
117
118
  # for one server
118
- # @return [VirtualBox::Dhcp] self, for easy call chaining
119
+ # @return [String] the name of the virtual network served by this DHCP server
119
120
  def from_dhcp_info(dhcp_info)
120
121
  info = Hash[dhcp_info.split("\n").map { |line|
121
122
  line.split(':', 2).map(&:strip)
122
123
  }]
123
124
 
124
- self.net_name = info['NetworkName']
125
125
  self.ip = info['IP']
126
126
  self.netmask = info['NetworkMask']
127
127
  self.start_ip = info['lowerIPAddress']
128
128
  self.end_ip = info['upperIPAddress']
129
- self
129
+
130
+ info['NetworkName']
130
131
  end
131
132
 
132
133
  # Converts an IP number into a string.
@@ -144,6 +145,8 @@ class Dhcp
144
145
  def self.ip_stob(ip_string)
145
146
  ip_string.split('.').map(&:to_i).pack('C*').unpack('N').first
146
147
  end
147
- end # class VirtualBox::Dhcp
148
+ end # class VirtualBox::Net::Dhcp
149
+
150
+ end # class VirtualBox::Net
148
151
 
149
152
  end # namespace VirtualBox
@@ -34,6 +34,21 @@ class Net
34
34
  # @return [String]
35
35
  attr_reader :mac
36
36
 
37
+ # The VirtualBox-powered DHCP server configured to serve this interface.
38
+ # @return [VirtualBox::Net::Dhcp, NilClass]
39
+ attr_accessor :dhcp
40
+
41
+ undef :dhcp=
42
+ def dhcp=(new_dhcp)
43
+ if new_dhcp.nil?
44
+ @dhcp = nil
45
+ elsif new_dhcp.kind_of? VirtualBox::Net::Dhcp
46
+ @dhcp = new_dhcp
47
+ else
48
+ @dhcp = VirtualBox::Net::Dhcp.new new_dhcp
49
+ end
50
+ end
51
+
37
52
  # Creates a virtual network specification rule based on the given attributes.
38
53
  #
39
54
  # The network is not automatically added to VirtualBox.
@@ -48,7 +63,7 @@ class Net
48
63
  # @return [Hash<Symbol, Object>] Ruby-friendly Hash that can be used to
49
64
  # re-create this virtual network specification
50
65
  def to_hash
51
- { :ip => ip, :netmask => netmask }
66
+ { :ip => ip, :netmask => netmask, :dhcp => dhcp && dhcp.to_hash }
52
67
  end
53
68
 
54
69
  # True if this virtual network has been added to VirtualBox.
@@ -68,12 +83,9 @@ class Net
68
83
  end
69
84
 
70
85
  # Create the network and pull its name.
71
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'hostonlyif',
72
- 'create']
73
- if result.status != 0
74
- raise 'Unexpected error code returned by VirtualBox'
75
- end
76
- unless match = /^interface\s+'(.*)'\s+.*created/i.match(result.output)
86
+ output = VirtualBox.run_command! ['VBoxManage', '--nologo', 'hostonlyif',
87
+ 'create']
88
+ unless match = /^interface\s+'(.*)'\s+.*created/i.match(output)
77
89
  raise "VirtualBox output does not include interface name"
78
90
  end
79
91
  @if_name = match[1]
@@ -85,16 +97,16 @@ class Net
85
97
  @mac = network.mac
86
98
 
87
99
  if (ip && ip != network.ip) || (netmask && netmask != network.netmask)
88
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'hostonlyif',
100
+ VirtualBox.run_command! ['VBoxManage', '--nologo', 'hostonlyif',
89
101
  'ipconfig', if_name, '--ip', ip, '--netmask', netmask]
90
- if result.status != 0
91
- raise 'Unexpected error code returned by VirtualBox'
92
- end
93
102
  else
94
103
  self.ip = network.ip
95
104
  self.netmask = network.netmask
96
105
  end
97
106
 
107
+ # Register the DHCP server, if it's connected.
108
+ dhcp.add self if dhcp
109
+
98
110
  self
99
111
  end
100
112
 
@@ -103,22 +115,25 @@ class Net
103
115
  # @return [VirtualBox::Net] self, for easy call chaining
104
116
  def remove
105
117
  unless if_name.nil?
118
+ dhcp.remove self if dhcp
106
119
  VirtualBox.run_command ['VBoxManage', 'hostonlyif', 'remove', if_name]
107
120
  end
108
121
  self
109
122
  end
110
123
 
111
- # The DHCP servers added to with VirtualBox.
124
+ # The virtual networks added to VirtualBox.
112
125
  #
113
- # @return [Array<VirtualBox::Dhcp>] all the DHCP servers added to VirtualBox
126
+ # @return [Array<VirtualBox::Net>] all the DHCP servers added to VirtualBox
114
127
  def self.all
115
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list', '--long',
116
- 'hostonlyifs']
117
- if result.status != 0
118
- raise 'Unexpected error code returned by VirtualBox'
128
+ dhcps = VirtualBox::Net::Dhcp.all
129
+
130
+ output = VirtualBox.run_command! ['VBoxManage', '--nologo', 'list',
131
+ '--long', 'hostonlyifs']
132
+ output.split("\n\n").map do |net_info|
133
+ net = new.from_net_info(net_info)
134
+ net.dhcp = dhcps[net.name]
135
+ net
119
136
  end
120
- result.output.split("\n\n").
121
- map { |net_info| new.from_net_info(net_info) }
122
137
  end
123
138
 
124
139
  # Parses information about a DHCP server returned by VirtualBox.
@@ -139,6 +154,37 @@ class Net
139
154
  self.netmask = info['NetworkMask']
140
155
  self
141
156
  end
142
- end # class VirtualBox::Dhcp
157
+
158
+
159
+ # Information about the NICs attached to the computer.
160
+ #
161
+ # @return [Array<Hash<Symbol, Object>>] an array with one hash per NIC; hashes
162
+ # have the following keys:
163
+ # :name:: the NIC device's name (use when setting a Nic's net_name)
164
+ # :ip:: the IP address (compare against 0.0.0.0 to see if it's live)
165
+ # :mask:: the network mask used to figure out broadcasting
166
+ # :mac:: the NICs MAC address (format: "AB0123456789")
167
+ def self.host_nics
168
+ @host_nics ||= host_nics!
169
+ end
170
+
171
+ # Queries VirtualBox for the network interfaces on the computer.
172
+ #
173
+ # @return (see .host_nics)
174
+ def self.host_nics!
175
+ output = VirtualBox.run_command! ['VBoxManage', '--nologo', 'list',
176
+ '--long', 'hostifs']
177
+ output.split("\n\n").map do |nic_info|
178
+ info = Hash[nic_info.split("\n").map { |line|
179
+ line.split(':', 2).map(&:strip)
180
+ }]
181
+ {
182
+ :name => info['Name'], :ip => info['IPAddress'],
183
+ :mask => info['NetworkMask'],
184
+ :mac => info['HardwareAddress'].upcase.gsub(/[^0-9A-F]/, '')
185
+ }
186
+ end
187
+ end
188
+ end # class VirtualBox::Net
143
189
 
144
190
  end # namespace VirtualBox
@@ -8,10 +8,10 @@ module VirtualBox
8
8
  # The open-source edition of VirtualBox has some limitations, such as no
9
9
  # support for RDP and USB devices.
10
10
  def self.ose?
11
- unless version.edition
11
+ unless version[:edition]
12
12
  raise 'VirtualBox is not installed on this machine.'
13
13
  end
14
- version.edition == 'OSE'
14
+ version[:edition] == 'OSE'
15
15
  end
16
16
 
17
17
  # Version information about the VirtualBox package installed on this machine.
@@ -26,12 +26,12 @@ module VirtualBox
26
26
  return @version_info unless @version_info.nil?
27
27
 
28
28
  cmd_result = run_command ['VBoxManage', '--version']
29
- if cmd_result.status != 0
30
- @version_info = Hashie::Mash.new
29
+ if cmd_result[:status] != 0
30
+ @version_info = {}
31
31
  return @version_info
32
32
  end
33
33
 
34
- output = cmd_result.output.strip
34
+ output = cmd_result[:output].strip
35
35
 
36
36
  if revision_offset = output.rindex('r')
37
37
  revision = output[revision_offset + 1, output.length].to_i
@@ -47,8 +47,8 @@ module VirtualBox
47
47
  edition = ''
48
48
  end
49
49
 
50
- @version_info = Hashie::Mash.new :release => output, :svn => revision,
51
- :edition => edition
50
+ @version_info = { :release => output, :svn => revision,
51
+ :edition => edition }
52
52
  end
53
53
 
54
54
  # Removes the cached information on the VirtualBox package version.
@@ -272,13 +272,9 @@ class Board
272
272
  # @return [Hash<String, String> mapping from each VirtualBox OS type ID to its
273
273
  # description
274
274
  def self.list_os_types
275
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list',
276
- '--long', 'ostypes']
277
- if result.status != 0
278
- raise 'Unexpected error code returned by VirtualBox'
279
- end
280
-
281
- types = result.output.split("\n\n").map do |os_info|
275
+ output = VirtualBox.run_command! ['VBoxManage', '--nologo', 'list',
276
+ '--long', 'ostypes']
277
+ types = output.split("\n\n").map do |os_info|
282
278
  i = Hash[os_info.split("\n").map { |line| line.split(':').map(&:strip) }]
283
279
  [i['ID'], i['Description']]
284
280
  end
@@ -55,12 +55,9 @@ class Disk
55
55
  when :dvd
56
56
  'dvddrive'
57
57
  end
58
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'storageattach',
58
+ VirtualBox.run_command! ['VBoxManage', '--nologo', 'storageattach',
59
59
  vm.uid, '--storagectl', io_bus.name, '--port', port.to_s,
60
60
  '--device', device.to_s, '--type', media_arg, '--medium', file]
61
- if result.status != 0
62
- raise 'Unexpected error code returned by VirtualBox'
63
- end
64
61
  self
65
62
  end
66
63
 
@@ -90,13 +87,9 @@ class Disk
90
87
  memo = options[:memo] || 'Created with the virtual_box RubyGem'
91
88
  variant = options[:prealloc] ? 'Fixed' : 'Standard'
92
89
 
93
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'createhd',
90
+ VirtualBox.run_command! ['VBoxManage', '--nologo', 'createhd',
94
91
  '--filename', path, '--size', size_mb.to_s, '--format', format.to_s,
95
92
  '--variant', variant]
96
- if result.status != 0
97
- raise 'Unexpected error code returned by VirtualBox'
98
- end
99
-
100
93
  new :file => path, :format => format, :media => :disk
101
94
  end
102
95
 
@@ -209,11 +209,8 @@ class IoBus
209
209
  # be removed from
210
210
  # @return [VirtualBox::Vm::IoBus] self, for easy call chaining
211
211
  def remove_from(vm)
212
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'storagectl',
213
- vm.uuid, '--name', name, '--remove']
214
- if result.status != 0
215
- raise 'Unexpected error code returned by VirtualBox'
216
- end
212
+ VirtualBox.run_command! ['VBoxManage', '--nologo', 'storagectl', vm.uuid,
213
+ '--name', name, '--remove']
217
214
  self
218
215
  end
219
216
 
@@ -223,11 +220,8 @@ class IoBus
223
220
  # added to
224
221
  # @return [VirtualBox::Vm::IoBus] self, for easy call chaining
225
222
  def add_bus_to(vm)
226
- command = ['VBoxManage', '--nologo', 'storagectl', vm.uid].concat to_params
227
- result = VirtualBox.run_command command
228
- if result.status != 0
229
- raise 'Unexpected error code returned by VirtualBox'
230
- end
223
+ VirtualBox.run_command! ['VBoxManage', '--nologo', 'storagectl',
224
+ vm.uid].concat(to_params)
231
225
  self
232
226
  end
233
227
 
@@ -177,39 +177,6 @@ class Nic
177
177
  { :mode => mode, :chip => chip, :net_name => net_name, :mac => mac,
178
178
  :trace_file => trace_file }
179
179
  end
180
-
181
- # Information about the NICs attached to the computer.
182
- #
183
- # @return [Array<Hash<Symbol, Object>>] an array with one hash per NIC; hashes
184
- # have the following keys:
185
- # :id:: the inteface id (use when setting a Nic's net_id)
186
- # :ip:: the IP address (check for 0.0.0.0 to see if it's live)
187
- # :mask:: the netmask
188
- # :mac:: the NICs MAC address
189
- def self.host_nics
190
- @host_nics ||= get_host_nics
191
- end
192
-
193
- # Queries VirtualBox for the network interfaces on the computer.
194
- #
195
- # @return (see .host_nics)
196
- def self.get_host_nics
197
- result = VirtualBox.run_command ['VBoxManage', '--nologo', 'list',
198
- '--long', 'hostifs']
199
- if result.status != 0
200
- raise 'Unexpected error code returned by VirtualBox'
201
- end
202
-
203
- result.output.split("\n\n").map do |nic_info|
204
- i = Hash[nic_info.split("\n").map { |line|
205
- line.split(':', 2).map(&:strip)
206
- }]
207
- {
208
- :id => i['Name'], :ip => i['IPAddress'], :mask => i['NetworkMask'],
209
- :mac => i['HardwareAddress'].upcase.gsub(/[^0-9A-F]/, '')
210
- }
211
- end
212
- end
213
180
  end # class VirtualBox::Vm::Nic
214
181
 
215
182
  end # class VirtualBox::Vm