vagrant 0.1.4 → 0.2.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/vagrant-box +1 -2
- data/bin/vagrant-down +1 -2
- data/bin/vagrant-halt +1 -2
- data/bin/vagrant-init +1 -2
- data/bin/vagrant-package +1 -2
- data/bin/vagrant-reload +1 -2
- data/bin/vagrant-resume +1 -2
- data/bin/vagrant-ssh +1 -2
- data/bin/vagrant-status +29 -0
- data/bin/vagrant-suspend +1 -2
- data/bin/vagrant-up +1 -2
- data/config/default.rb +5 -9
- data/keys/README.md +10 -0
- data/keys/vagrant +27 -0
- data/keys/vagrant.pub +1 -0
- data/lib/vagrant/actions/base.rb +14 -0
- data/lib/vagrant/actions/collection.rb +36 -0
- data/lib/vagrant/actions/runner.rb +4 -10
- data/lib/vagrant/actions/vm/boot.rb +4 -5
- data/lib/vagrant/actions/vm/customize.rb +17 -0
- data/lib/vagrant/actions/vm/destroy.rb +11 -2
- data/lib/vagrant/actions/vm/forward_ports.rb +24 -0
- data/lib/vagrant/actions/vm/import.rb +1 -0
- data/lib/vagrant/actions/vm/provision.rb +30 -52
- data/lib/vagrant/actions/vm/reload.rb +2 -2
- data/lib/vagrant/actions/vm/shared_folders.rb +37 -25
- data/lib/vagrant/actions/vm/up.rb +8 -4
- data/lib/vagrant/active_list.rb +66 -0
- data/lib/vagrant/commands.rb +44 -0
- data/lib/vagrant/config.rb +64 -47
- data/lib/vagrant/downloaders/file.rb +2 -12
- data/lib/vagrant/env.rb +48 -12
- data/lib/vagrant/provisioners/base.rb +22 -0
- data/lib/vagrant/provisioners/chef.rb +102 -0
- data/lib/vagrant/provisioners/chef_server.rb +96 -0
- data/lib/vagrant/provisioners/chef_solo.rb +67 -0
- data/lib/vagrant/ssh.rb +25 -6
- data/lib/vagrant/stacked_proc_runner.rb +33 -0
- data/lib/vagrant/vm.rb +8 -0
- data/lib/vagrant.rb +10 -5
- data/test/test_helper.rb +22 -6
- data/test/vagrant/actions/collection_test.rb +110 -0
- data/test/vagrant/actions/runner_test.rb +11 -7
- data/test/vagrant/actions/vm/boot_test.rb +7 -7
- data/test/vagrant/actions/vm/customize_test.rb +16 -0
- data/test/vagrant/actions/vm/destroy_test.rb +19 -6
- data/test/vagrant/actions/vm/forward_ports_test.rb +52 -0
- data/test/vagrant/actions/vm/import_test.rb +10 -3
- data/test/vagrant/actions/vm/provision_test.rb +75 -70
- data/test/vagrant/actions/vm/reload_test.rb +3 -2
- data/test/vagrant/actions/vm/shared_folders_test.rb +62 -9
- data/test/vagrant/actions/vm/up_test.rb +4 -4
- data/test/vagrant/active_list_test.rb +169 -0
- data/test/vagrant/config_test.rb +145 -29
- data/test/vagrant/downloaders/file_test.rb +4 -19
- data/test/vagrant/env_test.rb +96 -23
- data/test/vagrant/provisioners/base_test.rb +27 -0
- data/test/vagrant/provisioners/chef_server_test.rb +175 -0
- data/test/vagrant/provisioners/chef_solo_test.rb +142 -0
- data/test/vagrant/provisioners/chef_test.rb +116 -0
- data/test/vagrant/ssh_test.rb +29 -8
- data/test/vagrant/stacked_proc_runner_test.rb +43 -0
- data/test/vagrant/vm_test.rb +23 -0
- data/vagrant.gemspec +35 -8
- metadata +42 -11
- data/script/vagrant-ssh-expect.sh +0 -22
@@ -0,0 +1,67 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Provisioners
|
3
|
+
# This class implements provisioning via chef-solo.
|
4
|
+
class ChefSolo < Chef
|
5
|
+
def prepare
|
6
|
+
share_cookbook_folders
|
7
|
+
end
|
8
|
+
|
9
|
+
def provision!
|
10
|
+
chown_provisioning_folder
|
11
|
+
setup_json
|
12
|
+
setup_solo_config
|
13
|
+
run_chef_solo
|
14
|
+
end
|
15
|
+
|
16
|
+
def share_cookbook_folders
|
17
|
+
host_cookbook_paths.each_with_index do |cookbook, i|
|
18
|
+
Vagrant.config.vm.share_folder("vagrant-chef-solo-#{i}", cookbook_path(i), cookbook)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup_solo_config
|
23
|
+
solo_file = <<-solo
|
24
|
+
file_cache_path "#{Vagrant.config.chef.provisioning_path}"
|
25
|
+
cookbook_path #{cookbooks_path}
|
26
|
+
solo
|
27
|
+
|
28
|
+
logger.info "Uploading chef-solo configuration script..."
|
29
|
+
SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb"))
|
30
|
+
end
|
31
|
+
|
32
|
+
def run_chef_solo
|
33
|
+
logger.info "Running chef-solo..."
|
34
|
+
SSH.execute do |ssh|
|
35
|
+
ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream|
|
36
|
+
# TODO: Very verbose. It would be easier to save the data and only show it during
|
37
|
+
# an error, or when verbosity level is set high
|
38
|
+
logger.info("#{stream}: #{data}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def host_cookbook_paths
|
44
|
+
cookbooks = Vagrant.config.chef.cookbooks_path
|
45
|
+
cookbooks = [cookbooks] unless cookbooks.is_a?(Array)
|
46
|
+
cookbooks.collect! { |cookbook| File.expand_path(cookbook, Env.root_path) }
|
47
|
+
return cookbooks
|
48
|
+
end
|
49
|
+
|
50
|
+
def cookbook_path(i)
|
51
|
+
File.join(Vagrant.config.chef.provisioning_path, "cookbooks-#{i}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def cookbooks_path
|
55
|
+
result = []
|
56
|
+
host_cookbook_paths.each_with_index do |host_path, i|
|
57
|
+
result << cookbook_path(i)
|
58
|
+
end
|
59
|
+
|
60
|
+
# We're lucky that ruby's string and array syntax for strings is the
|
61
|
+
# same as JSON, so we can just convert to JSON here and use that
|
62
|
+
result = result.to_s if result.length == 1
|
63
|
+
result.to_json
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/vagrant/ssh.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
module Vagrant
|
2
2
|
class SSH
|
3
|
-
|
3
|
+
include Vagrant::Util
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def connect(opts={})
|
7
7
|
options = {}
|
8
|
-
[:host, :
|
8
|
+
[:host, :username, :private_key_path].each do |param|
|
9
9
|
options[param] = opts[param] || Vagrant.config.ssh.send(param)
|
10
10
|
end
|
11
11
|
|
12
|
-
Kernel.exec "#{
|
12
|
+
Kernel.exec "ssh -p #{port(opts)} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip
|
13
13
|
end
|
14
14
|
|
15
|
-
def execute
|
16
|
-
Net::SSH.start(Vagrant.config.ssh.host,
|
15
|
+
def execute(opts={})
|
16
|
+
Net::SSH.start(Vagrant.config.ssh.host,
|
17
|
+
Vagrant.config[:ssh][:username],
|
18
|
+
opts.merge( :port => port,
|
19
|
+
:keys => [Vagrant.config.ssh.private_key_path])) do |ssh|
|
17
20
|
yield ssh
|
18
21
|
end
|
19
22
|
end
|
@@ -29,7 +32,7 @@ module Vagrant
|
|
29
32
|
check_thread = Thread.new do
|
30
33
|
begin
|
31
34
|
Thread.current[:result] = false
|
32
|
-
|
35
|
+
execute(:timeout => Vagrant.config.ssh.timeout) do |ssh|
|
33
36
|
Thread.current[:result] = true
|
34
37
|
end
|
35
38
|
rescue Errno::ECONNREFUSED, Net::SSH::Disconnect
|
@@ -39,6 +42,22 @@ module Vagrant
|
|
39
42
|
|
40
43
|
check_thread.join(Vagrant.config.ssh.timeout)
|
41
44
|
return check_thread[:result]
|
45
|
+
rescue Net::SSH::AuthenticationFailed
|
46
|
+
error_and_exit(<<-msg)
|
47
|
+
SSH authentication failed! While this could be due to a variety of reasons,
|
48
|
+
the two most common are: private key path is incorrect or you're using a box
|
49
|
+
which was built for Vagrant 0.1.x.
|
50
|
+
|
51
|
+
Vagrant 0.2.x dropped support for password-based authentication. If you're
|
52
|
+
tring to `vagrant up` a box which does not support Vagrant's private/public
|
53
|
+
keypair, then this error will be raised. To resolve this, read the guide
|
54
|
+
on converting base boxes from password-based to keypairs here:
|
55
|
+
|
56
|
+
http://vagrantup.com/docs/converting_password_to_key_ssh.html
|
57
|
+
|
58
|
+
If the box was built for 0.2.x and contains a custom public key, perhaps
|
59
|
+
the path to the private key is incorrect. Check your `config.ssh.private_key_path`.
|
60
|
+
msg
|
42
61
|
end
|
43
62
|
|
44
63
|
def port(opts={})
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Vagrant
|
2
|
+
# Represents the "stacked proc runner" behavior which is used a
|
3
|
+
# couple places within Vagrant. This allows procs to "stack" on
|
4
|
+
# each other, then all execute in a single action. An example of
|
5
|
+
# its uses can be seen in the {Config} class.
|
6
|
+
module StackedProcRunner
|
7
|
+
# Returns the proc stack. This should always be called as the
|
8
|
+
# accessor of the stack. The instance variable itself should _never_
|
9
|
+
# be used.
|
10
|
+
#
|
11
|
+
# @return [Array<Proc>]
|
12
|
+
def proc_stack
|
13
|
+
@_proc_stack ||= []
|
14
|
+
end
|
15
|
+
|
16
|
+
# Adds (pushes) a proc to the stack. The actual proc added here is
|
17
|
+
# not executed, but merely stored.
|
18
|
+
#
|
19
|
+
# @param [Proc] block
|
20
|
+
def push_proc(&block)
|
21
|
+
proc_stack << block
|
22
|
+
end
|
23
|
+
|
24
|
+
# Executes all the procs on the stack, passing in the given arguments.
|
25
|
+
# The stack is not cleared afterwords. It is up to the user of this
|
26
|
+
# mixin to clear the stack by calling `proc_stack.clear`.
|
27
|
+
def run_procs!(*args)
|
28
|
+
proc_stack.each do |proc|
|
29
|
+
proc.call(*args)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/lib/vagrant/vm.rb
CHANGED
@@ -19,6 +19,14 @@ module Vagrant
|
|
19
19
|
@vm = vm
|
20
20
|
end
|
21
21
|
|
22
|
+
def uuid
|
23
|
+
vm ? vm.uuid : nil
|
24
|
+
end
|
25
|
+
|
26
|
+
def reload!
|
27
|
+
@vm = VirtualBox::VM.find(@vm.uuid)
|
28
|
+
end
|
29
|
+
|
22
30
|
def package(out_path, include_files=[])
|
23
31
|
add_action(Actions::VM::Export)
|
24
32
|
add_action(Actions::VM::Package, out_path, include_files)
|
data/lib/vagrant.rb
CHANGED
@@ -1,14 +1,19 @@
|
|
1
1
|
libdir = File.dirname(__FILE__)
|
2
|
-
$:.unshift(libdir)
|
3
2
|
PROJECT_ROOT = File.join(libdir, '..') unless defined?(PROJECT_ROOT)
|
4
3
|
|
5
4
|
# The libs which must be loaded prior to the rest
|
6
5
|
%w{tempfile open-uri json pathname logger uri net/http virtualbox net/ssh archive/tar/minitar
|
7
|
-
net/scp fileutils
|
8
|
-
require
|
6
|
+
net/scp fileutils}.each do |lib|
|
7
|
+
require lib
|
8
|
+
end
|
9
|
+
|
10
|
+
# The vagrant specific files which must be loaded prior to the rest
|
11
|
+
%w{vagrant/util vagrant/stacked_proc_runner vagrant/actions/base vagrant/downloaders/base vagrant/actions/collection
|
12
|
+
vagrant/actions/runner vagrant/config vagrant/provisioners/base vagrant/provisioners/chef}.each do |f|
|
13
|
+
require File.expand_path(f, libdir)
|
9
14
|
end
|
10
15
|
|
11
16
|
# Glob require the rest
|
12
|
-
Dir[File.join(
|
13
|
-
require f
|
17
|
+
Dir[File.join(libdir, "vagrant", "**", "*.rb")].each do |f|
|
18
|
+
require File.expand_path(f)
|
14
19
|
end
|
data/test/test_helper.rb
CHANGED
@@ -20,11 +20,10 @@ require 'mocha'
|
|
20
20
|
class Test::Unit::TestCase
|
21
21
|
# Clears the previous config and sets up the new config
|
22
22
|
def mock_config
|
23
|
-
Vagrant::Config.
|
24
|
-
Vagrant::Config.instance_variable_set(:@config, nil)
|
23
|
+
Vagrant::Config.reset!
|
25
24
|
|
26
25
|
Vagrant::Config.run do |config|
|
27
|
-
config.vagrant.dotfile_name = ".
|
26
|
+
config.vagrant.dotfile_name = ".vagrant"
|
28
27
|
|
29
28
|
config.ssh.username = "foo"
|
30
29
|
config.ssh.password = "bar"
|
@@ -32,21 +31,28 @@ class Test::Unit::TestCase
|
|
32
31
|
config.ssh.forwarded_port_key = "ssh"
|
33
32
|
config.ssh.max_tries = 10
|
34
33
|
config.ssh.timeout = 10
|
34
|
+
config.ssh.private_key_path = '~/foo'
|
35
35
|
|
36
36
|
config.vm.box = "foo"
|
37
37
|
config.vm.box_ovf = "box.ovf"
|
38
38
|
config.vm.base_mac = "42"
|
39
|
-
config.vm.project_directory = "/
|
39
|
+
config.vm.project_directory = "/vagrant"
|
40
40
|
config.vm.disk_image_format = 'VMDK'
|
41
41
|
config.vm.forward_port("ssh", 22, 2222)
|
42
|
+
config.vm.shared_folder_uid = nil
|
43
|
+
config.vm.shared_folder_gid = nil
|
42
44
|
|
43
45
|
config.package.name = 'vagrant'
|
44
46
|
config.package.extension = '.box'
|
45
47
|
|
48
|
+
# Chef
|
49
|
+
config.chef.chef_server_url = "http://localhost:4000"
|
50
|
+
config.chef.validation_key_path = "validation.pem"
|
51
|
+
config.chef.client_key_path = "/zoo/foo/bar.pem"
|
46
52
|
config.chef.cookbooks_path = "cookbooks"
|
47
|
-
config.chef.provisioning_path = "/tmp/
|
53
|
+
config.chef.provisioning_path = "/tmp/vagrant-chef"
|
48
54
|
config.chef.json = {
|
49
|
-
:recipes => ["
|
55
|
+
:recipes => ["vagrant_main"]
|
50
56
|
}
|
51
57
|
|
52
58
|
config.vagrant.home = '~/.home'
|
@@ -72,6 +78,7 @@ class Test::Unit::TestCase
|
|
72
78
|
vm = mock("vboxvm")
|
73
79
|
mock_vm = mock("vm")
|
74
80
|
action = action_klass.new(mock_vm, *args)
|
81
|
+
stub_default_action_dependecies(action)
|
75
82
|
|
76
83
|
mock_vm.stubs(:vm).returns(vm)
|
77
84
|
mock_vm.stubs(:vm=)
|
@@ -82,6 +89,11 @@ class Test::Unit::TestCase
|
|
82
89
|
[mock_vm, vm, action]
|
83
90
|
end
|
84
91
|
|
92
|
+
def stub_default_action_dependecies(mock, klass=MockAction)
|
93
|
+
mock.stubs(:precedes).returns([])
|
94
|
+
mock.stubs(:follows).returns([])
|
95
|
+
end
|
96
|
+
|
85
97
|
# Sets up the mocks and stubs for a downloader
|
86
98
|
def mock_downloader(downloader_klass)
|
87
99
|
tempfile = mock("tempfile")
|
@@ -90,3 +102,7 @@ class Test::Unit::TestCase
|
|
90
102
|
[downloader_klass.new, tempfile]
|
91
103
|
end
|
92
104
|
end
|
105
|
+
|
106
|
+
class MockAction; end
|
107
|
+
class MockActionOther; end
|
108
|
+
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class CollectionTest < Test::Unit::TestCase
|
4
|
+
context "checking uniqueness" do
|
5
|
+
setup do
|
6
|
+
@actions = Vagrant::Actions::Collection.new([1])
|
7
|
+
end
|
8
|
+
|
9
|
+
should "return true if there are duplicate classes in the collection" do
|
10
|
+
@actions << 1
|
11
|
+
assert @actions.duplicates?
|
12
|
+
end
|
13
|
+
|
14
|
+
should "return false it all the classes are unique" do
|
15
|
+
@actions << 1.0 << "foo"
|
16
|
+
assert !@actions.duplicates?
|
17
|
+
end
|
18
|
+
|
19
|
+
should "raise an exception when there are duplicates" do
|
20
|
+
@actions << 1
|
21
|
+
assert_raise Vagrant::Actions::DuplicateActionException do
|
22
|
+
@actions.duplicates!
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
should "not raise an exception when there are no duplicates" do
|
27
|
+
@actions << 1.0 << "foo"
|
28
|
+
assert_nothing_raised do
|
29
|
+
@actions.duplicates!
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "verifying dependencies" do
|
35
|
+
setup do
|
36
|
+
@mock_action = mock('action')
|
37
|
+
@mock_action.stubs(:class).returns(MockAction)
|
38
|
+
|
39
|
+
@mock_action2 = mock('action2')
|
40
|
+
@mock_action2.stubs(:class).returns(MockActionOther)
|
41
|
+
# see test_helper
|
42
|
+
stub_default_action_dependecies(@mock_action)
|
43
|
+
stub_default_action_dependecies(@mock_action2)
|
44
|
+
end
|
45
|
+
|
46
|
+
context "that come before an action" do
|
47
|
+
setup do
|
48
|
+
@mock_action.stubs(:follows).returns([MockActionOther])
|
49
|
+
end
|
50
|
+
should "raise an exception if they are not met" do
|
51
|
+
assert_raise Vagrant::Actions::DependencyNotSatisfiedException do
|
52
|
+
collection.new([@mock_action]).dependencies!
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
should "not raise an exception if they are met" do
|
57
|
+
assert_nothing_raised do
|
58
|
+
collection.new([@mock_action2, @mock_action]).dependencies!
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "that follow an an action" do
|
64
|
+
setup do
|
65
|
+
@mock_action.stubs(:precedes).returns([MockActionOther])
|
66
|
+
end
|
67
|
+
|
68
|
+
should "raise an exception if they are not met" do
|
69
|
+
assert_raise Vagrant::Actions::DependencyNotSatisfiedException do
|
70
|
+
collection.new([@mock_action]).dependencies!
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
should "not raise an exception if they are met" do
|
75
|
+
assert_nothing_raised do
|
76
|
+
collection.new([@mock_action, @mock_action2]).dependencies!
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "that are before and after an action" do
|
82
|
+
setup do
|
83
|
+
@mock_action.stubs(:precedes).returns([MockActionOther])
|
84
|
+
@mock_action.stubs(:follows).returns([MockActionOther])
|
85
|
+
end
|
86
|
+
|
87
|
+
should "raise an exception if they are met" do
|
88
|
+
assert_raise Vagrant::Actions::DependencyNotSatisfiedException do
|
89
|
+
collection.new([@mock_action2, @mock_action]).dependencies!
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
should "not raise and exception if they are met" do
|
94
|
+
assert_nothing_raised do
|
95
|
+
collection.new([@mock_action2, @mock_action, @mock_action2]).dependencies!
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "klasses" do
|
102
|
+
should "return a list of the collection element's classes" do
|
103
|
+
@action = mock('action')
|
104
|
+
assert_equal collection.new([@action]).klasses, [@action.class]
|
105
|
+
assert_equal collection.new([@action, 1.0, "foo"]).klasses, [@action.class, Float, String]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def collection; Vagrant::Actions::Collection end
|
110
|
+
end
|
@@ -6,6 +6,7 @@ class ActionRunnerTest < Test::Unit::TestCase
|
|
6
6
|
action.stubs(:prepare)
|
7
7
|
action.stubs(:execute!)
|
8
8
|
action.stubs(:cleanup)
|
9
|
+
stub_default_action_dependecies(action)
|
9
10
|
action
|
10
11
|
end
|
11
12
|
|
@@ -135,6 +136,7 @@ class ActionRunnerTest < Test::Unit::TestCase
|
|
135
136
|
should "clear the actions and run a single action if given to execute!" do
|
136
137
|
action = mock("action")
|
137
138
|
run_action = mock("action_run")
|
139
|
+
stub_default_action_dependecies(run_action)
|
138
140
|
run_class = mock("run_class")
|
139
141
|
run_class.expects(:new).once.returns(run_action)
|
140
142
|
@runner.actions << action
|
@@ -148,7 +150,6 @@ class ActionRunnerTest < Test::Unit::TestCase
|
|
148
150
|
end
|
149
151
|
|
150
152
|
should "clear actions after running execute!" do
|
151
|
-
@runner.actions << mock_fake_action
|
152
153
|
@runner.actions << mock_fake_action
|
153
154
|
assert !@runner.actions.empty? # sanity
|
154
155
|
@runner.execute!
|
@@ -158,9 +159,10 @@ class ActionRunnerTest < Test::Unit::TestCase
|
|
158
159
|
should "run #prepare on all actions, then #execute!" do
|
159
160
|
action_seq = sequence("action_seq")
|
160
161
|
actions = []
|
161
|
-
|
162
|
+
[MockAction, MockActionOther].each_with_index do |klass, i|
|
162
163
|
action = mock("action#{i}")
|
163
|
-
|
164
|
+
action.expects(:class).returns(klass)
|
165
|
+
stub_default_action_dependecies(action, klass)
|
164
166
|
@runner.actions << action
|
165
167
|
actions << action
|
166
168
|
end
|
@@ -176,10 +178,12 @@ class ActionRunnerTest < Test::Unit::TestCase
|
|
176
178
|
|
177
179
|
context "exceptions" do
|
178
180
|
setup do
|
179
|
-
@actions = [
|
180
|
-
|
181
|
-
|
182
|
-
|
181
|
+
@actions = [MockAction, MockActionOther].map do |klass|
|
182
|
+
action = mock_fake_action
|
183
|
+
action.expects(:class).returns(klass)
|
184
|
+
action.stubs(:rescue)
|
185
|
+
@runner.actions << action
|
186
|
+
action
|
183
187
|
end
|
184
188
|
|
185
189
|
@exception = Exception.new
|
@@ -7,6 +7,13 @@ class BootActionTest < Test::Unit::TestCase
|
|
7
7
|
mock_config
|
8
8
|
end
|
9
9
|
|
10
|
+
context "preparing" do
|
11
|
+
should "add the root shared folder" do
|
12
|
+
Vagrant.config.vm.expects(:share_folder).with("vagrant-root", Vagrant.config.vm.project_directory, Vagrant::Env.root_path).once
|
13
|
+
@action.prepare
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
10
17
|
context "execution" do
|
11
18
|
should "invoke the 'boot' around callback" do
|
12
19
|
boot_seq = sequence("boot_seq")
|
@@ -45,11 +52,4 @@ class BootActionTest < Test::Unit::TestCase
|
|
45
52
|
assert !@action.wait_for_boot(0)
|
46
53
|
end
|
47
54
|
end
|
48
|
-
|
49
|
-
context "callbacks" do
|
50
|
-
should "setup the root directory shared folder" do
|
51
|
-
expected = ["vagrant-root", Vagrant::Env.root_path, Vagrant.config.vm.project_directory]
|
52
|
-
assert_equal expected, @action.collect_shared_folders
|
53
|
-
end
|
54
|
-
end
|
55
55
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
2
|
+
|
3
|
+
class CustomizeActionTest < Test::Unit::TestCase
|
4
|
+
setup do
|
5
|
+
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Customize)
|
6
|
+
mock_config
|
7
|
+
end
|
8
|
+
|
9
|
+
context "executing" do
|
10
|
+
should "run the VM customization procs then save the VM" do
|
11
|
+
Vagrant.config.vm.expects(:run_procs!).with(@vm)
|
12
|
+
@vm.expects(:save).with(true).once
|
13
|
+
@action.execute!
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -2,23 +2,36 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
|
|
2
2
|
|
3
3
|
class DestroyActionTest < Test::Unit::TestCase
|
4
4
|
setup do
|
5
|
-
@
|
5
|
+
@runner, @vm, @action = mock_action(Vagrant::Actions::VM::Destroy)
|
6
6
|
mock_config
|
7
7
|
end
|
8
8
|
|
9
9
|
context "executing" do
|
10
|
-
|
11
|
-
@
|
10
|
+
should "invoke an around callback around the destroy" do
|
11
|
+
@runner.expects(:invoke_around_callback).with(:destroy).once
|
12
|
+
@action.execute!
|
12
13
|
end
|
13
14
|
|
14
|
-
should "
|
15
|
-
@
|
15
|
+
should "destroy VM and clear persist" do
|
16
|
+
@runner.stubs(:invoke_around_callback).yields
|
17
|
+
clear_seq = sequence("clear")
|
18
|
+
@action.expects(:destroy_vm).in_sequence(clear_seq)
|
19
|
+
@action.expects(:depersist).in_sequence(clear_seq)
|
16
20
|
@action.execute!
|
17
21
|
end
|
22
|
+
end
|
18
23
|
|
24
|
+
context "destroying the VM" do
|
19
25
|
should "destroy VM and attached images" do
|
20
26
|
@vm.expects(:destroy).with(:destroy_image => true).once
|
21
|
-
@action.
|
27
|
+
@action.destroy_vm
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "depersisting" do
|
32
|
+
should "call depersist_vm on Env" do
|
33
|
+
Vagrant::Env.expects(:depersist_vm).with(@runner).once
|
34
|
+
@action.depersist
|
22
35
|
end
|
23
36
|
end
|
24
37
|
end
|
@@ -6,6 +6,58 @@ class ForwardPortsActionTest < Test::Unit::TestCase
|
|
6
6
|
mock_config
|
7
7
|
end
|
8
8
|
|
9
|
+
context "checking for colliding ports" do
|
10
|
+
setup do
|
11
|
+
@forwarded_port = mock("forwarded_port")
|
12
|
+
@forwarded_port.stubs(:hostport)
|
13
|
+
@forwarded_ports = [@forwarded_port]
|
14
|
+
|
15
|
+
@vm = mock("vm")
|
16
|
+
@vm.stubs(:forwarded_ports).returns(@forwarded_ports)
|
17
|
+
@vm.stubs(:running?).returns(true)
|
18
|
+
@vm.stubs(:uuid).returns("foo")
|
19
|
+
@mock_vm.stubs(:uuid).returns("bar")
|
20
|
+
vms = [@vm]
|
21
|
+
VirtualBox::VM.stubs(:all).returns(vms)
|
22
|
+
|
23
|
+
mock_config do |config|
|
24
|
+
config.vm.forwarded_ports.clear
|
25
|
+
config.vm.forward_port("ssh", 22, 2222)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
should "ignore vms which aren't running" do
|
30
|
+
@vm.expects(:running?).returns(false)
|
31
|
+
@vm.expects(:forwarded_ports).never
|
32
|
+
@action.prepare
|
33
|
+
end
|
34
|
+
|
35
|
+
should "ignore vms which are equivalent to ours" do
|
36
|
+
@mock_vm.expects(:uuid).returns(@vm.uuid)
|
37
|
+
@vm.expects(:forwarded_ports).never
|
38
|
+
@action.prepare
|
39
|
+
end
|
40
|
+
|
41
|
+
should "not raise any errors if no forwarded ports collide" do
|
42
|
+
@forwarded_port.expects(:hostport).returns(80)
|
43
|
+
assert_nothing_raised { @action.prepare }
|
44
|
+
end
|
45
|
+
|
46
|
+
should "raise an ActionException if a port collides" do
|
47
|
+
@forwarded_port.expects(:hostport).returns(2222)
|
48
|
+
assert_raises(Vagrant::Actions::ActionException) {
|
49
|
+
@action.prepare
|
50
|
+
}
|
51
|
+
end
|
52
|
+
|
53
|
+
should "convert ports to strings prior to checking" do
|
54
|
+
@forwarded_port.expects(:hostport).returns("2222")
|
55
|
+
assert_raises(Vagrant::Actions::ActionException) {
|
56
|
+
@action.prepare
|
57
|
+
}
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
9
61
|
context "execution" do
|
10
62
|
should "clear all previous ports and forward new ports" do
|
11
63
|
exec_seq = sequence("exec_seq")
|
@@ -23,14 +23,21 @@ class ImportActionTest < Test::Unit::TestCase
|
|
23
23
|
end
|
24
24
|
|
25
25
|
should "call import on VirtualBox::VM with the proper base" do
|
26
|
-
VirtualBox::VM.expects(:import).once.with(@ovf_file)
|
27
|
-
@import.execute!
|
26
|
+
VirtualBox::VM.expects(:import).once.with(@ovf_file).returns("foo")
|
27
|
+
assert_nothing_raised { @import.execute! }
|
28
|
+
end
|
29
|
+
|
30
|
+
should "raise an exception if import is nil" do
|
31
|
+
@mock_vm.expects(:vm).returns(nil)
|
32
|
+
assert_raises(Vagrant::Actions::ActionException) {
|
33
|
+
@import.execute!
|
34
|
+
}
|
28
35
|
end
|
29
36
|
|
30
37
|
should "set the resulting VM as the VM of the Vagrant VM object" do
|
31
38
|
new_vm = mock("new_vm")
|
32
39
|
@mock_vm.expects(:vm=).with(new_vm).once
|
33
|
-
VirtualBox::VM.expects(:import).returns(new_vm)
|
40
|
+
VirtualBox::VM.expects(:import).returns(new_vm).returns("foo")
|
34
41
|
@import.execute!
|
35
42
|
end
|
36
43
|
end
|