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
|
# some extra setup to allow access to Vagrant managed machines
|
||||||
# outside the subsystem
|
# outside the subsystem
|
||||||
if Vagrant::Util::Platform.wsl?
|
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
|
end
|
||||||
|
|
||||||
if !Vagrant.in_installer? && !Vagrant.very_quiet?
|
if !Vagrant.in_installer? && !Vagrant.very_quiet?
|
||||||
|
|
|
@ -899,5 +899,9 @@ module Vagrant
|
||||||
class WSLVagrantAccessError < VagrantError
|
class WSLVagrantAccessError < VagrantError
|
||||||
error_key(:wsl_vagrant_access_error)
|
error_key(:wsl_vagrant_access_error)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
class WSLVirtualBoxWindowsAccessError < VagrantError
|
||||||
|
error_key(:wsl_virtualbox_windows_access)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -4,15 +4,18 @@ module Vagrant
|
||||||
autoload :CommandDeprecation, 'vagrant/util/command_deprecation'
|
autoload :CommandDeprecation, 'vagrant/util/command_deprecation'
|
||||||
autoload :Counter, 'vagrant/util/counter'
|
autoload :Counter, 'vagrant/util/counter'
|
||||||
autoload :CredentialScrubber, 'vagrant/util/credential_scrubber'
|
autoload :CredentialScrubber, 'vagrant/util/credential_scrubber'
|
||||||
|
autoload :DeepMerge, 'vagrant/util/deep_merge'
|
||||||
autoload :Env, 'vagrant/util/env'
|
autoload :Env, 'vagrant/util/env'
|
||||||
autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access'
|
autoload :HashWithIndifferentAccess, 'vagrant/util/hash_with_indifferent_access'
|
||||||
autoload :GuestInspection, 'vagrant/util/guest_inspection'
|
autoload :GuestInspection, 'vagrant/util/guest_inspection'
|
||||||
autoload :Platform, 'vagrant/util/platform'
|
autoload :Platform, 'vagrant/util/platform'
|
||||||
autoload :Retryable, 'vagrant/util/retryable'
|
autoload :Retryable, 'vagrant/util/retryable'
|
||||||
autoload :SafeExec, 'vagrant/util/safe_exec'
|
autoload :SafeExec, 'vagrant/util/safe_exec'
|
||||||
|
autoload :SilenceWarnings, 'vagrant/util/silence_warnings'
|
||||||
autoload :StackedProcRunner, 'vagrant/util/stacked_proc_runner'
|
autoload :StackedProcRunner, 'vagrant/util/stacked_proc_runner'
|
||||||
autoload :TemplateRenderer, 'vagrant/util/template_renderer'
|
|
||||||
autoload :StringBlockEditor, 'vagrant/util/string_block_editor'
|
autoload :StringBlockEditor, 'vagrant/util/string_block_editor'
|
||||||
autoload :Subprocess, 'vagrant/util/subprocess'
|
autoload :Subprocess, 'vagrant/util/subprocess'
|
||||||
|
autoload :TemplateRenderer, 'vagrant/util/template_renderer'
|
||||||
|
autoload :Which, 'vagrant/util/which'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -249,13 +249,52 @@ module Vagrant
|
||||||
wsl? && !path.to_s.downcase.start_with?("/mnt/")
|
wsl? && !path.to_s.downcase.start_with?("/mnt/")
|
||||||
end
|
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
|
# Allow Vagrant to access Vagrant managed machines outside the
|
||||||
# Windows Subsystem for Linux
|
# Windows Subsystem for Linux
|
||||||
#
|
#
|
||||||
# @return [Boolean]
|
# @return [Boolean]
|
||||||
def wsl_windows_access?
|
def wsl_windows_access?
|
||||||
if !defined?(@_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
|
end
|
||||||
@_wsl_windows_access
|
@_wsl_windows_access
|
||||||
end
|
end
|
||||||
|
@ -266,8 +305,12 @@ module Vagrant
|
||||||
# @return [Pathname]
|
# @return [Pathname]
|
||||||
def wsl_windows_accessible_path
|
def wsl_windows_accessible_path
|
||||||
if !defined?(@_wsl_windows_accessible_path)
|
if !defined?(@_wsl_windows_accessible_path)
|
||||||
access_path = ENV.fetch("VAGRANT_WSL_ACCESS_WINDOWS_USER_HOME_PATH",
|
access_path = ENV["VAGRANT_WSL_WINDOWS_ACCESS_USER_HOME_PATH"]
|
||||||
"/mnt/c/Users/#{ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]}")
|
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)
|
@_wsl_windows_accessible_path = Pathname.new(access_path)
|
||||||
end
|
end
|
||||||
@_wsl_windows_accessible_path
|
@_wsl_windows_accessible_path
|
||||||
|
@ -290,9 +333,12 @@ module Vagrant
|
||||||
# @param [Logger] logger Optional logger to display information
|
# @param [Logger] logger Optional logger to display information
|
||||||
def wsl_init(env, logger=nil)
|
def wsl_init(env, logger=nil)
|
||||||
if wsl?
|
if wsl?
|
||||||
if ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
if ENV["VAGRANT_WSL_ENABLE_WINDOWS_ACCESS"]
|
||||||
wsl_validate_matching_vagrant_versions!
|
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
|
if logger
|
||||||
logger.warn("Windows Subsystem for Linux detected. Allowing access to user: #{shared_user}")
|
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.")
|
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"]
|
if ENV["VAGRANT_HOME"] || ENV["VAGRANT_WSL_DISABLE_VAGRANT_HOME"]
|
||||||
logger.warn("VAGRANT_HOME environment variable already set. Not overriding!") if logger
|
logger.warn("VAGRANT_HOME environment variable already set. Not overriding!") if logger
|
||||||
else
|
else
|
||||||
home_path = wsl_windows_accessible_path
|
home_path = wsl_windows_accessible_path.to_s
|
||||||
ENV["VAGRANT_HOME"] = File.join(home_path, ".vagrant.d")
|
ENV["VAGRANT_HOME"] = File.join(home_path, ".vagrant.d")
|
||||||
if logger
|
if logger
|
||||||
logger.info("Overriding VAGRANT_HOME environment variable to configured windows user. (#{ENV["VAGRANT_HOME"]})")
|
logger.info("Overriding VAGRANT_HOME environment variable to configured windows user. (#{ENV["VAGRANT_HOME"]})")
|
||||||
end
|
end
|
||||||
|
true
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
if env.local_data_path.to_s.start_with?("/mnt/")
|
if env.local_data_path.to_s.start_with?("/mnt/")
|
||||||
|
@ -314,6 +361,45 @@ module Vagrant
|
||||||
end
|
end
|
||||||
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
|
# Confirm Vagrant versions installed within the WSL and the Windows system
|
||||||
# are the same. Raise error if they do not match.
|
# are the same. Raise error if they do not match.
|
||||||
def wsl_validate_matching_vagrant_versions!
|
def wsl_validate_matching_vagrant_versions!
|
||||||
|
|
|
@ -45,7 +45,19 @@ module VagrantPlugins
|
||||||
run_cmd += expose.map { |p| ['--expose', "#{p}"] }
|
run_cmd += expose.map { |p| ['--expose', "#{p}"] }
|
||||||
run_cmd += links.map { |k, v| ['--link', "#{k}:#{v}"] }
|
run_cmd += links.map { |k, v| ['--link', "#{k}:#{v}"] }
|
||||||
run_cmd += ports.map { |p| ['-p', p.to_s] }
|
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(--privileged) if params[:privileged]
|
||||||
run_cmd += %W(-h #{params[:hostname]}) if params[:hostname]
|
run_cmd += %W(-h #{params[:hostname]}) if params[:hostname]
|
||||||
run_cmd << "-t" if params[:pty]
|
run_cmd << "-t" if params[:pty]
|
||||||
|
|
|
@ -67,6 +67,10 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
elsif Vagrant::Util::Platform.wsl?
|
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.")
|
@logger.debug("Linux platform detected but executing within WSL. Locating VBoxManage.")
|
||||||
@vboxmanage_path = Vagrant::Util::Which.which("VBoxManage") || Vagrant::Util::Which.which("VBoxManage.exe")
|
@vboxmanage_path = Vagrant::Util::Which.which("VBoxManage") || Vagrant::Util::Which.which("VBoxManage.exe")
|
||||||
if !@vboxmanage_path
|
if !@vboxmanage_path
|
||||||
|
|
|
@ -270,7 +270,7 @@ module VagrantPlugins
|
||||||
end
|
end
|
||||||
|
|
||||||
def import(ovf)
|
def import(ovf)
|
||||||
ovf = Vagrant::Util::Platform.cygwin_windows_path(ovf)
|
ovf = Vagrant::Util::Platform.windows_path(ovf)
|
||||||
|
|
||||||
output = ""
|
output = ""
|
||||||
total = ""
|
total = ""
|
||||||
|
@ -614,10 +614,7 @@ module VagrantPlugins
|
||||||
|
|
||||||
def share_folders(folders)
|
def share_folders(folders)
|
||||||
folders.each do |folder|
|
folders.each do |folder|
|
||||||
hostpath = folder[:hostpath]
|
hostpath = Vagrant::Util::Platform.windows_path(folder[:hostpath])
|
||||||
if Vagrant::Util::Platform.windows?
|
|
||||||
hostpath = Vagrant::Util::Platform.windows_unc_path(hostpath)
|
|
||||||
end
|
|
||||||
args = ["--name",
|
args = ["--name",
|
||||||
folder[:name],
|
folder[:name],
|
||||||
"--hostpath",
|
"--hostpath",
|
||||||
|
|
|
@ -1538,7 +1538,14 @@ en:
|
||||||
please refer to the Vagrant documentation:
|
please refer to the Vagrant documentation:
|
||||||
|
|
||||||
https://www.vagrantup.com/docs/other/wsl
|
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
|
# Translations for config validation errors
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
|
|
@ -68,43 +68,36 @@ Vagrant to access them.
|
||||||
## Windows Access
|
## Windows Access
|
||||||
|
|
||||||
Working within the WSL provides a layer of isolation from the actual
|
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 system. In most cases Vagrant will need access to the actual
|
||||||
Windows environment, and then transition to using Vagrant within the
|
Windows system to function correctly. As most Vagrant providers will
|
||||||
WSL. Using Vagrant within the WSL will appear to be isolated from
|
need to be installed on Windows directly (not within the WSL) Vagrant
|
||||||
the Windows system. A new `VAGRANT_HOME` directory will be created within
|
will require Windows access. Access to the Windows system is controlled
|
||||||
the WSL (meaning all boxes will require re-downloading). Vagrant will also
|
via an environment variable: `VAGRANT_WSL_ENABLE_WINDOWS_ACCESS`. If
|
||||||
lose the ability to control Vagrant managed machines within Windows (due
|
this environment variable is set, Vagrant will access the Windows system
|
||||||
to user ID mismatches).
|
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:
|
||||||
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:
|
|
||||||
|
|
||||||
```
|
```
|
||||||
C:\Users\vagrant> bash
|
$ export VAGRANT_WSL_ENABLE_WINDOWS_ACCESS="1"
|
||||||
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...
|
|
||||||
```
|
```
|
||||||
|
|
||||||
It is important to note that file permissions cannot be enforced when Vagrant
|
This will enable Vagrant to access the Windows system outside of the
|
||||||
modifies the Windows file system. It is for this reason that you must explicitly
|
WSL and properly interact with Windows executables. This will automatically
|
||||||
enable this functionality with the express knowledge of the implication. If you
|
modify the `VAGRANT_HOME` environment variable if it is not already defined,
|
||||||
are unsure of how this may affect your system, do not enable this feature.
|
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
|
## Using Docker
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue