vagrantup 1.0.1 → 1.0.2

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -0
  3. data/bin/vagrant +2 -2
  4. data/lib/vagrant/action.rb +1 -0
  5. data/lib/vagrant/action/builtin.rb +1 -0
  6. data/lib/vagrant/action/vm/boot.rb +5 -0
  7. data/lib/vagrant/action/vm/check_port_collisions.rb +5 -1
  8. data/lib/vagrant/action/vm/provision.rb +4 -6
  9. data/lib/vagrant/action/vm/sane_defaults.rb +57 -0
  10. data/lib/vagrant/cli.rb +11 -5
  11. data/lib/vagrant/command/base.rb +28 -18
  12. data/lib/vagrant/command/box_add.rb +3 -0
  13. data/lib/vagrant/command/box_list.rb +4 -1
  14. data/lib/vagrant/command/box_remove.rb +4 -1
  15. data/lib/vagrant/command/box_repackage.rb +4 -1
  16. data/lib/vagrant/command/destroy.rb +5 -2
  17. data/lib/vagrant/command/gem.rb +5 -1
  18. data/lib/vagrant/command/halt.rb +5 -2
  19. data/lib/vagrant/command/init.rb +4 -1
  20. data/lib/vagrant/command/package.rb +4 -1
  21. data/lib/vagrant/command/provision.rb +6 -2
  22. data/lib/vagrant/command/reload.rb +7 -3
  23. data/lib/vagrant/command/resume.rb +5 -2
  24. data/lib/vagrant/command/ssh.rb +5 -2
  25. data/lib/vagrant/command/ssh_config.rb +10 -3
  26. data/lib/vagrant/command/status.rb +5 -2
  27. data/lib/vagrant/command/suspend.rb +5 -2
  28. data/lib/vagrant/command/up.rb +5 -2
  29. data/lib/vagrant/communication/ssh.rb +19 -12
  30. data/lib/vagrant/config/ssh.rb +1 -1
  31. data/lib/vagrant/errors.rb +10 -0
  32. data/lib/vagrant/guest/gentoo.rb +8 -0
  33. data/lib/vagrant/provisioners/chef_solo.rb +16 -0
  34. data/lib/vagrant/ssh.rb +5 -2
  35. data/lib/vagrant/ui.rb +6 -1
  36. data/lib/vagrant/util/is_port_open.rb +38 -0
  37. data/lib/vagrant/util/platform.rb +1 -1
  38. data/lib/vagrant/util/safe_puts.rb +31 -0
  39. data/lib/vagrant/version.rb +1 -1
  40. data/lib/vagrant/vm.rb +2 -2
  41. data/templates/commands/init/Vagrantfile.erb +6 -3
  42. data/templates/locales/en.yml +9 -0
  43. data/templates/provisioners/chef_solo/solo.erb +2 -0
  44. data/test/unit/vagrant/command/base_test.rb +1 -1
  45. data/test/unit/vagrant/util/is_port_open_test.rb +53 -0
  46. data/test/unit_legacy/vagrant/provisioners/chef_solo_test.rb +2 -1
  47. metadata +5 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9e371c7a61dc9b8d9400cec30e3ebbbc1cfdd1b0
4
- data.tar.gz: 312202b025df0c9526443a07fdac7ebe12a66b7f
3
+ metadata.gz: 4881add7aaa87715f372cca6beebdd072a0d422d
4
+ data.tar.gz: 9c102ab6573bdc7c8f05dcf49023a8bd9c4b6b81
5
5
  SHA512:
6
- metadata.gz: 06be04e82de2eb5bdde3c8a1461638b4861ba5d18924290d803c71248daad60a9474a38dc3baeda5dd5b3637f586dd4bc26cd823bdf0b639dbec06fd7fd82c8d
7
- data.tar.gz: 34df0d3207ede54215a099f1a5ae60b89c4e05cd2f655106cb4ae4a1e5fad538432c5a1ae53d6a0fe8782d6c566a7cdc3c5a11982feb2fbfa45f2c97d8267971
6
+ metadata.gz: 0d75ceaa126d3c13f3a6d13b881848baa767349cb52e2f6a560d3bafe086dbef5c63c606d81b40464cd61aa7accddf6f3a6c6fdbd2513e9723ace275bea006dc
7
+ data.tar.gz: fbe6c996e33357870f7bc0ac42018c806c63ce60b93e151b7091d7b057fc67b17f4c7302e0d7f893aea2c4fd156c8c9170f8ebe913ada5ea50c22511ece05e58
data/CHANGELOG.md CHANGED
@@ -1,5 +1,31 @@
1
+ ## 1.0.2 (March 25, 2012)
2
+
3
+ - Provisioners will still mount folders and such if `--no-provision` is
4
+ used, so that `vagrant provision` works. [GH-803]
5
+ - Nicer error message if an unsupported SSH key type is used. [GH-805]
6
+ - Gentoo guests can now have their host names changed. [GH-796]
7
+ - Relative paths can be used for the `config.ssh.private_key_path`
8
+ setting. [GH-808]
9
+ - `vagrant ssh` now works on Solaris, where `IdentitiesOnly` was not
10
+ an available option. [GH-820]
11
+ - Output works properly in the face of broken pipes. [GH-819]
12
+ - Enable Host IO Cache on the SATA controller by default.
13
+ - Chef-solo provisioner now supports encrypted data bags. [GH-816]
14
+ - Enable the NAT DNS proxy by default, allowing your DNS to continue
15
+ working when you switch networks. [GH-834]
16
+ - Checking for port forwarding collisions also checks for other applications
17
+ that are potentially listening on that port as well. [GH-821]
18
+ - Multiple VM names can be specified for the various commands now. For
19
+ example: `vagrant up web db service`. [GH-795]
20
+ - More robust error handling if a VM fails to boot. The error message
21
+ is much clearer now. [GH-825]
22
+
1
23
  ## 1.0.1 (March 11, 2012)
2
24
 
