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
@@ -4,9 +4,6 @@ module Vagrant
4
4
  # basic things such as the environment instance variable which all
5
5
  # config classes need as well as a basic `to_json` implementation.
6
6
  class Base
7
- # {Environment} that this config belongs to
8
- attr_accessor :env
9
-
10
7
  # {Top} of this configuration stack
11
8
  attr_accessor :top
12
9
 
@@ -32,6 +29,23 @@ module Vagrant
32
29
  end
33
30
  end
34
31
 
32
+ # A helper to access the environment that this configuration is for.
33
+ # This is obtained by getting the env from the {Top}.
34
+ #
35
+ # @return [Vagrant::Envrionment]
36
+ def env
37
+ top.env
38
+ end
39
+
40
+ # Allows setting options from a hash. By default this simply calls
41
+ # the `#{key}=` method on the config class with the value, which is
42
+ # the expected behavior most of the time.
43
+ def set_options(options)
44
+ options.each do |key, value|
45
+ send("#{key}=", value)
46
+ end
47
+ end
48
+
35
49
  # Called by {Top} after the configuration is loaded to validate
36
50
  # the configuaration objects. Subclasses should implement this
37
51
  # method and add any errors to the `errors` object given.
@@ -11,6 +11,7 @@ module Vagrant
11
11
  attr_accessor :timeout
12
12
  attr_writer :private_key_path
13
13
  attr_accessor :forward_agent
14
+ attr_accessor :forward_x11
14
15
 
15
16
  def private_key_path
16
17
  File.expand_path(@private_key_path, env.root_path)
@@ -0,0 +1,61 @@
1
+ module Vagrant
2
+ class Config
3
+ # This class is the "top" configure class, which handles registering
4
+ # other configuration classes as well as validation of all configured
5
+ # classes. This is the object which is returned by {Environment#config}
6
+ # and has accessors to all other configuration classes.
7
+ #
8
+ # If you're looking to create your own configuration class, see {Base}.
9
+ class Top < Base
10
+ @@configures = {} if !defined?(@@configures)
11
+
12
+ # The environment that this configuration is for.
13
+ attr_reader :env
14
+
15
+ class << self
16
+ # The list of registered configuration classes as well as the key
17
+ # they're registered under.
18
+ def configures_list
19
+ @@configures ||= {}
20
+ end
21
+
22
+ # Registers a configuration class with the given key. This method shouldn't
23
+ # be called. Instead, inherit from {Base} and call {Base.configures}.
24
+ def configures(key, klass)
25
+ configures_list[key] = klass
26
+ attr_reader key.to_sym
27
+ end
28
+ end
29
+
30
+ def initialize(env=nil)
31
+ self.class.configures_list.each do |key, klass|
32
+ config = klass.new
33
+ config.top = self
34
+ instance_variable_set("@#{key}".to_sym, config)
35
+ end
36
+
37
+ @env = env
38
+ end
39
+
40
+ # Validates the configuration classes of this instance and raises an
41
+ # exception if they are invalid. If you are implementing a custom configuration
42
+ # class, the method you want to implement is {Base#validate}. This is
43
+ # the method that checks all the validation, not one which defines
44
+ # validation rules.
45
+ def validate!
46
+ # Validate each of the configured classes and store the results into
47
+ # a hash.
48
+ errors = self.class.configures_list.inject({}) do |container, data|
49
+ key, _ = data
50
+ recorder = ErrorRecorder.new
51
+ send(key.to_sym).validate(recorder)
52
+ container[key.to_sym] = recorder if !recorder.errors.empty?
53
+ container
54
+ end
55
+
56
+ return if errors.empty?
57
+ raise Errors::ConfigValidationFailed, :messages => Util::TemplateRenderer.render("config/validation_failed", :errors => errors)
58
+ end
59
+ end
60
+ end
61
+ end
@@ -4,15 +4,10 @@ module Vagrant
4
4
  configures :vagrant
5
5
 
6
6
  attr_accessor :dotfile_name
7
- attr_accessor :home
8
7
  attr_accessor :host
9
8
 
10
- def initialize
11
- @home = nil
12
- end
13
-
14
9
  def validate(errors)
15
- [:dotfile_name, :home, :host].each do |field|
10
+ [:dotfile_name, :host].each do |field|
16
11
  errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym)
17
12
  end
18
13
  end
@@ -1,3 +1,6 @@
1
+ require 'vagrant/config/vm/sub_vm'
2
+ require 'vagrant/config/vm/provisioner'
3
+
1
4
  module Vagrant
2
5
  class Config
3
6
  class VMConfig < Base
@@ -14,28 +17,17 @@ module Vagrant
14
17
  attr_reader :forwarded_ports
