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.
Files changed (69) hide show
  1. data/Gemfile +1 -1
  2. data/Rakefile +1 -1
  3. data/VERSION +1 -1
  4. data/bin/vagrant-box +1 -2
  5. data/bin/vagrant-down +1 -2
  6. data/bin/vagrant-halt +1 -2
  7. data/bin/vagrant-init +1 -2
  8. data/bin/vagrant-package +1 -2
  9. data/bin/vagrant-reload +1 -2
  10. data/bin/vagrant-resume +1 -2
  11. data/bin/vagrant-ssh +1 -2
  12. data/bin/vagrant-status +29 -0
  13. data/bin/vagrant-suspend +1 -2
  14. data/bin/vagrant-up +1 -2
  15. data/config/default.rb +5 -9
  16. data/keys/README.md +10 -0
  17. data/keys/vagrant +27 -0
  18. data/keys/vagrant.pub +1 -0
  19. data/lib/vagrant/actions/base.rb +14 -0
  20. data/lib/vagrant/actions/collection.rb +36 -0
  21. data/lib/vagrant/actions/runner.rb +4 -10
  22. data/lib/vagrant/actions/vm/boot.rb +4 -5
  23. data/lib/vagrant/actions/vm/customize.rb +17 -0
  24. data/lib/vagrant/actions/vm/destroy.rb +11 -2
  25. data/lib/vagrant/actions/vm/forward_ports.rb +24 -0
  26. data/lib/vagrant/actions/vm/import.rb +1 -0
  27. data/lib/vagrant/actions/vm/provision.rb +30 -52
  28. data/lib/vagrant/actions/vm/reload.rb +2 -2
  29. data/lib/vagrant/actions/vm/shared_folders.rb +37 -25
  30. data/lib/vagrant/actions/vm/up.rb +8 -4
  31. data/lib/vagrant/active_list.rb +66 -0
  32. data/lib/vagrant/commands.rb +44 -0
  33. data/lib/vagrant/config.rb +64 -47
  34. data/lib/vagrant/downloaders/file.rb +2 -12
  35. data/lib/vagrant/env.rb +48 -12
  36. data/lib/vagrant/provisioners/base.rb +22 -0
  37. data/lib/vagrant/provisioners/chef.rb +102 -0
  38. data/lib/vagrant/provisioners/chef_server.rb +96 -0
  39. data/lib/vagrant/provisioners/chef_solo.rb +67 -0
  40. data/lib/vagrant/ssh.rb +25 -6
  41. data/lib/vagrant/stacked_proc_runner.rb +33 -0
  42. data/lib/vagrant/vm.rb +8 -0
  43. data/lib/vagrant.rb +10 -5
  44. data/test/test_helper.rb +22 -6
  45. data/test/vagrant/actions/collection_test.rb +110 -0
  46. data/test/vagrant/actions/runner_test.rb +11 -7
  47. data/test/vagrant/actions/vm/boot_test.rb +7 -7
  48. data/test/vagrant/actions/vm/customize_test.rb +16 -0
  49. data/test/vagrant/actions/vm/destroy_test.rb +19 -6
  50. data/test/vagrant/actions/vm/forward_ports_test.rb +52 -0
  51. data/test/vagrant/actions/vm/import_test.rb +10 -3
  52. data/test/vagrant/actions/vm/provision_test.rb +75 -70
  53. data/test/vagrant/actions/vm/reload_test.rb +3 -2
  54. data/test/vagrant/actions/vm/shared_folders_test.rb +62 -9
  55. data/test/vagrant/actions/vm/up_test.rb +4 -4
  56. data/test/vagrant/active_list_test.rb +169 -0
  57. data/test/vagrant/config_test.rb +145 -29
  58. data/test/vagrant/downloaders/file_test.rb +4 -19
  59. data/test/vagrant/env_test.rb +96 -23
  60. data/test/vagrant/provisioners/base_test.rb +27 -0
  61. data/test/vagrant/provisioners/chef_server_test.rb +175 -0
  62. data/test/vagrant/provisioners/chef_solo_test.rb +142 -0
  63. data/test/vagrant/provisioners/chef_test.rb +116 -0
  64. data/test/vagrant/ssh_test.rb +29 -8
  65. data/test/vagrant/stacked_proc_runner_test.rb +43 -0
  66. data/test/vagrant/vm_test.rb +23 -0
  67. data/vagrant.gemspec +35 -8
  68. metadata +42 -11
  69. data/script/vagrant-ssh-expect.sh +0 -22
