vagrantup 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +1 -1
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/bin/vagrant +1 -1
- data/bin/vagrant-box +1 -2
- data/bin/vagrant-down +1 -2
- data/bin/vagrant-halt +1 -2
- data/bin/vagrant-init +1 -2
- data/bin/vagrant-package +1 -2
- data/bin/vagrant-reload +1 -2
- data/bin/vagrant-resume +1 -2
- data/bin/vagrant-ssh +1 -2
- data/bin/vagrant-status +29 -0
- data/bin/vagrant-suspend +1 -2
- data/bin/vagrant-up +1 -2
- data/config/default.rb +5 -9
- data/keys/README.md +10 -0
- data/keys/vagrant +27 -0
- data/keys/vagrant.pub +1 -0
- data/lib/vagrant.rb +10 -5
- data/lib/vagrant/actions/base.rb +14 -0
- data/lib/vagrant/actions/box/download.rb +3 -0
- data/lib/vagrant/actions/collection.rb +36 -0
- data/lib/vagrant/actions/runner.rb +4 -10
- data/lib/vagrant/actions/vm/boot.rb +4 -5
- data/lib/vagrant/actions/vm/customize.rb +17 -0
- data/lib/vagrant/actions/vm/destroy.rb +11 -2
- data/lib/vagrant/actions/vm/forward_ports.rb +24 -0
- data/lib/vagrant/actions/vm/import.rb +1 -0
- data/lib/vagrant/actions/vm/provision.rb +30 -52
- data/lib/vagrant/actions/vm/reload.rb +2 -2
- data/lib/vagrant/actions/vm/shared_folders.rb +37 -25
- data/lib/vagrant/actions/vm/up.rb +8 -4
- data/lib/vagrant/active_list.rb +66 -0
- data/lib/vagrant/commands.rb +44 -0
- data/lib/vagrant/config.rb +64 -47
- data/lib/vagrant/downloaders/base.rb +3 -0
- data/lib/vagrant/downloaders/file.rb +11 -11
- data/lib/vagrant/env.rb +48 -12
- data/lib/vagrant/provisioners/base.rb +22 -0
- data/lib/vagrant/provisioners/chef.rb +102 -0
- data/lib/vagrant/provisioners/chef_server.rb +96 -0
- data/lib/vagrant/provisioners/chef_solo.rb +67 -0
- data/lib/vagrant/ssh.rb +25 -6
- data/lib/vagrant/stacked_proc_runner.rb +33 -0
- data/lib/vagrant/vm.rb +8 -0
- data/test/test_helper.rb +22 -6
- data/test/vagrant/actions/box/download_test.rb +11 -0
- data/test/vagrant/actions/collection_test.rb +110 -0
- data/test/vagrant/actions/runner_test.rb +11 -7
- data/test/vagrant/actions/vm/boot_test.rb +7 -7
- data/test/vagrant/actions/vm/customize_test.rb +16 -0
- data/test/vagrant/actions/vm/destroy_test.rb +19 -6
- data/test/vagrant/actions/vm/forward_ports_test.rb +52 -0
- data/test/vagrant/actions/vm/import_test.rb +10 -3
- data/test/vagrant/actions/vm/provision_test.rb +75 -70
- data/test/vagrant/actions/vm/reload_test.rb +3 -2
- data/test/vagrant/actions/vm/shared_folders_test.rb +62 -9
- data/test/vagrant/actions/vm/up_test.rb +4 -4
- data/test/vagrant/active_list_test.rb +169 -0
- data/test/vagrant/config_test.rb +145 -29
- data/test/vagrant/downloaders/base_test.rb +7 -0
- data/test/vagrant/downloaders/file_test.rb +12 -18
- data/test/vagrant/env_test.rb +96 -23
- data/test/vagrant/provisioners/base_test.rb +27 -0
- data/test/vagrant/provisioners/chef_server_test.rb +175 -0
- data/test/vagrant/provisioners/chef_solo_test.rb +142 -0
- data/test/vagrant/provisioners/chef_test.rb +116 -0
- data/test/vagrant/ssh_test.rb +29 -8
- data/test/vagrant/stacked_proc_runner_test.rb +43 -0
- data/test/vagrant/vm_test.rb +23 -0
- data/vagrant.gemspec +34 -7
- metadata +33 -5
- data/script/vagrant-ssh-expect.sh +0 -22
@@ -5,6 +5,9 @@ module Vagrant
|
|
5
5
|
class Base
|
6
6
|
include Vagrant::Util
|
7
7
|
|
8
|
+
# Called prior to execution so any error checks can be done
|
9
|
+
def prepare(source_url); end
|
10
|
+
|
8
11
|
# Downloads the source file to the destination file. It is up to
|
9
12
|
# implementors of this class to handle the logic.
|
10
13
|
def download!(source_url, destination_file); end
|
@@ -3,19 +3,19 @@ module Vagrant
|
|
3
3
|
# "Downloads" a file to a temporary file. Basically, this downloader
|
4
4
|
# simply does a file copy.
|
5
5
|
class File < Base
|
6
|
-
|
6
|
+
def prepare(source_url)
|
7
|
+
if !::File.file?(source_url)
|
8
|
+
raise Actions::ActionException.new(<<-msg)
|
9
|
+
The given box does not exist on the file system:
|
7
10
|
|
8
|
-
|
9
|
-
|
10
|
-
# and copy it into the other. In the future, we should do
|
11
|
-
# a system-level file copy (FileUtils.cp).
|
12
|
-
open(source_url) do |f|
|
13
|
-
loop do
|
14
|
-
break if f.eof?
|
15
|
-
destination_file.write(f.read(BUFFERSIZE))
|
16
|
-
end
|
11
|
+
#{source_url}
|
12
|
+
msg
|
17
13
|
end
|
18
14
|
end
|
15
|
+
|
16
|
+
def download!(source_url, destination_file)
|
17
|
+
FileUtils.cp(source_url, destination_file.path)
|
18
|
+
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
21
|
+
end
|
data/lib/vagrant/env.rb
CHANGED
@@ -24,21 +24,52 @@ module Vagrant
|
|
24
24
|
load_config!
|
25
25
|
load_home_directory!
|
26
26
|
load_box!
|
27
|
+
load_config!
|
28
|
+
check_virtualbox!
|
27
29
|
load_vm!
|
28
30
|
end
|
29
31
|
|
32
|
+
def check_virtualbox!
|
33
|
+
version = VirtualBox::Command.version
|
34
|
+
if version.nil?
|
35
|
+
error_and_exit(<<-msg)
|
36
|
+
Vagrant could not detect VirtualBox! Make sure VirtualBox is properly installed.
|
37
|
+
If VirtualBox is installed, you may need to tweak the paths to the `VBoxManage`
|
38
|
+
application which ships with VirtualBox and the path to the global XML configuration
|
39
|
+
which VirtualBox typically stores somewhere in your home directory.
|
40
|
+
|
41
|
+
The following shows how to configure VirtualBox. This can be done in the
|
42
|
+
Vagrantfile. Note that 90% of the time, you shouldn't need to do this if VirtualBox
|
43
|
+
is installed. Please use the various Vagrant support lines to request more information
|
44
|
+
if you can't get this working.
|
45
|
+
|
46
|
+
VirtualBox::Command.vboxmanage = "/path/to/my/VBoxManage"
|
47
|
+
VirtualBox::Global.vboxconfig = "~/path/to/VirtualBox.xml"
|
48
|
+
msg
|
49
|
+
elsif version.to_f < 3.1
|
50
|
+
error_and_exit(<<-msg)
|
51
|
+
Vagrant has detected that you have VirtualBox version #{version} installed!
|
52
|
+
Vagrant requires that you use at least VirtualBox version 3.1. Please install
|
53
|
+
a more recent version of VirtualBox to continue.
|
54
|
+
msg
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
30
58
|
def load_config!
|
31
59
|
# Prepare load paths for config files
|
32
60
|
load_paths = [File.join(PROJECT_ROOT, "config", "default.rb")]
|
33
61
|
load_paths << File.join(box.directory, ROOTFILE_NAME) if box
|
62
|
+
load_paths << File.join(home_path, ROOTFILE_NAME) if Vagrant.config.vagrant.home
|
34
63
|
load_paths << File.join(root_path, ROOTFILE_NAME) if root_path
|
35
64
|
|
36
65
|
# Then clear out the old data
|
37
66
|
Config.reset!
|
38
67
|
|
39
68
|
load_paths.each do |path|
|
40
|
-
|
41
|
-
|
69
|
+
if File.exist?(path)
|
70
|
+
logger.info "Loading config from #{path}..."
|
71
|
+
load path
|
72
|
+
end
|
42
73
|
end
|
43
74
|
|
44
75
|
# Execute the configurations
|
@@ -63,11 +94,6 @@ module Vagrant
|
|
63
94
|
return unless root_path
|
64
95
|
|
65
96
|
@@box = Box.find(Vagrant.config.vm.box) if Vagrant.config.vm.box
|
66
|
-
|
67
|
-
if @@box
|
68
|
-
logger.info("Reloading configuration to account for loaded box...")
|
69
|
-
load_config!
|
70
|
-
end
|
71
97
|
end
|
72
98
|
|
73
99
|
def load_vm!
|
@@ -81,18 +107,28 @@ module Vagrant
|
|
81
107
|
end
|
82
108
|
|
83
109
|
def persist_vm(vm)
|
110
|
+
# Save to the dotfile for this project
|
84
111
|
File.open(dotfile_path, 'w+') do |f|
|
85
112
|
f.write(vm.uuid)
|
86
113
|
end
|
114
|
+
|
115
|
+
# Also add to the global store
|
116
|
+
ActiveList.add(vm)
|
117
|
+
end
|
118
|
+
|
119
|
+
def depersist_vm(vm)
|
120
|
+
# Delete the dotfile if it exists
|
121
|
+
File.delete(dotfile_path) if File.exist?(dotfile_path)
|
122
|
+
|
123
|
+
# Remove from the global store
|
124
|
+
ActiveList.remove(vm)
|
87
125
|
end
|
88
126
|
|
89
127
|
def load_root_path!(path=nil)
|
90
|
-
path
|
128
|
+
path = Pathname.new(File.expand_path(path || Dir.pwd))
|
91
129
|
|
92
|
-
# Stop if we're at the root.
|
93
|
-
|
94
|
-
# researched.
|
95
|
-
return false if path.to_s == '/' || path.to_s =~ /^[A-Z]:\.$/
|
130
|
+
# Stop if we're at the root.
|
131
|
+
return false if path.root?
|
96
132
|
|
97
133
|
file = "#{path}/#{ROOTFILE_NAME}"
|
98
134
|
if File.exist?(file)
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Provisioners
|
3
|
+
# The base class for a "provisioner." A provisioner is responsible for
|
4
|
+
# provisioning a Vagrant system. This has been abstracted out to provide
|
5
|
+
# support for multiple solutions such as Chef Solo, Chef Client, and
|
6
|
+
# Puppet.
|
7
|
+
class Base
|
8
|
+
include Vagrant::Util
|
9
|
+
|
10
|
+
# This is the method called to "prepare" the provisioner. This is called
|
11
|
+
# before any actions are run by the action runner (see {Vagrant::Actions::Runner}).
|
12
|
+
# This can be used to setup shared folders, forward ports, etc. Whatever is
|
13
|
+
# necessary on a "meta" level.
|
14
|
+
def prepare; end
|
15
|
+
|
16
|
+
# This is the method called to provision the system. This method
|
17
|
+
# is expected to do whatever necessary to provision the system (create files,
|
18
|
+
# SSH, etc.)
|
19
|
+
def provision!; end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Provisioners
|
3
|
+
# This class is a base class where the common functinality shared between
|
4
|
+
# chef-solo and chef-client provisioning are stored. This is **not an actual
|
5
|
+
# provisioner**. Instead, {ChefSolo} or {ChefServer} should be used.
|
6
|
+
class Chef < Base
|
7
|
+
# This is the configuration which is available through `config.chef`
|
8
|
+
class ChefConfig < Vagrant::Config::Base
|
9
|
+
# Chef server specific config
|
10
|
+
attr_accessor :chef_server_url
|
11
|
+
attr_accessor :validation_key_path
|
12
|
+
attr_accessor :validation_client_name
|
13
|
+
attr_accessor :client_key_path
|
14
|
+
|
15
|
+
# Chef solo specific config
|
16
|
+
attr_accessor :cookbooks_path
|
17
|
+
|
18
|
+
# Shared config
|
19
|
+
attr_accessor :provisioning_path
|
20
|
+
attr_accessor :json
|
21
|
+
|
22
|
+
def initialize
|
23
|
+
@validation_client_name = "chef-validator"
|
24
|
+
@client_key_path = "/etc/chef/client.pem"
|
25
|
+
|
26
|
+
@cookbooks_path = "cookbooks"
|
27
|
+
@provisioning_path = "/tmp/vagrant-chef"
|
28
|
+
@json = {
|
29
|
+
:instance_role => "vagrant",
|
30
|
+
:run_list => ["recipe[vagrant_main]"]
|
31
|
+
}
|
32
|
+
end
|
33
|
+
|
34
|
+
# Returns the run list for the provisioning
|
35
|
+
def run_list
|
36
|
+
json[:run_list]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Sets the run list to the specified value
|
40
|
+
def run_list=(value)
|
41
|
+
json[:run_list] = value
|
42
|
+
end
|
43
|
+
|
44
|
+
# Adds a recipe to the run list
|
45
|
+
def add_recipe(name)
|
46
|
+
name = "recipe[#{name}]" unless name =~ /^recipe\[(.+?)\]$/
|
47
|
+
run_list << name
|
48
|
+
end
|
49
|
+
|
50
|
+
# Adds a role to the run list
|
51
|
+
def add_role(name)
|
52
|
+
name = "role[#{name}]" unless name =~ /^role\[(.+?)\]$/
|
53
|
+
run_list << name
|
54
|
+
end
|
55
|
+
|
56
|
+
def to_json
|
57
|
+
# Overridden so that the 'json' key could be removed, since its just
|
58
|
+
# merged into the config anyways
|
59
|
+
data = instance_variables_hash
|
60
|
+
data.delete(:json)
|
61
|
+
data.to_json
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
# Tell the Vagrant configure class about our custom configuration
|
66
|
+
Config.configures :chef, ChefConfig
|
67
|
+
|
68
|
+
def prepare
|
69
|
+
raise Actions::ActionException.new("Vagrant::Provisioners::Chef is not a valid provisioner! Use ChefSolo or ChefServer instead.")
|
70
|
+
end
|
71
|
+
|
72
|
+
def chown_provisioning_folder
|
73
|
+
logger.info "Setting permissions on chef provisioning folder..."
|
74
|
+
SSH.execute do |ssh|
|
75
|
+
ssh.exec!("sudo mkdir -p #{Vagrant.config.chef.provisioning_path}")
|
76
|
+
ssh.exec!("sudo chown #{Vagrant.config.ssh.username} #{Vagrant.config.chef.provisioning_path}")
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
def setup_json
|
81
|
+
logger.info "Generating chef JSON and uploading..."
|
82
|
+
|
83
|
+
# Set up initial configuration
|
84
|
+
data = {
|
85
|
+
:config => Vagrant.config,
|
86
|
+
:directory => Vagrant.config.vm.project_directory,
|
87
|
+
}
|
88
|
+
|
89
|
+
# And wrap it under the "vagrant" namespace
|
90
|
+
data = { :vagrant => data }
|
91
|
+
|
92
|
+
# Merge with the "extra data" which isn't put under the
|
93
|
+
# vagrant namespace by default
|
94
|
+
data.merge!(Vagrant.config.chef.json)
|
95
|
+
|
96
|
+
json = data.to_json
|
97
|
+
|
98
|
+
SSH.upload!(StringIO.new(json), File.join(Vagrant.config.chef.provisioning_path, "dna.json"))
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Provisioners
|
3
|
+
# This class implements provisioning via chef-client, allowing provisioning
|
4
|
+
# with a chef server.
|
5
|
+
class ChefServer < Chef
|
6
|
+
def prepare
|
7
|
+
if Vagrant.config.chef.validation_key_path.nil?
|
8
|
+
raise Actions::ActionException.new(<<-msg)
|
9
|
+
Chef server provisioning requires that the `config.chef.validation_key_path` configuration
|
10
|
+
be set to a path on your local machine of the validation key used to register the
|
11
|
+
VM with the chef server.
|
12
|
+
msg
|
13
|
+
elsif !File.file?(Vagrant.config.chef.validation_key_path)
|
14
|
+
raise Actions::ActionException.new(<<-msg)
|
15
|
+
The validation key set for `config.chef.validation_key_path` does not exist! This
|
16
|
+
file needs to exist so it can be uploaded to the virtual machine. It is
|
17
|
+
currently set to "#{Vagrant.config.chef.validation_key_path}"
|
18
|
+
msg
|
19
|
+
end
|
20
|
+
|
21
|
+
if Vagrant.config.chef.chef_server_url.nil?
|
22
|
+
raise Actions::ActionException.new(<<-msg)
|
23
|
+
Chef server provisioning requires that the `config.chef.chef_server_url` be set to the
|
24
|
+
URL of your chef server. Examples include "http://12.12.12.12:4000" and
|
25
|
+
"http://myserver.com:4000" (the port of course can be different, but 4000 is the default)
|
26
|
+
msg
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def provision!
|
31
|
+
chown_provisioning_folder
|
32
|
+
create_client_key_folder
|
33
|
+
upload_validation_key
|
34
|
+
setup_json
|
35
|
+
setup_config
|
36
|
+
run_chef_client
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_client_key_folder
|
40
|
+
logger.info "Creating folder to hold client key..."
|
41
|
+
path = Pathname.new(Vagrant.config.chef.client_key_path)
|
42
|
+
|
43
|
+
SSH.execute do |ssh|
|
44
|
+
ssh.exec!("sudo mkdir -p #{path.dirname}")
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
def upload_validation_key
|
49
|
+
logger.info "Uploading chef client validation key..."
|
50
|
+
SSH.upload!(validation_key_path, guest_validation_key_path)
|
51
|
+
end
|
52
|
+
|
53
|
+
def setup_config
|
54
|
+
solo_file = <<-solo
|
55
|
+
log_level :info
|
56
|
+
log_location STDOUT
|
57
|
+
ssl_verify_mode :verify_none
|
58
|
+
chef_server_url "#{Vagrant.config.chef.chef_server_url}"
|
59
|
+
|
60
|
+
validation_client_name "#{Vagrant.config.chef.validation_client_name}"
|
61
|
+
validation_key "#{guest_validation_key_path}"
|
62
|
+
client_key "#{Vagrant.config.chef.client_key_path}"
|
63
|
+
|
64
|
+
file_store_path "/srv/chef/file_store"
|
65
|
+
file_cache_path "/srv/chef/cache"
|
66
|
+
|
67
|
+
pid_file "/var/run/chef/chef-client.pid"
|
68
|
+
|
69
|
+
Mixlib::Log::Formatter.show_time = true
|
70
|
+
solo
|
71
|
+
|
72
|
+
logger.info "Uploading chef-client configuration script..."
|
73
|
+
SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "client.rb"))
|
74
|
+
end
|
75
|
+
|
76
|
+
def run_chef_client
|
77
|
+
logger.info "Running chef-client..."
|
78
|
+
SSH.execute do |ssh|
|
79
|
+
ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-client -c client.rb -j dna.json") do |channel, data, stream|
|
80
|
+
# TODO: Very verbose. It would be easier to save the data and only show it during
|
81
|
+
# an error, or when verbosity level is set high
|
82
|
+
logger.info("#{stream}: #{data}")
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def validation_key_path
|
88
|
+
File.expand_path(Vagrant.config.chef.validation_key_path, Env.root_path)
|
89
|
+
end
|
90
|
+
|
91
|
+
def guest_validation_key_path
|
92
|
+
File.join(Vagrant.config.chef.provisioning_path, "validation.pem")
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
module Vagrant
|
2
|
+
module Provisioners
|
3
|
+
# This class implements provisioning via chef-solo.
|
4
|
+
class ChefSolo < Chef
|
5
|
+
def prepare
|
6
|
+
share_cookbook_folders
|
7
|
+
end
|
8
|
+
|
9
|
+
def provision!
|
10
|
+
chown_provisioning_folder
|
11
|
+
setup_json
|
12
|
+
setup_solo_config
|
13
|
+
run_chef_solo
|
14
|
+
end
|
15
|
+
|
16
|
+
def share_cookbook_folders
|
17
|
+
host_cookbook_paths.each_with_index do |cookbook, i|
|
18
|
+
Vagrant.config.vm.share_folder("vagrant-chef-solo-#{i}", cookbook_path(i), cookbook)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def setup_solo_config
|
23
|
+
solo_file = <<-solo
|
24
|
+
file_cache_path "#{Vagrant.config.chef.provisioning_path}"
|
25
|
+
cookbook_path #{cookbooks_path}
|
26
|
+
solo
|
27
|
+
|
28
|
+
logger.info "Uploading chef-solo configuration script..."
|
29
|
+
SSH.upload!(StringIO.new(solo_file), File.join(Vagrant.config.chef.provisioning_path, "solo.rb"))
|
30
|
+
end
|
31
|
+
|
32
|
+
def run_chef_solo
|
33
|
+
logger.info "Running chef-solo..."
|
34
|
+
SSH.execute do |ssh|
|
35
|
+
ssh.exec!("cd #{Vagrant.config.chef.provisioning_path} && sudo chef-solo -c solo.rb -j dna.json") do |channel, data, stream|
|
36
|
+
# TODO: Very verbose. It would be easier to save the data and only show it during
|
37
|
+
# an error, or when verbosity level is set high
|
38
|
+
logger.info("#{stream}: #{data}")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def host_cookbook_paths
|
44
|
+
cookbooks = Vagrant.config.chef.cookbooks_path
|
45
|
+
cookbooks = [cookbooks] unless cookbooks.is_a?(Array)
|
46
|
+
cookbooks.collect! { |cookbook| File.expand_path(cookbook, Env.root_path) }
|
47
|
+
return cookbooks
|
48
|
+
end
|
49
|
+
|
50
|
+
def cookbook_path(i)
|
51
|
+
File.join(Vagrant.config.chef.provisioning_path, "cookbooks-#{i}")
|
52
|
+
end
|
53
|
+
|
54
|
+
def cookbooks_path
|
55
|
+
result = []
|
56
|
+
host_cookbook_paths.each_with_index do |host_path, i|
|
57
|
+
result << cookbook_path(i)
|
58
|
+
end
|
59
|
+
|
60
|
+
# We're lucky that ruby's string and array syntax for strings is the
|
61
|
+
# same as JSON, so we can just convert to JSON here and use that
|
62
|
+
result = result.to_s if result.length == 1
|
63
|
+
result.to_json
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/vagrant/ssh.rb
CHANGED
@@ -1,19 +1,22 @@
|
|
1
1
|
module Vagrant
|
2
2
|
class SSH
|
3
|
-
|
3
|
+
include Vagrant::Util
|
4
4
|
|
5
5
|
class << self
|
6
6
|
def connect(opts={})
|
7
7
|
options = {}
|
8
|
-
[:host, :
|
8
|
+
[:host, :username, :private_key_path].each do |param|
|
9
9
|
options[param] = opts[param] || Vagrant.config.ssh.send(param)
|
10
10
|
end
|
11
11
|
|
12
|
-
Kernel.exec "#{
|
12
|
+
Kernel.exec "ssh -p #{port(opts)} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i #{options[:private_key_path]} #{options[:username]}@#{options[:host]}".strip
|
13
13
|
end
|
14
14
|
|
15
|
-
def execute
|
16
|
-
Net::SSH.start(Vagrant.config.ssh.host,
|
15
|
+
def execute(opts={})
|
16
|
+
Net::SSH.start(Vagrant.config.ssh.host,
|
17
|
+
Vagrant.config[:ssh][:username],
|
18
|
+
opts.merge( :port => port,
|
19
|
+
:keys => [Vagrant.config.ssh.private_key_path])) do |ssh|
|
17
20
|
yield ssh
|
18
21
|
end
|
19
22
|
end
|
@@ -29,7 +32,7 @@ module Vagrant
|
|
29
32
|
check_thread = Thread.new do
|
30
33
|
begin
|
31
34
|
Thread.current[:result] = false
|
32
|
-
|
35
|
+
execute(:timeout => Vagrant.config.ssh.timeout) do |ssh|
|
33
36
|
Thread.current[:result] = true
|
34
37
|
end
|
35
38
|
rescue Errno::ECONNREFUSED, Net::SSH::Disconnect
|
@@ -39,6 +42,22 @@ module Vagrant
|
|
39
42
|
|
40
43
|
check_thread.join(Vagrant.config.ssh.timeout)
|
41
44
|
return check_thread[:result]
|
45
|
+
rescue Net::SSH::AuthenticationFailed
|
46
|
+
error_and_exit(<<-msg)
|
47
|
+
SSH authentication failed! While this could be due to a variety of reasons,
|
48
|
+
the two most common are: private key path is incorrect or you're using a box
|
49
|
+
which was built for Vagrant 0.1.x.
|
50
|
+
|
51
|
+
Vagrant 0.2.x dropped support for password-based authentication. If you're
|
52
|
+
tring to `vagrant up` a box which does not support Vagrant's private/public
|
53
|
+
keypair, then this error will be raised. To resolve this, read the guide
|
54
|
+
on converting base boxes from password-based to keypairs here:
|
55
|
+
|
56
|
+
http://vagrantup.com/docs/converting_password_to_key_ssh.html
|
57
|
+
|
58
|
+
If the box was built for 0.2.x and contains a custom public key, perhaps
|
59
|
+
the path to the private key is incorrect. Check your `config.ssh.private_key_path`.
|
60
|
+
msg
|
42
61
|
end
|
43
62
|
|
44
63
|
def port(opts={})
|