25
+ - Installers are now bundled with Ruby 1.9.3p125. Previously they were
26
+ bundled with 1.9.3p0. This actually fixes some IO issues with Windows.
27
+ - Windows installer now outputs a `vagrant` binary that will work in msys
28
+ or Cygwin environments.
3
29
  - Fix crashing issue which manifested itself in multi-VM environments.
4
30
  - Add missing `rubygems` require in `environment.rb` to avoid
5
31
  possible load errors. [GH-781]
data/bin/vagrant CHANGED
@@ -39,8 +39,8 @@ begin
39
39
  logger.debug("Loading environment")
40
40
  env.load!
41
41
 
42
- # Execute the CLI interface
43
- env.cli(ARGV)
42
+ # Execute the CLI interface, and exit with the proper error code
43
+ exit(env.cli(ARGV))
44
44
  rescue Vagrant::Errors::VagrantError => e
45
45
  logger.error("Vagrant experienced an error! Details:")
46
46
  logger.error(e.inspect)
@@ -54,6 +54,7 @@ module Vagrant
54
54
  autoload :ProvisionerCleanup, 'vagrant/action/vm/provisioner_cleanup'
55
55
  autoload :PruneNFSExports, 'vagrant/action/vm/prune_nfs_exports'
56
56
  autoload :Resume, 'vagrant/action/vm/resume'
57
+ autoload :SaneDefaults, 'vagrant/action/vm/sane_defaults'
57
58
  autoload :ShareFolders, 'vagrant/action/vm/share_folders'
58
59
  autoload :SetupPackageFiles, 'vagrant/action/vm/setup_package_files'
59
60
  autoload :Suspend, 'vagrant/action/vm/suspend'
@@ -46,6 +46,7 @@ module Vagrant
46
46
  use VM::HostName
47
47
  use VM::ClearNetworkInterfaces
48
48
  use VM::Network
49
+ use VM::SaneDefaults
49
50
  use VM::Customize
50
51
  use VM::Boot
51
52
  end
@@ -35,6 +35,11 @@ module Vagrant
35
35
  # get shown
36
36
  return true if @env[:interrupted]
37
37
 
38
+ # If the VM is not starting or running, something went wrong
39
+ # and we need to show a useful error.
40
+ state = @env[:vm].state
41
+ raise Errors::VMFailedToRun if state != :starting && state != :running
42
+
38
43
  sleep 2 if !@env["vagrant.test"]
39
44
  end
40
45
 
@@ -1,9 +1,13 @@
1
+ require "vagrant/util/is_port_open"
2
+
1
3
  module Vagrant
2
4
  module Action
3
5
  module VM
4
6
  # Action that checks to make sure there are no forwarded port collisions,
5
7
  # and raises an exception if there is.
6
8
  class CheckPortCollisions
9
+ include Util::IsPortOpen
10
+
7
11
  def initialize(app, env)
8
12
  @app = app
9
13
  end
@@ -29,7 +33,7 @@ module Vagrant
29
33
  hostport = options[:hostport].to_i
30
34
  hostport = current[options[:name]] if current.has_key?(options[:name])
31
35
 
32
- if existing.include?(hostport)
36
+ if existing.include?(hostport) || is_port_open?("localhost", hostport)
33
37
  # We have a collision! Handle it
34
38
  send("handle_#{handler}".to_sym, options, existing)
35
39
  end
@@ -19,12 +19,10 @@ module Vagrant
19
19
  # We set this here so that even if this value is changed in the future,
20
20
  # it stays constant to what we expect here in this moment.
21
21
  enabled = env["provision.enabled"]
22
- if enabled
23
- # Instantiate and prepare the provisioners. Preparation must happen here
24
- # so that shared folders and such can properly take effect.
25
- provisioners = enabled_provisioners
26
- provisioners.map { |p| p.prepare }
27
- end
22
+ # Instantiate and prepare the provisioners. Preparation must happen here
23
+ # so that shared folders and such can properly take effect.
24
+ provisioners = enabled_provisioners
25
+ provisioners.map { |p| p.prepare }
28
26
 
29
27
  @app.call(env)
30
28
 
@@ -0,0 +1,57 @@
1
+ require "log4r"
2
+
3
+ module Vagrant
4
+ module Action
5
+ module VM
6
+ # This middleware enforces some sane defaults on the virtualbox
7
+ # VM which help with performance, stability, and in some cases
8
+ # behavior.
9
+ class SaneDefaults
10
+ def initialize(app, env)
11
+ @logger = Log4r::Logger.new("vagrant::action::vm::sanedefaults")
12
+ @app = app
13
+ end
14
+
15
+ def call(env)
16
+ # Set the env on an instance variable so we can access it in
17
+ # helpers.
18
+ @env = env
19
+
20
+ # Enable the host IO cache on the sata controller. Note that
21
+ # if this fails then its not a big deal, so we don't raise any
22
+ # errors. The Host IO cache vastly improves disk IO performance
23
+ # for VMs.
24
+ command = [
25
+ "storagectl", env[:vm].uuid,
26
+ "--name", "SATA Controller",
27
+ "--hostiocache", "on"
28
+ ]
29
+ attempt_and_log(command, "Enabling the Host I/O cache on the SATA controller...")
30
+
31
+ # Enable the DNS proxy while in NAT mode. This shields the guest
32
+ # VM from external DNS changs on the host machine.
33
+ command = [
34
+ "modifyvm", env[:vm].uuid,
35
+ "--natdnsproxy1", "on"
36
+ ]
37
+ attempt_and_log(command, "Enable the NAT DNS proxy on adapter 1...")
38
+
39
+ @app.call(env)
40
+ end
41
+
42
+ protected
43
+
44
+ # This is just a helper method that executes a single command, logs
45
+ # the given string to the log, and also includes the exit status in
46
+ # the log message.
47
+ #
48
+ # @param [Array] command Command to run
49
+ # @param [String] log Log message to write.
50
+ def attempt_and_log(command, log)
51
+ result = @env[:vm].driver.execute_command(command)
52
+ @logger.info("#{log} (exit status = #{result.exit_code})")
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
data/lib/vagrant/cli.rb CHANGED
@@ -21,21 +21,27 @@ module Vagrant
21
21
  :version => Vagrant::VERSION),
