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.
Files changed (99) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/CHANGELOG.md +37 -0
  4. data/Gemfile +0 -8
  5. data/README.md +5 -0
  6. data/config/default.rb +1 -3
  7. data/contrib/README.md +12 -0
  8. data/contrib/emacs/vagrant.el +8 -0
  9. data/contrib/vim/vagrantfile.vim +9 -0
  10. data/lib/vagrant/action/box/download.rb +0 -1
  11. data/lib/vagrant/action/box.rb +11 -0
  12. data/lib/vagrant/action/builtin.rb +1 -2
  13. data/lib/vagrant/action/env.rb +7 -0
  14. data/lib/vagrant/action/general.rb +8 -0
  15. data/lib/vagrant/action/vm/boot.rb +3 -2
  16. data/lib/vagrant/action/vm/check_box.rb +1 -0
  17. data/lib/vagrant/action/vm/clean_machine_folder.rb +1 -1
  18. data/lib/vagrant/action/vm/destroy.rb +1 -1
  19. data/lib/vagrant/action/vm/destroy_unused_network_interfaces.rb +7 -12
  20. data/lib/vagrant/action/vm/network.rb +1 -1
  21. data/lib/vagrant/action/vm/nfs.rb +3 -1
  22. data/lib/vagrant/action/vm/provision.rb +14 -25
  23. data/lib/vagrant/action/vm/share_folders.rb +11 -4
  24. data/lib/vagrant/action/vm.rb +30 -0
  25. data/lib/vagrant/action.rb +12 -0
  26. data/lib/vagrant/command.rb +25 -0
  27. data/lib/vagrant/config/base.rb +17 -3
  28. data/lib/vagrant/config/ssh.rb +2 -2
  29. data/lib/vagrant/config/top.rb +61 -0
  30. data/lib/vagrant/config/vagrant.rb +1 -6
  31. data/lib/vagrant/config/vm/provisioner.rb +56 -0
  32. data/lib/vagrant/config/vm/sub_vm.rb +17 -0
  33. data/lib/vagrant/config/vm.rb +34 -20
  34. data/lib/vagrant/config.rb +78 -128
  35. data/lib/vagrant/downloaders/file.rb +1 -0
  36. data/lib/vagrant/downloaders/http.rb +9 -0
  37. data/lib/vagrant/downloaders.rb +7 -0
  38. data/lib/vagrant/environment.rb +26 -14
  39. data/lib/vagrant/errors.rb +5 -15
  40. data/lib/vagrant/hosts.rb +7 -0
  41. data/lib/vagrant/provisioners/base.rb +19 -1
  42. data/lib/vagrant/provisioners/chef.rb +31 -52
  43. data/lib/vagrant/provisioners/chef_server.rb +34 -10
  44. data/lib/vagrant/provisioners/chef_solo.rb +31 -9
  45. data/lib/vagrant/provisioners/puppet.rb +111 -60
  46. data/lib/vagrant/provisioners/puppet_server.rb +57 -0
  47. data/lib/vagrant/provisioners.rb +8 -0
  48. data/lib/vagrant/ssh/session.rb +81 -0
  49. data/lib/vagrant/ssh.rb +6 -76
  50. data/lib/vagrant/systems/base.rb +16 -1
  51. data/lib/vagrant/systems/debian.rb +26 -0
  52. data/lib/vagrant/systems/gentoo.rb +27 -0
  53. data/lib/vagrant/systems/linux/config.rb +21 -0
  54. data/lib/vagrant/systems/linux/error.rb +9 -0
  55. data/lib/vagrant/systems/linux.rb +14 -56
  56. data/lib/vagrant/systems/redhat.rb +31 -0
  57. data/lib/vagrant/systems.rb +9 -0
  58. data/lib/vagrant/test_helpers.rb +1 -1
  59. data/lib/vagrant/version.rb +1 -1
  60. data/lib/vagrant/vm.rb +25 -5
  61. data/lib/vagrant.rb +14 -18
  62. data/templates/chef_solo_solo.erb +11 -3
  63. data/templates/commands/init/Vagrantfile.erb +13 -11
  64. data/templates/locales/en.yml +76 -26
  65. data/templates/{network_entry.erb → network_entry_debian.erb} +0 -0
  66. data/templates/network_entry_gentoo.erb +7 -0
  67. data/templates/network_entry_redhat.erb +8 -0
  68. data/templates/ssh_config.erb +1 -1
  69. data/test/vagrant/action/vm/check_box_test.rb +1 -0
  70. data/test/vagrant/action/vm/clean_machine_folder_test.rb +6 -4
  71. data/test/vagrant/action/vm/destroy_test.rb +1 -1
  72. data/test/vagrant/action/vm/destroy_unused_network_interfaces_test.rb +10 -7
  73. data/test/vagrant/action/vm/nfs_test.rb +7 -1
  74. data/test/vagrant/action/vm/provision_test.rb +24 -79
  75. data/test/vagrant/action/vm/share_folders_test.rb +6 -1
  76. data/test/vagrant/command/helpers_test.rb +2 -2
  77. data/test/vagrant/config/base_test.rb +0 -6
  78. data/test/vagrant/config/vagrant_test.rb +0 -8
  79. data/test/vagrant/config/vm/provisioner_test.rb +92 -0
  80. data/test/vagrant/config/vm_test.rb +8 -0
  81. data/test/vagrant/config_test.rb +49 -89
  82. data/test/vagrant/downloaders/file_test.rb +18 -4
  83. data/test/vagrant/environment_test.rb +36 -12
  84. data/test/vagrant/provisioners/base_test.rb +28 -1
  85. data/test/vagrant/provisioners/chef_server_test.rb +50 -41
  86. data/test/vagrant/provisioners/chef_solo_test.rb +39 -16
  87. data/test/vagrant/provisioners/chef_test.rb +11 -81
  88. data/test/vagrant/provisioners/puppet_server_test.rb +69 -0
  89. data/test/vagrant/provisioners/puppet_test.rb +116 -69
  90. data/test/vagrant/{ssh_session_test.rb → ssh/session_test.rb} +0 -0
  91. data/test/vagrant/ssh_test.rb +20 -7
  92. data/test/vagrant/systems/base_test.rb +18 -0
  93. data/test/vagrant/systems/linux_test.rb +2 -2
  94. data/test/vagrant/vm_test.rb +33 -5
  95. data/vagrant.gemspec +6 -5
  96. metadata +38 -14
  97. data/lib/vagrant/action/vm/disable_networks.rb +0 -34
  98. data/lib/vagrant/util/glob_loader.rb +0 -24
  99. 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 #{env.config.chef.provisioning_path}")
