costan-virtual_box 0.0.2 → 0.0.3

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