vagrant 0.7.0.beta → 0.7.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. data/.gitignore +2 -0
  2. data/CHANGELOG.md +26 -0
  3. data/Gemfile +0 -8
  4. data/config/default.rb +1 -2
  5. data/contrib/README.md +12 -0
  6. data/contrib/emacs/vagrant.el +8 -0
  7. data/contrib/vim/vagrantfile.vim +9 -0
  8. data/lib/vagrant.rb +14 -18
  9. data/lib/vagrant/action.rb +12 -0
  10. data/lib/vagrant/action/box.rb +11 -0
  11. data/lib/vagrant/action/box/download.rb +0 -1
  12. data/lib/vagrant/action/env.rb +7 -0
  13. data/lib/vagrant/action/general.rb +8 -0
  14. data/lib/vagrant/action/vm.rb +30 -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/network.rb +1 -1
  18. data/lib/vagrant/action/vm/nfs.rb +3 -1
  19. data/lib/vagrant/action/vm/provision.rb +14 -25
  20. data/lib/vagrant/action/vm/share_folders.rb +11 -4
  21. data/lib/vagrant/command.rb +25 -0
  22. data/lib/vagrant/config.rb +78 -128
  23. data/lib/vagrant/config/base.rb +17 -3
  24. data/lib/vagrant/config/ssh.rb +1 -0
  25. data/lib/vagrant/config/top.rb +61 -0
  26. data/lib/vagrant/config/vagrant.rb +1 -6
  27. data/lib/vagrant/config/vm.rb +34 -20
  28. data/lib/vagrant/config/vm/provisioner.rb +56 -0
  29. data/lib/vagrant/config/vm/sub_vm.rb +17 -0
  30. data/lib/vagrant/downloaders.rb +7 -0
  31. data/lib/vagrant/downloaders/file.rb +1 -0
  32. data/lib/vagrant/downloaders/http.rb +9 -0
  33. data/lib/vagrant/environment.rb +25 -13
  34. data/lib/vagrant/errors.rb +0 -15
  35. data/lib/vagrant/hosts.rb +7 -0
  36. data/lib/vagrant/provisioners.rb +8 -0
  37. data/lib/vagrant/provisioners/base.rb +19 -1
  38. data/lib/vagrant/provisioners/chef.rb +31 -52
  39. data/lib/vagrant/provisioners/chef_server.rb +34 -10
  40. data/lib/vagrant/provisioners/chef_solo.rb +31 -9
  41. data/lib/vagrant/provisioners/puppet.rb +70 -60
  42. data/lib/vagrant/provisioners/puppet_server.rb +57 -0
  43. data/lib/vagrant/ssh.rb +3 -72
  44. data/lib/vagrant/ssh/session.rb +81 -0
  45. data/lib/vagrant/systems.rb +9 -0
  46. data/lib/vagrant/systems/base.rb +16 -1
  47. data/lib/vagrant/systems/debian.rb +26 -0
  48. data/lib/vagrant/systems/gentoo.rb +27 -0
  49. data/lib/vagrant/systems/linux.rb +14 -56
  50. data/lib/vagrant/systems/linux/config.rb +21 -0
  51. data/lib/vagrant/systems/linux/error.rb +9 -0
  52. data/lib/vagrant/systems/redhat.rb +31 -0
  53. data/lib/vagrant/test_helpers.rb +1 -1
  54. data/lib/vagrant/version.rb +1 -1
  55. data/lib/vagrant/vm.rb +25 -5
  56. data/templates/chef_solo_solo.erb +11 -3
  57. data/templates/locales/en.yml +65 -25
  58. data/templates/{network_entry.erb → network_entry_debian.erb} +0 -0
  59. data/templates/network_entry_gentoo.erb +7 -0
  60. data/templates/network_entry_redhat.erb +8 -0
  61. data/test/vagrant/action/vm/check_box_test.rb +1 -0
  62. data/test/vagrant/action/vm/nfs_test.rb +7 -1
  63. data/test/vagrant/action/vm/provision_test.rb +24 -79
  64. data/test/vagrant/action/vm/share_folders_test.rb +6 -1
  65. data/test/vagrant/command/helpers_test.rb +2 -2
  66. data/test/vagrant/config/base_test.rb +0 -6
  67. data/test/vagrant/config/vagrant_test.rb +0 -8
  68. data/test/vagrant/config/vm/provisioner_test.rb +92 -0
  69. data/test/vagrant/config/vm_test.rb +8 -0
  70. data/test/vagrant/config_test.rb +49 -89
  71. data/test/vagrant/downloaders/file_test.rb +18 -4
  72. data/test/vagrant/environment_test.rb +36 -12
  73. data/test/vagrant/provisioners/base_test.rb +28 -1
  74. data/test/vagrant/provisioners/chef_server_test.rb +50 -41
  75. data/test/vagrant/provisioners/chef_solo_test.rb +39 -16
  76. data/test/vagrant/provisioners/chef_test.rb +11 -81
  77. data/test/vagrant/provisioners/puppet_server_test.rb +69 -0
  78. data/test/vagrant/provisioners/puppet_test.rb +69 -54
  79. data/test/vagrant/{ssh_session_test.rb → ssh/session_test.rb} +0 -0
  80. data/test/vagrant/ssh_test.rb +12 -1
  81. data/test/vagrant/systems/base_test.rb +18 -0
  82. data/test/vagrant/systems/linux_test.rb +2 -2
  83. data/test/vagrant/vm_test.rb +33 -5
  84. data/vagrant.gemspec +6 -5
  85. metadata +42 -16
  86. data/lib/vagrant/util/glob_loader.rb +0 -24
