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,175 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ChefServerProvisionerTest < Test::Unit::TestCase
4
+ setup do
5
+ @action = Vagrant::Provisioners::ChefServer.new
6
+
7
+ Vagrant::SSH.stubs(:execute)
8
+ Vagrant::SSH.stubs(:upload!)
9
+
10
+ mock_config
11
+ end
12
+
13
+ context "provisioning" do
14
+ should "run the proper sequence of methods in order" do
15
+ prov_seq = sequence("prov_seq")
16
+ @action.expects(:chown_provisioning_folder).once.in_sequence(prov_seq)
17
+ @action.expects(:create_client_key_folder).once.in_sequence(prov_seq)
18
+ @action.expects(:upload_validation_key).once.in_sequence(prov_seq)
19
+ @action.expects(:setup_json).once.in_sequence(prov_seq)
20
+ @action.expects(:setup_config).once.in_sequence(prov_seq)
21
+ @action.expects(:run_chef_client).once.in_sequence(prov_seq)
22
+ @action.provision!
23
+ end
24
+ end
25
+
26
+ context "preparing" do
27
+ setup do
28
+ File.stubs(:file?).returns(true)
29
+ end
30
+
31
+ should "not raise an exception if validation_key_path is set" do
32
+ mock_config do |config|
33
+ config.chef.validation_key_path = "7"
34
+ end
35
+
36
+ assert_nothing_raised { @action.prepare }
37
+ end
38
+
39
+ should "raise an exception if validation_key_path is nil" do
40
+ mock_config do |config|
41
+ config.chef.validation_key_path = nil
42
+ end
43
+
44
+ assert_raises(Vagrant::Actions::ActionException) {
45
+ @action.prepare
46
+ }
47
+ end
48
+
49
+ should "not raise an exception if validation_key_path does exist" do
50
+ mock_config do |config|
51
+ config.chef.validation_key_path = "7"
52
+ end
53
+
54
+ File.expects(:file?).with(Vagrant.config.chef.validation_key_path).returns(true)
55
+ assert_nothing_raised { @action.prepare }
56
+ end
57
+
58
+ should "raise an exception if validation_key_path doesn't exist" do
59
+ mock_config do |config|
60
+ config.chef.validation_key_path = "7"
61
+ end
62
+
63
+ File.expects(:file?).with(Vagrant.config.chef.validation_key_path).returns(false)
64
+ assert_raises(Vagrant::Actions::ActionException) {
65
+ @action.prepare
66
+ }
67
+ end
68
+
69
+ should "not raise an exception if chef_server_url is set" do
70
+ mock_config do |config|
71
+ config.chef.chef_server_url = "7"
72
+ end
73
+
74
+ assert_nothing_raised { @action.prepare }
75
+ end
76
+
77
+ should "raise an exception if chef_server_url is nil" do
78
+ mock_config do |config|
79
+ config.chef.chef_server_url = nil
80
+ end
81
+
82
+ assert_raises(Vagrant::Actions::ActionException) {
83
+ @action.prepare
84
+ }
85
+ end
86
+ end
87
+
88
+ context "creating the client key folder" do
89
+ setup do
90
+ @raw_path = "/foo/bar/baz.pem"
91
+ mock_config do |config|
92
+ config.chef.client_key_path = @raw_path
93
+ end
94
+
95
+ @path = Pathname.new(@raw_path)
96
+ end
97
+
98
+ should "create the folder using the dirname of the path" do
99
+ ssh = mock("ssh")
100
+ ssh.expects(:exec!).with("sudo mkdir -p #{@path.dirname}").once
101
+ Vagrant::SSH.expects(:execute).yields(ssh)
102
+ @action.create_client_key_folder
103
+ end
104
+ end
105
+
106
+ context "uploading the validation key" do
107
+ should "upload the validation key to the provisioning path" do
108
+ @action.expects(:validation_key_path).once.returns("foo")
109
+ @action.expects(:guest_validation_key_path).once.returns("bar")
110
+ Vagrant::SSH.expects(:upload!).with("foo", "bar").once
111
+ @action.upload_validation_key
112
+ end
113
+ end
114
+
115
+ context "the validation key path" do
116
+ should "expand the configured key path" do
117
+ result = mock("result")
118
+ File.expects(:expand_path).with(Vagrant.config.chef.validation_key_path, Vagrant::Env.root_path).once.returns(result)
119
+ assert_equal result, @action.validation_key_path
120
+ end
121
+ end
122
+
123
+ context "the guest validation key path" do
124
+ should "be the provisioning path joined with validation.pem" do
125
+ result = mock("result")
126
+ File.expects(:join).with(Vagrant.config.chef.provisioning_path, "validation.pem").once.returns(result)
127
+ assert_equal result, @action.guest_validation_key_path
128
+ end
129
+ end
130
+
131
+ context "generating and uploading chef client configuration file" do
132
+ setup do
133
+ @action.stubs(:guest_validation_key_path).returns("foo")
134
+ end
135
+
136
+ should "upload properly generate the configuration file using configuration data" do
137
+ expected_config = <<-config
138
+ log_level :info
139
+ log_location STDOUT
140
+ ssl_verify_mode :verify_none
141
+ chef_server_url "#{Vagrant.config.chef.chef_server_url}"
142
+
143
+ validation_client_name "#{Vagrant.config.chef.validation_client_name}"
144
+ validation_key "#{@action.guest_validation_key_path}"
145
+ client_key "#{Vagrant.config.chef.client_key_path}"
146
+
147
+ file_store_path "/srv/chef/file_store"
148
+ file_cache_path "/srv/chef/cache"
149
+
150
+ pid_file "/var/run/chef/chef-client.pid"
151
+
152
+ Mixlib::Log::Formatter.show_time = true
153
+ config
154
+
155
+ StringIO.expects(:new).with(expected_config).once
156
+ @action.setup_config
157
+ end
158
+
159
+ should "upload this file as client.rb to the provisioning folder" do
160
+ StringIO.expects(:new).returns("foo")
161
+ File.expects(:join).with(Vagrant.config.chef.provisioning_path, "client.rb").once.returns("bar")
162
+ Vagrant::SSH.expects(:upload!).with("foo", "bar").once
163
+ @action.setup_config
164
+ end
165
+ end
166
+
167
+ context "running chef client" do
168
+ should "cd into the provisioning directory and run chef client" do
169
+ ssh = mock("ssh")
170
+ ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-client -c client.rb -j dna.json").once
171
+ Vagrant::SSH.expects(:execute).yields(ssh)
172
+ @action.run_chef_client
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,142 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ChefSoloProvisionerTest < Test::Unit::TestCase
4
+ setup do
5
+ @action = Vagrant::Provisioners::ChefSolo.new
6
+
7
+ Vagrant::SSH.stubs(:execute)
8
+ Vagrant::SSH.stubs(:upload!)
9
+
10
+ mock_config
11
+ end
12
+
13
+ context "preparing" do
14
+ should "share cookbook folders" do
15
+ @action.expects(:share_cookbook_folders).once
16
+ @action.prepare
17
+ end
18
+ end
19
+
20
+ context "provisioning" do
21
+ should "run the proper sequence of methods in order" do
22
+ prov_seq = sequence("prov_seq")
23
+ @action.expects(:chown_provisioning_folder).once.in_sequence(prov_seq)
24
+ @action.expects(:setup_json).once.in_sequence(prov_seq)
25
+ @action.expects(:setup_solo_config).once.in_sequence(prov_seq)
26
+ @action.expects(:run_chef_solo).once.in_sequence(prov_seq)
27
+ @action.provision!
28
+ end
29
+ end
30
+
31
+ context "sharing cookbook folders" do
32
+ setup do
33
+ @host_cookbook_paths = ["foo", "bar"]
34
+ @action.stubs(:host_cookbook_paths).returns(@host_cookbook_paths)
35
+ end
36
+
37
+ should "share each cookbook folder" do
38
+ share_seq = sequence("share_seq")
39
+ @host_cookbook_paths.each_with_index do |cookbook, i|
40
+ Vagrant.config.vm.expects(:share_folder).with("vagrant-chef-solo-#{i}", @action.cookbook_path(i), cookbook).in_sequence(share_seq)
41
+ end
42
+
43
+ @action.share_cookbook_folders
44
+ end
45
+ end
46
+
47
+ context "host cookbooks paths" do
48
+ should "expand the path of the cookbooks relative to the environment root path" do
49
+ @cookbook = "foo"
50
+ @expanded = "bar"
51
+ File.expects(:expand_path).with(@cookbook, Vagrant::Env.root_path).returns(@expanded)
52
+
53
+ mock_config do |config|
54
+ config.chef.cookbooks_path = @cookbook
55
+ end
56
+
57
+ assert_equal [@expanded], @action.host_cookbook_paths
58
+ end
59
+
60
+ should "return as an array if was originally a string" do
61
+ File.stubs(:expand_path).returns("foo")
62
+
63
+ mock_config do |config|
64
+ config.chef.cookbooks_path = "foo"
65
+ end
66
+
67
+ assert_equal ["foo"], @action.host_cookbook_paths
68
+ end
69
+
70
+ should "return the array of cookbooks if its an array" do
71
+ cookbooks = ["foo", "bar"]
72
+ mock_config do |config|
73
+ config.chef.cookbooks_path = cookbooks
74
+ end
75
+
76
+ expand_seq = sequence('expand_seq')
77
+ cookbooks.each do |cookbook|
78
+ File.expects(:expand_path).with(cookbook, Vagrant::Env.root_path).returns(cookbook)
79
+ end
80
+
81
+ assert_equal cookbooks, @action.host_cookbook_paths
82
+ end
83
+ end
84
+
85
+ context "cookbooks path" do
86
+ should "return a proper path to a single cookbook" do
87
+ expected = File.join(Vagrant.config.chef.provisioning_path, "cookbooks-5")
88
+ assert_equal expected, @action.cookbook_path(5)
89
+ end
90
+
91
+ should "return array-representation of cookbook paths if multiple" do
92
+ @cookbooks = (0..5).inject([]) do |acc, i|
93
+ acc << @action.cookbook_path(i)
94
+ end
95
+
96
+ mock_config do |config|
97
+ config.chef.cookbooks_path = @cookbooks
98
+ end
99
+
100
+ assert_equal @cookbooks.to_json, @action.cookbooks_path
101
+ end
102
+
103
+ should "return a single string representation if cookbook paths is single" do
104
+ @cookbooks = @action.cookbook_path(0)
105
+
106
+ mock_config do |config|
107
+ config.chef.cookbooks_path = @cookbooks
108
+ end
109
+
110
+ assert_equal @cookbooks.to_json, @action.cookbooks_path
111
+ end
112
+ end
113
+
114
+ context "generating and uploading chef solo configuration file" do
115
+ should "upload properly generate the configuration file using configuration data" do
116
+ expected_config = <<-config
117
+ file_cache_path "#{Vagrant.config.chef.provisioning_path}"
118
+ cookbook_path #{@action.cookbooks_path}
119
+ config
120
+
121
+ StringIO.expects(:new).with(expected_config).once
122
+ @action.setup_solo_config
123
+ end
124
+
125
+ should "upload this file as solo.rb to the provisioning folder" do
126
+ @action.expects(:cookbooks_path).returns("cookbooks")
127
+ StringIO.expects(:new).returns("foo")
128
+ File.expects(:join).with(Vagrant.config.chef.provisioning_path, "solo.rb").once.returns("bar")
129
+ Vagrant::SSH.expects(:upload!).with("foo", "bar").once
130
+ @action.setup_solo_config
131
+ end
132
+ end
133
+
134
+ context "running chef solo" do
135
+ should "cd into the provisioning directory and run chef solo" do
136
+ ssh = mock("ssh")
137
+ ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json").once
138
+ Vagrant::SSH.expects(:execute).yields(ssh)
139
+ @action.run_chef_solo
140
+ end
141
+ end
142
+ end
@@ -0,0 +1,116 @@
1
+ require File.join(File.dirname(__FILE__), '..', '..', 'test_helper')
2
+
3
+ class ChefProvisionerTest < Test::Unit::TestCase
4
+ setup do
5
+ @action = Vagrant::Provisioners::Chef.new
6
+
7
+ Vagrant::SSH.stubs(:execute)
8
+ Vagrant::SSH.stubs(:upload!)
9
+
10
+ mock_config
11
+ end
12
+
13
+ context "preparing" do
14
+ should "raise an ActionException" do
15
+ assert_raises(Vagrant::Actions::ActionException) {
16
+ @action.prepare
17
+ }
18
+ end
19
+ end
20
+
21
+ context "config" do
22
+ setup do
23
+ @config = Vagrant::Provisioners::Chef::ChefConfig.new
24
+ @config.run_list.clear
25
+ end
26
+
27
+ should "not include the 'json' key in the config dump" do
28
+ result = JSON.parse(@config.to_json)
29
+ assert !result.has_key?("json")
30
+ end
31
+
32
+ should "provide accessors to the run list" do
33
+ @config.run_list << "foo"
34
+ assert !@config.run_list.empty?
35
+ assert_equal ["foo"], @config.run_list
36
+ end
37
+
38
+ should "provide a writer for the run list" do
39
+ data = mock("data")
40
+
41
+ assert_nothing_raised {
42
+ @config.run_list = data
43
+ assert_equal data, @config.run_list
44
+ }
45
+ end
46
+
47
+ should "add a recipe to the run list" do
48
+ @config.add_recipe("foo")
49
+ assert_equal "recipe[foo]", @config.run_list[0]
50
+ end
51
+
52
+ should "not wrap the recipe in 'recipe[]' if it was in the name" do
53
+ @config.add_recipe("recipe[foo]")
54
+ assert_equal "recipe[foo]", @config.run_list[0]
55
+ end
56
+
57
+ should "add a role to the run list" do
58
+ @config.add_role("user")
59
+ assert_equal "role[user]", @config.run_list[0]
60
+ end
61
+
62
+ should "not wrap the role in 'role[]' if it was in the name" do
63
+ @config.add_role("role[user]")
64
+ assert_equal "role[user]", @config.run_list[0]
65
+ end
66
+ end
67
+
68
+ context "permissions on provisioning folder" do
69
+ should "create and chown the folder to the ssh user" do
70
+ ssh_seq = sequence("ssh_seq")
71
+ ssh = mock("ssh")
72
+ ssh.expects(:exec!).with("sudo mkdir -p #{Vagrant.config.chef.provisioning_path}").once.in_sequence(ssh_seq)
73
+ ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}").once.in_sequence(ssh_seq)
74
+ Vagrant::SSH.expects(:execute).yields(ssh)
75
+ @action.chown_provisioning_folder
76
+ end
77
+ end
78
+
79
+ context "generating and uploading json" do
80
+ def assert_json
81
+ Vagrant::SSH.expects(:upload!).with do |json, path|
82
+ data = JSON.parse(json.read)
83
+ yield data
84
+ true
85
+ end
86
+
87
+ @action.setup_json
88
+ end
89
+
90
+ should "merge in the extra json specified in the config" do
91
+ Vagrant.config.chef.json = { :foo => "BAR" }
92
+ assert_json do |data|
93
+ assert_equal "BAR", data["foo"]
94
+ end
95
+ end
96
+
97
+ should "add the directory as a special case to the JSON" do
98
+ assert_json do |data|
99
+ assert_equal Vagrant.config.vm.project_directory, data["vagrant"]["directory"]
100
+ end
101
+ end
102
+
103
+ should "add the config to the JSON" do
104
+ assert_json do |data|
105
+ assert_equal Vagrant.config.vm.project_directory, data["vagrant"]["config"]["vm"]["project_directory"]
106
+ end
107
+ end
108
+
109
+ should "upload a StringIO to dna.json" do
110
+ StringIO.expects(:new).with(anything).returns("bar")
111
+ File.expects(:join).with(Vagrant.config.chef.provisioning_path, "dna.json").once.returns("baz")
112
+ Vagrant::SSH.expects(:upload!).with("bar", "baz").once
113
+ @action.setup_json
114
+ end
115
+ end
116
+ end
@@ -6,21 +6,31 @@ class SshTest < Test::Unit::TestCase
6
6
  end
7
7
 
8
8
  context "connecting to SSH" do
9
- setup do
10
- @script = Vagrant::SSH::SCRIPT
11
- end
12
-
13
9
  test "should call exec with defaults when no options are supplied" do
14
10
  ssh = Vagrant.config.ssh
15
- Kernel.expects(:exec).with("#{@script} #{ssh[:username]} #{ssh[:password]} #{ssh[:host]} #{Vagrant::SSH.port}")
11
+ ssh_exec_expect(Vagrant::SSH.port,
12
+ Vagrant.config.ssh.private_key_path,
13
+ Vagrant.config.ssh.username,
14
+ Vagrant.config.ssh.host)
16
15
  Vagrant::SSH.connect
17
16
  end
18
17
 
19
18
  test "should call exec with supplied params" do
20
- args = {:username => 'bar', :password => 'baz', :host => 'bak', :port => 'bag'}
21
- Kernel.expects(:exec).with("#{@script} #{args[:username]} #{args[:password]} #{args[:host]} #{args[:port]}")
19
+ args = {:username => 'bar', :private_key_path => 'baz', :host => 'bak', :port => 'bag'}
20
+ ssh_exec_expect(args[:port], args[:private_key_path], args[:username], args[:host])
22
21
  Vagrant::SSH.connect(args)