@@ -2,102 +2,107 @@ require File.join(File.dirname(__FILE__), '..', '..', '..', 'test_helper')
2
2
 
3
3
  class ProvisionActionTest < Test::Unit::TestCase
4
4
  setup do
5
- @mock_vm, @vm, @action = mock_action(Vagrant::Actions::VM::Provision)
6
-
7
- Vagrant::SSH.stubs(:execute)
8
- Vagrant::SSH.stubs(:upload!)
9
-
5
+ @runner, @vm, @action = mock_action(Vagrant::Actions::VM::Provision)
10
6
  mock_config
11
7
  end
12
8
 
13
- context "shared folders" do
14
- should "setup shared folder on VM for the cookbooks" do
15
- File.expects(:expand_path).with(Vagrant.config.chef.cookbooks_path, Vagrant::Env.root_path).returns("foo")
16
- @action.expects(:cookbooks_path).returns("bar")
17
- assert_equal ["vagrant-provisioning", "foo", "bar"], @action.collect_shared_folders
9
+ context "initialization" do
10
+ should "have a nil provisioner by default" do
11
+ assert_nil @action.provisioner
18
12
  end
19
13
  end
20
14
 
21
- context "cookbooks path" do
22
- should "return the proper cookbook path" do
23
- cookbooks_path = File.join(Vagrant.config.chef.provisioning_path, "cookbooks")
24
- assert_equal cookbooks_path, @action.cookbooks_path
15
+ context "executing" do
16
+ should "do nothing if the provisioner is nil" do
17
+ @action.expects(:provisioner).returns(nil)
18
+ assert_nothing_raised { @action.execute! }
25
19
  end
26
- end
27
20
 