@@ -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
data/lib/vagrant/ssh.rb CHANGED
@@ -3,6 +3,8 @@ require 'net/ssh'
3
3
  require 'net/scp'
4
4
  require 'mario'
5
5
 
6
+ require 'vagrant/ssh/session'
7
+
6
8
  module Vagrant
7
9
  # Manages SSH access to a specific environment. Allows an environment to
8
10
  # replace the process with SSH itself, run a specific set of commands,
@@ -42,6 +44,7 @@ module Vagrant
42
44
  "-o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes",
43
45
  "-i #{options[:private_key_path]}"]
44
46
  command_options << "-o ForwardAgent=yes" if env.config.ssh.forward_agent
47
+ command_options << "-o ForwardX11=yes" if env.config.ssh.forward_x11
45
48
 
46
49
  # Some hackery going on here. On Mac OS X Leopard (10.5), exec fails
47
50
  # (GH-51). As a workaround, we fork and wait. On all other platforms,
@@ -162,76 +165,4 @@ module Vagrant
162
165
  return env.config.ssh.port
163
166
  end
164
167
  end
165
-
166
- class SSH
167
- # A helper class which wraps around `Net::SSH::Connection::Session`
168
- # in order to provide basic command error checking while still
169
- # providing access to the actual session object.
170
- class Session
171
- include Util::Retryable
172
-
173
- attr_reader :session
174
-
175
- def initialize(session)
176
- @session = session
177
- end
178
-
179
- # Executes a given command on the SSH session and blocks until
180
- # the command completes. This is an almost line for line copy of
181
- # the actual `exec!` implementation, except that this
182
- # implementation also reports `:exit_status` to the block if given.
183
- def exec!(command, options=nil, &block)
184
- options = {
185
- :error_check => true
186
- }.merge(options || {})
187
-
188
- block ||= Proc.new do |ch, type, data|
189
- check_exit_status(data, command, options) if type == :exit_status && options[:error_check]
190
-
191
- ch[:result] ||= ""
192
- ch[:result] << data if [:stdout, :stderr].include?(type)
193
- end
194
-
195
- retryable(:tries => 5, :on => IOError, :sleep => 0.5) do
196
- metach = session.open_channel do |channel|
197
- channel.exec(command) do |ch, success|
198
- raise "could not execute command: #{command.inspect}" unless success
199
-
200
- # Output stdout data to the block
201
- channel.on_data do |ch2, data|
202
- block.call(ch2, :stdout, data)
203
- end
204
-
205
- # Output stderr data to the block
206
- channel.on_extended_data do |ch2, type, data|
207
- block.call(ch2, :stderr, data)
208
- end
209
-
210
- # Output exit status information to the block
211
- channel.on_request("exit-status") do |ch2, data|
212
- block.call(ch2, :exit_status, data.read_long)
213
- end
214
- end
215
- end
216
-
217
- metach.wait
218
- metach[:result]
219
- end
220
- end
221
-
222
- # Checks for an erroroneous exit status and raises an exception
223
- # if so.
224
- def check_exit_status(exit_status, command, options=nil)
225
- if exit_status != 0
226
- options = {
227
- :_error_class => Errors::VagrantError,
228
- :_key => :ssh_bad_exit_status,
229
- :command => command
230
- }.merge(options || {})
231
-
232
- raise options[:_error_class], options
233
- end
234
- end
235
- end
236
- end
237
168
  end