23
22
  end
23
+
24
+ def ssh_exec_expect(port, key_path, uname, host)
25
+ Kernel.expects(:exec).with() do |arg|
26
+ assert arg =~ /^ssh/
27
+ assert arg =~ /-p #{port}/
28
+ assert arg =~ /-i #{key_path}/
29
+ assert arg =~ /#{uname}@#{host}/
30
+ # TODO options not tested for as they may be removed, they may be removed
31
+ true
32
+ end
33
+ end
24
34
  end
25
35
 
26
36
  context "executing ssh commands" do
@@ -29,7 +39,7 @@ class SshTest < Test::Unit::TestCase
29
39
  assert_equal Vagrant.config.ssh.host, host
30
40
  assert_equal Vagrant.config.ssh.username, username
31
41
  assert_equal Vagrant::SSH.port, opts[:port]
32
- assert_equal Vagrant.config.ssh.password, opts[:password]
42
+ assert_equal [Vagrant.config.ssh.private_key_path], opts[:keys]
33
43
  true
34
44
  end
35
45
  Vagrant::SSH.execute
@@ -89,6 +99,17 @@ class SshTest < Test::Unit::TestCase
89
99
  assert !Vagrant::SSH.up?
90
100
  }
91
101
  end
102
+
103
+ should "specifity the timeout as an option to execute" do
104
+ Vagrant::SSH.expects(:execute).with(:timeout => Vagrant.config.ssh.timeout).yields(true)
105
+ assert Vagrant::SSH.up?
106
+ end
107
+
108
+ should "error and exit if a Net::SSH::AuthenticationFailed is raised" do
109
+ Vagrant::SSH.expects(:execute).raises(Net::SSH::AuthenticationFailed)
110
+ Vagrant::SSH.expects(:error_and_exit).once
111
+ Vagrant::SSH.up?
112
+ end
92
113
  end
93
114
 
94
115
  context "getting the ssh port" do