Merge pull request #8915 from briancain/6656/master/format-windows-paths-for-ssh-config
Format windows paths for ssh_config command
This commit is contained in:
commit
dbc23fccab
|
@ -4,6 +4,7 @@ require "tmpdir"
|
||||||
|
|
||||||
require "vagrant/util/subprocess"
|
require "vagrant/util/subprocess"
|
||||||
require "vagrant/util/powershell"
|
require "vagrant/util/powershell"
|
||||||
|
require "vagrant/util/which"
|
||||||
|
|
||||||
module Vagrant
|
module Vagrant
|
||||||
module Util
|
module Util
|
||||||
|
@ -19,6 +20,15 @@ module Vagrant
|
||||||
@_cygwin
|
@_cygwin
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def msys?
|
||||||
|
if !defined?(@_msys)
|
||||||
|
@_msys = ENV["VAGRANT_DETECTED_OS"].to_s.downcase.include?("msys") ||
|
||||||
|
platform.include?("msys") ||
|
||||||
|
ENV["OSTYPE"].to_s.downcase.include?("msys")
|
||||||
|
end
|
||||||
|
@_msys
|
||||||
|
end
|
||||||
|
|
||||||
def wsl?
|
def wsl?
|
||||||
if !defined?(@_wsl)
|
if !defined?(@_wsl)
|
||||||
@_wsl = false
|
@_wsl = false
|
||||||
|
@ -93,15 +103,20 @@ module Vagrant
|
||||||
# @param [String] path
|
# @param [String] path
|
||||||
# @return [String]
|
# @return [String]
|
||||||
def cygwin_path(path)
|
def cygwin_path(path)
|
||||||
if cygwin?
|
|
||||||
begin
|
begin
|
||||||
# First try the real cygpath
|
# We have to revert to the old env
|
||||||
process = Subprocess.execute("cygpath", "-u", "-a", path.to_s)
|
# path here, otherwise it looks like
|
||||||
|
# msys2 ends up using the wrong cygpath
|
||||||
|
# binary and ends up with a `/cygdrive`
|
||||||
|
# when it doesn't exist in msys2
|
||||||
|
original_path_env = ENV['PATH']
|
||||||
|
ENV['PATH'] = ENV['VAGRANT_OLD_ENV_PATH']
|
||||||
|
cygpath = Vagrant::Util::Which.which("cygpath")
|
||||||
|
cygpath.gsub!("/", '\\')
|
||||||
|
process = Subprocess.execute(
|
||||||
|
cygpath, "-u", "-a", path.to_s)
|
||||||
return process.stdout.chomp
|
return process.stdout.chomp
|
||||||
rescue Errors::CommandUnavailableWindows
|
rescue Errors::CommandUnavailableWindows => e
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Sometimes cygpath isn't available (msys). Instead, do what we
|
# Sometimes cygpath isn't available (msys). Instead, do what we
|
||||||
# can with bash tricks.
|
# can with bash tricks.
|
||||||
process = Subprocess.execute(
|
process = Subprocess.execute(
|
||||||
|
@ -110,7 +125,13 @@ module Vagrant
|
||||||
"--norc",
|
"--norc",
|
||||||
"-c", "cd #{Shellwords.escape(path)} && pwd")
|
"-c", "cd #{Shellwords.escape(path)} && pwd")
|
||||||
return process.stdout.chomp
|
return process.stdout.chomp
|
||||||
|
ensure
|
||||||
|
ENV['PATH'] = original_path_env
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# Identical to cygwin_path for now
|
||||||
|
alias_method :msys_path, :cygwin_path
|
||||||
|
|
||||||
# This takes any path and converts it to a full-length Windows
|
# This takes any path and converts it to a full-length Windows
|
||||||
# path on Windows machines in Cygwin.
|
# path on Windows machines in Cygwin.
|
||||||
|
@ -264,6 +285,23 @@ module Vagrant
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Takes a windows path and formats it to the
|
||||||
|
# 'unix' style (i.e. `/cygdrive/c` or `/c/`)
|
||||||
|
#
|
||||||
|
# @param [Pathname, String] path Path to convert
|
||||||
|
# @param [Hash] hash of arguments
|
||||||
|
# @return [String]
|
||||||
|
def format_windows_path(path, *args)
|
||||||
|
path = cygwin_path(path) if cygwin?
|
||||||
|
path = msys_path(path) if msys?
|
||||||
|
path = wsl_to_windows_path(path) if wsl?
|
||||||
|
if windows? || wsl?
|
||||||
|
path = windows_unc_path(path) if !args.include?(:disable_unc)
|
||||||
|
end
|
||||||
|
|
||||||
|
path
|
||||||
|
end
|
||||||
|
|
||||||
# Automatically convert a given path to a Windows path. Will only
|
# Automatically convert a given path to a Windows path. Will only
|
||||||
# be applied if running on a Windows host. If running on Windows
|
# be applied if running on a Windows host. If running on Windows
|
||||||
# host within the WSL, the actual Windows path will be returned.
|
# host within the WSL, the actual Windows path will be returned.
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
require 'optparse'
|
require 'optparse'
|
||||||
|
|
||||||
require "vagrant/util/safe_puts"
|
require "vagrant/util/safe_puts"
|
||||||
|
require "vagrant/util/platform"
|
||||||
|
|
||||||
module VagrantPlugins
|
module VagrantPlugins
|
||||||
module CommandSSHConfig
|
module CommandSSHConfig
|
||||||
|
@ -11,6 +12,10 @@ module VagrantPlugins
|
||||||
"outputs OpenSSH valid configuration to connect to the machine"
|
"outputs OpenSSH valid configuration to connect to the machine"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def convert_win_paths(paths)
|
||||||
|
paths.map! { |path| Vagrant::Util::Platform.format_windows_path(path, :disable_unc) }
|
||||||
|
end
|
||||||
|
|
||||||
def execute
|
def execute
|
||||||
options = {}
|
options = {}
|
||||||
|
|
||||||
|
@ -32,6 +37,10 @@ module VagrantPlugins
|
||||||
ssh_info = machine.ssh_info
|
ssh_info = machine.ssh_info
|
||||||
raise Vagrant::Errors::SSHNotReady if ssh_info.nil?
|
raise Vagrant::Errors::SSHNotReady if ssh_info.nil?
|
||||||
|
|
||||||
|
if Vagrant::Util::Platform.windows?
|
||||||
|
ssh_info[:private_key_path] = convert_win_paths(ssh_info[:private_key_path])
|
||||||
|
end
|
||||||
|
|
||||||
variables = {
|
variables = {
|
||||||
host_key: options[:host] || machine.name || "vagrant",
|
host_key: options[:host] || machine.name || "vagrant",
|
||||||
ssh_host: ssh_info[:host],
|
ssh_host: ssh_info[:host],
|
||||||
|
|
|
@ -24,7 +24,7 @@ describe VagrantPlugins::CommandSSHConfig::Command do
|
||||||
username: "testuser",
|
username: "testuser",
|
||||||
keys_only: true,
|
keys_only: true,
|
||||||
paranoid: false,
|
paranoid: false,
|
||||||
private_key_path: [],
|
private_key_path: ["/home/vagrant/.private/keys.key"],
|
||||||
forward_agent: false,
|
forward_agent: false,
|
||||||
forward_x11: false
|
forward_x11: false
|
||||||
}}
|
}}
|
||||||
|
@ -53,6 +53,7 @@ Host #{machine.name}
|
||||||
UserKnownHostsFile /dev/null
|
UserKnownHostsFile /dev/null
|
||||||
StrictHostKeyChecking no
|
StrictHostKeyChecking no
|
||||||
PasswordAuthentication no
|
PasswordAuthentication no
|
||||||
|
IdentityFile /home/vagrant/.private/keys.key
|
||||||
IdentitiesOnly yes
|
IdentitiesOnly yes
|
||||||
LogLevel FATAL
|
LogLevel FATAL
|
||||||
SSHCONFIG
|
SSHCONFIG
|
||||||
|
@ -136,5 +137,19 @@ Host #{machine.name}
|
||||||
expect(output).not_to include('StrictHostKeyChecking ')
|
expect(output).not_to include('StrictHostKeyChecking ')
|
||||||
expect(output).not_to include('UserKnownHostsFile ')
|
expect(output).not_to include('UserKnownHostsFile ')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "formats windows paths if windows" do
|
||||||
|
allow(machine).to receive(:ssh_info) { ssh_info.merge(private_key_path: ["C:\\path\\to\\vagrant\\home.key"]) }
|
||||||
|
allow(Vagrant::Util::Platform).to receive(:format_windows_path).and_return("/home/vagrant/home.key")
|
||||||
|
allow(Vagrant::Util::Platform).to receive(:windows?).and_return(true)
|
||||||
|
|
||||||
|
output = ""
|
||||||
|
allow(subject).to receive(:safe_puts) do |data|
|
||||||
|
output += data if data
|
||||||
|
end
|
||||||
|
|
||||||
|
subject.execute
|
||||||
|
expect(output).to include('IdentityFile /home/vagrant/home.key')
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -5,8 +5,27 @@ require "vagrant/util/platform"
|
||||||
describe Vagrant::Util::Platform do
|
describe Vagrant::Util::Platform do
|
||||||
include_context "unit"
|
include_context "unit"
|
||||||
|
|
||||||
|
|
||||||
subject { described_class }
|
subject { described_class }
|
||||||
|
|
||||||
|
describe "#cygwin_path" do
|
||||||
|
let(:path) { "C:\\msys2\\home\\vagrant" }
|
||||||
|
let(:updated_path) { "/home/vagrant" }
|
||||||
|
let(:subprocess_result) do
|
||||||
|
double("subprocess_result").tap do |result|
|
||||||
|
allow(result).to receive(:exit_code).and_return(0)
|
||||||
|
allow(result).to receive(:stdout).and_return(updated_path)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "takes a windows path and returns a formatted path" do
|
||||||
|
allow(Vagrant::Util::Which).to receive(:which).and_return("C:/msys2/cygpath")
|
||||||
|
allow(Vagrant::Util::Subprocess).to receive(:execute).and_return(subprocess_result)
|
||||||
|
|
||||||
|
expect(subject.cygwin_path(path)).to eq("/home/vagrant")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#cygwin?" do
|
describe "#cygwin?" do
|
||||||
before do
|
before do
|
||||||
allow(subject).to receive(:platform).and_return("test")
|
allow(subject).to receive(:platform).and_return("test")
|
||||||
|
@ -51,6 +70,50 @@ describe Vagrant::Util::Platform do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "#msys?" do
|
||||||
|
before do
|
||||||
|
allow(subject).to receive(:platform).and_return("test")
|
||||||
|
described_class.reset!
|
||||||
|
end
|
||||||
|
|
||||||
|
after do
|
||||||
|
described_class.reset!
|
||||||
|
end
|
||||||
|
|
||||||
|
around do |example|
|
||||||
|
with_temp_env(VAGRANT_DETECTED_OS: "nope", PATH: "") do
|
||||||
|
example.run
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true if VAGRANT_DETECTED_OS includes msys" do
|
||||||
|
with_temp_env(VAGRANT_DETECTED_OS: "msys") do
|
||||||
|
expect(subject).to be_msys
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true if OSTYPE includes msys" do
|
||||||
|
with_temp_env(OSTYPE: "msys") do
|
||||||
|
expect(subject).to be_msys
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns true if platform has msys" do
|
||||||
|
allow(subject).to receive(:platform).and_return("msys")
|
||||||
|
expect(subject).to be_msys
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false if the PATH contains msys" do
|
||||||
|
with_temp_env(PATH: "C:/msys") do
|
||||||
|
expect(subject).to_not be_msys
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false if nothing is available" do
|
||||||
|
expect(subject).to_not be_msys
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "#fs_real_path" do
|
describe "#fs_real_path" do
|
||||||
it "fixes drive letters on Windows", :windows do
|
it "fixes drive letters on Windows", :windows do
|
||||||
expect(described_class.fs_real_path("c:/foo").to_s).to eql("C:/foo")
|
expect(described_class.fs_real_path("c:/foo").to_s).to eql("C:/foo")
|
||||||
|
|
Loading…
Reference in New Issue