costan-virtual_box 0.0.2 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +2 -0
- data/lib/virtual_box/registry.rb +23 -8
- data/lib/virtual_box/vm/lifecycle.rb +36 -8
- data/test/lifecycle_test.rb +54 -9
- data/test/registry_test.rb +29 -11
- data/virtual_box.gemspec +2 -2
- metadata +2 -2
data/CHANGELOG
CHANGED
data/lib/virtual_box/registry.rb
CHANGED
@@ -6,16 +6,11 @@
|
|
6
6
|
|
7
7
|
# :nodoc: namespace
|
8
8
|
module VirtualBox
|
9
|
-
#
|
9
|
+
# Parses a VBoxManage command result into VM metadata information.
|
10
10
|
#
|
11
|
-
#
|
12
|
-
|
13
|
-
# returns nil.
|
14
|
-
def self.all_vms_metadata
|
15
|
-
result = VirtualBox.shell_command('VBoxManage --nologo list vms')
|
11
|
+
# This method works for 'VBoxManage show vms | runningvms'
|
12
|
+
def self._vm_metadata_from_command_result(result)
|
16
13
|
return nil unless result[:status] == 0
|
17
|
-
|
18
|
-
|
19
14
|
vms = []
|
20
15
|
result[:output].each_line do |line|
|
21
16
|
line.strip!
|
@@ -25,4 +20,24 @@ module VirtualBox
|
|
25
20
|
end
|
26
21
|
vms
|
27
22
|
end
|
23
|
+
|
24
|
+
# The names and UUIDs of all the VMs registered with VirtualBox.
|
25
|
+
#
|
26
|
+
# Returns an array with one hash per registered VM. Each hash has the keys
|
27
|
+
# +:name+ and +:uuid+. In case of failure (e.g. VirtualBox is not installed),
|
28
|
+
# returns nil.
|
29
|
+
def self.all_vms_metadata
|
30
|
+
result = VirtualBox.shell_command('VBoxManage --nologo list vms')
|
31
|
+
_vm_metadata_from_command_result result
|
32
|
+
end
|
33
|
+
|
34
|
+
# The names and UUIDs of the VMs running inside VirtualBox right now.
|
35
|
+
#
|
36
|
+
# Returns an array with one hash per running VM. Each hash has the keys
|
37
|
+
# +:name+ and +:uuid+. In case of failure (e.g. VirtualBox is not installed),
|
38
|
+
# returns nil.
|
39
|
+
def self.running_vms_metadata
|
40
|
+
result = VirtualBox.shell_command('VBoxManage --nologo list runningvms')
|
41
|
+
_vm_metadata_from_command_result result
|
42
|
+
end
|
28
43
|
end # namespace VirtualBox
|
@@ -22,17 +22,43 @@ module Lifecycle
|
|
22
22
|
# support is disabled; VirtualBox OSE does not support RDP, so the
|
23
23
|
# call will raise an exception
|
24
24
|
def start(options = {})
|
25
|
-
if options[:gui]
|
26
|
-
command = "VBoxManage --nologo startvm #{uuid} --type gui"
|
27
|
-
else
|
28
|
-
command = "VBoxHeadless --startvm #{uuid}"
|
29
|
-
end
|
30
|
-
|
31
25
|
if VirtualBox.ose?
|
32
26
|
raise 'Cannot enable RDP support on VirtualBox OSE' if options[:rdp]
|
27
|
+
end
|
28
|
+
|
29
|
+
if options[:gui]
|
30
|
+
command = "VBoxManage --nologo startvm #{uuid} --type gui"
|
33
31
|
else
|
34
|
-
command
|
32
|
+
command = "VBoxManage --nologo startvm #{uuid} --type headless"
|
35
33
|
end
|
34
|
+
return false unless VirtualBox.shell_command(command)[:status] == 0
|
35
|
+
|
36
|
+
options[:rdp] ? control(:vrdp, :on) : true
|
37
|
+
end
|
38
|
+
|
39
|
+
# Stops the virtual machine simulation.
|
40
|
+
#
|
41
|
+
# This is equivalent to pulling the power cord from a physical machine.
|
42
|
+
#
|
43
|
+
# Returns +true+ for success, and +false+ for failure.
|
44
|
+
def stop
|
45
|
+
control :power_off
|
46
|
+
end
|
47
|
+
|
48
|
+
# Controls a started virtual machine.
|
49
|
+
#
|
50
|
+
# The following actions are supported:
|
51
|
+
# :power_off:: hard power-off (pulling the power cord from the machine)
|
52
|
+
# :acpi_power_button:: Power button press
|
53
|
+
# :inject_nmi:: NMI (non-maskable interrupt)
|
54
|
+
# :vrdp:: enables or disables the VM's RDP server (set +action_data+ to :on
|
55
|
+
# or :off)
|
56
|
+
#
|
57
|
+
# Returns +true+ for success, and +false+ for failure.
|
58
|
+
def control(action, action_data = nil)
|
59
|
+
action = action.to_s.gsub '_', ''
|
60
|
+
command = "VBoxManage --nologo controlvm #{uuid} #{action}"
|
61
|
+
command += " #{action_data}" if action_data
|
36
62
|
VirtualBox.shell_command(command)[:status] == 0
|
37
63
|
end
|
38
64
|
|
@@ -41,7 +67,9 @@ module Lifecycle
|
|
41
67
|
# Args:
|
42
68
|
# config_path:: path to the VM configuration file that will be created
|
43
69
|
#
|
44
|
-
def create_configuration(config_path = nil)
|
70
|
+
def create_configuration(config_path = nil)
|
71
|
+
raise 'Cannot create a configuration without a VM name' unless name
|
72
|
+
|
45
73
|
command = %|VBoxManage --nologo createvm --name "#{name}"|
|
46
74
|
if config_path
|
47
75
|
command += %| --settingsfile "#{File.expand_path config_path}"|
|
data/test/lifecycle_test.rb
CHANGED
@@ -112,7 +112,7 @@ class LifecycleTest < Test::Unit::TestCase
|
|
112
112
|
|
113
113
|
def test_register_unregister_configuration_live
|
114
114
|
@vm.name = 'virtual_box test Register'
|
115
|
-
assert @vm.create_configuration('./
|
115
|
+
assert @vm.create_configuration('./register_test.xml'),
|
116
116
|
'Configuration creation failed'
|
117
117
|
assert @vm.register_configuration, 'Registration failed'
|
118
118
|
|
@@ -129,7 +129,7 @@ class LifecycleTest < Test::Unit::TestCase
|
|
129
129
|
def test_start
|
130
130
|
flexmock(VirtualBox).should_receive(:ose?).and_return(false)
|
131
131
|
flexmock(VirtualBox).should_receive(:shell_command).once.
|
132
|
-
with("
|
132
|
+
with("VBoxManage --nologo startvm #{@uuid} --type headless").
|
133
133
|
and_return({:status => 0, :output => ""})
|
134
134
|
|
135
135
|
assert @vm.start
|
@@ -138,7 +138,10 @@ class LifecycleTest < Test::Unit::TestCase
|
|
138
138
|
def test_start_rdp
|
139
139
|
flexmock(VirtualBox).should_receive(:ose?).and_return(false)
|
140
140
|
flexmock(VirtualBox).should_receive(:shell_command).once.
|
141
|
-
with("
|
141
|
+
with("VBoxManage --nologo startvm #{@uuid} --type headless").
|
142
|
+
and_return({:status => 0, :output => ""})
|
143
|
+
flexmock(VirtualBox).should_receive(:shell_command).once.
|
144
|
+
with("VBoxManage --nologo controlvm #{@uuid} vrdp on").
|
142
145
|
and_return({:status => 0, :output => ""})
|
143
146
|
|
144
147
|
assert @vm.start(:rdp => true)
|
@@ -146,11 +149,7 @@ class LifecycleTest < Test::Unit::TestCase
|
|
146
149
|
|
147
150
|
def test_start_with_ose
|
148
151
|
flexmock(VirtualBox).should_receive(:ose?).and_return(true)
|
149
|
-
|
150
|
-
with("VBoxHeadless --startvm #{@uuid}").
|
151
|
-
and_return({:status => 0, :output => ""})
|
152
|
-
|
153
|
-
assert @vm.start
|
152
|
+
test_start
|
154
153
|
end
|
155
154
|
|
156
155
|
def test_start_rdp_with_ose
|
@@ -164,9 +163,55 @@ class LifecycleTest < Test::Unit::TestCase
|
|
164
163
|
def test_start_gui_with_error
|
165
164
|
flexmock(VirtualBox).should_receive(:ose?).and_return(false)
|
166
165
|
flexmock(VirtualBox).should_receive(:shell_command).once.
|
167
|
-
with("VBoxManage --nologo startvm #{@uuid} --type gui
|
166
|
+
with("VBoxManage --nologo startvm #{@uuid} --type gui").
|
168
167
|
and_return({:status => 127, :output => ""})
|
169
168
|
|
170
169
|
assert_equal false, @vm.start(:gui => true)
|
171
170
|
end
|
171
|
+
|
172
|
+
def test_start_rdp_with_error
|
173
|
+
flexmock(VirtualBox).should_receive(:ose?).and_return(false)
|
174
|
+
flexmock(VirtualBox).should_receive(:shell_command).once.
|
175
|
+
with("VBoxManage --nologo startvm #{@uuid} --type headless").
|
176
|
+
and_return({:status => 0, :output => ""})
|
177
|
+
flexmock(VirtualBox).should_receive(:shell_command).once.
|
178
|
+
with("VBoxManage --nologo controlvm #{@uuid} vrdp on").
|
179
|
+
and_return({:status => 127, :output => ""})
|
180
|
+
|
181
|
+
assert_equal false, @vm.start(:rdp => true)
|
182
|
+
end
|
183
|
+
|
184
|
+
def test_stop
|
185
|
+
flexmock(VirtualBox).should_receive(:shell_command).once.
|
186
|
+
with("VBoxManage --nologo controlvm #{@uuid} poweroff").
|
187
|
+
and_return({:status => 0, :output => ""})
|
188
|
+
|
189
|
+
assert_equal true, @vm.stop
|
190
|
+
end
|
191
|
+
|
192
|
+
def test_stop_error
|
193
|
+
flexmock(VirtualBox).should_receive(:shell_command).once.
|
194
|
+
and_return({:status => 127, :output => ""})
|
195
|
+
assert_equal false, @vm.stop
|
196
|
+
end
|
197
|
+
|
198
|
+
def test_start_stop_live
|
199
|
+
@vm.name = 'virtual_box test Start'
|
200
|
+
assert @vm.create_configuration('./start_test.xml'),
|
201
|
+
'Configuration creation failed'
|
202
|
+
assert @vm.register_configuration, 'Registration failed'
|
203
|
+
|
204
|
+
assert @vm.start, 'Starting failed'
|
205
|
+
Kernel.sleep 0.5 # Wait for the VM to start.
|
206
|
+
vm_metadata = {:name => @vm.name, :uuid => @vm.uuid}
|
207
|
+
assert VirtualBox.running_vms_metadata.include?(vm_metadata),
|
208
|
+
'Running VM does not show up in listing'
|
209
|
+
assert @vm.stop, 'Stopping failed'
|
210
|
+
Kernel.sleep 0.5 # Wait for the VM to die.
|
211
|
+
assert !VirtualBox.running_vms_metadata.include?(vm_metadata),
|
212
|
+
'Unregistred VM still shows up in listing'
|
213
|
+
|
214
|
+
assert @vm.unregister_configuration, 'Unregistration failed'
|
215
|
+
assert @vm.delete_configuration, 'Configuration deletion failed'
|
216
|
+
end
|
172
217
|
end
|
data/test/registry_test.rb
CHANGED
@@ -23,24 +23,42 @@ class RegistryTest < Test::Unit::TestCase
|
|
23
23
|
with('VBoxManage --nologo list vms').
|
24
24
|
and_return({:status => 0, :output => mock_output})
|
25
25
|
|
26
|
-
|
27
|
-
assert_equal 2, vms.length, 'Wrong VM count'
|
28
|
-
assert_equal({:name => 'TEM',
|
29
|
-
:uuid => '0e6e5f5c-7438-4a4c-94cf-39b79b28f8e3'},
|
30
|
-
vms.first)
|
31
|
-
assert_equal({:name => 'TEM Firmware IDE',
|
32
|
-
:uuid => '0c21709e-7f29-41c0-a0ac-ff528f50edbf'},
|
33
|
-
vms.last)
|
26
|
+
_check_vm_metadata VirtualBox.all_vms_metadata
|
34
27
|
end
|
35
28
|
|
36
29
|
def test_all_vms_metadata_error
|
37
30
|
flexmock(VirtualBox).should_receive(:shell_command).
|
38
|
-
|
39
|
-
and_return({:status => 127, :output => 'Command not found'})
|
40
|
-
|
31
|
+
and_return({:status => 127, :output => 'Command not found'})
|
41
32
|
assert_nil VirtualBox.all_vms_metadata
|
42
33
|
end
|
43
34
|
|
35
|
+
def test_running_vms_metadata
|
36
|
+
mock_output = File.read File.join(@testdata_path,
|
37
|
+
'list_vms_output.txt')
|
38
|
+
|
39
|
+
flexmock(VirtualBox).should_receive(:shell_command).
|
40
|
+
with('VBoxManage --nologo list runningvms').
|
41
|
+
and_return({:status => 0, :output => mock_output})
|
42
|
+
|
43
|
+
_check_vm_metadata VirtualBox.running_vms_metadata
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_running_vms_metadata_error
|
47
|
+
flexmock(VirtualBox).should_receive(:shell_command).
|
48
|
+
and_return({:status => 127, :output => 'Command not found'})
|
49
|
+
assert_nil VirtualBox.running_vms_metadata
|
50
|
+
end
|
51
|
+
|
52
|
+
def _check_vm_metadata(metadata)
|
53
|
+
assert_equal 2, metadata.length, 'Wrong VM count'
|
54
|
+
assert_equal({:name => 'TEM',
|
55
|
+
:uuid => '0e6e5f5c-7438-4a4c-94cf-39b79b28f8e3'},
|
56
|
+
metadata.first)
|
57
|
+
assert_equal({:name => 'TEM Firmware IDE',
|
58
|
+
:uuid => '0c21709e-7f29-41c0-a0ac-ff528f50edbf'},
|
59
|
+
metadata.last)
|
60
|
+
end
|
61
|
+
|
44
62
|
# NOTE: The live test for all_vms_metadata is done in lifecycle_test.rb, under
|
45
63
|
# test_register_unregister_configurations_live
|
46
64
|
end
|
data/virtual_box.gemspec
CHANGED
@@ -2,11 +2,11 @@
|
|
2
2
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = %q{virtual_box}
|
5
|
-
s.version = "0.0.
|
5
|
+
s.version = "0.0.3"
|
6
6
|
|
7
7
|
s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
|
8
8
|
s.authors = ["Victor Costan"]
|
9
|
-
s.date = %q{2009-08-
|
9
|
+
s.date = %q{2009-08-31}
|
10
10
|
s.description = %q{Ruby API for VirtualBox (Sun's OSS virtualization software).}
|
11
11
|
s.email = %q{victor@zergling.net}
|
12
12
|
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README.textile", "lib/virtual_box.rb", "lib/virtual_box/command_line.rb", "lib/virtual_box/registry.rb", "lib/virtual_box/version.rb", "lib/virtual_box/vm.rb", "lib/virtual_box/vm/general_settings.rb", "lib/virtual_box/vm/identity.rb", "lib/virtual_box/vm/lifecycle.rb"]
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: costan-virtual_box
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Victor Costan
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-08-
|
12
|
+
date: 2009-08-31 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|