@@ -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
@@ -0,0 +1,9 @@
1
+ # These can't be autoloaded because they have to register functionality
2
+ # with Vagrant core.
3
+ require 'vagrant/systems/base'
4
+ require 'vagrant/systems/linux'
5
+ require 'vagrant/systems/solaris'
6
+
7
+ require 'vagrant/systems/debian'
8
+ require 'vagrant/systems/gentoo'
9
+ require 'vagrant/systems/redhat'
@@ -15,6 +15,10 @@ module Vagrant
15
15
  # required by systems can and will change at any time. Any
16
16
  # changes will be noted on release notes.**
17
17
  class Base
18
+ class BaseError < Errors::VagrantError
19
+ error_namespace("vagrant.systems.base")
20
+ end
21
+
18
22
  include Vagrant::Util
19
23
 
20
24
  # The VM which this system is tied to.
@@ -27,6 +31,15 @@ module Vagrant
27
31
  @vm = vm
28
32
  end
29
33
 
34
+ # This method is automatically called when the system is available (when
35
+ # Vagrant can successfully SSH into the machine) to give the system a chance
36
+ # to determine the distro and return a distro-specific system.
37
+ #
38
+ # **Warning:** If a return value which subclasses from {Base} is
39
+ # returned, Vagrant will use it as the new system instance for the
40
+ # class.
41
+ def distro_dispatch; end
42
+
30
43
  # Halt the machine. This method should gracefully shut down the
31
44
  # operating system. This method will cause `vagrant halt` and associated
32
45
  # commands to _block_, meaning that if the machine doesn't halt
@@ -55,7 +68,9 @@ module Vagrant
55
68
 
56
69
  # Prepares the system for host only networks. This is called
57
70
  # once prior to any `enable_host_only_network` calls.
58
- def prepare_host_only_network; end
71
+ def prepare_host_only_network(net_options=nil)
72
+ raise BaseError, :_key => :unsupported_host_only
73
+ end
59
74
 
60
75
  # Setup the system by adding a new host only network. This
61
76
  # method should configure and bring up the interface for the