28
- context "permissions on provisioning folder" do
29
- should "chown the folder to the ssh user" do
30
- ssh = mock("ssh")
31
- ssh.expects(:exec!).with("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
32
- Vagrant::SSH.expects(:execute).yields(ssh)
33
- @action.chown_provisioning_folder
21
+ should "call `provision!` on the provisioner" do
22
+ provisioner = mock("provisioner")
23
+ provisioner.expects(:provision!).once
24
+ @action.expects(:provisioner).twice.returns(provisioner)
25
+ @action.execute!
34
26
  end
35
27
  end
36
28
 
37
- context "generating and uploading json" do
38
- def assert_json
39
- Vagrant::SSH.expects(:upload!).with do |json, path|
40
- data = JSON.parse(json.read)
41
- yield data
42
- true
29
+ context "preparing" do
30
+ context "with a nil provisioner" do
31
+ setup do
32
+ mock_config do |config|
33
+ config.vm.provisioner = nil
34
+ end
43
35
  end
44
36
 
45
- @action.setup_json
37
+ should "not set a provisioner if set to nil" do
38
+ @action.prepare
39
+ assert_nil @action.provisioner
40
+ end
46
41
  end
47
42
 
48
- should "merge in the extra json specified in the config" do
49
- Vagrant.config.chef.json = { :foo => "BAR" }
50
- assert_json do |data|
51
- assert_equal "BAR", data["foo"]
43
+ context "with a Class provisioner" do
44
+ setup do
45
+ @instance = mock("instance")
46
+ @instance.stubs(:is_a?).with(Vagrant::Provisioners::Base).returns(true)
47
+ @instance.stubs(:prepare)
48
+ @klass = mock("klass")
49
+ @klass.stubs(:is_a?).with(Class).returns(true)
50
+ @klass.stubs(:new).returns(@instance)
51
+
52
+ mock_config do |config|
53
+ config.vm.provisioner = @klass
54
+ end
52
55
  end
53
- end
54
56
 
55
- should "add the directory as a special case to the JSON" do
56
- assert_json do |data|
57
- assert_equal Vagrant.config.vm.project_directory, data["vagrant"]["directory"]
57
+ should "set the provisioner to an instantiation of the class" do
58
+ @klass.expects(:new).once.returns(@instance)
59
+ assert_nothing_raised { @action.prepare }
60
+ assert_equal @instance, @action.provisioner
58
61
  end
59
- end
60
62
 
61
- should "add the config to the JSON" do
62
- assert_json do |data|
63
- assert_equal Vagrant.config.vm.project_directory, data["vagrant"]["config"]["vm"]["project_directory"]
63
+ should "call prepare on the instance" do
64
+ @instance.expects(:prepare).once
65
+ @action.prepare
64
66
  end
65
- end
66
67
 
67
- should "upload a StringIO to dna.json" do
68
- StringIO.expects(:new).with(anything).returns("bar")
69
- File.expects(:join).with(Vagrant.config.chef.provisioning_path, "dna.json").once.returns("baz")
70
- Vagrant::SSH.expects(:upload!).with("bar", "baz").once
71
- @action.setup_json
68
+ should "raise an exception if the class is not a subclass of the provisioner base" do
69
+ @instance.expects(:is_a?).with(Vagrant::Provisioners::Base).returns(false)
70
+ assert_raises(Vagrant::Actions::ActionException) {
71
+ @action.prepare
72
+ }
73
+ end
72
74
  end
73
- end
74
75
 
75
- context "generating and uploading chef solo configuration file" do
76
- should "upload properly generate the configuration file using configuration data" do
77
- expected_config = <<-config
78
- file_cache_path "#{Vagrant.config.chef.provisioning_path}"
79
- cookbook_path "#{@action.cookbooks_path}"
80
- config
76
+ context "with a Symbol provisioner" do
77
+ def provisioner_expectation(symbol, provisioner)
78
+ mock_config do |config|
79
+ config.vm.provisioner = symbol
80
+ end
81
+
82
+ instance = mock("instance")
83
+ instance.expects(:prepare).once
84
+ provisioner.expects(:new).returns(instance)
85
+ assert_nothing_raised { @action.prepare }
86
+ assert_equal instance, @action.provisioner
87
+ end
81
88
 
82
- StringIO.expects(:new).with(expected_config).once
83
- @action.setup_solo_config
84
- end
89
+ should "raise an ActionException if its an unknown symbol" do
90
+ mock_config do |config|
91
+ config.vm.provisioner = :this_will_never_exist
92
+ end
85
93
 
86
- should "upload this file as solo.rb to the provisioning folder" do
87
- @action.expects(:cookbooks_path).returns("cookbooks")
88
- StringIO.expects(:new).returns("foo")
89
- File.expects(:join).with(Vagrant.config.chef.provisioning_path, "solo.rb").once.returns("bar")
90
- Vagrant::SSH.expects(:upload!).with("foo", "bar").once
91
- @action.setup_solo_config
92
- end
93
- end
94
+ assert_raises(Vagrant::Actions::ActionException) {
95
+ @action.prepare
96
+ }
97
+ end
98
+
99
+ should "set :chef_solo to the ChefSolo provisioner" do
100
+ provisioner_expectation(:chef_solo, Vagrant::Provisioners::ChefSolo)
101
+ end
94
102
 
95
- context "running chef solo" do
96
- should "cd into the provisioning directory and run chef solo" do
97
- ssh = mock("ssh")
98
- ssh.expects(:exec!).with("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json").once
99
- Vagrant::SSH.expects(:execute).yields(ssh)
100
- @action.run_chef_solo
103
+ should "set :chef_server to the ChefServer provisioner" do
104
+ provisioner_expectation(:chef_server, Vagrant::Provisioners::ChefServer)
105
+ end
101
106
  end
102
107
  end
103
108
  end
@@ -8,7 +8,7 @@ class ReloadActionTest < Test::Unit::TestCase
8
8
 
9
9
  context "sub-actions" do
10
10
  setup do
11
- @default_order = [Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot]
11
+ @default_order = [Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot]
12
12
  @vm.stubs(:running?).returns(false)
13
13
  end
14
14
 
@@ -33,7 +33,8 @@ class ReloadActionTest < Test::Unit::TestCase
33
33
 
34
34
  should "add in the provisioning step if enabled" do
35
35
  mock_config do |config|
36
- config.chef.enabled = true
36
+ # Dummy provisioner to test
37
+ config.vm.provisioner = "foo"
37
38
  end
38
39
 
39
40
  @default_order.push(Vagrant::Actions::VM::Provision)
@@ -12,17 +12,58 @@ class SharedFoldersActionTest < Test::Unit::TestCase
12
12
  folders
13
13
  end
14
14
 
15
+ context "before boot" do
16
+ should "clear folders and create metadata, in order" do
17
+ before_seq = sequence("before")
18
+ @action.expects(:clear_shared_folders).once.in_sequence(before_seq)
19
+ @action.expects(:create_metadata).once.in_sequence(before_seq)
20
+ @action.before_boot
21
+ end
22
+ end
23
+
15
24
  context "collecting shared folders" do
16
- should "return the arrays that the callback returns" do
17
- result = [[1,2,3],[4,5,6]]
18
- @mock_vm.expects(:invoke_callback).with(:collect_shared_folders).once.returns(result)
25
+ setup do
26
+ File.stubs(:expand_path).returns("baz")
27
+ end
28
+
29
+ should "convert the vagrant config values into an array" do
30
+ mock_config do |config|
31
+ config.vm.shared_folders.clear
32
+ config.vm.share_folder("foo", "bar", "baz")
33
+ end
34
+
35
+ result = [["foo", "baz", "bar"]]
19
36
  assert_equal result, @action.shared_folders
20
37
  end
21
38
 
22
- should "filter out invalid results" do
23
- result = [[1,2,3],[4,5]]
24
- @mock_vm.expects(:invoke_callback).with(:collect_shared_folders).once.returns(result)
25
- assert_equal [[1,2,3]], @action.shared_folders
39
+ should "expand the path of the host folder" do
40
+ File.expects(:expand_path).with("baz").once.returns("expanded_baz")
41
+
42
+ mock_config do |config|
43
+ config.vm.shared_folders.clear
44
+ config.vm.share_folder("foo", "bar", "baz")
45
+ end
46
+
47
+ result = [["foo", "expanded_baz", "bar"]]
48
+ assert_equal result, @action.shared_folders
49
+ end
50
+ end
51
+
52
+ context "clearing shared folders" do
53
+ setup do
54
+ @shared_folder = mock("shared_folder")
55
+ @shared_folders = [@shared_folder]
56
+ @vm.stubs(:shared_folders).returns(@shared_folders)
57
+ end
58
+
59
+ should "call destroy on each shared folder then reload" do
60
+ destroy_seq = sequence("destroy")
61
+ @shared_folders.each do |sf|
62
+ sf.expects(:destroy).once.in_sequence(destroy_seq)
63
+ end
64
+
65
+ @mock_vm.expects(:reload!).once.in_sequence(destroy_seq)
66
+ @action.clear_shared_folders
26
67
  end
27
68
  end
28
69
 
@@ -39,7 +80,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase
39
80
  @vm.stubs(:shared_folders).returns(shared_folders)
40
81
  @vm.expects(:save).with(true).once
41
82
 
42
- @action.before_boot
83
+ @action.create_metadata
43
84
  end
44
85
  end
45
86
 
@@ -78,7 +119,7 @@ class SharedFoldersActionTest < Test::Unit::TestCase
78
119
  end
79
120
 
80
121
  should "execute the proper mount command" do
81
- @ssh.expects(:exec!).with("sudo mount -t vboxsf #{@name} #{@guestpath}").returns(@success_return)
122
+ @ssh.expects(:exec!).with("sudo mount -t vboxsf -o uid=#{Vagrant.config.ssh.username},gid=#{Vagrant.config.ssh.username} #{@name} #{@guestpath}").returns(@success_return)
82
123
  mount_folder
83
124
  end
84
125
 
@@ -113,5 +154,17 @@ class SharedFoldersActionTest < Test::Unit::TestCase
113
154
  mount_folder
114
155
  }