22
- ssh.exec!("sudo chown #{env.config.ssh.username} #{env.config.chef.provisioning_path}")
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 => env.config.chef.log_level.to_sym
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(env.config.chef.provisioning_path, filename))
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!(env.config.chef.json)
55
+ data.merge!(config.json)
49
56
 
50
57
  json = data.to_json
51
58
 
52
- vm.ssh.upload!(StringIO.new(json), File.join(env.config.chef.provisioning_path, "dna.json"))
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 ChefConfig < Vagrant::Config::Base
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
- :instance_role => "vagrant",
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 env.config.chef.validation_key_path.nil?
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 env.config.chef.chef_server_url.nil?
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(env.config.chef.client_key_path)
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 => env.config.chef.node_name,
41
- :chef_server_url => env.config.chef.chef_server_url,
42
- :validation_client_name => env.config.chef.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 => env.config.chef.client_key_path
68
+ :client_key => config.client_key_path
45
69
  })
46
70
  end
47
71
 
48
72
  def run_chef_client
49
- command = "cd #{env.config.chef.provisioning_path} && sudo -E chef-client -c client.rb -j dna.json"
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(env.config.chef.validation_key_path, env.root_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(env.config.chef.provisioning_path, "validation.pem")
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 => env.config.chef.node_name,
33
- :provisioning_path => env.config.chef.provisioning_path,
54
+ :node_name => config.node_name,
55
+ :provisioning_path => config.provisioning_path,
34
56
  :cookbooks_path => cookbooks_path,
35
- :recipe_url => env.config.chef.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 #{env.config.chef.provisioning_path} && sudo -E chef-solo -c solo.rb -j dna.json"
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(env.config.chef.provisioning_path, args.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(env.config.chef.cookbooks_path)
115
+ host_folder_paths(config.cookbooks_path)
94
116
  end
95
117
 
96
118
  def host_role_paths
97
- host_folder_paths(env.config.chef.roles_path)
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(env.config.chef.cookbooks_path, "cookbooks").to_json
131
+ folders_path(config.cookbooks_path, "cookbooks").to_json
110
132
  end
111
133
 
112
134
  def roles_path
113
- folders_path(env.config.chef.roles_path, "roles").to_json
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
- class PuppetError < Vagrant::Errors::VagrantError
5
- error_namespace("vagrant.provisioners.puppet")
6
- end
7
+ class Puppet < Base
8
+ register :puppet
7
9
 
8
- class PuppetConfig < Vagrant::Config::Base
9
- configures :puppet
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
- attr_accessor :manifest_file
12
- attr_accessor :manifests_path
13
- attr_accessor :pp_path
14
- attr_accessor :options
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
- def initialize
17
- @manifest_file = ""
18
- @manifests_path = "manifests"
19
- @pp_path = "/tmp/vagrant-puppet"
20
- @options = []
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
- class Puppet < Base
25
- def prepare
26
- check_manifest_dir
27
- share_manifests
28
- end
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
- def provision!
31
- verify_binary("puppet")
32
- create_pp_path
33
- set_manifest
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
- def check_manifest_dir
38
- Dir.mkdir(env.config.puppet.manifests_path) unless File.directory?(env.config.puppet.manifests_path)
39
- end
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
- def share_manifests
42
- env.config.vm.share_folder("manifests", env.config.puppet.pp_path, env.config.puppet.manifests_path)
43
- end
51
+ def validate(errors)
52
+ super
44
53
 
45
- def verify_binary(binary)
46
- vm.ssh.execute do |ssh|
47
- ssh.exec!("which #{binary}", :error_class => PuppetError, :_key => :puppet_not_detected, :binary => binary)
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
- def create_pp_path
52
- vm.ssh.execute do |ssh|
53
- ssh.exec!("sudo mkdir -p #{env.config.puppet.pp_path}")
54
- ssh.exec!("sudo chown #{env.config.ssh.username} #{env.config.puppet.pp_path}")
72
+ def prepare
73
+ set_module_paths
74
+ share_manifests
75
+ share_module_paths
55
76
  end
56
- end
57
77
 
58
- def set_manifest
59
- @manifest = !env.config.puppet.manifest_file.empty? ? env.config.puppet.manifest_file : "#{env.config.vm.box}.pp"
78
+ def provision!
79
+ verify_binary("puppet")
80
+ run_puppet_client
81
+ end
60
82
 
61
- if File.exists?("#{env.config.puppet.manifests_path}/#{@manifest}")
62
- env.ui.info I18n.t("vagrant.provisioners.puppet.manifest_to_run", :manifest => @manifest)
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
- def run_puppet_client
70
- options = env.config.puppet.options
71
- options = options.join(" ") if options.is_a?(Array)
72
- command = "cd #{env.config.puppet.pp_path} && sudo -E puppet #{options} #{@manifest}"
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
- env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet")
122
+ env.ui.info I18n.t("vagrant.provisioners.puppet.running_puppet", :manifest => config.computed_manifest_file)
75
123
 
76
- vm.ssh.execute do |ssh|
77
- ssh.exec!(command) do |channel, type, data|
78
- ssh.check_exit_status(data, command) if type == :exit_status
79
- env.ui.info("#{data}: #{type}") if type != :exit_status
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