22
22
  :prefix => false)
23
23
 
24
- return
24
+ return 0
25
25
  elsif @main_args.include?("-h") || @main_args.include?("--help")
26
26
  # Help is next in short-circuiting everything. Print
27
27
  # the help and exit.
28
- return help
28
+ help
29
+ return 0
29
30
  end
30
31
 
31
32
  # If we reached this far then we must have a subcommand. If not,
32
33
  # then we also just print the help and exit.
33
34
  command_class = Vagrant.commands.get(@sub_command.to_sym) if @sub_command
34
- return help if !command_class || !@sub_command
35
+ if !command_class || !@sub_command
36
+ help
37
+ return 0
38
+ end
35
39
  @logger.debug("Invoking command class: #{command_class} #{@sub_args.inspect}")
36
40
 
37
- # Initialize and execute the command class.
38
- command_class.new(@sub_args, @env).execute
41
+ # Initialize and execute the command class, returning the exit status.
42
+ result = command_class.new(@sub_args, @env).execute
43
+ result = 0 if !result.is_a?(Fixnum)
44
+ return result
39
45
  end
40
46
 
41
47
  # This prints out the help for the CLI.
@@ -1,5 +1,7 @@
1
1
  require 'log4r'
2
2
 
3
+ require "vagrant/util/safe_puts"
4
+
3
5
  module Vagrant
4
6
  module Command
5
7
  # Base class for any CLI commands.
@@ -7,6 +9,8 @@ module Vagrant
7
9
  # This class provides documentation on the interface as well as helper
8
10
  # functions that a command has.
9
11
  class Base
12
+ include Util::SafePuts
13
+
10
14
  def initialize(argv, env)
11
15
  @argv = argv
12
16
  @env = env
@@ -41,7 +45,7 @@ module Vagrant
41
45
 
42
46
  # Add the help option, which must be on every command.
43
47
  opts.on_tail("-h", "--help", "Print this help") do
44
- puts opts.help
48
+ safe_puts(opts.help)
45
49
  return nil
46
50
  end
47
51
 
@@ -60,32 +64,38 @@ module Vagrant
60
64
  # @param [String] name The name of the VM. Nil if every VM.
61
65
  # @param [Boolean] single_target If true, then an exception will be
62
66
  # raised if more than one target is found.
63
- def with_target_vms(name=nil, options=nil)
67
+ def with_target_vms(names=nil, options=nil)
64
68
  # Using VMs requires a Vagrant environment to be properly setup
65
69
  raise Errors::NoEnvironmentError if !@env.root_path
66
70
 
67
71
  # Setup the options hash
68
72
  options ||= {}
69
73
 
74
+ # Require that names be an array
75
+ names ||= []
76
+ names = [names] if !names.is_a?(Array)
77
+
70
78
  # First determine the proper array of VMs.
71
79
  vms = []
72
- if name
73
- raise Errors::MultiVMEnvironmentRequired if !@env.multivm?
74
-
75
- if name =~ /^\/(.+?)\/$/
76
- # This is a regular expression name, so we convert to a regular
77
- # expression and allow that sort of matching.
78
- regex = Regexp.new($1.to_s)
79
-
80
- @env.vms.each do |name, vm|
81
- vms << vm if name =~ regex
80
+ if names.length > 0
81
+ names.each do |name|
82
+ raise Errors::MultiVMEnvironmentRequired if !@env.multivm?
83
+
84
+ if name =~ /^\/(.+?)\/$/
85
+ # This is a regular expression name, so we convert to a regular
86
+ # expression and allow that sort of matching.
87
+ regex = Regexp.new($1.to_s)
88
+
89
+ @env.vms.each do |name, vm|
90
+ vms << vm if name =~ regex
91
+ end
92
+
93
+ raise Errors::VMNoMatchError if vms.empty?
94
+ else
95
+ # String name, just look for a specific VM
96
+ vms << @env.vms[name.to_sym]
97
+ raise Errors::VMNotFoundError, :name => name if !vms[0]
82
98
  end
83
-
84
- raise Errors::VMNoMatchError if vms.empty?
85
- else
86
- # String name, just look for a specific VM
87
- vms << @env.vms[name.to_sym]
88
- raise Errors::VMNotFoundError, :name => name if !vms[0]
89
99
  end
90
100
  else
91
101
  vms = @env.vms_ordered
@@ -28,6 +28,9 @@ module Vagrant
28
28
  end
29
29
 
30
30
  @env.boxes.add(argv[0], argv[1])
31
+
32
+ # Success, exit status 0
33
+ 0
31
34
  end
32
35
  end
33
36
  end
@@ -19,7 +19,10 @@ module Vagrant
19
19
  return @env.ui.warn(I18n.t("vagrant.commands.box.no_installed_boxes"), :prefix => false)
20
20
  end
21
21
  boxes.each { |b| @env.ui.info(b.name, :prefix => false) }
22
- end
22
+
23
+ # Success, exit status 0
24
+ 0
25
+ end
23
26
  end
24
27
  end
25
28
  end
@@ -18,7 +18,10 @@ module Vagrant
18
18
  b = @env.boxes.find(argv[0])
19
19
  raise Errors::BoxNotFound, :name => argv[0] if !b
20
20
  b.destroy
21
- end
21
+
22
+ # Success, exit status 0
23
+ 0
24
+ end
22
25
  end
23
26
  end
24
27
  end
@@ -18,7 +18,10 @@ module Vagrant
18
18
  b = @env.boxes.find(argv[0])
19
19
  raise Errors::BoxNotFound, :name => argv[0] if !b
20
20
  b.repackage
21
- end
21
+
22
+ # Success, exit status 0
23
+ 0
24
+ end
22
25
  end
