Vagrant::SSH no longer handles actual communication with the VM
This commit is contained in:
parent
8577935121
commit
19c1340e40
|
@ -23,7 +23,7 @@ module Vagrant
|
||||||
raise Errors::VMNotCreatedError if !vm.created?
|
raise Errors::VMNotCreatedError if !vm.created?
|
||||||
raise Errors::VMInaccessible if !vm.state == :inaccessible
|
raise Errors::VMInaccessible if !vm.state == :inaccessible
|
||||||
|
|
||||||
ssh_info = vm.ssh_info
|
ssh_info = vm.ssh.info
|
||||||
variables = {
|
variables = {
|
||||||
:host_key => options[:host] || vm.name || "vagrant",
|
:host_key => options[:host] || vm.name || "vagrant",
|
||||||
:ssh_host => ssh_info[:host],
|
:ssh_host => ssh_info[:host],
|
||||||
|
|
|
@ -57,6 +57,12 @@ module Vagrant
|
||||||
scp = Net::SCP.new(connection)
|
scp = Net::SCP.new(connection)
|
||||||
scp.upload!(from, to)
|
scp.upload!(from, to)
|
||||||
end
|
end
|
||||||
|
rescue Net::SCP::Error => e
|
||||||
|
# If we get the exit code of 127, then this means SCP is unavailable.
|
||||||
|
raise Errors::SCPUnavailable if e.message =~ /\(127\)/
|
||||||
|
|
||||||
|
# Otherwise, just raise the error up
|
||||||
|
raise
|
||||||
end
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
@ -77,7 +83,7 @@ module Vagrant
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check that the private key permissions are valid
|
# Check that the private key permissions are valid
|
||||||
check_key_permissions(ssh_info[:private_key_path])
|
@vm.ssh.check_key_permissions(ssh_info[:private_key_path])
|
||||||
|
|
||||||
# Connect to SSH, giving it a few tries
|
# Connect to SSH, giving it a few tries
|
||||||
@logger.debug("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}")
|
@logger.debug("Connecting to SSH: #{ssh_info[:host]}:#{ssh_info[:port]}")
|
||||||
|
@ -149,29 +155,6 @@ module Vagrant
|
||||||
# Return the final exit status
|
# Return the final exit status
|
||||||
return exit_status
|
return exit_status
|
||||||
end
|
end
|
||||||
|
|
||||||
# Checks the file permissions for a private key, resetting them
|
|
||||||
# if needed.
|
|
||||||
def check_key_permissions(key_path)
|
|
||||||
# Windows systems don't have this issue
|
|
||||||
return if Util::Platform.windows?
|
|
||||||
|
|
||||||
@logger.debug("Checking key permissions: #{key_path}")
|
|
||||||
stat = File.stat(key_path)
|
|
||||||
|
|
||||||
if stat.owned? && Util::FileMode.from_octal(stat.mode) != "600"
|
|
||||||
@logger.info("Attempting to correct key permissions to 0600")
|
|
||||||
File.chmod(0600, key_path)
|
|
||||||
|
|
||||||
if Util::FileMode.from_octal(stat.mode) != "600"
|
|
||||||
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue Errno::EPERM
|
|
||||||
# This shouldn't happen since we verified we own the file, but
|
|
||||||
# it is possible in theory, so we raise an error.
|
|
||||||
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
require 'log4r'
|
require 'log4r'
|
||||||
require 'net/ssh'
|
|
||||||
require 'net/scp'
|
require 'vagrant/util/file_mode'
|
||||||
|
require 'vagrant/util/platform'
|
||||||
|
require 'vagrant/util/safe_exec'
|
||||||
|
|
||||||
module Vagrant
|
module Vagrant
|
||||||
# Manages SSH access to a specific environment. Allows an environment to
|
# Manages SSH access to a specific environment. Allows an environment to
|
||||||
# replace the process with SSH itself, run a specific set of commands,
|
# replace the process with SSH itself, run a specific set of commands,
|
||||||
# upload files, or even check if a host is up.
|
# upload files, or even check if a host is up.
|
||||||
class SSH
|
class SSH
|
||||||
# Autoload this guy because he is really only used in one location
|
|
||||||
# and not for every Vagrant command.
|
|
||||||
autoload :Session, 'vagrant/ssh/session'
|
|
||||||
|
|
||||||
include Util::Retryable
|
|
||||||
include Util::SafeExec
|
include Util::SafeExec
|
||||||
|
|
||||||
def initialize(vm)
|
def initialize(vm)
|
||||||
|
@ -19,6 +16,36 @@ module Vagrant
|
||||||
@logger = Log4r::Logger.new("vagrant::ssh")
|
@logger = Log4r::Logger.new("vagrant::ssh")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Returns a hash of information necessary for accessing this
|
||||||
|
# virtual machine via SSH.
|
||||||
|
#
|
||||||
|
# @return [Hash]
|
||||||
|
def info
|
||||||
|
results = {
|
||||||
|
:host => @vm.config.ssh.host,
|
||||||
|
:port => @vm.config.ssh.port || @vm.driver.ssh_port(@vm.config.ssh.guest_port),
|
||||||
|
:username => @vm.config.ssh.username,
|
||||||
|
:forward_agent => @vm.config.ssh.forward_agent,
|
||||||
|
:forward_x11 => @vm.config.ssh.forward_x11
|
||||||
|
}
|
||||||
|
|
||||||
|
# This can happen if no port is set and for some reason Vagrant
|
||||||
|
# can't detect an SSH port.
|
||||||
|
raise Errors::SSHPortNotDetected if !results[:port]
|
||||||
|
|
||||||
|
# Determine the private key path, which is either set by the
|
||||||
|
# configuration or uses just the built-in insecure key.
|
||||||
|
pk_path = @vm.config.ssh.private_key_path || @vm.env.default_private_key_path
|
||||||
|
results[:private_key_path] = File.expand_path(pk_path, @vm.env.root_path)
|
||||||
|
|
||||||
|
# We need to check and fix the private key permissions
|
||||||
|
# to make sure that SSH gets a key with 0600 perms.
|
||||||
|
check_key_permissions(results[:private_key_path])
|
||||||
|
|
||||||
|
# Return the results
|
||||||
|
return results
|
||||||
|
end
|
||||||
|
|
||||||
# Connects to the environment's virtual machine, replacing the ruby
|
# Connects to the environment's virtual machine, replacing the ruby
|
||||||
# process with an SSH process. This method optionally takes a hash
|
# process with an SSH process. This method optionally takes a hash
|
||||||
# of options which override the configuration values.
|
# of options which override the configuration values.
|
||||||
|
@ -26,9 +53,12 @@ module Vagrant
|
||||||
# to skip filling in some default values, such as private_key_path and
|
# to skip filling in some default values, such as private_key_path and
|
||||||
# username.
|
# username.
|
||||||
def connect(opts={})
|
def connect(opts={})
|
||||||
|
# Get the SSH information and cache it here
|
||||||
|
ssh_info = info
|
||||||
|
|
||||||
if Util::Platform.windows?
|
if Util::Platform.windows?
|
||||||
raise Errors::SSHUnavailableWindows, :key_path => private_key_path,
|
raise Errors::SSHUnavailableWindows, :key_path => ssh_info[:private_key_path],
|
||||||
:ssh_port => port(opts)
|
:ssh_port => ssh_info[:port]
|
||||||
end
|
end
|
||||||
|
|
||||||
raise Errors::SSHUnavailable if !Kernel.system("which ssh > /dev/null 2>&1")
|
raise Errors::SSHUnavailable if !Kernel.system("which ssh > /dev/null 2>&1")
|
||||||
|
@ -38,22 +68,19 @@ module Vagrant
|
||||||
plain_mode = opts[:plain_mode]
|
plain_mode = opts[:plain_mode]
|
||||||
|
|
||||||
options = {}
|
options = {}
|
||||||
options[:port] = port(opts)
|
options[:host] = ssh_info[:host]
|
||||||
options[:private_key_path] = private_key_path
|
options[:port] = ssh_info[:port]
|
||||||
[:host, :username].each do |param|
|
options[:username] = ssh_info[:username]
|
||||||
options[param] = opts[param] || @vm.config.ssh.send(param)
|
options[:private_key_path] = ssh_info[:private_key_path]
|
||||||
end
|
|
||||||
|
|
||||||
check_key_permissions(options[:private_key_path])
|
|
||||||
|
|
||||||
# Command line options
|
# Command line options
|
||||||
command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null",
|
command_options = ["-p #{options[:port]}", "-o UserKnownHostsFile=/dev/null",
|
||||||
"-o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes",
|
"-o StrictHostKeyChecking=no", "-o IdentitiesOnly=yes",
|
||||||
"-o LogLevel=ERROR"]
|
"-o LogLevel=ERROR"]
|
||||||
command_options << "-i #{options[:private_key_path]}" if !plain_mode
|
command_options << "-i #{options[:private_key_path]}" if !plain_mode
|
||||||
command_options << "-o ForwardAgent=yes" if @vm.config.ssh.forward_agent
|
command_options << "-o ForwardAgent=yes" if ssh_info[:forward_agent]
|
||||||
|
|
||||||
if @vm.config.ssh.forward_x11
|
if ssh_info[:forward_x11]
|
||||||
# Both are required so that no warnings are shown regarding X11
|
# Both are required so that no warnings are shown regarding X11
|
||||||
command_options << "-o ForwardX11=yes"
|
command_options << "-o ForwardX11=yes"
|
||||||
command_options << "-o ForwardX11Trusted=yes"
|
command_options << "-o ForwardX11Trusted=yes"
|
||||||
|
@ -66,141 +93,27 @@ module Vagrant
|
||||||
safe_exec(command)
|
safe_exec(command)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Opens an SSH connection to this environment's virtual machine and yields
|
# Checks the file permissions for a private key, resetting them
|
||||||
# a Net::SSH object which can be used to execute remote commands.
|
# if needed.
|
||||||
def execute(opts={})
|
|
||||||
# Check the key permissions to avoid SSH hangs
|
|
||||||
check_key_permissions(private_key_path)
|
|
||||||
|
|
||||||
# Merge in any additional options
|
|
||||||
opts = opts.dup
|
|
||||||
opts[:forward_agent] = true if @vm.config.ssh.forward_agent
|
|
||||||
opts[:port] ||= port
|
|
||||||
|
|
||||||
@logger.info("Connecting to SSH: #{@vm.config.ssh.host} #{opts[:port]}")
|
|
||||||
|
|
||||||
# The exceptions which are acceptable to retry on during
|
|
||||||
# attempts to connect to SSH
|
|
||||||
exceptions = [Errno::ECONNREFUSED, Net::SSH::Disconnect]
|
|
||||||
|
|
||||||
# Connect to SSH and gather the session
|
|
||||||
session = retryable(:tries => @vm.config.ssh.max_tries, :on => exceptions) do
|
|
||||||
connection = Net::SSH.start(@vm.config.ssh.host,
|
|
||||||
@vm.config.ssh.username,
|
|
||||||
opts.merge( :keys => [private_key_path],
|
|
||||||
:keys_only => true,
|
|
||||||
:user_known_hosts_file => [],
|
|
||||||
:paranoid => false,
|
|
||||||
:config => false))
|
|
||||||
|
|
||||||
sleep 4 # Hacky but helps with issue #391, #455, etc.
|
|
||||||
|
|
||||||
SSH::Session.new(connection, @vm)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Yield our session for executing
|
|
||||||
return yield session if block_given?
|
|
||||||
rescue Errno::ECONNREFUSED
|
|
||||||
raise Errors::SSHConnectionRefused
|
|
||||||
end
|
|
||||||
|
|
||||||
# Uploads a file from `from` to `to`. `from` is expected to be a filename
|
|
||||||
# or StringIO, and `to` is expected to be a path. This method simply forwards
|
|
||||||
# the arguments to `Net::SCP#upload!` so view that for more information.
|
|
||||||
def upload!(from, to)
|
|
||||||
retryable(:tries => 5, :on => IOError) do
|
|
||||||
execute do |ssh|
|
|
||||||
scp = Net::SCP.new(ssh.session)
|
|
||||||
scp.upload!(from, to)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
rescue Net::SCP::Error => e
|
|
||||||
# If we get the exit code of 127, then this means SCP is unavailable.
|
|
||||||
raise Errors::SCPUnavailable if e.message =~ /\(127\)/
|
|
||||||
|
|
||||||
# Otherwise, just raise the error up
|
|
||||||
raise
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks if this environment's machine is up (i.e. responding to SSH).
|
|
||||||
#
|
|
||||||
# @return [Boolean]
|
|
||||||
def up?
|
|
||||||
@logger.debug("Checking whether SSH is up")
|
|
||||||
|
|
||||||
# We have to determine the port outside of the block since it uses
|
|
||||||
# API calls which can only be used from the main thread in JRuby on
|
|
||||||
# Windows
|
|
||||||
ssh_port = port
|
|
||||||
|
|
||||||
require 'timeout'
|
|
||||||
Timeout.timeout(@vm.config.ssh.timeout) do
|
|
||||||
execute(:timeout => @vm.config.ssh.timeout, :port => ssh_port) { |ssh| }
|
|
||||||
end
|
|
||||||
|
|
||||||
@logger.info("SSH is up!")
|
|
||||||
true
|
|
||||||
rescue Net::SSH::AuthenticationFailed
|
|
||||||
raise Errors::SSHAuthenticationFailed
|
|
||||||
rescue Timeout::Error, Errno::ECONNREFUSED, Net::SSH::Disconnect,
|
|
||||||
Errors::SSHConnectionRefused => e
|
|
||||||
@logger.info("SSH not up: #{e.inspect}")
|
|
||||||
return false
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks the file permissions for the private key, resetting them
|
|
||||||
# if needed, or on failure erroring.
|
|
||||||
def check_key_permissions(key_path)
|
def check_key_permissions(key_path)
|
||||||
# Windows systems don't have this issue
|
# Windows systems don't have this issue
|
||||||
return if Util::Platform.windows?
|
return if Util::Platform.windows?
|
||||||
|
|
||||||
@logger.info("Checking key permissions: #{key_path}")
|
@logger.debug("Checking key permissions: #{key_path}")
|
||||||
|
|
||||||
stat = File.stat(key_path)
|
stat = File.stat(key_path)
|
||||||
|
|
||||||
if stat.owned? && file_perms(key_path) != "600"
|
if stat.owned? && Util::FileMode.from_octal(stat.mode) != "600"
|
||||||
@logger.info("Attempting to correct key permissions to 0600")
|
@logger.info("Attempting to correct key permissions to 0600")
|
||||||
|
|
||||||
File.chmod(0600, key_path)
|
File.chmod(0600, key_path)
|
||||||
raise Errors::SSHKeyBadPermissions, :key_path => key_path if file_perms(key_path) != "600"
|
|
||||||
end
|
if Util::FileMode.from_octal(stat.mode) != "600"
|
||||||
rescue Errno::EPERM
|
|
||||||
# This shouldn't happen since we verify we own the file, but just
|
|
||||||
# in case.
|
|
||||||
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns the file permissions of a given file. This is fairly unix specific
|
|
||||||
# and probably doesn't belong in this class. Will be refactored out later.
|
|
||||||
def file_perms(path)
|
|
||||||
perms = sprintf("%o", File.stat(path).mode)
|
|
||||||
perms.reverse[0..2].reverse
|
|
||||||
end
|
end
|
||||||
|
rescue Errno::EPERM
|
||||||
# Returns the port which is either given in the options hash or taken from
|
# This shouldn't happen since we verified we own the file, but
|
||||||
# the config by finding it in the forwarded ports hash based on the
|
# it is possible in theory, so we raise an error.
|
||||||
# `config.ssh.forwarded_port_key`.
|
raise Errors::SSHKeyBadPermissions, :key_path => key_path
|
||||||
def port(opts={})
|
|
||||||
# Check if port was specified in options hash
|
|
||||||
return opts[:port] if opts[:port]
|
|
||||||
|
|
||||||
# Check if a port was specified in the config
|
|
||||||
return @vm.config.ssh.port if @vm.config.ssh.port
|
|
||||||
|
|
||||||
# Check if we have an SSH forwarded port
|
|
||||||
@vm.driver.read_forwarded_ports.each do |_, name, hostport, guestport|
|
|
||||||
if guestport == @vm.config.ssh.guest_port
|
|
||||||
return hostport
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# This should NEVER happen.
|
|
||||||
raise Errors::SSHPortNotDetected
|
|
||||||
end
|
|
||||||
|
|
||||||
def private_key_path
|
|
||||||
path = @vm.config.ssh.private_key_path || @vm.env.default_private_key_path
|
|
||||||
File.expand_path(path, @vm.env.root_path)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,135 +0,0 @@
|
||||||
module Vagrant
|
|
||||||
class SSH
|
|
||||||
# A helper class which wraps around `Net::SSH::Connection::Session`
|
|
||||||
# in order to provide basic command error checking while still
|
|
||||||
# providing access to the actual session object.
|
|
||||||
class Session
|
|
||||||
include Util::Retryable
|
|
||||||
|
|
||||||
attr_reader :session
|
|
||||||
|
|
||||||
def initialize(session, vm)
|
|
||||||
@session = session
|
|
||||||
@vm = vm
|
|
||||||
end
|
|
||||||
|
|
||||||
# Executes a given command and simply returns true/false if the
|
|
||||||
# command succeeded or not.
|
|
||||||
def test?(command)
|
|
||||||
exec!(command) do |ch, type, data|
|
|
||||||
return true if type == :exit_status && data == 0
|
|
||||||
end
|
|
||||||
|
|
||||||
false
|
|
||||||
end
|
|
||||||
|
|
||||||
# Executes a given command on the SSH session using `sudo` and
|
|
||||||
# blocks until the command completes. This takes the same parameters
|
|
||||||
# as {#exec!}. The only difference is that the command can be an
|
|
||||||
# array of commands, which will be placed into the same script.
|
|
||||||
#
|
|
||||||
# This is different than just calling {#exec!} with `sudo`, since
|
|
||||||
# this command is tailor-made to be compliant with older versions
|
|
||||||
# of `sudo`.
|
|
||||||
def sudo!(commands, options=nil, &block)
|
|
||||||
channel = session.open_channel do |ch|
|
|
||||||
ch.exec("sudo -H #{@vm.config.ssh.shell} -l") do |ch2, success|
|
|
||||||
# Set the terminal
|
|
||||||
ch2.send_data "export TERM=vt100\n"
|
|
||||||
|
|
||||||
# Output each command as if they were entered on the command line
|
|
||||||
[commands].flatten.each do |command|
|
|
||||||
ch2.send_data "#{command}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remember to exit or we'll hang!
|
|
||||||
ch2.send_data "exit\n"
|
|
||||||
|
|
||||||
# Setup the callbacks with our options so we get all the
|
|
||||||
# stdout/stderr and error checking goodies
|
|
||||||
setup_channel_callbacks(ch2, commands, options, block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
channel.wait
|
|
||||||
channel[:result]
|
|
||||||
end
|
|
||||||
|
|
||||||
# Executes a given command on the SSH session and blocks until
|
|
||||||
# the command completes. This is an almost line for line copy of
|
|
||||||
# the actual `exec!` implementation, except that this
|
|
||||||
# implementation also reports `:exit_status` to the block if given.
|
|
||||||
def exec!(commands, options=nil, &block)
|
|
||||||
retryable(:tries => @vm.config.ssh.max_tries, :on => [IOError, Net::SSH::Disconnect], :sleep => 1.0) do
|
|
||||||
metach = session.open_channel do |ch|
|
|
||||||
ch.exec("#{@vm.config.ssh.shell} -l") do |ch2, success|
|
|
||||||
# Set the terminal
|
|
||||||
ch2.send_data "export TERM=vt100\n"
|
|
||||||
|
|
||||||
# Output the commands as if they were entered on the command line
|
|
||||||
[commands].flatten.each do |command|
|
|
||||||
ch2.send_data "#{command}\n"
|
|
||||||
end
|
|
||||||
|
|
||||||
# Remember to exit
|
|
||||||
ch2.send_data "exit\n"
|
|
||||||
|
|
||||||
# Setup the callbacks
|
|
||||||
setup_channel_callbacks(ch2, commands, options, block)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
metach.wait
|
|
||||||
metach[:result]
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sets up the channel callbacks to properly check exit statuses and
|
|
||||||
# callback on stdout/stderr.
|
|
||||||
def setup_channel_callbacks(channel, command, options, block)
|
|
||||||
options = { :error_check => true }.merge(options || {})
|
|
||||||
|
|
||||||
block ||= Proc.new do |ch, type, data|
|
|
||||||
check_exit_status(data, command, options, ch[:result]) if type == :exit_status && options[:error_check]
|
|
||||||
|
|
||||||
ch[:result] ||= ""
|
|
||||||
ch[:result] << data if [:stdout, :stderr].include?(type)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Output stdout data to the block
|
|
||||||
channel.on_data do |ch2, data|
|
|
||||||
# This clears the screen, we want to filter it out.
|
|
||||||
data.gsub!("\e[H", "")
|
|
||||||
|
|
||||||
block.call(ch2, :stdout, data)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Output stderr data to the block
|
|
||||||
channel.on_extended_data do |ch2, type, data|
|
|
||||||
block.call(ch2, :stderr, data)
|
|
||||||
end
|
|
||||||
|
|
||||||
# Output exit status information to the block
|
|
||||||
channel.on_request("exit-status") do |ch2, data|
|
|
||||||
block.call(ch2, :exit_status, data.read_long)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Checks for an erroroneous exit status and raises an exception
|
|
||||||
# if so.
|
|
||||||
def check_exit_status(exit_status, commands, options=nil, output=nil)
|
|
||||||
if exit_status != 0
|
|
||||||
output ||= '[no output]'
|
|
||||||
options = {
|
|
||||||
:_error_class => Errors::VagrantError,
|
|
||||||
:_key => :ssh_bad_exit_status,
|
|
||||||
:command => [commands].flatten.join("\n"),
|
|
||||||
:output => output
|
|
||||||
}.merge(options || {})
|
|
||||||
|
|
||||||
raise options[:_error_class], options
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -74,34 +74,6 @@ module Vagrant
|
||||||
@ssh ||= SSH.new(self)
|
@ssh ||= SSH.new(self)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Returns a hash of information necessary for accessing this
|
|
||||||
# virtual machine via SSH.
|
|
||||||
#
|
|
||||||
# @return [Hash]
|
|
||||||
def ssh_info
|
|
||||||
results = {
|
|
||||||
:host => config.ssh.host,
|
|
||||||
:port => config.ssh.port || driver.ssh_port(config.ssh.guest_port),
|
|
||||||
:username => config.ssh.username,
|
|
||||||
:forward_agent => config.ssh.forward_agent,
|
|
||||||
:forward_x11 => config.ssh.forward_x11
|
|
||||||
}
|
|
||||||
|
|
||||||
# This can happen if no port is set and for some reason Vagrant
|
|
||||||
# can't detect an SSH port.
|
|
||||||
raise Errors::SSHPortNotDetected if !results[:port]
|
|
||||||
|
|
||||||
# Determine the private key path, which is either set by the
|
|
||||||
# configuration or uses just the built-in insecure key.
|
|
||||||
pk_path = config.ssh.private_key_path || env.default_private_key_path
|
|
||||||
results[:private_key_path] = File.expand_path(pk_path, env.root_path)
|
|
||||||
|
|
||||||
# TODO: Check and fix key permissions
|
|
||||||
|
|
||||||
# Return the results
|
|
||||||
return results
|
|
||||||
end
|
|
||||||
|
|
||||||
# Returns the state of the VM as a symbol.
|
# Returns the state of the VM as a symbol.
|
||||||
#
|
#
|
||||||
# @return [Symbol]
|
# @return [Symbol]
|
||||||
|
|
Loading…
Reference in New Issue