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 CHANGED
@@ -1,3 +1,5 @@
1
+ v0.0.3. VM life-cycle management: start and stop.
2
+
1
3
  v0.0.2. Configuration life-cycle management: VM creation and registration.
2
4
 
3
5
  v0.0.1. Initial release.
@@ -6,16 +6,11 @@
6
6
 
7
7
  # :nodoc: namespace
8
8
  module VirtualBox
9
- # The names and UUIDs of all the VMs registered with VirtualBox.
9
+ # Parses a VBoxManage command result into VM metadata information.
10
10
  #
11
- # Returns an array with one hash per registered VM. Each hash has the keys
12
- # +:name+ and +:uuid+. In case of failure (e.g. VirtualBox is not installed),
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 += " --vrdp #{options[:rdp] ? 'on' : 'off'}"
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}"|
@@ -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('./create_test.xml'),
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("VBoxHeadless --startvm #{@uuid} --vrdp off").
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("VBoxHeadless --startvm #{@uuid} --vrdp on").
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
- flexmock(VirtualBox).should_receive(:shell_command).once.
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 --vrdp off").
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
@@ -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
- vms = VirtualBox.all_vms_metadata
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
- with('VBoxManage --nologo list vms').
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
@@ -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.2"
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-30}
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.2
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-30 00:00:00 -07:00
12
+ date: 2009-08-31 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency