vagrantup 0.6.9 → 0.7.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.
- checksums.yaml +4 -4
- data/.gitignore +2 -0
- data/CHANGELOG.md +37 -0
- data/Gemfile +0 -8
- data/README.md +5 -0
- data/config/default.rb +1 -3
- data/contrib/README.md +12 -0
- data/contrib/emacs/vagrant.el +8 -0
- data/contrib/vim/vagrantfile.vim +9 -0
- data/lib/vagrant/action/box/download.rb +0 -1
- data/lib/vagrant/action/box.rb +11 -0
- data/lib/vagrant/action/builtin.rb +1 -2
- data/lib/vagrant/action/env.rb +7 -0
- data/lib/vagrant/action/general.rb +8 -0
- data/lib/vagrant/action/vm/boot.rb +3 -2
- data/lib/vagrant/action/vm/check_box.rb +1 -0
- data/lib/vagrant/action/vm/clean_machine_folder.rb +1 -1
- data/lib/vagrant/action/vm/destroy.rb +1 -1
- data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +7 -12
- data/lib/vagrant/action/vm/network.rb +1 -1
- data/lib/vagrant/action/vm/nfs.rb +3 -1
- data/lib/vagrant/action/vm/provision.rb +14 -25
- data/lib/vagrant/action/vm/share_folders.rb +11 -4
- data/lib/vagrant/action/vm.rb +30 -0
- data/lib/vagrant/action.rb +12 -0
- data/lib/vagrant/command.rb +25 -0
- data/lib/vagrant/config/base.rb +17 -3
- data/lib/vagrant/config/ssh.rb +2 -2
- data/lib/vagrant/config/top.rb +61 -0
- data/lib/vagrant/config/vagrant.rb +1 -6
- data/lib/vagrant/config/vm/provisioner.rb +56 -0
- data/lib/vagrant/config/vm/sub_vm.rb +17 -0
- data/lib/vagrant/config/vm.rb +34 -20
- data/lib/vagrant/config.rb +78 -128
- data/lib/vagrant/downloaders/file.rb +1 -0
- data/lib/vagrant/downloaders/http.rb +9 -0
- data/lib/vagrant/downloaders.rb +7 -0
- data/lib/vagrant/environment.rb +26 -14
- data/lib/vagrant/errors.rb +5 -15
- data/lib/vagrant/hosts.rb +7 -0
- data/lib/vagrant/provisioners/base.rb +19 -1
- data/lib/vagrant/provisioners/chef.rb +31 -52
- data/lib/vagrant/provisioners/chef_server.rb +34 -10
- data/lib/vagrant/provisioners/chef_solo.rb +31 -9
- data/lib/vagrant/provisioners/puppet.rb +111 -60
- data/lib/vagrant/provisioners/puppet_server.rb +57 -0
- data/lib/vagrant/provisioners.rb +8 -0
- data/lib/vagrant/ssh/session.rb +81 -0
- data/lib/vagrant/ssh.rb +6 -76
- data/lib/vagrant/systems/base.rb +16 -1
- data/lib/vagrant/systems/debian.rb +26 -0
- data/lib/vagrant/systems/gentoo.rb +27 -0
- data/lib/vagrant/systems/linux/config.rb +21 -0
- data/lib/vagrant/systems/linux/error.rb +9 -0
- data/lib/vagrant/systems/linux.rb +14 -56
- data/lib/vagrant/systems/redhat.rb +31 -0
- data/lib/vagrant/systems.rb +9 -0
- data/lib/vagrant/test_helpers.rb +1 -1
- data/lib/vagrant/version.rb +1 -1
- data/lib/vagrant/vm.rb +25 -5
- data/lib/vagrant.rb +14 -18
- data/templates/chef_solo_solo.erb +11 -3
- data/templates/commands/init/Vagrantfile.erb +13 -11
- data/templates/locales/en.yml +76 -26
- data/templates/{network_entry.erb → network_entry_debian.erb} +0 -0
- data/templates/network_entry_gentoo.erb +7 -0
- data/templates/network_entry_redhat.erb +8 -0
- data/templates/ssh_config.erb +1 -1
- data/test/vagrant/action/vm/check_box_test.rb +1 -0
- data/test/vagrant/action/vm/clean_machine_folder_test.rb +6 -4
- data/test/vagrant/action/vm/destroy_test.rb +1 -1
- data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +10 -7
- data/test/vagrant/action/vm/nfs_test.rb +7 -1
- data/test/vagrant/action/vm/provision_test.rb +24 -79
- data/test/vagrant/action/vm/share_folders_test.rb +6 -1
- data/test/vagrant/command/helpers_test.rb +2 -2
- data/test/vagrant/config/base_test.rb +0 -6
- data/test/vagrant/config/vagrant_test.rb +0 -8
- data/test/vagrant/config/vm/provisioner_test.rb +92 -0
- data/test/vagrant/config/vm_test.rb +8 -0
- data/test/vagrant/config_test.rb +49 -89
- data/test/vagrant/downloaders/file_test.rb +18 -4
- data/test/vagrant/environment_test.rb +36 -12
- data/test/vagrant/provisioners/base_test.rb +28 -1
- data/test/vagrant/provisioners/chef_server_test.rb +50 -41
- data/test/vagrant/provisioners/chef_solo_test.rb +39 -16
- data/test/vagrant/provisioners/chef_test.rb +11 -81
- data/test/vagrant/provisioners/puppet_server_test.rb +69 -0
- data/test/vagrant/provisioners/puppet_test.rb +116 -69
- data/test/vagrant/{ssh_session_test.rb → ssh/session_test.rb} +0 -0
- data/test/vagrant/ssh_test.rb +20 -7
- data/test/vagrant/systems/base_test.rb +18 -0
- data/test/vagrant/systems/linux_test.rb +2 -2
- data/test/vagrant/vm_test.rb +33 -5
- data/vagrant.gemspec +6 -5
- metadata +38 -14
- data/lib/vagrant/action/vm/disable_networks.rb +0 -34
- data/lib/vagrant/util/glob_loader.rb +0 -24
- data/test/vagrant/action/vm/disable_networks_test.rb +0 -48
|
@@ -12,23 +12,30 @@ module Vagrant
|
|
|
12
12
|
vm.ssh.execute do |ssh|
|
|
13
13
|
# Checks for the existence of chef binary and error if it
|
|
14
14
|
# doesn't exist.
|
|
15
|
-
ssh.exec!("which #{binary}", :error_class => ChefError, :_key => :chef_not_detected, :binary => binary)
|
|
15
|
+
ssh.exec!("sudo -i which #{binary}", :error_class => ChefError, :_key => :chef_not_detected, :binary => binary)
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
19
|
def chown_provisioning_folder
|
|
20
20
|
vm.ssh.execute do |ssh|
|
|
21
|
-
ssh.exec!("sudo mkdir -p #{
|
|
22
|
-
ssh.exec!("sudo chown #{env.config.ssh.username} #{
|
|
21
|
+
ssh.exec!("sudo mkdir -p #{config.provisioning_path}")
|
|
22
|
+
ssh.exec!("sudo chown #{env.config.ssh.username} #{config.provisioning_path}")
|
|
23
23
|
end
|
|
24
24
|
end
|
|
25
25
|
|
|
26
26
|
def setup_config(template, filename, template_vars)
|
|
27
27
|
config_file = TemplateRenderer.render(template, {
|
|
28
|
-
:log_level =>
|
|
28
|
+
:log_level => config.log_level.to_sym,
|
|
29
|
+
:http_proxy => config.http_proxy,
|
|
30
|
+
:http_proxy_user => config.http_proxy_user,
|
|
31
|
+
:http_proxy_pass => config.http_proxy_pass,
|
|
32
|
+
:https_proxy => config.https_proxy,
|
|
33
|
+
:https_proxy_user => config.https_proxy_user,
|
|
34
|
+
:https_proxy_pass => config.https_proxy_pass,
|
|
35
|
+
:no_proxy => config.no_proxy
|
|
29
36
|
}.merge(template_vars))
|
|
30
37
|
|
|
31
|
-
vm.ssh.upload!(StringIO.new(config_file), File.join(
|
|
38
|
+
vm.ssh.upload!(StringIO.new(config_file), File.join(config.provisioning_path, filename))
|
|
32
39
|
end
|
|
33
40
|
|
|
34
41
|
def setup_json
|
|
@@ -45,11 +52,11 @@ module Vagrant
|
|
|
45
52
|
|
|
46
53
|
# Merge with the "extra data" which isn't put under the
|
|
47
54
|
# vagrant namespace by default
|
|
48
|
-
data.merge!(
|
|
55
|
+
data.merge!(config.json)
|
|
49
56
|
|
|
50
57
|
json = data.to_json
|
|
51
58
|
|
|
52
|
-
vm.ssh.upload!(StringIO.new(json), File.join(
|
|
59
|
+
vm.ssh.upload!(StringIO.new(json), File.join(config.provisioning_path, "dna.json"))
|
|
53
60
|
end
|
|
54
61
|
end
|
|
55
62
|
|
|
@@ -61,37 +68,31 @@ module Vagrant
|
|
|
61
68
|
|
|
62
69
|
class Chef < Base
|
|
63
70
|
# This is the configuration which is available through `config.chef`
|
|
64
|
-
class
|
|
65
|
-
configures :chef
|
|
66
|
-
|
|
67
|
-
# Chef server specific config
|
|
68
|
-
attr_accessor :chef_server_url
|
|
69
|
-
attr_accessor :validation_key_path
|
|
70
|
-
attr_accessor :validation_client_name
|
|
71
|
-
attr_accessor :client_key_path
|
|
72
|
-
attr_accessor :node_name
|
|
73
|
-
|
|
74
|
-
# Chef solo specific config
|
|
75
|
-
attr_accessor :cookbooks_path
|
|
76
|
-
attr_accessor :roles_path
|
|
77
|
-
attr_accessor :recipe_url
|
|
78
|
-
|
|
71
|
+
class Config < Vagrant::Config::Base
|
|
79
72
|
# Shared config
|
|
73
|
+
attr_accessor :node_name
|
|
80
74
|
attr_accessor :provisioning_path
|
|
81
75
|
attr_accessor :log_level
|
|
82
76
|
attr_accessor :json
|
|
77
|
+
attr_accessor :http_proxy
|
|
78
|
+
attr_accessor :http_proxy_user
|
|
79
|
+
attr_accessor :http_proxy_pass
|
|
80
|
+
attr_accessor :https_proxy
|
|
81
|
+
attr_accessor :https_proxy_user
|
|
82
|
+
attr_accessor :https_proxy_pass
|
|
83
|
+
attr_accessor :no_proxy
|
|
83
84
|
|
|
84
85
|
def initialize
|
|
85
|
-
@validation_client_name = "chef-validator"
|
|
86
|
-
@client_key_path = "/etc/chef/client.pem"
|
|
87
|
-
|
|
88
|
-
@cookbooks_path = ["cookbooks", [:vm, "cookbooks"]]
|
|
89
|
-
@roles_path = []
|
|
90
86
|
@provisioning_path = "/tmp/vagrant-chef"
|
|
91
87
|
@log_level = :info
|
|
92
|
-
@json = {
|
|
93
|
-
|
|
94
|
-
|
|
88
|
+
@json = { :instance_role => "vagrant" }
|
|
89
|
+
@http_proxy = nil
|
|
90
|
+
@http_proxy_user = nil
|
|
91
|
+
@http_proxy_pass = nil
|
|
92
|
+
@https_proxy = nil
|
|
93
|
+
@https_proxy_user = nil
|
|
94
|
+
@https_proxy_pass = nil
|
|
95
|
+
@no_proxy = nil
|
|
95
96
|
end
|
|
96
97
|
|
|
97
98
|
# Returns the run list for the provisioning
|
|
@@ -123,28 +124,6 @@ module Vagrant
|
|
|
123
124
|
result.delete("json")
|
|
124
125
|
result
|
|
125
126
|
end
|
|
126
|
-
|
|
127
|
-
def validate(errors)
|
|
128
|
-
if top.vm.provisioner == :chef_solo
|
|
129
|
-
# Validate chef solo settings
|
|
130
|
-
errors.add(I18n.t("vagrant.config.chef.cookbooks_path_empty")) if !cookbooks_path || [cookbooks_path].flatten.empty?
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
if top.vm.provisioner == :chef_server
|
|
134
|
-
# Validate chef server settings
|
|
135
|
-
errors.add(I18n.t("vagrant.config.chef.server_url_empty")) if !chef_server_url || chef_server_url.strip == ""
|
|
136
|
-
errors.add(I18n.t("vagrant.config.chef.validation_key_path")) if !validation_key_path
|
|
137
|
-
end
|
|
138
|
-
|
|
139
|
-
if top.vm.provisioner == :chef_solo
|
|
140
|
-
# On chef solo, a run list MUST be specified
|
|
141
|
-
errors.add(I18n.t("vagrant.config.chef.run_list_empty")) if !json[:run_list] || run_list.empty?
|
|
142
|
-
elsif top.vm.provisioner == :chef_server
|
|
143
|
-
# On chef server, the run list is allowed to be nil, which causes it
|
|
144
|
-
# to sync with the chef server.
|
|
145
|
-
errors.add(I18n.t("vagrant.config.chef.run_list_empty")) if json[:run_list] && run_list.empty?
|
|
146
|
-
end
|
|
147
|
-
end
|
|
148
127
|
end
|
|
149
128
|
end
|
|
150
129
|
end
|
|
@@ -5,10 +5,34 @@ module Vagrant
|
|
|
5
5
|
# This class implements provisioning via chef-client, allowing provisioning
|
|
6
6
|
# with a chef server.
|
|
7
7
|
class ChefServer < Chef
|
|
8
|
+
register :chef_server
|
|
9
|
+
|
|
10
|
+
class Config < Chef::Config
|
|
11
|
+
attr_accessor :chef_server_url
|
|
12
|
+
attr_accessor :validation_key_path
|
|
13
|
+
attr_accessor :validation_client_name
|
|
14
|
+
attr_accessor :client_key_path
|
|
15
|
+
|
|
16
|
+
def initialize
|
|
17
|
+
super
|
|
18
|
+
|
|
19
|
+
@validation_client_name = "chef-validator"
|
|
20
|
+
@client_key_path = "/etc/chef/client.pem"
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def validate(errors)
|
|
24
|
+
super
|
|
25
|
+
|
|
26
|
+
errors.add(I18n.t("vagrant.config.chef.server_url_empty")) if !chef_server_url || chef_server_url.strip == ""
|
|
27
|
+
errors.add(I18n.t("vagrant.config.chef.validation_key_path")) if !validation_key_path
|
|
28
|
+
errors.add(I18n.t("vagrant.config.chef.run_list_empty")) if json[:run_list] && run_list.empty?
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
8
32
|
def prepare
|
|
9
|
-
raise ChefError, :server_validation_key_required if
|
|
33
|
+
raise ChefError, :server_validation_key_required if config.validation_key_path.nil?
|
|
10
34
|
raise ChefError, :server_validation_key_doesnt_exist if !File.file?(validation_key_path)
|
|
11
|
-
raise ChefError, :server_url_required if
|
|
35
|
+
raise ChefError, :server_url_required if config.chef_server_url.nil?
|
|
12
36
|
end
|
|
13
37
|
|
|
14
38
|
def provision!
|
|
@@ -23,7 +47,7 @@ module Vagrant
|
|
|
23
47
|
|
|
24
48
|
def create_client_key_folder
|
|
25
49
|
env.ui.info I18n.t("vagrant.provisioners.chef.client_key_folder")
|
|
26
|
-
path = Pathname.new(
|
|
50
|
+
path = Pathname.new(config.client_key_path)
|
|
27
51
|
|
|
28
52
|
vm.ssh.execute do |ssh|
|
|
29
53
|
ssh.exec!("sudo mkdir -p #{path.dirname}")
|
|
@@ -37,16 +61,16 @@ module Vagrant
|
|
|
37
61
|
|
|
38
62
|
def setup_server_config
|
|
39
63
|
setup_config("chef_server_client", "client.rb", {
|
|
40
|
-
:node_name =>
|
|
41
|
-
:chef_server_url =>
|
|
42
|
-
:validation_client_name =>
|
|
64
|
+
:node_name => config.node_name,
|
|
65
|
+
:chef_server_url => config.chef_server_url,
|
|
66
|
+
:validation_client_name => config.validation_client_name,
|
|
43
67
|
:validation_key => guest_validation_key_path,
|
|
44
|
-
:client_key =>
|
|
68
|
+
:client_key => config.client_key_path
|
|
45
69
|
})
|
|
46
70
|
end
|
|
47
71
|
|
|
48
72
|
def run_chef_client
|
|
49
|
-
command = "cd #{
|
|
73
|
+
command = "sudo -i 'cd #{config.provisioning_path} && chef-client -c client.rb -j dna.json'"
|
|
50
74
|
|
|
51
75
|
env.ui.info I18n.t("vagrant.provisioners.chef.running_client")
|
|
52
76
|
vm.ssh.execute do |ssh|
|
|
@@ -61,11 +85,11 @@ module Vagrant
|
|
|
61
85
|
end
|
|
62
86
|
|
|
63
87
|
def validation_key_path
|
|
64
|
-
File.expand_path(
|
|
88
|
+
File.expand_path(config.validation_key_path, env.root_path)
|
|
65
89
|
end
|
|
66
90
|
|
|
67
91
|
def guest_validation_key_path
|
|
68
|
-
File.join(
|
|
92
|
+
File.join(config.provisioning_path, "validation.pem")
|
|
69
93
|
end
|
|
70
94
|
end
|
|
71
95
|
end
|
|
@@ -2,6 +2,28 @@ module Vagrant
|
|
|
2
2
|
module Provisioners
|
|
3
3
|
# This class implements provisioning via chef-solo.
|
|
4
4
|
class ChefSolo < Chef
|
|
5
|
+
register :chef_solo
|
|
6
|
+
|
|
7
|
+
class Config < Chef::Config
|
|
8
|
+
attr_accessor :cookbooks_path
|
|
9
|
+
attr_accessor :roles_path
|
|
10
|
+
attr_accessor :recipe_url
|
|
11
|
+
|
|
12
|
+
def initialize
|
|
13
|
+
super
|
|
14
|
+
|
|
15
|
+
@cookbooks_path = ["cookbooks", [:vm, "cookbooks"]]
|
|
16
|
+
@roles_path = []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def validate(errors)
|
|
20
|
+
super
|
|
21
|
+
|
|
22
|
+
errors.add(I18n.t("vagrant.config.chef.cookbooks_path_empty")) if !cookbooks_path || [cookbooks_path].flatten.empty?
|
|
23
|
+
errors.add(I18n.t("vagrant.config.chef.run_list_empty")) if !json[:run_list] || run_list.empty?
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
5
27
|
def prepare
|
|
6
28
|
share_cookbook_folders
|
|
7
29
|
share_role_folders
|
|
@@ -29,16 +51,16 @@ module Vagrant
|
|
|
29
51
|
|
|
30
52
|
def setup_solo_config
|
|
31
53
|
setup_config("chef_solo_solo", "solo.rb", {
|
|
32
|
-
:node_name =>
|
|
33
|
-
:provisioning_path =>
|
|
54
|
+
:node_name => config.node_name,
|
|
55
|
+
:provisioning_path => config.provisioning_path,
|
|
34
56
|
:cookbooks_path => cookbooks_path,
|
|
35
|
-
:recipe_url =>
|
|
57
|
+
:recipe_url => config.recipe_url,
|
|
36
58
|
:roles_path => roles_path,
|
|
37
59
|
})
|
|
38
60
|
end
|
|
39
61
|
|
|
40
62
|
def run_chef_solo
|
|
41
|
-
command = "cd #{
|
|
63
|
+
command = "sudo -i 'cd #{config.provisioning_path} && chef-solo -c solo.rb -j dna.json'"
|
|
42
64
|
|
|
43
65
|
env.ui.info I18n.t("vagrant.provisioners.chef.running_solo")
|
|
44
66
|
vm.ssh.execute do |ssh|
|
|
@@ -64,7 +86,7 @@ module Vagrant
|
|
|
64
86
|
end
|
|
65
87
|
|
|
66
88
|
def folder_path(*args)
|
|
67
|
-
File.join(
|
|
89
|
+
File.join(config.provisioning_path, args.join("-"))
|
|
68
90
|
end
|
|
69
91
|
|
|
70
92
|
def folders_path(folders, folder)
|
|
@@ -90,11 +112,11 @@ module Vagrant
|
|
|
90
112
|
end
|
|
91
113
|
|
|
92
114
|
def host_cookbook_paths
|
|
93
|
-
host_folder_paths(
|
|
115
|
+
host_folder_paths(config.cookbooks_path)
|
|
94
116
|
end
|
|
95
117
|
|
|
96
118
|
def host_role_paths
|
|
97
|
-
host_folder_paths(
|
|
119
|
+
host_folder_paths(config.roles_path)
|
|
98
120
|
end
|
|
99
121
|
|
|
100
122
|
def cookbook_path(i)
|
|
@@ -106,11 +128,11 @@ module Vagrant
|
|
|
106
128
|
end
|
|
107
129
|
|
|
108
130
|
def cookbooks_path
|
|
109
|
-
folders_path(
|
|
131
|
+
folders_path(config.cookbooks_path, "cookbooks").to_json
|
|
110
132
|
end
|
|
111
133
|
|
|
112
134
|
def roles_path
|
|
113
|
-
folders_path(
|
|
135
|
+
folders_path(config.roles_path, "roles").to_json
|
|
114
136
|
end
|
|
115
137
|
end
|
|
116
138
|
end
|
|
@@ -1,85 +1,136 @@
|
|
|
1
1
|
module Vagrant
|
|
2
2
|
module Provisioners
|
|
3
|
+
class PuppetError < Vagrant::Errors::VagrantError
|
|
4
|
+
error_namespace("vagrant.provisioners.puppet")
|
|
5
|
+
end
|
|
3
6
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
end
|
|
7
|
+
class Puppet < Base
|
|
8
|
+
register :puppet
|
|
7
9
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
+
class Config < Vagrant::Config::Base
|
|
11
|
+
attr_accessor :manifest_file
|
|
12
|
+
attr_accessor :manifests_path
|
|
13
|
+
attr_accessor :module_path
|
|
14
|
+
attr_accessor :pp_path
|
|
15
|
+
attr_accessor :options
|
|
10
16
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
17
|
+
def initialize
|
|
18
|
+
@manifest_file = nil
|
|
19
|
+
@manifests_path = "manifests"
|
|
20
|
+
@module_path = nil
|
|
21
|
+
@pp_path = "/tmp/vagrant-puppet"
|
|
22
|
+
@options = []
|
|
23
|
+
end
|
|
15
24
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
end
|
|
22
|
-
end
|
|
25
|
+
# Returns the manifests path expanded relative to the root path of the
|
|
26
|
+
# environment.
|
|
27
|
+
def expanded_manifests_path
|
|
28
|
+
Pathname.new(manifests_path).expand_path(env.root_path)
|
|
29
|
+
end
|
|
23
30
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
# Returns the manifest file if set otherwise returns the box name pp file
|
|
32
|
+
# which may or may not exist.
|
|
33
|
+
def computed_manifest_file
|
|
34
|
+
manifest_file || "#{top.vm.box}.pp"
|
|
35
|
+
end
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
run_puppet_client
|
|
35
|
-
end
|
|
37
|
+
# Returns the module paths as an array of paths expanded relative to the
|
|
38
|
+
# root path.
|
|
39
|
+
def expanded_module_paths
|
|
40
|
+
return [] if !module_path
|
|
36
41
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
42
|
+
# Get all the paths and expand them relative to the root path, returning
|
|
43
|
+
# the array of expanded paths
|
|
44
|
+
paths = module_path
|
|
45
|
+
paths = [paths] if !paths.is_a?(Array)
|
|
46
|
+
paths.map do |path|
|
|
47
|
+
Pathname.new(path).expand_path(env.root_path)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
40
50
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
end
|
|
51
|
+
def validate(errors)
|
|
52
|
+
super
|
|
44
53
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
54
|
+
# Manifests path/file validation
|
|
55
|
+
if !expanded_manifests_path.directory?
|
|
56
|
+
errors.add(I18n.t("vagrant.provisioners.puppet.manifests_path_missing", :path => expanded_manifests_path))
|
|
57
|
+
else
|
|
58
|
+
if !expanded_manifests_path.join(computed_manifest_file).file?
|
|
59
|
+
errors.add(I18n.t("vagrant.provisioners.puppet.manifest_missing", :manifest => computed_manifest_file))
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# Module paths validation
|
|
64
|
+
expanded_module_paths.each do |path|
|
|
65
|
+
if !path.directory?
|
|
66
|
+
errors.add(I18n.t("vagrant.provisioners.puppet.module_path_missing", :path => path))
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
48
70
|
end
|
|
49
|
-
end
|
|
50
71
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
72
|
+
def prepare
|
|
73
|
+
set_module_paths
|
|
74
|
+
share_manifests
|
|
75
|
+
share_module_paths
|
|
55
76
|
end
|
|
56
|
-
end
|
|
57
77
|
|
|
58
|
-
|
|
59
|
-
|
|
78
|
+
def provision!
|
|
79
|
+
verify_binary("puppet")
|
|
80
|
+
run_puppet_client
|
|
81
|
+
end
|
|
60
82
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
return @manifest
|
|
64
|
-
else
|
|
65
|
-
raise PuppetError, :_key => :manifest_missing, :manifest => @manifest
|
|
83
|
+
def share_manifests
|
|
84
|
+
env.config.vm.share_folder("manifests", manifests_guest_path, config.expanded_manifests_path)
|
|
66
85
|
end
|
|
67
|
-
end
|
|
68
86
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
87
|
+
def share_module_paths
|
|
88
|
+
count = 0
|
|
89
|
+
@module_paths.each do |from, to|
|
|
90
|
+
# Sorry for the cryptic key here, but VirtualBox has a strange limit on
|
|
91
|
+
# maximum size for it and its something small (around 10)
|
|
92
|
+
env.config.vm.share_folder("v-pp-m#{count}", to, from)
|
|
93
|
+
count += 1
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def set_module_paths
|
|
98
|
+
@module_paths = {}
|
|
99
|
+
config.expanded_module_paths.each_with_index do |path, i|
|
|
100
|
+
@module_paths[path] = File.join(config.pp_path, "modules-#{i}")
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def manifests_guest_path
|
|
105
|
+
File.join(config.pp_path, "manifests")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def verify_binary(binary)
|
|
109
|
+
vm.ssh.execute do |ssh|
|
|
110
|
+
ssh.exec!("sudo -i which #{binary}", :error_class => PuppetError, :_key => :puppet_not_detected, :binary => binary)
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def run_puppet_client
|
|
115
|
+
options = [config.options].flatten
|
|
116
|
+
options << "--modulepath '#{@module_paths.values.join(':')}'" if !@module_paths.empty?
|
|
117
|
+
options << config.computed_manifest_file
|
|
118
|
+
options = options.join(" ")
|
|
119
|
+
|
|
120
|
+
command = "sudo -i 'cd #{manifests_guest_path}; puppet #{options}'"
|
|
73
121
|
|
|
74
|
-
|
|
122
|
+
env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet", :manifest => config.computed_manifest_file)
|
|
75
123
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
124
|
+
vm.ssh.execute do |ssh|
|
|
125
|
+
ssh.exec! command do |ch, type, data|
|
|
126
|
+
if type == :exit_status
|
|
127
|
+
ssh.check_exit_status(data, command)
|
|
128
|
+
else
|
|
129
|
+
env.ui.info(data)
|
|
130
|
+
end
|
|
131
|
+
end
|
|
80
132
|
end
|
|
81
133
|
end
|
|
82
134
|
end
|
|
83
135
|
end
|
|
84
|
-
end
|
|
85
136
|
end
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
module Provisioners
|
|
3
|
+
class PuppetServerError < Vagrant::Errors::VagrantError
|
|
4
|
+
error_namespace("vagrant.provisioners.puppet_server")
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
class PuppetServer < Base
|
|
8
|
+
register :puppet_server
|
|
9
|
+
|
|
10
|
+
class Config < Vagrant::Config::Base
|
|
11
|
+
attr_accessor :puppet_server
|
|
12
|
+
attr_accessor :puppet_node
|
|
13
|
+
attr_accessor :options
|
|
14
|
+
|
|
15
|
+
def initialize
|
|
16
|
+
@puppet_server = "puppet"
|
|
17
|
+
@puppet_node = "puppet_node"
|
|
18
|
+
@options = []
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def provision!
|
|
23
|
+
verify_binary("puppetd")
|
|
24
|
+
run_puppetd_client
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def verify_binary(binary)
|
|
28
|
+
vm.ssh.execute do |ssh|
|
|
29
|
+
ssh.shell do |sh|
|
|
30
|
+
sh.execute("sudo -i which #{binary}", :error_class => PuppetServerError, :_key => :puppetd_not_detected, :binary => binary)
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def run_puppetd_client
|
|
36
|
+
options = config.options
|
|
37
|
+
options = options.join(" ") if options.is_a?(Array)
|
|
38
|
+
if config.puppet_node
|
|
39
|
+
cn = config.puppet_node
|
|
40
|
+
else
|
|
41
|
+
cn = env.config.vm.box
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
command = "sudo -i puppetd #{options} --server #{config.puppet_server} --certname #{cn}"
|
|
45
|
+
|
|
46
|
+
env.ui.info I18n.t("vagrant.provisioners.puppet_server.running_puppetd")
|
|
47
|
+
|
|
48
|
+
vm.ssh.execute do |ssh|
|
|
49
|
+
ssh.exec!(command) do |channel, type, data|
|
|
50
|
+
ssh.check_exit_status(data, command) if type == :exit_status
|
|
51
|
+
env.ui.info(data) if type != :exit_status
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# These aren't autoloaded because they have to register things such
|
|
2
|
+
# as configuration classes right away with Vagrant.
|
|
3
|
+
require 'vagrant/provisioners/base'
|
|
4
|
+
require 'vagrant/provisioners/chef'
|
|
5
|
+
require 'vagrant/provisioners/chef_server'
|
|
6
|
+
require 'vagrant/provisioners/chef_solo'
|
|
7
|
+
require 'vagrant/provisioners/puppet'
|
|
8
|
+
require 'vagrant/provisioners/puppet_server'
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
module Vagrant
|
|
2
|
+
class SSH
|
|
3
|
+
# A helper class which wraps around `Net::SSH::Connection::Session`
|
|
4
|
+
# in order to provide basic command error checking while still
|
|
5
|
+
# providing access to the actual session object.
|
|
6
|
+
class Session
|
|
7
|
+
include Util::Retryable
|
|
8
|
+
|
|
9
|
+
attr_reader :session
|
|
10
|
+
|
|
11
|
+
def initialize(session)
|
|
12
|
+
@session = session
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Executes a given command and simply returns true/false if the
|
|
16
|
+
# command succeeded or not.
|
|
17
|
+
def test?(command)
|
|
18
|
+
exec!(command) do |ch, type, data|
|
|
19
|
+
return true if type == :exit_status && data == 0
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
false
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# Executes a given command on the SSH session and blocks until
|
|
26
|
+
# the command completes. This is an almost line for line copy of
|
|
27
|
+
# the actual `exec!` implementation, except that this
|
|
28
|
+
# implementation also reports `:exit_status` to the block if given.
|
|
29
|
+
def exec!(command, options=nil, &block)
|
|
30
|
+
options = { :error_check => true }.merge(options || {})
|
|
31
|
+
|
|
32
|
+
block ||= Proc.new do |ch, type, data|
|
|
33
|
+
check_exit_status(data, command, options) if type == :exit_status && options[:error_check]
|
|
34
|
+
|
|
35
|
+
ch[:result] ||= ""
|
|
36
|
+
ch[:result] << data if [:stdout, :stderr].include?(type)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
retryable(:tries => 5, :on => IOError, :sleep => 0.5) do
|
|
40
|
+
metach = session.open_channel do |channel|
|
|
41
|
+
channel.exec(command) do |ch, success|
|
|
42
|
+
raise "could not execute command: #{command.inspect}" unless success
|
|
43
|
+
|
|
44
|
+
# Output stdout data to the block
|
|
45
|
+
channel.on_data do |ch2, data|
|
|
46
|
+
block.call(ch2, :stdout, data)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
# Output stderr data to the block
|
|
50
|
+
channel.on_extended_data do |ch2, type, data|
|
|
51
|
+
block.call(ch2, :stderr, data)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Output exit status information to the block
|
|
55
|
+
channel.on_request("exit-status") do |ch2, data|
|
|
56
|
+
block.call(ch2, :exit_status, data.read_long)
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
metach.wait
|
|
62
|
+
metach[:result]
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# Checks for an erroroneous exit status and raises an exception
|
|
67
|
+
# if so.
|
|
68
|
+
def check_exit_status(exit_status, command, options=nil)
|
|
69
|
+
if exit_status != 0
|
|
70
|
+
options = {
|
|
71
|
+
:_error_class => Errors::VagrantError,
|
|
72
|
+
:_key => :ssh_bad_exit_status,
|
|
73
|
+
:command => command
|
|
74
|
+
}.merge(options || {})
|
|
75
|
+
|
|
76
|
+
raise options[:_error_class], options
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|