Support running Vagrant within the Windows Subsystem for Linux
This commit is contained in:
parent
b9862ce847
commit
83b0c87f52
|
@ -112,6 +112,13 @@ begin
|
|||
argv += argv_extra
|
||||
end
|
||||
|
||||
# If we are running with the Windows Subsystem for Linux do
|
||||
# some extra setup to allow access to Vagrant managed machines
|
||||
# outside the subsystem
|
||||
if Vagrant::Util::Platform.wsl?
|
||||
Vagrant::Util::Platform.wsl_init(logger)
|
||||
end
|
||||
|
||||
# Create the environment, which is the cwd of wherever the
|
||||
# `vagrant` command was invoked from
|
||||
logger.debug("Creating Vagrant environment")
|
||||
|
|
|
@ -780,6 +780,10 @@ module Vagrant
|
|||
error_key(:vboxmanage_not_found_error)
|
||||
end
|
||||
|
||||
class VBoxManageNotFoundWSLError < VagrantError
|
||||
error_key(:vboxmanage_not_found_wsl_error)
|
||||
end
|
||||
|
||||
class VirtualBoxBrokenVersion040214 < VagrantError
|
||||
error_key(:virtualbox_broken_version_040214)
|
||||
end
|
||||
|
|
|
@ -28,6 +28,27 @@ module Vagrant
|
|||
return @_cygwin
|
||||
end
|
||||
|
||||
def wsl?
|
||||
if !defined?(@_wsl)
|
||||
@_wsl = false
|
||||
original_verbose = $VERBOSE
|
||||
begin
|
||||
$VERBOSE = nil
|
||||
# Use PATH values to check for `/mnt/c` path indicative of WSL
|
||||
if ENV.fetch("PATH", "").downcase.include?("/mnt/c")
|
||||
# Validate WSL via uname output
|
||||
uname = Subprocess.execute("uname", "-r")
|
||||
if uname.exit_code == 0 && uname.stdout.downcase.include?("microsoft")
|
||||
@_wsl = true
|
||||
end
|
||||
end
|
||||
ensure
|
||||
$VERBOSE = original_verbose
|
||||
end
|
||||
end
|
||||
@_wsl
|
||||
end
|
||||
|
||||
[:darwin, :bsd, :freebsd, :linux, :solaris].each do |type|
|
||||
define_method("#{type}?") do
|
||||
platform.include?(type.to_s)
|
||||
|
@ -223,6 +244,72 @@ module Vagrant
|
|||
return @_platform
|
||||
end
|
||||
|
||||
# Determine if given path is within the WSL rootfs. Returns
|
||||
# true if within the subsystem, or false if outside the subsystem.
|
||||
#
|
||||
# @param [String] path Path to check
|
||||
# @return [Boolean] path is within subsystem
|
||||
def wsl_path?(path)
|
||||
wsl? && !path.to_s.downcase.start_with?("/mnt/")
|
||||
end
|
||||
|
||||
# Allow Vagrant to access Vagrant managed machines outside the
|
||||
# Windows Subsystem for Linux
|
||||
#
|
||||
# @return [Boolean]
|
||||
def wsl_windows_access?
|
||||
if !defined?(@_wsl_windows_access)
|
||||
@_wsl_windows_access = wsl? && ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
||||
end
|
||||
@_wsl_windows_access
|
||||
end
|
||||
|
||||
# The allowed windows system path Vagrant can manage from the Windows
|
||||
# Subsystem for Linux
|
||||
#
|
||||
# @return [Pathname]
|
||||
def wsl_windows_accessible_path
|
||||
if !defined?(@_wsl_windows_accessible_path)
|
||||
access_path = ENV.fetch("VAGRANT_WSL_ACCESS_WINDOWS_USER_HOME_PATH",
|
||||
"/mnt/c/Users/#{ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]}")
|
||||
@_wsl_windows_accessible_path = Pathname.new(access_path)
|
||||
end
|
||||
@_wsl_windows_accessible_path
|
||||
end
|
||||
|
||||
# Checks given path to determine if Vagrant is allowed to bypass checks
|
||||
#
|
||||
# @param [String] path Path to check
|
||||
# @return [Boolean] Vagrant is allowed to bypass checks
|
||||
def wsl_windows_access_bypass?(path)
|
||||
wsl? && wsl_windows_access? &&
|
||||
path.to_s.start_with?(wsl_windows_accessible_path.to_s)
|
||||
end
|
||||
|
||||
# If running within the Windows Subsystem for Linux, this will provide
|
||||
# simple setup to allow sharing of the user's VAGRANT_HOME directory
|
||||
# within the subsystem
|
||||
#
|
||||
# @param [Logger] logger Optional logger to display information
|
||||
def wsl_init(logger=nil)
|
||||
if wsl? && ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
||||
shared_user = ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
||||
if logger
|
||||
logger.warn("Windows Subsystem for Linux detected. Allowing access to user: #{shared_user}")
|
||||
logger.warn("Vagrant will be allowed to control Vagrant managed machines within the user's home path.")
|
||||
end
|
||||
if ENV["VAGRANT_HOME"] || ENV["VAGRANT_WSL_DISABLE_VAGRANT_HOME"]
|
||||
logger.warn("VAGRANT_HOME environment variable already set. Not overriding!") if logger
|
||||
else
|
||||
home_path = wsl_windows_accessible_path
|
||||
ENV["VAGRANT_HOME"] = File.join(home_path, ".vagrant.d")
|
||||
if logger
|
||||
logger.info("Overriding VAGRANT_HOME environment variable to configured windows user. (#{ENV["VAGRANT_HOME"]})")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @private
|
||||
# Reset the cached values for platform. This is not considered a public
|
||||
# API and should only be used for testing.
|
||||
|
|
|
@ -28,7 +28,7 @@ module Vagrant
|
|||
def self.check_key_permissions(key_path)
|
||||
# Don't do anything if we're on Windows, since Windows doesn't worry
|
||||
# about key permissions.
|
||||
return if Platform.windows?
|
||||
return if Platform.windows? || Platform.wsl_windows_access_bypass?(key_path)
|
||||
|
||||
LOGGER.debug("Checking key permissions: #{key_path}")
|
||||
stat = key_path.stat
|
||||
|
|
|
@ -66,6 +66,12 @@ module VagrantPlugins
|
|||
break
|
||||
end
|
||||
end
|
||||
elsif Vagrant::Util::Platform.wsl?
|
||||
@logger.debug("Linux platform detected but executing within WSL. Locating VBoxManage.")
|
||||
@vboxmanage_path = Vagrant::Util::Which.which("VBoxManage") || Vagrant::Util::Which.which("VBoxManage.exe")
|
||||
if !@vboxmanage_path
|
||||
raise Vagrant::Errors::VBoxManageNotFoundWSLError
|
||||
end
|
||||
end
|
||||
|
||||
# Fall back to hoping for the PATH to work out
|
||||
|
|
|
@ -84,11 +84,15 @@ module VagrantPlugins
|
|||
def state
|
||||
# We have to check if the UID matches to avoid issues with
|
||||
# VirtualBox.
|
||||
uid = @machine.uid
|
||||
if uid && uid.to_s != Process.uid.to_s
|
||||
raise Vagrant::Errors::VirtualBoxUserMismatch,
|
||||
original_uid: uid.to_s,
|
||||
uid: Process.uid.to_s
|
||||
if Vagrant::Util::Platform.wsl_windows_access_bypass?(@machine.data_dir)
|
||||
@logger.warn("Skipping UID check on machine by user request for WSL Windows access.")
|
||||
else
|
||||
uid = @machine.uid
|
||||
if uid && uid.to_s != Process.uid.to_s
|
||||
raise Vagrant::Errors::VirtualBoxUserMismatch,
|
||||
original_uid: uid.to_s,
|
||||
uid: Process.uid.to_s
|
||||
end
|
||||
end
|
||||
|
||||
# Determine the ID of the state here.
|
||||
|
|
|
@ -1381,6 +1381,16 @@ en:
|
|||
log out and log back in for the new environmental variables to take
|
||||
effect. If you're on Linux or Mac, verify your PATH contains the folder
|
||||
that has VBoxManage in it.
|
||||
vboxmanage_not_found_wsl_error: |-
|
||||
The "VBoxManage.exe" command or one of its dependencies could not
|
||||
be found. Please verify VirtualBox is properly installed. You can verify
|
||||
everything is okay by running "VBoxManage.exe --version" and verifying
|
||||
that the VirtualBox version is outputted.
|
||||
|
||||
If you just installed VirtualBox, you have to log out and log back in for
|
||||
the new environmental variables to take effect. Using the VirtualBox
|
||||
provider within the WSL requires VirtualBox executables to be available
|
||||
on the system PATH.
|
||||
virtualbox_broken_version_040214: |-
|
||||
Vagrant detected you have VirtualBox 4.2.14 installed. VirtualBox
|
||||
4.2.14 contains a critical bug which prevents it from working with
|
||||
|
|
Loading…
Reference in New Issue