vagrantup 0.1.4 → 0.2.0

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.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -1
  3. data/Rakefile +1 -1
  4. data/VERSION +1 -1
  5. data/bin/vagrant +1 -1
  6. data/bin/vagrant-box +1 -2
  7. data/bin/vagrant-down +1 -2
  8. data/bin/vagrant-halt +1 -2
  9. data/bin/vagrant-init +1 -2
  10. data/bin/vagrant-package +1 -2
  11. data/bin/vagrant-reload +1 -2
  12. data/bin/vagrant-resume +1 -2
  13. data/bin/vagrant-ssh +1 -2
  14. data/bin/vagrant-status +29 -0
  15. data/bin/vagrant-suspend +1 -2
  16. data/bin/vagrant-up +1 -2
  17. data/config/default.rb +5 -9
  18. data/keys/README.md +10 -0
  19. data/keys/vagrant +27 -0
  20. data/keys/vagrant.pub +1 -0
  21. data/lib/vagrant.rb +10 -5
  22. data/lib/vagrant/actions/base.rb +14 -0
  23. data/lib/vagrant/actions/box/download.rb +3 -0
  24. data/lib/vagrant/actions/collection.rb +36 -0
  25. data/lib/vagrant/actions/runner.rb +4 -10
  26. data/lib/vagrant/actions/vm/boot.rb +4 -5
  27. data/lib/vagrant/actions/vm/customize.rb +17 -0
  28. data/lib/vagrant/actions/vm/destroy.rb +11 -2
  29. data/lib/vagrant/actions/vm/forward_ports.rb +24 -0
  30. data/lib/vagrant/actions/vm/import.rb +1 -0
  31. data/lib/vagrant/actions/vm/provision.rb +30 -52
  32. data/lib/vagrant/actions/vm/reload.rb +2 -2
  33. data/lib/vagrant/actions/vm/shared_folders.rb +37 -25
  34. data/lib/vagrant/actions/vm/up.rb +8 -4
  35. data/lib/vagrant/active_list.rb +66 -0
  36. data/lib/vagrant/commands.rb +44 -0
  37. data/lib/vagrant/config.rb +64 -47
  38. data/lib/vagrant/downloaders/base.rb +3 -0
  39. data/lib/vagrant/downloaders/file.rb +11 -11
  40. data/lib/vagrant/env.rb +48 -12
  41. data/lib/vagrant/provisioners/base.rb +22 -0
  42. data/lib/vagrant/provisioners/chef.rb +102 -0
  43. data/lib/vagrant/provisioners/chef_server.rb +96 -0
  44. data/lib/vagrant/provisioners/chef_solo.rb +67 -0
  45. data/lib/vagrant/ssh.rb +25 -6
  46. data/lib/vagrant/stacked_proc_runner.rb +33 -0
  47. data/lib/vagrant/vm.rb +8 -0
  48. data/test/test_helper.rb +22 -6
  49. data/test/vagrant/actions/box/download_test.rb +11 -0
  50. data/test/vagrant/actions/collection_test.rb +110 -0
  51. data/test/vagrant/actions/runner_test.rb +11 -7
  52. data/test/vagrant/actions/vm/boot_test.rb +7 -7
  53. data/test/vagrant/actions/vm/customize_test.rb +16 -0
  54. data/test/vagrant/actions/vm/destroy_test.rb +19 -6
  55. data/test/vagrant/actions/vm/forward_ports_test.rb +52 -0
  56. data/test/vagrant/actions/vm/import_test.rb +10 -3
  57. data/test/vagrant/actions/vm/provision_test.rb +75 -70
  58. data/test/vagrant/actions/vm/reload_test.rb +3 -2
  59. data/test/vagrant/actions/vm/shared_folders_test.rb +62 -9
  60. data/test/vagrant/actions/vm/up_test.rb +4 -4
  61. data/test/vagrant/active_list_test.rb +169 -0
  62. data/test/vagrant/config_test.rb +145 -29
  63. data/test/vagrant/downloaders/base_test.rb +7 -0
  64. data/test/vagrant/downloaders/file_test.rb +12 -18
  65. data/test/vagrant/env_test.rb +96 -23
  66. data/test/vagrant/provisioners/base_test.rb +27 -0
  67. data/test/vagrant/provisioners/chef_server_test.rb +175 -0
  68. data/test/vagrant/provisioners/chef_solo_test.rb +142 -0
  69. data/test/vagrant/provisioners/chef_test.rb +116 -0
  70. data/test/vagrant/ssh_test.rb +29 -8
  71. data/test/vagrant/stacked_proc_runner_test.rb +43 -0
  72. data/test/vagrant/vm_test.rb +23 -0
  73. data/vagrant.gemspec +34 -7
  74. metadata +33 -5
  75. data/script/vagrant-ssh-expect.sh +0 -22
@@ -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/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.instance_variable_set(:@config_runners, nil)
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 = ".hobo"
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 = "/hobo"
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/hobo-chef"
53
+ config.chef.provisioning_path = "/tmp/vagrant-chef"
48
54
  config.chef.json = {
49
- :recipes => ["hobo_main"]
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
+
@@ -16,6 +16,10 @@ class DownloadBoxActionTest < Test::Unit::TestCase
16
16
  @uri = mock("uri")
17
17
  @uri.stubs(:is_a?).returns(false)
18
18
  URI.stubs(:parse).returns(@uri)
19
+
20
+ @downloader = mock("downloader")
21
+ Vagrant::Downloaders::File.any_instance.stubs(:prepare)
22
+ Vagrant::Downloaders::HTTP.any_instance.stubs(:prepare)
19
23
  end
20
24
 
21
25
  should "raise an exception if no URI type is matched" do
@@ -25,6 +29,13 @@ class DownloadBoxActionTest < Test::Unit::TestCase
25
29
  }
26
30
  end
27
31
 
32
+ should "call #prepare on the downloader" do
33
+ @downloader.expects(:prepare).with(@runner.uri).once
34
+ Vagrant::Downloaders::File.expects(:new).returns(@downloader)
35
+ @uri.stubs(:is_a?).with(URI::Generic).returns(true)
36
+ @action.prepare
37
+ end
38
+
28
39
  should "set the downloader to file if URI is generic" do
29
40
  @uri.stubs(:is_a?).with(URI::Generic).returns(true)
30
41
  @action.prepare
@@ -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
- 5.times do |i|
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 = [mock_fake_action, mock_fake_action]
180
- @actions.each do |a|
181
- a.stubs(:rescue)
182
- @runner.actions << a
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
- @mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Destroy)
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
- setup do
11
- @vm.stubs(:destroy)
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 "invoke an around callback around the destroy" do
15
- @mock_vm.expects(:invoke_around_callback).with(:destroy).once
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.execute!
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")