Support vbox provider within WSL rootfs. Make Windows access easier.
Enables proper setup of VMs started from within WSL rootfs paths. Updates setup for Windows access when working within the WSL to auto-detect settings instead of relying on user defined environment variables.
This commit is contained in:
parent
87a0f98a9f
commit
3c44ce9742
|
@ -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,17 @@ 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'
|
||||
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?
|
||||
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!
|
||||
|
|
|
@ -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