23
26
  end
24
27
  end
@@ -20,7 +20,7 @@ module Vagrant
20
20
  return if !argv
21
21
 
22
22
  @logger.debug("'Destroy' each target VM...")
23
- with_target_vms(argv[0], :reverse => true) do |vm|
23
+ with_target_vms(argv, :reverse => true) do |vm|
24
24
  if vm.created?
25
25
  # Boolean whether we should actually go through with the destroy
26
26
  # or not. This is true only if the "--force" flag is set or if the
@@ -55,7 +55,10 @@ module Vagrant
55
55
  vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
56
56
  end
57
57
  end
58
- end
58
+
59
+ # Success, exit status 0
60
+ 0
61
+ end
59
62
  end
60
63
  end
61
64
  end
@@ -1,9 +1,13 @@
1
1
  require "rubygems"
2
2
  require "rubygems/gem_runner"
3
3
 
4
+ require "vagrant/util/safe_puts"
5
+
4
6
  module Vagrant
5
7
  module Command
6
8
  class Gem < Base
9
+ include Util::SafePuts
10
+
7
11
  def execute
8
12
  # Bundler sets up its own custom gem load paths such that our
9
13
  # own gems are never loaded. Therefore, give an error if a user
@@ -20,7 +24,7 @@ module Vagrant
20
24
  if @argv.empty? || @argv.include?("-h") || @argv.include?("--help")
21
25
  @env.ui.info(I18n.t("vagrant.commands.gem.help_preamble"),
22
26
  :prefix => false)
23
- puts
27
+ safe_puts
24
28
  end
25
29
 
26
30
  # We just proxy the arguments onto a real RubyGems command
@@ -21,7 +21,7 @@ module Vagrant
21
21
  return if !argv
22
22
 
23
23
  @logger.debug("Halt command: #{argv.inspect} #{options.inspect}")
24
- with_target_vms(argv[0]) do |vm|
24
+ with_target_vms(argv) do |vm|
25
25
  if vm.created?
26
26
  @logger.info("Halting #{vm.name}")
27
27
  vm.halt(:force => options[:force])
@@ -30,7 +30,10 @@ module Vagrant
30
30
  vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
31
31
  end
32
32
  end
33
- end
33
+
34
+ # Success, exit status 0
35
+ 0
36
+ end
34
37
  end
35
38
  end
36
39
  end
@@ -31,7 +31,10 @@ module Vagrant
31
31
 
32
32
  @env.ui.info(I18n.t("vagrant.commands.init.success"),
33
33
  :prefix => false)
34
- end
34
+
35
+ # Success, exit status 0
36
+ 0
37
+ end
35
38
  end
36
39
  end
37
40
  end
@@ -39,7 +39,10 @@ module Vagrant
39
39
  else
40
40
  package_target(argv[0], options)
41
41
  end
42
- end
42
+
43
+ # Success, exit status 0
44
+ 0
45
+ end
43
46
 
44
47
  protected
45
48
 
@@ -16,7 +16,8 @@ module Vagrant
16
16
 
17
17
  # Go over each VM and provision!
18
18
  @logger.debug("'provision' each target VM...")
19
- with_target_vms(argv[0]) do |vm|
19
+ with_target_vms(argv) do |vm|
20
+
20
21
  if vm.created?
21
22
  if vm.state == :running
22
23
  @logger.info("Provisioning: #{vm.name}")
@@ -30,7 +31,10 @@ module Vagrant
30
31
  vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
31
32
  end
32
33
  end
33
- end
34
+
35
+ # Success, exit status 0
36
+ 0
37
+ end
34
38
  end
35
39
  end
36
40
  end
@@ -9,7 +9,8 @@ module Vagrant
9
9
 
10
10
  def execute
11
11
  options = {}
12
- opts = OptionParser.new do |opts|
12
+
13
+ opts = OptionParser.new do |opts|
13
14
  opts.banner = "Usage: vagrant reload [vm-name]"
14
15
  opts.separator ""
15
16
  build_start_options(opts, options)
@@ -20,7 +21,7 @@ module Vagrant
20
21
  return if !argv
21
22
 
22
23
  @logger.debug("'reload' each target VM...")
23
- with_target_vms(argv[0]) do |vm|
24
+ with_target_vms(argv) do |vm|
24
25
  if vm.created?
25
26
  @logger.info("Reloading: #{vm.name}")
26
27
  vm.reload(options)
@@ -29,7 +30,10 @@ module Vagrant
29
30
  vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
30
31
  end
31
32
  end
32
- end
33
+
34
+ # Success, exit status 0
35
+ 0
36
+ end
33
37
  end
34
38
  end
35
39
  end
@@ -15,7 +15,7 @@ module Vagrant
15
15
  return if !argv
16
16
 
17
17
  @logger.debug("'resume' each target VM...")
18
- with_target_vms(argv[0]) do |vm|
18
+ with_target_vms(argv) do |vm|
19
19
  if vm.created?
20
20
  @logger.info("Resume: #{vm.name}")
21
21
  vm.resume
@@ -24,7 +24,10 @@ module Vagrant
24
24
  vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
25
25
  end
26
26
  end
27
- end
27
+
28
+ # Success, exit status 0
29
+ 0
30
+ end
28
31
  end
29
32
  end
30
33
  end
@@ -36,7 +36,7 @@ module Vagrant
36
36
  argv = [] if argv == ssh_args
37
37
 
38
38
  # Execute the actual SSH
39
- with_target_vms(argv[0], :single_target => true) do |vm|
39
+ with_target_vms(argv, :single_target => true) do |vm|
40
40
  # Basic checks that are required for proper SSH
41
41
  raise Errors::VMNotCreatedError if !vm.created?
42
42
  raise Errors::VMInaccessible if !vm.state == :inaccessible
@@ -53,7 +53,10 @@ module Vagrant
53
53
  ssh_connect(vm, opts)
54
54
  end
55
55
  end
56
- end
56
+
57
+ # Success, exit status 0
58
+ 0
59
+ end
57
60
 