115
156
  end
157
+
158
+ should "add uid AND gid to mount" do
159
+ uid = "foo"
160
+ gid = "bar"
161
+ mock_config do |config|
162
+ config.vm.shared_folder_uid = uid
163
+ config.vm.shared_folder_gid = gid
164
+ end
165
+
166
+ @ssh.expects(:exec!).with("sudo mount -t vboxsf -o uid=#{uid},gid=#{gid} #{@name} #{@guestpath}").returns(@success_return)
167
+ mount_folder
168
+ end
116
169
  end
117
170
  end
@@ -10,7 +10,7 @@ class UpActionTest < Test::Unit::TestCase
10
10
  setup do
11
11
  File.stubs(:file?).returns(true)
12
12
  File.stubs(:exist?).returns(true)
13
- @default_order = [Vagrant::Actions::VM::Import, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot]
13
+ @default_order = [Vagrant::Actions::VM::Import, Vagrant::Actions::VM::Customize, Vagrant::Actions::VM::ForwardPorts, Vagrant::Actions::VM::SharedFolders, Vagrant::Actions::VM::Boot]
14
14
  end
15
15
 
16
16
  def setup_action_expectations
@@ -47,7 +47,7 @@ class UpActionTest < Test::Unit::TestCase
47
47
 
48
48
  should "add in the provisioning step if enabled" do
49
49
  mock_config do |config|
50
- config.chef.enabled = true
50
+ config.vm.provisioner = "foo"
51
51
  end
52
52
 
53
53
  @default_order.push(Vagrant::Actions::VM::Provision)
@@ -78,8 +78,8 @@ class UpActionTest < Test::Unit::TestCase
78
78
 
79
79
  context "persisting" do
80
80
  should "persist the VM with Env" do
81
- @vm.stubs(:uuid)
82
- Vagrant::Env.expects(:persist_vm).with(@vm).once
81
+ @mock_vm.stubs(:uuid)
82
+ Vagrant::Env.expects(:persist_vm).with(@mock_vm).once
83
83
  @action.persist
84
84
  end
85
85
  end
@@ -0,0 +1,169 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper')
2
+
3
+ class ActiveListTest < Test::Unit::TestCase
4
+ setup do
5
+ mock_config
6
+ end
7
+
8
+ context "class methods" do
9
+ context "loading" do
10
+ should "load if reload is given" do
11
+ File.stubs(:file?).returns(true)
12
+ File.expects(:open).once
13
+ Vagrant::ActiveList.list(true)
14
+ end
15
+
16
+ should "not load if the active json file doesn't exist" do
17
+ File.expects(:file?).with(Vagrant::ActiveList.path).returns(false)
18
+ File.expects(:open).never
19
+ assert_equal [], Vagrant::ActiveList.list(true)
20
+ end
21
+
22
+ should "parse the JSON by reading the file" do
23
+ file = mock("file")
24
+ data = mock("data")
25
+ result = mock("result")
26
+ File.expects(:file?).returns(true)
27
+ File.expects(:open).with(Vagrant::ActiveList.path, 'r').once.yields(file)
28
+ file.expects(:read).returns(data)
29
+ JSON.expects(:parse).with(data).returns(result)
30
+ assert_equal result, Vagrant::ActiveList.list(true)
31
+ end
32
+
33
+ should "not load if reload flag is false and already loaded" do
34
+ File.expects(:file?).once.returns(false)
35
+ result = Vagrant::ActiveList.list(true)
36
+ assert result.equal?(Vagrant::ActiveList.list)
37
+ assert result.equal?(Vagrant::ActiveList.list)
38
+ assert result.equal?(Vagrant::ActiveList.list)
39
+ end
40
+ end
41
+
42
+ context "vms" do
43
+ setup do
44
+ @list = ["foo", "bar"]
45
+ Vagrant::ActiveList.stubs(:list).returns(@list)
46
+ end
47
+
48
+ should "return the list, but with each value as a VM" do
49
+ new_seq = sequence("new")
50
+ results = []
51
+ @list.each do |item|
52
+ result = mock("result-#{item}")
53
+ Vagrant::VM.expects(:find).with(item).returns(result).in_sequence(new_seq)
54
+ results << result
55
+ end
56
+
57
+ assert_equal results, Vagrant::ActiveList.vms
58
+ end
59
+
60
+ should "compact out the nil values" do
61
+ Vagrant::VM.stubs(:find).returns(nil)
62
+ results = Vagrant::ActiveList.vms
63
+ assert results.empty?
64
+ end
65
+ end
66
+
67
+ context "filtered list" do
68
+ should "return a list of UUIDs from the VMs" do
69
+ vms = []
70
+ result = []
71
+ 5.times do |i|
72
+ vm = mock("vm#{i}")
73
+ vm.expects(:uuid).returns(i)
74
+ result << i
75
+ vms << vm
76
+ end
77
+
78
+ Vagrant::ActiveList.stubs(:vms).returns(vms)
79
+ assert_equal result, Vagrant::ActiveList.filtered_list
80
+ end
81
+ end
82
+
83
+ context "adding a VM to the list" do
84
+ setup do
85
+ @list = []
86
+ Vagrant::ActiveList.stubs(:list).returns(@list)
87
+ Vagrant::ActiveList.stubs(:save)
88
+
89
+ @uuid = "foo"
90
+ @vm = mock("vm")
91
+ @vm.stubs(:uuid).returns(@uuid)
92
+ end
93
+
94
+ should "add the VMs UUID to the list" do
95
+ Vagrant::ActiveList.add(@vm)
96
+ assert_equal [@uuid], @list
97
+ end
98
+
99
+ should "uniq the array so multiples never exist" do
100
+ @list << @uuid
101
+ assert_equal 1, @list.length
102
+ Vagrant::ActiveList.add(@vm)
103
+ assert_equal 1, @list.length
104
+ end
105
+
106
+ should "save after adding" do
107
+ save_seq = sequence('save')
108
+ @list.expects(:<<).in_sequence(save_seq)
109
+ Vagrant::ActiveList.expects(:save).in_sequence(save_seq)
110
+ Vagrant::ActiveList.add(@vm)
111
+ end
112
+ end
113
+
114
+ context "deleting a VM from the list" do
115
+ setup do
116
+ @list = ["bar"]
117
+ Vagrant::ActiveList.stubs(:list).returns(@list)
118
+ Vagrant::ActiveList.stubs(:save)
119
+
120
+ @uuid = "bar"
121
+ @vm = mock("vm")
122
+ @vm.stubs(:uuid).returns(@uuid)
123
+ @vm.stubs(:is_a?).with(Vagrant::VM).returns(true)
124
+ end
125
+
126
+ should "delete the uuid from the list of a VM" do
127
+ Vagrant::ActiveList.remove(@vm)
128
+ assert @list.empty?
129
+ end
130
+
131
+ should "delete just the string if a string is given" do
132
+ @list << "zoo"
133
+ Vagrant::ActiveList.remove("zoo")
134
+ assert !@list.include?("zoo")
135
+ end
136
+
137
+ should "save after removing" do
138
+ save_seq = sequence('save')
139
+ @list.expects(:delete).in_sequence(save_seq)
140
+ Vagrant::ActiveList.expects(:save).in_sequence(save_seq)
141
+ Vagrant::ActiveList.remove(@vm)
142
+ end
143
+ end
144
+
145
+ context "saving" do
146
+ setup do
147
+ @filtered = ["zoo"]
148
+ Vagrant::ActiveList.stubs(:filtered_list).returns(@filtered)
149
+ end
150
+
151
+ should "open the JSON path and save to it" do
152
+ file = mock("file")
153
+ File.expects(:open).with(Vagrant::ActiveList.path, "w+").yields(file)
154
+ file.expects(:write).with(@filtered.to_json)
155
+ Vagrant::ActiveList.save
156
+ end
157
+ end
158
+
159
+ context "path" do
160
+ setup do
161
+ Vagrant::Env.stubs(:home_path).returns("foo")
162
+ end
163
+
164
+ should "return the active file within the home path" do
165
+ assert_equal File.join(Vagrant::Env.home_path, Vagrant::ActiveList::FILENAME), Vagrant::ActiveList.path
166
+ end
167
+ end
168
+ end
169
+ end