15
18
  attr_reader :shared_folders
16
19
  attr_reader :network_options
17
- attr_reader :hd_location
20
+ attr_reader :provisioners
18
21
  attr_accessor :disk_image_format
19
- attr_accessor :provisioner
20
22
  attr_writer :shared_folder_uid
21
23
  attr_writer :shared_folder_gid
22
24
  attr_accessor :system
23
25
 
24
- # Represents a SubVM. This class is only used here in the VMs
25
- # hash.
26
- class SubVM
27
- include Util::StackedProcRunner
28
-
29
- def options
30
- @options ||= {}
31
- end
32
- end
33
-
34
26
  def initialize
35
27
  @forwarded_ports = {}
36
28
  @shared_folders = {}
37
- @provisioner = nil
38
29
  @network_options = []
30
+ @provisioners = []
39
31
  end
40
32
 
41
33
  def forward_port(name, guestport, hostport, options=nil)
@@ -68,6 +60,17 @@ module Vagrant
68
60
  @network_options[options[:adapter]] = options
69
61
  end
70
62
 
63
+ def provision(name, options=nil, &block)
64
+ @provisioners << Provisioner.new(top, name, options, &block)
65
+ end
66
+
67
+ # This shows an error message to smooth the transition for the
68
+ # backwards incompatible provisioner syntax change introduced
69
+ # in Vagrant 0.7.0.
70
+ def provisioner=(_value)
71
+ raise Errors::VagrantError, :_key => :provisioner_equals_not_supported
72
+ end
73
+
71
74
  def shared_folder_uid
72
75
  @shared_folder_uid || env.config.ssh.username
73
76
  end
@@ -95,14 +98,25 @@ module Vagrant
95
98
  end
96
99
 
97
100
  def define(name, options=nil, &block)
101
+ name = name.to_sym
98
102
  options ||= {}
103
+
104
+ # Add the name to the array of VM keys. This array is used to
105
+ # preserve the order in which VMs are defined.
99
106
  defined_vm_keys << name
100
- defined_vms[name.to_sym] ||= SubVM.new
101
- defined_vms[name.to_sym].options.merge!(options)
102
- defined_vms[name.to_sym].push_proc(&block)
107
+
108
+ # Add the SubVM to the hash of defined VMs
109
+ defined_vms[name] ||= SubVM.new
110
+ defined_vms[name].options.merge!(options)
111
+ defined_vms[name].push_proc(&block)
103
112
  end
104
113
 
105
114
  def validate(errors)
115
+ errors.add(I18n.t("vagrant.config.vm.box_missing")) if !box
116
+ errors.add(I18n.t("vagrant.config.vm.box_not_found", :name => box)) if box && !box_url && !env.box
117
+ errors.add(I18n.t("vagrant.config.vm.boot_mode_invalid")) if ![:vrdp, :gui].include?(boot_mode.to_sym)
118
+ errors.add(I18n.t("vagrant.config.vm.base_mac_invalid")) if env.box && !base_mac
119
+
106
120
  shared_folders.each do |name, options|
107
121
  if !File.directory?(File.expand_path(options[:hostpath].to_s, env.root_path))