58
61
  protected
59
62
 
@@ -1,8 +1,12 @@
1
1
  require 'optparse'
2
2
 
3
+ require "vagrant/util/safe_puts"
4
+
3
5
  module Vagrant
4
6
  module Command
5
7
  class SSHConfig < Base
8
+ include Util::SafePuts
9
+
6
10
  def execute
7
11
  options = {}
8
12
 
@@ -19,7 +23,7 @@ module Vagrant
19
23
  argv = parse_options(opts)
20
24
  return if !argv
21
25
 
22
- with_target_vms(argv[0], :single_target => true) do |vm|
26
+ with_target_vms(argv, :single_target => true) do |vm|
23
27
  raise Errors::VMNotCreatedError if !vm.created?
24
28
  raise Errors::VMInaccessible if !vm.state == :inaccessible
25
29
 
@@ -36,9 +40,12 @@ module Vagrant
36
40
 
37
41
  # Render the template and output directly to STDOUT
38
42
  template = "commands/ssh_config/config"
39
- $stdout.puts(Util::TemplateRenderer.render(template, variables))
43
+ safe_puts(Util::TemplateRenderer.render(template, variables))
40
44
  end
41
- end
45
+
46
+ # Success, exit status 0
47
+ 0
48
+ end
42
49
  end
43
50
  end
44
51
  end
@@ -16,7 +16,7 @@ module Vagrant
16
16
 
17
17
  state = nil
18
18
  results = []
19
- with_target_vms(argv[0]) do |vm|
19
+ with_target_vms(argv) do |vm|
20
20
  state = vm.state.to_s if !state
21
21
  results << "#{vm.name.to_s.ljust(25)}#{vm.state.to_s.gsub("_", " ")}"
22
22
  end
@@ -27,7 +27,10 @@ module Vagrant
27
27
  :states => results.join("\n"),
28
28
  :message => I18n.t("vagrant.commands.status.#{state}")),
29
29
  :prefix => false)
30
- end
30
+
31
+ # Success, exit status 0
32
+ 0
33
+ end
31
34
  end
32
35
  end
33
36
  end
@@ -15,7 +15,7 @@ module Vagrant
15
15
  return if !argv
16
16
 
17
17
  @logger.debug("'suspend' each target VM...")
18
- with_target_vms(argv[0]) do |vm|
18
+ with_target_vms(argv) do |vm|
19
19
  if vm.created?
20
20
  @logger.info("Suspending: #{vm.name}")
21
21
  vm.suspend
@@ -24,7 +24,10 @@ module Vagrant
24
24
  vm.ui.info I18n.t("vagrant.commands.common.vm_not_created")
25
25
  end
26
26
  end
27
- end
27
+
28
+ # Success, exit status 0
29
+ 0
30
+ end
28
31
  end
29
32
  end
30
33
  end
@@ -21,7 +21,7 @@ module Vagrant
21
21
 
22
22
  # Go over each VM and bring it up
23
23
  @logger.debug("'Up' each target VM...")
24
- with_target_vms(argv[0]) do |vm|
24
+ with_target_vms(argv) do |vm|
25
25
  if vm.created?
26
26
  @logger.info("Booting: #{vm.name}")
27
27
  vm.ui.info I18n.t("vagrant.commands.up.vm_created")
@@ -31,7 +31,10 @@ module Vagrant
31
31
  vm.up(options)
32
32
  end
33
33
  end
34
- end
34
+
35
+ # Success, exit status 0
36
+ 0
37
+ end
35
38
  end
36
39
  end
37
40
  end
@@ -129,10 +129,24 @@ module Vagrant
129
129
  @vm.ssh.check_key_permissions(ssh_info[:private_key_path])
130
130
 
131
131
  # Connect to SSH, giving it a few tries
132
- @logger.info("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}")
133
- exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect]
134
- connection = retryable(:tries => @vm.config.ssh.max_tries, :on => exceptions) do
135
- Net::SSH.start(ssh_info[:host], ssh_info[:username], opts)
132
+ connection = nil
133
+ begin
134
+ @logger.info("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}")
135
+ exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect]
136
+ connection = retryable(:tries => @vm.config.ssh.max_tries, :on => exceptions) do
137
+ Net::SSH.start(ssh_info[:host], ssh_info[:username], opts)
138
+ end
139
+ rescue Net::SSH::AuthenticationFailed
140
+ # This happens if authentication failed. We wrap the error in our
141
+ # own exception.
142
+ raise Errors::SSHAuthenticationFailed
143
+ rescue Errno::ECONNREFUSED
144
+ # This is raised if we failed to connect the max amount of times
145
+ raise Errors::SSHConnectionRefused
146
+ rescue NotImplementedError
147
+ # This is raised if a private key type that Net-SSH doesn't support
148
+ # is used. Show a nicer error.
149
+ raise Errors::SSHKeyTypeNotSupported
136
150
  end
137
151
 
138
152
  @connection = connection
@@ -145,14 +159,7 @@ module Vagrant
145
159
  # Yield the connection that is ready to be used and
146
160
  # return the value of the block
147
161
  return yield connection if block_given?
148
- rescue Net::SSH::AuthenticationFailed
149
- # This happens if authentication failed. We wrap the error in our
150
- # own exception.
151
- raise Errors::SSHAuthenticationFailed
152
- rescue Errno::ECONNREFUSED
153
- # This is raised if we failed to connect the max amount of times
154
- raise Errors::SSHConnectionRefused
155
- end
162
+ end
156
163
 
157
164
  # Executes the command on an SSH connection within a login shell.
158
165
  def shell_execute(connection, command, sudo=false)
@@ -18,7 +18,7 @@ module Vagrant
18
18
  errors.add(I18n.t("vagrant.config.common.error_empty", :field => field)) if !instance_variable_get("@#{field}".to_sym)
19
19
  end
20
20
 
21
- if private_key_path && !File.file?(private_key_path)
21
+ if private_key_path && !File.file?(File.expand_path(private_key_path, env.root_path))
22
22
  errors.add(I18n.t("vagrant.config.ssh.private_key_missing", :path => private_key_path))
23
23
  end
24
24
  end
@@ -318,6 +318,11 @@ module Vagrant
318
318
  error_key(:ssh_key_bad_permissions)
319
319
  end
320
320
 
321
+ class SSHKeyTypeNotSupported < VagrantError
322
+ status_code(76)
323
+ error_key(:ssh_key_type_not_supported)
324
+ end
325
+
321
326
  class SSHPortNotDetected < VagrantError
322
327
  status_code(50)
323
328
  error_key(:ssh_port_not_detected)
@@ -388,6 +393,11 @@ module Vagrant
388
393
  error_key(:failed_to_boot, "vagrant.actions.vm.boot")
389
394
  end
390
395
 
396
+ class VMFailedToRun < VagrantError
397
+ status_code(77)
398
+ error_key(:failed_to_run, "vagrant.actions.vm.boot")
399
+ end
400
+
391
401
  class VMGuestError < VagrantError
392
402
  status_code(39)
393
403
  error_namespace("vagrant.errors.guest")
@@ -33,6 +33,14 @@ module Vagrant
33
33
  vm.channel.sudo("/etc/init.d/net.eth#{network[:interface]} start")
34
34
  end
35
35
  end
36
+
37
+ def change_host_name(name)
38
+ if !vm.channel.test("sudo hostname --fqdn | grep '#{name}'")
39
+ vm.channel.sudo("echo 'hostname=#{name.split('.')[0]}' > /etc/conf.d/hostname")
40
+ vm.channel.sudo("sed -i 's@^\\(127[.]0[.]1[.]1[[:space:]]\\+\\)@\\1#{name} #{name.split('.')[0]} @' /etc/hosts")
41
+ vm.channel.sudo("hostname #{name.split('.')[0]}")
42
+ end
43
+ end
36
44
  end
37
45
  end
38
46
  end
@@ -15,6 +15,10 @@ module Vagrant
15
15
  attr_accessor :data_bags_path
16
16
  attr_accessor :recipe_url
17
17
  attr_accessor :nfs
18
+ attr_accessor :encrypted_data_bag_secret_key_path
19
+ attr_accessor :encrypted_data_bag_secret
20
+
21
+ def encrypted_data_bag_secret; @encrypted_data_bag_secret || "/tmp/encrypted_data_bag_secret"; end
18
22
 
19
23
  def initialize
20
24
  super
@@ -86,6 +90,7 @@ module Vagrant
86
90
 
87
91
  verify_binary(chef_binary_path("chef-solo"))
88
92
  chown_provisioning_folder
93
+ upload_encrypted_data_bag_secret if config.encrypted_data_bag_secret_key_path
89
94
  setup_json
90
95
  setup_solo_config
91
96
  run_chef_solo
@@ -155,6 +160,12 @@ module Vagrant
155
160
  end
156
161
  end
157
162
 
163
+ def upload_encrypted_data_bag_secret
164
+ env[:ui].info I18n.t("vagrant.provisioners.chef.upload_encrypted_data_bag_secret_key")
165
+ env[:vm].channel.upload(encrypted_data_bag_secret_key_path,
166
+ config.encrypted_data_bag_secret)
167
+ end
168
+
158
169
  def setup_solo_config
159
170
  cookbooks_path = guest_paths(@cookbook_folders)
160
171
  roles_path = guest_paths(@role_folders).first
@@ -167,6 +178,7 @@ module Vagrant
167
178
  :recipe_url => config.recipe_url,
168
179
  :roles_path => roles_path,
169
180
  :data_bags_path => data_bags_path,
181
+ :encrypted_data_bag_secret => config.encrypted_data_bag_secret,
170
182
  })
171
183
  end
172
184
 
@@ -207,6 +219,10 @@ module Vagrant
207
219
  end
208
220
  end
209
221
 
222
+ def encrypted_data_bag_secret_key_path
223
+ File.expand_path(config.encrypted_data_bag_secret_key_path, env[:root_path])
224
+ end
225
+
210
226
  protected
211
227
 
212
228
  # Extracts only the remote paths from a list of folders
data/lib/vagrant/ssh.rb CHANGED
@@ -76,8 +76,11 @@ module Vagrant
76
76
 
77
77
  # Command line options
78
78
  command_options = ["-p", options[:port].to_s, "-o", "UserKnownHostsFile=/dev/null",
79
- "-o", "StrictHostKeyChecking=no", "-o", "IdentitiesOnly=yes",
80
- "-o", "LogLevel=ERROR"]
79
+ "-o", "StrictHostKeyChecking=no", "-o", "LogLevel=ERROR"]
80
+
81
+ # Solaris/OpenSolaris/Illumos uses SunSSH which doesn't support the IdentitiesOnly option
82
+ command_options += ["-o", "IdentitiesOnly=yes"] unless Util::Platform.solaris?
83
+
81
84
  command_options += ["-i", options[:private_key_path]] if !plain_mode
82
85
  command_options += ["-o", "ForwardAgent=yes"] if ssh_info[:forward_agent]
83
86
 
data/lib/vagrant/ui.rb CHANGED
@@ -1,5 +1,7 @@
1
1
  require "log4r"
2
2
 
3
+ require "vagrant/util/safe_puts"
4
+
3
5
  module Vagrant
4
6
  module UI
5
7
  # Vagrant UIs handle communication with the outside world (typically
@@ -43,6 +45,8 @@ module Vagrant
43
45
  # This is a UI implementation that outputs the text as is. It
44
46
  # doesn't add any color.
45
47
  class Basic < Interface
48
+ include Util::SafePuts
49
+
46
50
  # Use some light meta-programming to create the various methods to
47
51
  # output text to the UI. These all delegate the real functionality
48
52
  # to `say`.
@@ -112,7 +116,8 @@ module Vagrant
112
116
  channel = type == :error || opts[:channel] == :error ? $stderr : $stdout
113
117
 
114
118
  # Output!
115
- channel.send(printer, format_message(type, message, opts))
119
+ safe_puts(format_message(type, message, opts),
120
+ :io => channel, :printer => printer)
116
121
  end
117
122
 
118
123
  # This is called by `say` to format the message for output.
@@ -0,0 +1,38 @@
1
+ require "socket"
2
+ require "timeout"
3
+
4
+ module Vagrant
5
+ module Util
6
+ # Contains the method {#is_ruby_open?} to check if a port is open
7
+ # (listening) or closed (not in use). This method isn't completely
8
+ # fool-proof, but it works enough of the time to be useful.
9
+ module IsPortOpen
10
+ # Checks if a port is open (listening) on a given host and port.
11
+ #
12
+ # @param [String] host Hostname or IP address.
13
+ # @param [Integer] port Port to check.
14
+ # @return [Boolean] `true` if the port is open (listening), `false`
15
+ # otherwise.
16
+ def is_port_open?(host, port)
17
+ # We wrap this in a timeout because once in awhile the TCPSocket
18
+ # _will_ hang, but this signals that the port is closed.
19
+ Timeout.timeout(1) do
20
+ # Attempt to make a connection
21
+ s = TCPSocket.new(host, port)
22
+
23
+ # A connection was made! Properly clean up the socket, not caring
24
+ # at all if any exception is raised, because we already know the
25
+ # result.
26
+ s.close rescue nil
27
+
28
+ # The port is open if we reached this point, since we were able
29
+ # to connect.
30
+ return true
31
+ end
32
+ rescue Timeout::Error, Errno::ECONNREFUSED, Errno::EHOSTUNREACH
33
+ # Any of the above exceptions signal that the port is closed.
34
+ return false
35
+ end
36
+ end
37
+ end
38
+ end
@@ -14,7 +14,7 @@ module Vagrant
14
14
  platform.include?("darwin9")
15
15
  end
16
16
 
17
- [:darwin, :bsd, :freebsd, :linux].each do |type|
17
+ [:darwin, :bsd, :freebsd, :linux, :solaris].each do |type|
18
18
  define_method("#{type}?") do
19
19
  platform.include?(type.to_s)
20
20
  end
@@ -0,0 +1,31 @@
1
+ module Vagrant
2
+ module Util
3
+ # This module provides a `safe_puts` method which outputs to
4
+ # the given IO object, and rescues any broken pipe errors and
5
+ # ignores them. This is useful in cases where you're outputting
6
+ # to stdout, for example, and the stdout is closed, but you want to
7
+ # keep running.
8
+ module SafePuts
9
+ # Uses `puts` on the given IO object and safely ignores any
10
+ # Errno::EPIPE.
11
+ #
12
+ # @param [String] message Message to output.
13
+ # @param [Hash] opts Options hash.
14
+ def safe_puts(message=nil, opts=nil)
15
+ message ||= ""
16
+ opts = {
17
+ :io => $stdout,
18
+ :printer => :puts
19
+ }.merge(opts || {})
20
+
21
+ begin
22
+ opts[:io].send(opts[:printer], message)
23
+ rescue Errno::EPIPE
24
+ # This is what makes this a `safe` puts.
25
+ return
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
@@ -2,5 +2,5 @@ module Vagrant
2
2
  # This will always be up to date with the current version of Vagrant,
3
3
  # since it is used to generate the gemspec and is also the source of
4
4
  # the version for `vagrant -v`
5
- VERSION = "1.0.1"
5
+ VERSION = "1.0.2"
6
6
  end
data/lib/vagrant/vm.rb CHANGED
@@ -49,11 +49,11 @@ module Vagrant
49
49
  @logger.info("Loading guest: #{guest}")
50
50
 
51
51
  if guest.is_a?(Class)
52
- raise Errors::VMGuestError, :_key => :invalid_class, :system => guest.to_s if !(guest <= Guest::Base)
52
+ raise Errors::VMGuestError, :_key => :invalid_class, :guest => guest.to_s if !(guest <= Guest::Base)
53
53
  @guest = guest.new(self)
54
54
  elsif guest.is_a?(Symbol)
55
55
  guest_klass = Vagrant.guests.get(guest)
56
- raise Errors::VMGuestError, :_key => :unknown_type, :system => guest.to_s if !guest_klass
56
+ raise Errors::VMGuestError, :_key => :unknown_type, :guest => guest.to_s if !guest_klass
57
57
  @guest = guest_klass.new(self)
58
58
  else
59
59
  raise Errors::VMGuestError, :unspecified
@@ -59,11 +59,14 @@ Vagrant::Config.run do |config|
59
59
  # puppet.manifest_file = "<%= box_name %>.pp"
60
60
  # end
61
61
 
62
- # Enable provisioning with chef solo, specifying a cookbooks path (relative
63
- # to this Vagrantfile), and adding some recipes and/or roles.
62
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
63
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
64
+ # some recipes and/or roles.
64
65
  #
65
66
  # config.vm.provision :chef_solo do |chef|
66
- # chef.cookbooks_path = "cookbooks"
67
+ # chef.cookbooks_path = "../my-recipes/cookbooks"
68
+ # chef.roles_path = "../my-recipes/roles"
69
+ # chef.data_bags_path = "../my-recipes/data_bags"
67
70
  # chef.add_recipe "mysql"
68
71
  # chef.add_role "web"
69
72
  #
@@ -124,6 +124,10 @@ en:
124
124
  permissions on the following file to 0600 and then try running this command again:
125
125
 
126
126
  %{key_path}
127
+ ssh_key_type_not_supported: |-
128
+ The private key you're attempting to use with this Vagrant box uses
129
+ an unsupported encryption type. The SSH library Vagrant uses does not support
130
+ this key type. Please use `ssh-rsa` or `ssh-dss` instead.
127
131
  ssh_port_not_detected: |-