@@ -0,0 +1,26 @@
1
+ module Vagrant
2
+ module Systems
3
+ class Debian < Linux
4
+ def prepare_host_only_network(net_options=nil)
5
+ # Remove any previous host only network additions to the
6
+ # interface file.
7
+ vm.ssh.execute do |ssh|
8
+ # Clear out any previous entries
9
+ ssh.exec!("sudo sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces")
10
+ ssh.exec!("sudo su -c 'cat /tmp/vagrant-network-interfaces > /etc/network/interfaces'")
11
+ end
12
+ end
13
+
14
+ def enable_host_only_network(net_options)
15
+ entry = TemplateRenderer.render('network_entry_debian', :net_options => net_options)
16
+ vm.ssh.upload!(StringIO.new(entry), "/tmp/vagrant-network-entry")
17
+
18
+ vm.ssh.execute do |ssh|
19
+ ssh.exec!("sudo /sbin/ifdown eth#{net_options[:adapter]} 2> /dev/null")
20
+ ssh.exec!("sudo su -c 'cat /tmp/vagrant-network-entry >> /etc/network/interfaces'")
21
+ ssh.exec!("sudo /sbin/ifup eth#{net_options[:adapter]}")
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,27 @@
1
+ module Vagrant
2
+ module Systems
3
+ class Gentoo < Linux
4
+ def prepare_host_only_network(net_options=nil)
5
+ # Remove any previous host only network additions to the
6
+ # interface file.
7
+ vm.ssh.execute do |ssh|
8
+ # Clear out any previous entries
9
+ ssh.exec!("sudo sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/conf.d/net > /tmp/vagrant-network-interfaces")
10
+ ssh.exec!("sudo su -c 'cat /tmp/vagrant-network-interfaces > /etc/conf.d/net'")
11
+ end
12
+ end
13
+
14
+ def enable_host_only_network(net_options)
15
+ entry = TemplateRenderer.render('network_entry_gentoo', :net_options => net_options)
16
+ vm.ssh.upload!(StringIO.new(entry), "/tmp/vagrant-network-entry")
17
+
18
+ vm.ssh.execute do |ssh|
19
+ ssh.exec!("sudo ln -s /etc/init.d/net.lo /etc/init.d/net.eth#{net_options[:adapter]}")
20
+ ssh.exec!("sudo /etc/init.d/net.eth#{net_options[:adapter]} stop 2> /dev/null")
21
+ ssh.exec!("sudo su -c 'cat /tmp/vagrant-network-entry >> /etc/conf.d/net'")
22
+ ssh.exec!("sudo /etc/init.d/net.eth#{net_options[:adapter]} start")
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -1,32 +1,20 @@
1
+ require 'vagrant/systems/linux/error'
2
+ require 'vagrant/systems/linux/config'
3
+
1
4
  module Vagrant
2
5
  module Systems
3
- # A general Vagrant system implementation for "linux." In general,
4
- # any linux-based OS will work fine with this system, although its
5
- # not tested exhaustively. BSD or other based systems may work as
6
- # well, but that hasn't been tested at all.
7
- #
8
- # At any rate, this system implementation should server as an
9
- # example of how to implement any custom systems necessary.
10
6
  class Linux < Base
11
- # A custom config class which will be made accessible via `config.linux`
12
- # This is not necessary for all system implementers, of course. However,
13
- # generally, Vagrant tries to make almost every aspect of its execution
14
- # configurable, and this assists that goal.
15
- class LinuxConfig < Vagrant::Config::Base
16
- configures :linux
17
-
18
- attr_accessor :halt_timeout
19
- attr_accessor :halt_check_interval
20
-
21
- def initialize
22
- @halt_timeout = 30
23
- @halt_check_interval = 1
7
+ def distro_dispatch
8
+ vm.ssh.execute do |ssh|
9
+ return :debian if ssh.test?("cat /etc/debian_version")
10
+ return :gentoo if ssh.test?("cat /etc/gentoo-release")
11
+ return :redhat if ssh.test?("cat /etc/redhat-release")
24
12
  end
13
+
14
+ # Can't detect the distro, assume vanilla linux
15
+ nil
25
16
  end
26
17
 
27
- #-------------------------------------------------------------------
28
- # Overridden methods
29
- #-------------------------------------------------------------------
30
18
  def halt
31
19
  vm.env.ui.info I18n.t("vagrant.systems.linux.attempting_halt")
