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
|
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,17 @@ 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'
|
||||||
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?
|
||||||
|
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!
|
||||||
|
|
|
@ -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