128
132
  Vagrant couldn't determine the SSH port for your VM! Vagrant attempts to
129
133
  automatically find a forwarded port that matches your `config.ssh.guest_port`
@@ -327,6 +331,11 @@ en:
327
331
  failed_to_boot: |-
328
332
  Failed to connect to VM via SSH. Please verify the VM successfully booted
329
333
  by looking at the VirtualBox GUI.
334
+ failed_to_run: |-
335
+ The VM failed to remain in the "running" state while attempting to boot.
336
+ This is normally caused by a misconfiguration or host system incompatibilities.
337
+ Please open the VirtualBox GUI and attempt to boot the virtual machine
338
+ manually to get a more informative error message.
330
339
  bridged_networking:
331
340
  available: |-
332
341
  Available bridged network interfaces:
@@ -6,6 +6,8 @@ cookbook_path <%= cookbooks_path.inspect %>
6
6
  role_path <%= roles_path.inspect %>
7
7
  log_level <%= log_level.inspect %>
8
8
 
9
+ encrypted_data_bag_secret "<%= encrypted_data_bag_secret %>"
10
+
9
11
  <% if data_bags_path -%>
10
12
  data_bag_path <%= data_bags_path.inspect %>
11
13
  <% end %>
@@ -33,7 +33,7 @@ describe Vagrant::Command::Base do
33
33
  ["-h", "--help"].each do |help_string|
34
34
  it "returns nil and prints the help if '#{help_string}' is given" do
35
35
  instance = klass.new([help_string], nil)
36
- instance.should_receive(:puts)
36
+ instance.should_receive(:safe_puts)
37
37
  instance.parse_options(OptionParser.new).should be_nil
38
38
  end
39
39
  end
@@ -0,0 +1,53 @@
1
+ require File.expand_path("../../../base", __FILE__)
2
+
3
+ require "socket"
4
+
5
+ require "vagrant/util/is_port_open"
6
+
7
+ describe Vagrant::Util::IsPortOpen do
8
+ let(:klass) do
9
+ Class.new do
10
+ extend Vagrant::Util::IsPortOpen
11
+ end
12
+ end
13
+
14
+ let(:open_port) { 52811 }
15
+ let(:closed_port) { 52811 }
16
+
17
+ it "should report open ports" do
18
+ # Start a thread which listens on a port
19
+ thr = Thread.new do
20
+ server = TCPServer.new(open_port)
21
+ Thread.current[:running] = true
22
+
23
+ # Wait until we're told to die
24
+ Thread.current[:die] = false
25
+ while !Thread.current[:die]
26
+ Thread.pass
27
+ end
28
+
29
+ # Die!
30
+ server.close
31
+ end
32
+
33
+ # Wait until the server is running
34
+ while !thr[:running]
35
+ Thread.pass
36
+ end
37
+
38
+ # Verify that we report the port is open
39
+ klass.is_port_open?("localhost", open_port).should be
40
+
41
+ # Kill the thread
42
+ thr[:die] = true
43
+ thr.join
44
+ end
45
+
46
+ it "should report closed ports" do
47
+ # This CAN fail, since port 52811 might actually be in use, but I'm
48
+ # not sure what to do except choose some random port and hope for the
49
+ # best, really.
50
+ klass.is_port_open?("localhost", closed_port).should_not be
51
+ end
52
+ end
53
+
@@ -87,7 +87,8 @@ class ChefSoloProvisionerTest < Test::Unit::TestCase
87
87
  :cookbooks_path => @action.guest_paths(@action.cookbook_folders),
88
88
  :recipe_url => @config.recipe_url,
89
89
  :roles_path => @action.guest_paths(@action.role_folders).first,
90
- :data_bags_path => @action.guest_paths(@action.data_bags_folders).first
90
+ :data_bags_path => @action.guest_paths(@action.data_bags_folders).first,
91
+ :encrypted_data_bag_secret => @config.encrypted_data_bag_secret
91
92
  })
92
93
 
93
94
  @action.setup_solo_config
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vagrantup
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mitchell Hashimoto
@@ -289,6 +289,7 @@ files:
289
289
  - lib/vagrant/action/vm/provisioner_cleanup.rb
290
290
  - lib/vagrant/action/vm/prune_nfs_exports.rb
291
291
  - lib/vagrant/action/vm/resume.rb
292
+ - lib/vagrant/action/vm/sane_defaults.rb
292
293
  - lib/vagrant/action/vm/setup_package_files.rb
293
294
  - lib/vagrant/action/vm/share_folders.rb
294
295
  - lib/vagrant/action/vm/suspend.rb
@@ -390,11 +391,13 @@ files:
390
391
  - lib/vagrant/util/file_checksum.rb
391
392
  - lib/vagrant/util/file_mode.rb
392
393
  - lib/vagrant/util/hash_with_indifferent_access.rb
394
+ - lib/vagrant/util/is_port_open.rb
393
395
  - lib/vagrant/util/line_ending_helpers.rb
394
396
  - lib/vagrant/util/network_ip.rb
395
397
  - lib/vagrant/util/platform.rb
396
398
  - lib/vagrant/util/retryable.rb
397
399
  - lib/vagrant/util/safe_exec.rb
400
+ - lib/vagrant/util/safe_puts.rb
398
401
  - lib/vagrant/util/stacked_proc_runner.rb
399
402
  - lib/vagrant/util/subprocess.rb
400
403
  - lib/vagrant/util/template_renderer.rb
@@ -553,6 +556,7 @@ files:
553
556
  - test/unit/vagrant/util/ansi_escape_code_remover_test.rb
554
557
  - test/unit/vagrant/util/file_checksum_test.rb
555
558
  - test/unit/vagrant/util/hash_with_indifferent_access_test.rb
559
+ - test/unit/vagrant/util/is_port_open_test.rb
556
560
  - test/unit/vagrant/util/line_endings_helper_test.rb
557
561
  - test/unit/vagrant/util/network_ip_test.rb
558
562
  - test/unit/vagrant/util/retryable_test.rb