costan-virtual_box 0.0.1 → 0.0.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/CHANGELOG CHANGED
@@ -1 +1,3 @@
1
+ v0.0.2. Configuration life-cycle management: VM creation and registration.
2
+
1
3
  v0.0.1. Initial release.
data/Manifest CHANGED
@@ -1,17 +1,21 @@
1
1
  CHANGELOG
2
+ LICENSE
3
+ Manifest
4
+ README.textile
5
+ Rakefile
6
+ lib/virtual_box.rb
2
7
  lib/virtual_box/command_line.rb
8
+ lib/virtual_box/registry.rb
3
9
  lib/virtual_box/version.rb
10
+ lib/virtual_box/vm.rb
4
11
  lib/virtual_box/vm/general_settings.rb
5
12
  lib/virtual_box/vm/identity.rb
6
13
  lib/virtual_box/vm/lifecycle.rb
7
- lib/virtual_box/vm.rb
8
- lib/virtual_box.rb
9
- LICENSE
10
- Manifest
11
- Rakefile
12
- README.textile
13
14
  test/command_line_test.rb
14
15
  test/general_settings_test.rb
15
16
  test/lifecycle_test.rb
17
+ test/registry_test.rb
16
18
  test/version_test.rb
19
+ testdata/createvm_output.txt
17
20
  testdata/golden_general_params.txt
21
+ testdata/list_vms_output.txt
@@ -5,6 +5,7 @@
5
5
  # License:: MIT
6
6
 
7
7
  require 'virtual_box/command_line.rb'
8
+ require 'virtual_box/registry.rb'
8
9
  require 'virtual_box/version.rb'
9
10
  require 'virtual_box/vm/general_settings.rb'
10
11
  require 'virtual_box/vm/identity.rb'