32
20
  vm.ssh.execute do |ssh|
@@ -57,43 +45,19 @@ module Vagrant
57
45
  folders.each do |name, opts|
58
46
  vm.ssh.execute do |ssh|
59
47
  ssh.exec!("sudo mkdir -p #{opts[:guestpath]}")
60
- ssh.exec!("sudo mount #{ip}:#{opts[:hostpath]} #{opts[:guestpath]}")
48
+ ssh.exec!("sudo mount #{ip}:#{opts[:hostpath]} #{opts[:guestpath]}", :error_class => LinuxError, :_key => :mount_nfs_fail)
61
49
  end
62
50
  end
63
51
  end
64
52
 
65
- def prepare_host_only_network
66
- # Remove any previous host only network additions to the
67
- # interface file.
68
- vm.ssh.execute do |ssh|
69
- # Verify debian/ubuntu
70
- ssh.exec!("cat /etc/debian_version", :error_class => LinuxError, :_key => :network_not_debian)
71
-
72
- # Clear out any previous entries
73
- ssh.exec!("sudo sed -e '/^#VAGRANT-BEGIN/,/^#VAGRANT-END/ d' /etc/network/interfaces > /tmp/vagrant-network-interfaces")
74
- ssh.exec!("sudo su -c 'cat /tmp/vagrant-network-interfaces > /etc/network/interfaces'")
75
- end
76
- end
77
-
78
- def enable_host_only_network(net_options)
79
- entry = TemplateRenderer.render('network_entry', :net_options => net_options)
80
- vm.ssh.upload!(StringIO.new(entry), "/tmp/vagrant-network-entry")
81
-
82
- vm.ssh.execute do |ssh|
83
- ssh.exec!("sudo /sbin/ifdown eth#{net_options[:adapter]} 2> /dev/null")
84
- ssh.exec!("sudo su -c 'cat /tmp/vagrant-network-entry >> /etc/network/interfaces'")
85
- ssh.exec!("sudo /sbin/ifup eth#{net_options[:adapter]}")
86
- end
87
- end
88
-
89
53
  #-------------------------------------------------------------------
90
54
  # "Private" methods which assist above methods
91
55
  #-------------------------------------------------------------------
92
56
  def mount_folder(ssh, name, guestpath, sleeptime=5)
93
57
  # Determine the permission string to attach to the mount command
94
58
  perms = []
95
- perms << "uid=#{vm.env.config.vm.shared_folder_uid}"
96
- perms << "gid=#{vm.env.config.vm.shared_folder_gid}"
59
+ perms << "uid=`id -u #{vm.env.config.vm.shared_folder_uid}`"
60
+ perms << "gid=`id -g #{vm.env.config.vm.shared_folder_gid}`"
97
61
  perms = " -o #{perms.join(",")}" if !perms.empty?
98
62
 
99
63
  attempts = 0
@@ -111,11 +75,5 @@ module Vagrant
111
75
  end
112
76
  end
113
77
  end
114
-
115
- class Linux < Base
116
- class LinuxError < Errors::VagrantError
117
- error_namespace("vagrant.systems.linux")
118
- end
119
- end
120
78
  end
121
79
  end
@@ -0,0 +1,21 @@
1
+ module Vagrant
2
+ module Systems
3
+ class Linux < Vagrant::Systems::Base
4
+ # A custom config class which will be made accessible via `config.linux`
5
+ # This is not necessary for all system implementers, of course. However,
6
+ # generally, Vagrant tries to make almost every aspect of its execution
7
+ # configurable, and this assists that goal.
8
+ class LinuxConfig < Vagrant::Config::Base
9
+ configures :linux
10
+
11
+ attr_accessor :halt_timeout
12
+ attr_accessor :halt_check_interval
13
+
14
+ def initialize
15
+ @halt_timeout = 30
16
+ @halt_check_interval = 1
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end