108
122
  errors.add(I18n.t("vagrant.config.vm.shared_folder_hostpath_missing",
@@ -111,10 +125,10 @@ module Vagrant
111
125
  end
112
126
  end
113
127
 
114
- errors.add(I18n.t("vagrant.config.vm.box_missing")) if !box
115
- errors.add(I18n.t("vagrant.config.vm.box_not_found", :name => box)) if box && !box_url && !env.box
116
- errors.add(I18n.t("vagrant.config.vm.boot_mode_invalid")) if ![:vrdp, :gui].include?(boot_mode.to_sym)
117
- errors.add(I18n.t("vagrant.config.vm.base_mac_invalid")) if env.box && !base_mac
128
+ # Each provisioner can validate itself
129
+ provisioners.each do |prov|
130
+ prov.validate(errors)
131
+ end
118
132
  end
119
133
  end
120
134
  end
@@ -0,0 +1,56 @@
1
+ module Vagrant
2
+ class Config
3
+ class VMConfig < Base
4
+ # Represents a single configured provisioner for a VM.
5
+ class Provisioner
6
+ attr_reader :top
7
+ attr_reader :shortcut
8
+ attr_reader :provisioner
9
+ attr_reader :config
10
+
11
+ def initialize(top, shortcut, options=nil, &block)
12
+ @top = top
13
+ @shortcut = shortcut
14
+ @provisioner = shortcut
15
+ @provisioner = Provisioners::Base.registered[shortcut] if shortcut.is_a?(Symbol)
16
+ @config = nil
17
+
18
+ configure(options, &block)
19
+ end
20
+
21
+ # Configures the provisioner if it can (if it is valid).
22
+ def configure(options=nil, &block)
23
+ # We don't want ancestors to be searched. This is the default in 1.8,
24
+ # but not in 1.9, hence this hackery.
25
+ const_args = ["Config"]
26
+ const_args << false if RUBY_VERSION >= "1.9"
27
+
28
+ # We assume that every provisioner has a `Config` class beneath
29
+ # it for configuring.
30
+ return if !@provisioner || !@provisioner.const_defined?(*const_args)
31
+
32
+ # Instantiate the config class and configure it
33
+ @config = @provisioner.const_get(*const_args).new
34
+ @config.top = top
35
+ @config.set_options(options) if options
36
+ block.call(@config) if block
37
+ end
38
+
39
+ def validate(errors)
40
+ if !provisioner
41
+ # If we don't have a provisioner then the whole thing is invalid.
42
+ errors.add(I18n.t("vagrant.config.vm.provisioner_not_found", :shortcut => shortcut))
43
+ return
44
+ end
45
+
46
+ if !(provisioner <= Provisioners::Base)
47
+ errors.add(I18n.t("vagrant.config.vm.provisioner_invalid_class", :shortcut => shortcut))
48
+ end
49
+
50
+ # Pass on validation to the provisioner config
51
+ config.validate(errors) if config
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,17 @@
1
+ module Vagrant
2
+ class Config
3
+ class VMConfig < Base
4
+ # Represents a single sub-VM in a multi-VM environment.
5
+ class SubVM
6
+ include Util::StackedProcRunner
7
+
8
+ attr_reader :options
9
+
10
+ def initialize
11
+ @options = {}
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+
@@ -0,0 +1,7 @@
1
+ module Vagrant
2
+ module Downloaders
3
+ autoload :Base, 'vagrant/downloaders/base'
4
+ autoload :File, 'vagrant/downloaders/file'
5
+ autoload :HTTP, 'vagrant/downloaders/http'
6
+ end
7
+ end
@@ -14,6 +14,7 @@ module Vagrant
14
14
  end
15
15
 
16
16
  def download!(source_url, destination_file)
17
+ env.ui.info I18n.t("vagrant.downloaders.file.download")
17
18
  FileUtils.cp(source_url, destination_file.path)
18
19
  end
19
20
  end
@@ -25,7 +25,16 @@ module Vagrant
25
25
  end
26
26
 
27
27
  http.start do |h|
28
+ env.ui.info I18n.t("vagrant.downloaders.http.download", :url => source_url)
29
+
28
30
  h.request_get(uri.request_uri) do |response|
31
+ if response.is_a?(Net::HTTPRedirection)
32
+ # Follow the HTTP redirect.
33
+ # TODO: Error on some redirect limit
34
+ download!(response["Location"], destination_file)
35
+ return
36
+ end
37
+
29
38
  total = response.content_length
30
39
  progress = 0
31
40
  segment_count = 0
@@ -9,6 +9,7 @@ module Vagrant
9
9
  ROOTFILE_NAME = "Vagrantfile"
10
10
  HOME_SUBDIRS = ["tmp", "boxes", "logs"]
11
11
  DEFAULT_VM = :default
12
+ DEFAULT_HOME = "~/.vagrant"
12
13
 
13
14
  # Parent environment (in the case of multi-VMs)
14
15
  attr_reader :parent
@@ -23,6 +24,9 @@ module Vagrant
23
24
  # The {UI} object to communicate with the outside world.
24
25
  attr_writer :ui
25
26
 
27
+ # The {Config} object representing the Vagrantfile loader
28
+ attr_reader :config_loader
29
+
26
30
  #---------------------------------------------------------------
27
31
  # Class Methods
28
32
  #---------------------------------------------------------------
@@ -33,7 +37,6 @@ module Vagrant
33
37
  version = VirtualBox.version
34
38
  raise Errors::VirtualBoxNotDetected if version.nil?
35
39
  raise Errors::VirtualBoxInvalidVersion, :version => version.to_s if version.to_f < 4.0
36
- raise Errors::VirtualBoxInvalidOSE, :version => version.to_s if version.to_s.downcase.include?("ose")
37
40
  rescue Errors::VirtualBoxNotDetected
38
41
  # On 64-bit Windows, show a special error. This error is a subclass
39
42
  # of VirtualBoxNotDetected, so libraries which use Vagrant can just
@@ -79,12 +82,11 @@ module Vagrant
79
82
  root_path.join(config.vagrant.dotfile_name) rescue nil
80
83
  end
81
84
 
82
- # The path to the home directory, expanded relative to the root path,
83
- # and converted into a Pathname object.
85
+ # The path to the home directory and converted into a Pathname object.
84
86
  #
85
87
  # @return [Pathname]
86
88
  def home_path
87
- @_home_path ||= Pathname.new(File.expand_path(config.vagrant.home, root_path))
89
+ @_home_path ||= Pathname.new(File.expand_path(ENV["VAGRANT_HOME"] || DEFAULT_HOME))
88
90
  end
89
91
 
90
92
  # The path to the Vagrant tmp directory
@@ -114,7 +116,8 @@ module Vagrant
114
116
  #
115
117
  # @return [String]
116
118
  def resource
117
- vm.name rescue "vagrant"
119
+ result = vm.name rescue nil
120
+ result || "vagrant"
118
121
  end
119
122
 
120
123
  # Returns the collection of boxes for the environment.
@@ -146,7 +149,7 @@ module Vagrant
146
149
  #
147
150
  # @return [Array<VM>]
148
151
  def vms_ordered
149
- @vms_enum ||= config.vm.defined_vm_keys.map {|name| @vms[name]}
152
+ @vms_enum ||= config.vm.defined_vm_keys.map { |name| @vms[name] }
150
153
  end
151
154
 
152
155
  # Returns the primary VM associated with this environment. This
@@ -305,6 +308,14 @@ module Vagrant
305
308
  self
306
309
  end
307
310
 
311
+ # Reloads the configuration of this environment.
312
+ def reload_config!
313
+ @config = nil
314
+ @config_loader = nil
315
+ load_config!
316
+ self
317
+ end
318
+
308
319
  # Loads this environment's configuration and stores it in the {#config}
309
320
  # variable. The configuration loaded by this method is specified to
310
321
  # this environment, meaning that it will use the given root directory
@@ -313,22 +324,23 @@ module Vagrant
313
324
  first_run = @config.nil?
314
325
 
315
326
  # First load the initial, non config-dependent Vagrantfiles
316
- loader = Config.new(self)
317
- loader.queue << File.expand_path("config/default.rb", Vagrant.source_root)
318
- loader.queue << File.join(box.directory, ROOTFILE_NAME) if !first_run && box
319
- loader.queue << File.join(home_path, ROOTFILE_NAME) if !first_run && home_path
320
- loader.queue << File.join(root_path, ROOTFILE_NAME) if root_path
327
+ @config_loader ||= Config.new(parent ? parent.config_loader : nil)
328
+ @config_loader.load_order = [:default, :box, :home, :root, :sub_vm]
329
+ @config_loader.set(:default, File.expand_path("config/default.rb", Vagrant.source_root))
330
+ @config_loader.set(:box, File.join(box.directory, ROOTFILE_NAME)) if !first_run && vm && box
331
+ @config_loader.set(:home, File.join(home_path, ROOTFILE_NAME)) if !first_run && home_path
332
+ @config_loader.set(:root, File.join(root_path, ROOTFILE_NAME)) if root_path
321
333
 
322
334
  # If this environment is representing a sub-VM, then we push that
323
335
  # proc on as the last configuration.
324
336
  if vm
325
337
  subvm = parent.config.vm.defined_vms[vm.name]
326
- loader.queue << subvm.proc_stack if subvm
338
+ @config_loader.set(:sub_vm, subvm.proc_stack) if subvm
327
339
  end
328
340
 
329
341
  # Execute the configuration stack and store the result as the final
330
342
  # value in the config ivar.
331
- @config = loader.load!
343
+ @config = @config_loader.load(self)
332
344
 
333
345
  # (re)load the logger
334
346
  @logger = nil
@@ -230,16 +230,6 @@ module Vagrant
230
230
  error_key(:dotfile_error, "vagrant.actions.vm.persist")
231
231
  end
232
232
 
233
- class ProvisionInvalidClass < VagrantError
234
- status_code(35)
235
- error_key(:invalid_class, "vagrant.actions.vm.provision")
236
- end
237
-
238
- class ProvisionUnknownType < VagrantError
239
- status_code(36)
240
- error_key(:unknown_type, "vagrant.actions.vm.provision")
241
- end
242
-
243
233
  class SSHAuthenticationFailed < VagrantError
244
234
  status_code(11)
245
235
  error_key(:ssh_authentication_failed)
@@ -275,11 +265,6 @@ module Vagrant
275
265
  error_key(:vagrantfile_syntax_error)
276
266
  end
277
267
 
278
- class VirtualBoxInvalidOSE < VagrantError
279
- status_code(9)
280
- error_key(:virtualbox_invalid_ose)
281
- end
282
-
283
268
  class VirtualBoxInvalidVersion < VagrantError
284
269
  status_code(17)
285
270
  error_key(:virtualbox_invalid_version)