Merge pull request #8582 from chrisroberts/updates/wsl
Update WSL integration
This commit is contained in:
commit
6c83743980
|
@ -121,7 +121,11 @@ begin
|
|||
# some extra setup to allow access to Vagrant managed machines
|
||||
# outside the subsystem
|
||||
if Vagrant::Util::Platform.wsl?
|
||||
Vagrant::Util::Platform.wsl_init(env, logger)
|
||||
recreate_env = Vagrant::Util::Platform.wsl_init(env, logger)
|
||||
if recreate_env
|
||||
logger.info("Re-creating Vagrant environment due to WSL modifications.")
|
||||
env = Vagrant::Environment.new(opts)
|
||||
end
|
||||
end
|
||||
|
||||
if !Vagrant.in_installer? && !Vagrant.very_quiet?
|
||||
|
|
|
@ -899,5 +899,9 @@ module Vagrant
|
|||
class WSLVagrantAccessError < VagrantError
|
||||
error_key(:wsl_vagrant_access_error)
|
||||
end
|
||||
|
||||
class WSLVirtualBoxWindowsAccessError < VagrantError
|
||||
error_key(:wsl_virtualbox_windows_access)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,15 +4,18 @@ module Vagrant
|
|||
autoload :CommandDeprecation, 'vagrant/util/command_deprecation'
|
||||
autoload :Counter, 'vagrant/util/counter'
|
||||
autoload :CredentialScrubber, 'vagrant/util/credential_scrubber'
|
||||
autoload :DeepMerge, 'vagrant/util/deep_merge'
|
||||
autoload :Env, 'vagrant/util/env'
|
||||
autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access'
|
||||
autoload :GuestInspection, 'vagrant/util/guest_inspection'
|
||||
autoload :Platform, 'vagrant/util/platform'
|
||||
autoload :Retryable, 'vagrant/util/retryable'
|
||||
autoload :SafeExec, 'vagrant/util/safe_exec'
|
||||
autoload :SilenceWarnings, 'vagrant/util/silence_warnings'
|
||||
autoload :StackedProcRunner, 'vagrant/util/stacked_proc_runner'
|
||||
autoload :TemplateRenderer, 'vagrant/util/template_renderer'
|
||||
autoload :StringBlockEditor, 'vagrant/util/string_block_editor'
|
||||
autoload :Subprocess, 'vagrant/util/subprocess'
|
||||
autoload :TemplateRenderer, 'vagrant/util/template_renderer'
|
||||
autoload :Which, 'vagrant/util/which'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -249,13 +249,52 @@ module Vagrant
|
|||
wsl? && !path.to_s.downcase.start_with?("/mnt/")
|
||||
end
|
||||
|
||||
# Convert a WSL path to the local Windows path. This is useful
|
||||
# for conversion when calling out to Windows executables from
|
||||
# the WSL
|
||||
#
|
||||
# @param [String, Pathname] path Path to convert
|
||||
# @return [String]
|
||||
def wsl_to_windows_path(path)
|
||||
if wsl? && wsl_windows_access?
|
||||
if wsl_path?(path)
|
||||
parts = path.split("/")
|
||||
parts.delete_if(&:empty?)
|
||||
[wsl_windows_appdata_local, "lxss", *parts].join("\\")
|
||||
else
|
||||
path = path.to_s.sub("/mnt/", "")
|
||||
parts = path.split("/")
|
||||
parts.first << ":"
|
||||
path = parts.join("\\")
|
||||
path
|
||||
end
|
||||
else
|
||||
path
|
||||
end
|
||||
end
|
||||
|
||||
# Automatically convert a given path to a Windows path. Will only
|
||||
# be applied if running on a Windows host. If running on Windows
|
||||
# host within the WSL, the actual Windows path will be returned.
|
||||
#
|
||||
# @param [Pathname, String] path Path to convert
|
||||
# @return [String]
|
||||
def windows_path(path)
|
||||
path = cygwin_windows_path(path)
|
||||
path = wsl_to_windows_path(path)
|
||||
if windows? || wsl?
|
||||
path = windows_unc_path(path)
|
||||
end
|
||||
path
|
||||
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"]
|
||||
@_wsl_windows_access = wsl? && ENV["VAGRANT_WSL_ENABLE_WINDOWS_ACCESS"]
|
||||
end
|
||||
@_wsl_windows_access
|
||||
end
|
||||
|
@ -266,8 +305,12 @@ module Vagrant
|
|||
# @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"]}")
|
||||
access_path = ENV["VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH"]
|
||||
if access_path.to_s.empty?
|
||||
access_path = wsl_windows_home.gsub("\\", "/").sub(":", "")
|
||||
access_path[0] = access_path[0].downcase
|
||||
access_path = "/mnt/#{access_path}"
|
||||
end
|
||||
@_wsl_windows_accessible_path = Pathname.new(access_path)
|
||||
end
|
||||
@_wsl_windows_accessible_path
|
||||
|
@ -290,9 +333,12 @@ module Vagrant
|
|||
# @param [Logger] logger Optional logger to display information
|
||||
def wsl_init(env, logger=nil)
|
||||
if wsl?
|
||||
if ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
||||
if ENV["VAGRANT_WSL_ENABLE_WINDOWS_ACCESS"]
|
||||
wsl_validate_matching_vagrant_versions!
|
||||
shared_user = ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
||||
shared_user = ENV["VAGRANT_WSL_WINDOWS_ACCESS_USER"]
|
||||
if shared_user.to_s.empty?
|
||||
shared_user = wsl_windows_username
|
||||
end
|
||||
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.")
|
||||
|
@ -300,11 +346,12 @@ module Vagrant
|
|||
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
|
||||
home_path = wsl_windows_accessible_path.to_s
|
||||
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
|
||||
true
|
||||
end
|
||||
else
|
||||
if env.local_data_path.to_s.start_with?("/mnt/")
|
||||
|
@ -314,6 +361,45 @@ module Vagrant
|
|||
end
|
||||
end
|
||||
|
||||
# Fetch the Windows username currently in use
|
||||
#
|
||||
# @return [String, Nil]
|
||||
def wsl_windows_username
|
||||
if !@_wsl_windows_username
|
||||
result = Util::Subprocess.execute("cmd.exe", "/c", "echo %USERNAME%")
|
||||
if result.exit_code == 0
|
||||
@_wsl_windows_username = result.stdout.strip
|
||||
end
|
||||
end
|
||||
@_wsl_windows_username
|
||||
end
|
||||
|
||||
# Fetch the Windows user home directory
|
||||
#
|
||||
# @return [String, Nil]
|
||||
def wsl_windows_home
|
||||
if !@_wsl_windows_home
|
||||
result = Util::Subprocess.execute("cmd.exe", "/c" "echo %USERPROFILE%")
|
||||
if result.exit_code == 0
|
||||
@_wsl_windows_home = result.stdout.gsub("\"", "").strip
|
||||
end
|
||||
end
|
||||
@_wsl_windows_home
|
||||
end
|
||||
|
||||
# Fetch the Windows user local app data directory
|
||||
#
|
||||
# @return [String, Nil]
|
||||
def wsl_windows_appdata_local
|
||||
if !@_wsl_windows_appdata_local
|
||||
result = Util::Subprocess.execute("cmd.exe", "/c", "echo %LOCALAPPDATA%")
|
||||
if result.exit_code == 0
|
||||
@_wsl_windows_appdata_local = result.stdout.gsub("\"", "").strip
|
||||
end
|
||||
end
|
||||
@_wsl_windows_appdata_local
|
||||
end
|
||||
|
||||
# Confirm Vagrant versions installed within the WSL and the Windows system
|
||||
# are the same. Raise error if they do not match.
|
||||
def wsl_validate_matching_vagrant_versions!
|
||||
|
|
|
@ -45,7 +45,19 @@ module VagrantPlugins
|
|||
run_cmd += expose.map { |p| ['--expose', "#{p}"] }
|
||||
run_cmd += links.map { |k, v| ['--link', "#{k}:#{v}"] }
|
||||
run_cmd += ports.map { |p| ['-p', p.to_s] }
|
||||
run_cmd += volumes.map { |v| ['-v', v.to_s] }
|
||||
run_cmd += volumes.map { |v|
|
||||
v = v.to_s
|
||||
if v.include?(":") && (Vagrant::Util::Platform.windows? || Vagrant::Util::Platform.wsl?)
|
||||
host, guest = v.split(":", 2)
|
||||
host = Vagrant::Util::Platform.windows_path(host)
|
||||
# NOTE: Docker does not support UNC style paths (which also
|
||||
# means that there's no long path support). Hopefully this
|
||||
# will be fixed someday and the gsub below can be removed.
|
||||
host.gsub!(/^[^A-Za-z]+/, "")
|
||||
v = [host, guest].join(":")
|
||||
end
|
||||
['-v', v.to_s]
|
||||
}
|
||||
run_cmd += %W(--privileged) if params[:privileged]
|
||||
run_cmd += %W(-h #{params[:hostname]}) if params[:hostname]
|
||||
run_cmd << "-t" if params[:pty]
|
||||
|
|
|
@ -67,6 +67,10 @@ module VagrantPlugins
|
|||
end
|
||||
end
|
||||
elsif Vagrant::Util::Platform.wsl?
|
||||
if !Vagrant::Util::Platform.wsl_windows_access?
|
||||
@logger.error("No user Windows access defined for the Windows Subsystem for Linux. This is required for VirtualBox.")
|
||||
raise Vagrant::Errors::WSLVirtualBoxWindowsAccessError
|
||||
end
|
||||
@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
|
||||
|
|
|
@ -270,7 +270,7 @@ module VagrantPlugins
|
|||
end
|
||||
|
||||
def import(ovf)
|
||||
ovf = Vagrant::Util::Platform.cygwin_windows_path(ovf)
|
||||
ovf = Vagrant::Util::Platform.windows_path(ovf)
|
||||
|
||||
output = ""
|
||||
total = ""
|
||||
|
@ -614,10 +614,7 @@ module VagrantPlugins
|
|||
|
||||
def share_folders(folders)
|
||||
folders.each do |folder|
|
||||
hostpath = folder[:hostpath]
|
||||
if Vagrant::Util::Platform.windows?
|
||||
hostpath = Vagrant::Util::Platform.windows_unc_path(hostpath)
|
||||
end
|
||||
hostpath = Vagrant::Util::Platform.windows_path(folder[:hostpath])
|
||||
args = ["--name",
|
||||
folder[:name],
|
||||
"--hostpath",
|
||||
|
|
|
@ -1538,7 +1538,14 @@ en:
|
|||
please refer to the Vagrant documentation:
|
||||
|
||||
https://www.vagrantup.com/docs/other/wsl
|
||||
wsl_virtualbox_windows_access: |-
|
||||
Vagrant is unable to use the VirtualBox provider from the Windows Subsystem for
|
||||
Linux without access to the Windows environment. Enabling this access must be
|
||||
done with caution and an understanding of the implications. For more information
|
||||
on enabing Windows access and using VirtualBox from the Windows Subsystem for
|
||||
Linux, please refer to the Vagrant documentation:
|
||||
|
||||
https://www.vagrantup.com/docs/other/wsl
|
||||
#-------------------------------------------------------------------------------
|
||||
# Translations for config validation errors
|
||||
#-------------------------------------------------------------------------------
|
||||
|
|
|
@ -68,43 +68,36 @@ Vagrant to access them.
|
|||
## Windows Access
|
||||
|
||||
Working within the WSL provides a layer of isolation from the actual
|
||||
Windows system. In some cases, a user may be using Vagrant in a regular
|
||||
Windows environment, and then transition to using Vagrant within the
|
||||
WSL. Using Vagrant within the WSL will appear to be isolated from
|
||||
the Windows system. A new `VAGRANT_HOME` directory will be created within
|
||||
the WSL (meaning all boxes will require re-downloading). Vagrant will also
|
||||
lose the ability to control Vagrant managed machines within Windows (due
|
||||
to user ID mismatches).
|
||||
|
||||
Vagrant supports enabling user access to provide seamless behavior and
|
||||
control between Vagrant on Windows and Vagrant on WSL. By setting the
|
||||
`VAGRANT_WSL_ACCESS_WINDOWS_USER` environment variable, Vagrant will
|
||||
allow access to Vagrant managed machines in that user's home path in
|
||||
Windows (`C:\Users\vagrant` for example), as well as share the `VAGRANT_HOME`
|
||||
directory. Below is a demonstration of the behavior:
|
||||
Windows system. In most cases Vagrant will need access to the actual
|
||||
Windows system to function correctly. As most Vagrant providers will
|
||||
need to be installed on Windows directly (not within the WSL) Vagrant
|
||||
will require Windows access. Access to the Windows system is controlled
|
||||
via an environment variable: `VAGRANT_WSL_ENABLE_WINDOWS_ACCESS`. If
|
||||
this environment variable is set, Vagrant will access the Windows system
|
||||
to run executables and enable things like synced folders. When running
|
||||
in a bash shell within WSL, the environment variable can be setup like so:
|
||||
|
||||
```
|
||||
C:\Users\vagrant> bash
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ mkdir test
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ cd test
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant/test$ vagrant init hashicorp/precisec4
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ vagrant up
|
||||
Vagrant will not operate outside the Windows Subsystem for Linux unless explicitly
|
||||
instructed. Due to the inability to enforce expected Linux file ownership and
|
||||
permissions on the Windows system, Vagrant will not make modifications to prevent
|
||||
unexpected errors. To learn more about this, and the options that are available,
|
||||
please refer to the Vagrant documentation:
|
||||
|
||||
https://www.vagrantup.com/docs/other/wsl
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ export VAGRANT_WSL_ACCESS_WINDOWS_USER=vagrant
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ vagrant up
|
||||
Bringing machine 'default' up with 'virtualbox' provider...
|
||||
$ export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"
|
||||
```
|
||||
|
||||
It is important to note that file permissions cannot be enforced when Vagrant
|
||||
modifies the Windows file system. It is for this reason that you must explicitly
|
||||
enable this functionality with the express knowledge of the implication. If you
|
||||
are unsure of how this may affect your system, do not enable this feature.
|
||||
This will enable Vagrant to access the Windows system outside of the
|
||||
WSL and properly interact with Windows executables. This will automatically
|
||||
modify the `VAGRANT_HOME` environment variable if it is not already defined,
|
||||
setting it to be within the user's home directory on Windows.
|
||||
|
||||
It is important to note that paths shared with the Windows system will
|
||||
not have Linux permissions enforced. For example, when a directory within
|
||||
the WSL is synced to a guest using the VirtualBox provider, any local
|
||||
permissions defined on that directory (or its contents) will not be
|
||||
visible from the guest. Likewise, any files created from the guest within
|
||||
the synced folder will be world readable/writeable in WSL.
|
||||
|
||||
Other useful WSL related environment variables:
|
||||
|
||||
* `VAGRANT_WSL_WINDOWS_ACCESS_USER` - Override current Windows username
|
||||
* `VAGRANT_WSL_DISABLE_VAGRANT_HOME` - Do not modify the `VAGRANT_HOME` variable
|
||||
* `VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH` - Custom Windows system home path
|
||||
|
||||
## Using Docker
|
||||
|
||||
|
|
Loading…
Reference in New Issue