@@ -0,0 +1,28 @@
1
+ # VirtualBox version detection.
2
+ #
3
+ # Author:: Victor Costan
4
+ # Copyright:: Copyright (C) 2009 Zergling.Net
5
+ # License:: MIT
6
+
7
+ # :nodoc: namespace
8
+ module VirtualBox
9
+ # The names and UUIDs of all the VMs registered with VirtualBox.
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')
16
+ return nil unless result[:status] == 0
17
+
18
+
19
+ vms = []
20
+ result[:output].each_line do |line|
21
+ line.strip!
22
+ guid_start = line.rindex ?{
23
+ vms << { :name => line[1, guid_start - 3],
24
+ :uuid => line[guid_start + 1, line.length - guid_start - 2] }
25
+ end
26
+ vms
27
+ end
28
+ end # namespace VirtualBox
@@ -1,4 +1,4 @@
1
- # VM identity (name and UUID) management.
1
+ # VM identity (name, UUID, configuration file) management.
2
2
  #
3
3
  # Author:: Victor Costan
4
4
  # Copyright:: Copyright (C) 2009 Zergling.Net
@@ -18,19 +18,24 @@ module Identity
18
18
 
19
19
  # The VM's UUID (unique id).
20
20
  attr_accessor :uuid
21
-
22
- # Resets the VM's name and UUID.
21
+
22
+ attr_accessor :config_file
23
+
24
+ # Resets the VM's identity (name, UUID, configuration file).
23
25
  def reset_identity
24
26
  @name = nil
25
- @uuid = nil
27
+ @uuid = nil
28
+ @config_file = nil
26
29
  end
27
30
 
31
+ undef :uuid
28
32
  # :nodoc: documented as attribute
29
33
  def uuid
30
34
  # TODO(overmind): obtain UUID from name if it's not available
31
35
  @uuid
32
36
  end
33
37
 
38
+ undef :name
34
39
  # :nodoc: documented as attribute
35
40
  def name
36
41
  # TODO(overmind): obtain name from UUID if it's not available
@@ -23,7 +23,7 @@ module Lifecycle
23
23
  # call will raise an exception
24
24
  def start(options = {})
25
25
  if options[:gui]
26
- command = "VBoxManage startvm #{uuid} --type gui"
26
+ command = "VBoxManage --nologo startvm #{uuid} --type gui"
27
27
  else
28
28
  command = "VBoxHeadless --startvm #{uuid}"
29
29
  end
@@ -34,7 +34,64 @@ module Lifecycle
34
34
  command += " --vrdp #{options[:rdp] ? 'on' : 'off'}"
35
35
  end
36
36
  VirtualBox.shell_command(command)[:status] == 0
37
- end
37
+ end
38
+
39
+ # Creates the virtual machine configuration in VirtualBox.
40
+ #
41
+ # Args:
42
+ # config_path:: path to the VM configuration file that will be created
43
+ #
44
+ def create_configuration(config_path = nil)
45
+ command = %|VBoxManage --nologo createvm --name "#{name}"|
46
+ if config_path
47
+ command += %| --settingsfile "#{File.expand_path config_path}"|
48
+ end
49
+
50
+ result = VirtualBox.shell_command command
51
+ raise 'VM creation failed' unless result[:status] == 0
52
+
53
+ uuid_match = /^UUID: (.*)$/.match result[:output]
54
+ unless uuid_match
55
+ raise "VM creation didn't output a UUID:\n#{result[:output]}"
56
+ end
57
+ self.uuid = uuid_match[1]
58
+ config_match = /^Settings file: '(.*)'$/.match result[:output]
59
+ unless uuid_match
60
+ raise "VM creation didn't output a config file path:\n#{result[:output]}"
61
+ end
62
+ self.config_file = config_match[1]
63
+
64
+ true
65
+ end
66
+
67
+ # Registers the VM configuration with the VirtualBox installation.
68
+ #
69
+ # Returns: +true+ for success, +false+ if registration failed
70
+ def register_configuration
71
+ raise 'Call create_configuration before registering' unless config_file
72
+
73
+ command = %|VBoxManage --nologo registervm "#{config_file}"|
74
+ result = VirtualBox.shell_command command
75
+ result[:status] == 0
76
+ end
77
+
78
+ # Unregisters the VM configuration from the VirtualBox installation.
79
+ #
80
+ # Returns: +true+ for success, +false+ if de-registration failed
81
+ def unregister_configuration
82
+ raise "Can't unregister a configuration without a UUID" unless uuid
83
+
84
+ result = VirtualBox.shell_command "VBoxManage --nologo unregistervm #{uuid}"
85
+ result[:status] == 0
86
+ end
87
+
88
+ # Deletes the VM configuration.
89
+ #
90
+ # Returns: +true+ for success, +false+ if de-registration failed
91
+ def delete_configuration
92
+ File.delete config_file
93
+ true
94
+ end
38
95
  end # module Lifecycle
39
96
 
40
97
  end # class VM
@@ -8,6 +8,7 @@ require 'test/unit'
8
8
 
9
9
  class GeneralSettingsTest < Test::Unit::TestCase
10
10
  def setup
11
+ super
11
12
  @testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
12
13
  @vm = VirtualBox::VM.new
13
14
  end
@@ -13,11 +13,119 @@ class LifecycleTest < Test::Unit::TestCase
13
13
  def setup
14
14
  super
15
15
 
16
- @uuid = 'test-uuid'
16
+ @testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
17
+
18
+ @uuid = '0c21709e-7f29-41c0-a0ac-ff528f50edbf'
17
19
  @vm = VirtualBox::VM.new
18
20
  @vm.uuid = @uuid
19
21
  end
22
+
23
+
24
+ def _test_create
25
+ assert_equal @uuid, @vm.uuid, 'UUID parsing failed'
26
+ assert_equal '/Users/victor/Library/VirtualBox/Machines/virtual_box test ' +
27
+ 'Create/virtual_box test Create.xml', @vm.config_file,
28
+ 'Config file parsing failed'
29
+ end
30
+
31
+ def test_create
32
+ mock_output = File.read File.join(@testdata_path, 'createvm_output.txt')
33
+ flexmock(VirtualBox).should_receive(:shell_command).
34
+ with('VBoxManage --nologo createvm --name "virtual_box test Create"').
35
+ and_return({:status => 0, :output => mock_output})
36
+
37
+ @vm.name = 'virtual_box test Create'
38
+ assert @vm.create_configuration, 'Configuration creation failed'
39
+ end
40
+
41
+ def test_create_with_path
42
+ mock_output = File.read File.join(@testdata_path, 'createvm_output.txt')
43
+ flexmock(VirtualBox).should_receive(:shell_command).
44
+ with('VBoxManage --nologo createvm --name "virtual_box test Create"' +
45
+ ' --settingsfile "' + File.expand_path('vms/testing.xml') + '"').
46
+ and_return({:status => 0, :output => mock_output})
47
+
48
+ @vm.name = 'virtual_box test Create'
49
+ assert @vm.create_configuration('vms/testing.xml'),
50
+ 'Configuration creation failed'
51
+ end
52
+
53
+ def test_create_error
54
+ flexmock(VirtualBox).should_receive(:shell_command).
55
+ and_return({:status => 127, :output => 'Command not found'})
56
+
57
+ assert_raise(RuntimeError) do
58
+ @vm.create_configuration
59
+ end
60
+ end
61
+
62
+ def test_create_delete_live
63
+ @vm.name = 'virtual_box test Create'
64
+ assert @vm.create_configuration('./create_test.xml'),
65
+ 'Configuration creation failed'
66
+
67
+ assert File.exist?(@vm.config_file), 'Configuration file not created'
68
+ assert_equal '<?xml ', File.read(@vm.config_file)[0, 6],
69
+ 'Configuration path does not contain an XML config file'
70
+
71
+
72
+ assert @vm.delete_configuration, 'Configuration deletion failed'
73
+ assert !File.exist?(@vm.config_file), 'Configuration file not deleted'
74
+ end
75
+
76
+ def test_register_configuration
77
+ @vm.config_file = config_path = '/prod/vms/testing.xml'
78
+ flexmock(VirtualBox).should_receive(:shell_command).
79
+ with(%|VBoxManage --nologo registervm "#{config_path}"|).
80
+ and_return({:status => 0, :output => ''})
81
+
82
+ assert @vm.register_configuration
83
+ end
84
+
85
+ def test_register_error
86
+ @vm.config_file = config_path = '/prod/vms/testing.xml'
87
+ flexmock(VirtualBox).should_receive(:shell_command).
88
+ and_return({:status => 127, :output => 'Command not found'})
89
+ assert !@vm.register_configuration
90
+ end
91
+
92
+ def test_register_without_creating_config
93
+ assert_raise(RuntimeError) do
94
+ @vm.register_configuration
95
+ end
96
+ end
20
97
 
98
+ def test_unregister_configuration
99
+ @vm.config_file = config_path = '/prod/vms/testing.xml'
100
+ flexmock(VirtualBox).should_receive(:shell_command).
101
+ with("VBoxManage --nologo unregistervm #{@uuid}").
102
+ and_return({:status => 0, :output => ''})
103
+
104
+ assert @vm.unregister_configuration
105
+ end
106
+
107
+ def test_unregister_error
108
+ flexmock(VirtualBox).should_receive(:shell_command).
109
+ and_return({:status => 127, :output => 'Command not found'})
110
+ assert !@vm.unregister_configuration
111
+ end
112
+
113
+ def test_register_unregister_configuration_live
114
+ @vm.name = 'virtual_box test Register'
115
+ assert @vm.create_configuration('./create_test.xml'),
116
+ 'Configuration creation failed'
117
+ assert @vm.register_configuration, 'Registration failed'
118
+
119
+ vm_metadata = {:name => @vm.name, :uuid => @vm.uuid}
120
+ assert VirtualBox.all_vms_metadata.include?(vm_metadata),
121
+ 'Registred VM does not show up in listing'
122
+ assert @vm.unregister_configuration, 'Unregistration failed'
123
+ assert !VirtualBox.all_vms_metadata.include?(vm_metadata),
124
+ 'Unregistred VM still shows up in listing'
125
+
126
+ assert @vm.delete_configuration, 'Configuration deletion failed'
127
+ end
128
+
21
129
  def test_start
22
130
  flexmock(VirtualBox).should_receive(:ose?).and_return(false)
23
131
  flexmock(VirtualBox).should_receive(:shell_command).once.
@@ -56,7 +164,7 @@ class LifecycleTest < Test::Unit::TestCase
56
164
  def test_start_gui_with_error
57
165
  flexmock(VirtualBox).should_receive(:ose?).and_return(false)
58
166
  flexmock(VirtualBox).should_receive(:shell_command).once.
59
- with("VBoxManage startvm #{@uuid} --type gui --vrdp off").
167
+ with("VBoxManage --nologo startvm #{@uuid} --type gui --vrdp off").
60
168
  and_return({:status => 127, :output => ""})
61
169
 
62
170
  assert_equal false, @vm.start(:gui => true)
@@ -0,0 +1,46 @@
1
+ # Author:: Victor Costan
2
+ # Copyright:: Copyright (C) 2009 Zergling.Net
3
+ # License:: MIT
4
+
5
+ require 'virtual_box'
6
+ require 'test/unit'
7
+
8
+ require 'rubygems'
9
+ require 'flexmock/test_unit'
10
+
11
+
12
+ class RegistryTest < Test::Unit::TestCase
13
+ def setup
14
+ super
15
+ @testdata_path = File.join(File.dirname(__FILE__), '..', 'testdata')
16
+ end
17
+
18
+ def test_all_vms_metadata
19
+ mock_output = File.read File.join(@testdata_path,
20
+ 'list_vms_output.txt')
21
+
22
+ flexmock(VirtualBox).should_receive(:shell_command).
23
+ with('VBoxManage --nologo list vms').
24
+ and_return({:status => 0, :output => mock_output})
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)
34
+ end
35
+
36
+ def test_all_vms_metadata_error
37
+ flexmock(VirtualBox).should_receive(:shell_command).
38
+ with('VBoxManage --nologo list vms').
39
+ and_return({:status => 127, :output => 'Command not found'})
40
+
41
+ assert_nil VirtualBox.all_vms_metadata
42
+ end
43
+
44
+ # NOTE: The live test for all_vms_metadata is done in lifecycle_test.rb, under
45
+ # test_register_unregister_configurations_live
46
+ end
@@ -0,0 +1,3 @@
1
+ Virtual machine 'virtual_box test Create' is created.
2
+ UUID: 0c21709e-7f29-41c0-a0ac-ff528f50edbf
3
+ Settings file: '/Users/victor/Library/VirtualBox/Machines/virtual_box test Create/virtual_box test Create.xml'
@@ -0,0 +1,2 @@
1
+ "TEM" {0e6e5f5c-7438-4a4c-94cf-39b79b28f8e3}
2
+ "TEM Firmware IDE" {0c21709e-7f29-41c0-a0ac-ff528f50edbf}
@@ -2,22 +2,22 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{virtual_box}
5
- s.version = "0.0.1"
5
+ s.version = "0.0.2"
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-21}
9
+ s.date = %q{2009-08-30}
10
10
  s.description = %q{Ruby API for VirtualBox (Sun's OSS virtualization software).}
11
11
  s.email = %q{victor@zergling.net}
12
- s.extra_rdoc_files = ["CHANGELOG", "lib/virtual_box/command_line.rb", "lib/virtual_box/version.rb", "lib/virtual_box/vm/general_settings.rb", "lib/virtual_box/vm/identity.rb", "lib/virtual_box/vm/lifecycle.rb", "lib/virtual_box/vm.rb", "lib/virtual_box.rb", "LICENSE", "README.textile"]
13
- s.files = ["CHANGELOG", "lib/virtual_box/command_line.rb", "lib/virtual_box/version.rb", "lib/virtual_box/vm/general_settings.rb", "lib/virtual_box/vm/identity.rb", "lib/virtual_box/vm/lifecycle.rb", "lib/virtual_box/vm.rb", "lib/virtual_box.rb", "LICENSE", "Manifest", "Rakefile", "README.textile", "test/command_line_test.rb", "test/general_settings_test.rb", "test/lifecycle_test.rb", "test/version_test.rb", "testdata/golden_general_params.txt", "virtual_box.gemspec"]
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"]
13
+ s.files = ["CHANGELOG", "LICENSE", "Manifest", "README.textile", "Rakefile", "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", "test/command_line_test.rb", "test/general_settings_test.rb", "test/lifecycle_test.rb", "test/registry_test.rb", "test/version_test.rb", "testdata/createvm_output.txt", "testdata/golden_general_params.txt", "testdata/list_vms_output.txt", "virtual_box.gemspec"]
14
14
  s.homepage = %q{http://github.com/costan/virtual_box}
15
15
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Virtual_box", "--main", "README.textile"]
16
16
  s.require_paths = ["lib"]
17
17
  s.rubyforge_project = %q{zerglings}
18
18
  s.rubygems_version = %q{1.3.5}
19
19
  s.summary = %q{Ruby API for VirtualBox (Sun's OSS virtualization software).}
20
- s.test_files = ["test/command_line_test.rb", "test/general_settings_test.rb", "test/lifecycle_test.rb", "test/version_test.rb"]
20
+ s.test_files = ["test/command_line_test.rb", "test/general_settings_test.rb", "test/lifecycle_test.rb", "test/registry_test.rb", "test/version_test.rb"]
21
21
 
22
22
  if s.respond_to? :specification_version then
23
23
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
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.1
4
+ version: 0.0.2
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-21 00:00:00 -07:00
12
+ date: 2009-08-30 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -40,37 +40,41 @@ extensions: []
40
40
 
41
41
  extra_rdoc_files:
42
42
  - CHANGELOG
43
+ - LICENSE
44
+ - README.textile
45
+ - lib/virtual_box.rb
43
46
  - lib/virtual_box/command_line.rb
47
+ - lib/virtual_box/registry.rb
44
48
  - lib/virtual_box/version.rb
49
+ - lib/virtual_box/vm.rb
45
50
  - lib/virtual_box/vm/general_settings.rb
46
51
  - lib/virtual_box/vm/identity.rb
47
52
  - lib/virtual_box/vm/lifecycle.rb
48
- - lib/virtual_box/vm.rb
49
- - lib/virtual_box.rb
50
- - LICENSE
51
- - README.textile
52
53
  files:
53
54
  - CHANGELOG
55
+ - LICENSE
56
+ - Manifest
57
+ - README.textile
58
+ - Rakefile
59
+ - lib/virtual_box.rb
54
60
  - lib/virtual_box/command_line.rb
61
+ - lib/virtual_box/registry.rb
55
62
  - lib/virtual_box/version.rb
63
+ - lib/virtual_box/vm.rb
56
64
  - lib/virtual_box/vm/general_settings.rb
57
65
  - lib/virtual_box/vm/identity.rb
58
66
  - lib/virtual_box/vm/lifecycle.rb
59
- - lib/virtual_box/vm.rb
60
- - lib/virtual_box.rb
61
- - LICENSE
62
- - Manifest
63
- - Rakefile
64
- - README.textile
65
67
  - test/command_line_test.rb
66
68
  - test/general_settings_test.rb
67
69
  - test/lifecycle_test.rb
70
+ - test/registry_test.rb
68
71
  - test/version_test.rb
72
+ - testdata/createvm_output.txt
69
73
  - testdata/golden_general_params.txt
74
+ - testdata/list_vms_output.txt
70
75
  - virtual_box.gemspec
71
76
  has_rdoc: false
72
77
  homepage: http://github.com/costan/virtual_box
73
- licenses:
74
78
  post_install_message:
75
79
  rdoc_options:
76
80
  - --line-numbers
@@ -96,7 +100,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
96
100
  requirements: []
97
101
 
98
102
  rubyforge_project: zerglings
99
- rubygems_version: 1.3.5
103
+ rubygems_version: 1.2.0
100
104
  signing_key:
101
105
  specification_version: 3
102
106
  summary: Ruby API for VirtualBox (Sun's OSS virtualization software).
@@ -104,4 +108,5 @@ test_files:
104
108
  - test/command_line_test.rb
105
109
  - test/general_settings_test.rb
106
110
  - test/lifecycle_test.rb
111
+ - test/registry_test.rb
107
112
  - test/version_test.rb