Merge pull request #8570 from chrisroberts/enhancement/wsl-support
Add support for running within WSL
This commit is contained in:
commit
37901cd43c
|
@ -117,6 +117,13 @@ begin
|
|||
logger.debug("Creating Vagrant environment")
|
||||
env = Vagrant::Environment.new(opts)
|
||||
|
||||
# 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(env, logger)
|
||||
end
|
||||
|
||||
if !Vagrant.in_installer? && !Vagrant.very_quiet?
|
||||
# If we're not in the installer, warn.
|
||||
env.ui.warn(I18n.t("vagrant.general.not_in_installer") + "\n", prefix: false)
|
||||
|
|
|
@ -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
|
||||
|
@ -887,5 +891,13 @@ module Vagrant
|
|||
class VMPowerOffToPackage < VagrantError
|
||||
error_key(:power_off, "vagrant.actions.vm.export")
|
||||
end
|
||||
|
||||
class WSLVagrantVersionMismatch < VagrantError
|
||||
error_key(:wsl_vagrant_version_mismatch)
|
||||
end
|
||||
|
||||
class WSLVagrantAccessError < VagrantError
|
||||
error_key(:wsl_vagrant_access_error)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -28,6 +28,23 @@ module Vagrant
|
|||
return @_cygwin
|
||||
end
|
||||
|
||||
def wsl?
|
||||
if !defined?(@_wsl)
|
||||
@_wsl = false
|
||||
SilenceWarnings.silence! do
|
||||
# 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
|
||||
end
|
||||
end
|
||||
@_wsl
|
||||
end
|
||||
|
||||
[:darwin, :bsd, :freebsd, :linux, :solaris].each do |type|
|
||||
define_method("#{type}?") do
|
||||
platform.include?(type.to_s)
|
||||
|
@ -223,6 +240,99 @@ 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 [Environment] env
|
||||
# @param [Logger] logger Optional logger to display information
|
||||
def wsl_init(env, logger=nil)
|
||||
if wsl?
|
||||
if ENV["VAGRANT_WSL_ACCESS_WINDOWS_USER"]
|
||||
wsl_validate_matching_vagrant_versions!
|
||||
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
|
||||
else
|
||||
if env.local_data_path.to_s.start_with?("/mnt/")
|
||||
raise Vagrant::Errors::WSLVagrantAccessError
|
||||
end
|
||||
end
|
||||
end
|
||||
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!
|
||||
valid = false
|
||||
result = Util::Subprocess.execute("vagrant.exe", "version")
|
||||
if result.exit_code == 0
|
||||
windows_version = result.stdout.match(/Installed Version: (?<version>.+$)/)
|
||||
if windows_version
|
||||
windows_version = windows_version[:version].strip
|
||||
valid = windows_version == Vagrant::VERSION
|
||||
end
|
||||
end
|
||||
if !valid
|
||||
raise Vagrant::Errors::WSLVagrantVersionMismatch,
|
||||
wsl_version: Vagrant::VERSION,
|
||||
windows_version: windows_version || "unknown"
|
||||
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
|
||||
|
|
|
@ -29,12 +29,14 @@ module Vagrant
|
|||
exts = ENV['PATHEXT'].split(';')
|
||||
end
|
||||
|
||||
SilenceWarnings.silence! do
|
||||
ENV['PATH'].encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '').split(File::PATH_SEPARATOR).each do |path|
|
||||
exts.each do |ext|
|
||||
exe = "#{path}#{File::SEPARATOR}#{cmd}#{ext}"
|
||||
return exe if File.executable? exe
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
end
|
||||
|
|
|
@ -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,12 +84,16 @@ module VagrantPlugins
|
|||
def state
|
||||
# We have to check if the UID matches to avoid issues with
|
||||
# VirtualBox.
|
||||
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.
|
||||
state_id = nil
|
||||
|
|
|
@ -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
|
||||
|
@ -1510,6 +1520,24 @@ en:
|
|||
VM must be running to open SSH connection. Run `vagrant up`
|
||||
to start the virtual machine.
|
||||
test_key: "test value"
|
||||
wsl_vagrant_version_mismatch: |-
|
||||
Vagrant cannot currently enable access to manage machines within the Windows
|
||||
environment because the version of Vagrant installed on Windows does not
|
||||
match this version of Vagrant running within the Windows Subsystem for Linux.
|
||||
Please ensure both installation of Vagrant are the same. If you do not want
|
||||
update your Vagrant installations you can disable Windows access by unsetting
|
||||
the `VAGRANT_WSL_ACCESS_WINDOWS_USER` environment variable.
|
||||
|
||||
Windows Vagrant version: %{windows_version}
|
||||
Windows Subsystem for Linux Vagrant version: %{wsl_version}
|
||||
wsl_vagrant_access_error: |-
|
||||
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
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
# Translations for config validation errors
|
||||
|
|
|
@ -0,0 +1,118 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Vagrant and Windows Subsystem for Linux"
|
||||
sidebar_current: "other-wsl"
|
||||
description: |-
|
||||
An overview of using Vagrant on Windows within the Windows Subsystem
|
||||
for Linux.
|
||||
---
|
||||
|
||||
# Vagrant and Windows Subsystem for Linux
|
||||
|
||||
Windows has recently introduced a new feature called the Windows Subsystem
|
||||
for Linux (WSL). This is a beta feature available in developer mode on recent
|
||||
releases of Windows 10. It is important to note that this feature is still
|
||||
in _beta_ on Windows, and Vagrant support should be considered _alpha_.
|
||||
|
||||
<div class="alert alert-warning">
|
||||
<strong>Warning: Advanced Topic!</strong> Using Vagrant within the Windows
|
||||
Subsystem for Linux is an advanced topic that only experienced Vagrant users
|
||||
who are reasonably comfortable with Windows, WSL, and Linux should approach.
|
||||
</div>
|
||||
|
||||
|
||||
# Installation
|
||||
|
||||
Installation requires WSL, Ubuntu on Windows, and Vagrant. Read on for installation
|
||||
instructions for each item.
|
||||
|
||||
## Windows Subsystem for Linux and Ubuntu on Windows
|
||||
|
||||
First install the Windows Subsystem for Linux, followed by Ubuntu on Windows. This guide
|
||||
from Microsoft walks through the process:
|
||||
|
||||
* https://msdn.microsoft.com/en-us/commandline/wsl/install_guide
|
||||
|
||||
## Vagrant Installation
|
||||
|
||||
Vagrant _must_ be installed within Ubuntu on Windows. Even though the `vagrant.exe`
|
||||
file can be executed from within the WSL, it will not function as expected. To
|
||||
install Vagrant into the WSL, follow these steps:
|
||||
|
||||
* Download the 64-bit Debian package from the downloads page.
|
||||
* Open a `cmd` or `powershell` window
|
||||
* Enter the command: `bash`
|
||||
* Install vagrant: `sudo dpkg -i vagrant_VERSION_x86_64.deb`
|
||||
|
||||
```
|
||||
C:\Users\vagrant> bash
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ sudo dpkg -i vagrant_VERSION_x86_64.deb
|
||||
[sudo] password for vagrant:
|
||||
(Reading database ... 31885 files and directories currently installed.)
|
||||
Preparing to unpack vagrant_VERSION_x86_64.deb ...
|
||||
Unpacking vagrant (1:VERSION) ...
|
||||
Setting up vagrant (1:VERSION) ...
|
||||
vagrant@vagrant-10:/mnt/c/Users/vagrant$ vagrant help
|
||||
Usage: vagrant [options] <command> [<args>]
|
||||
```
|
||||
|
||||
# Vagrant Usage
|
||||
|
||||
Vagrant will detect when it is being run within the WSL and adjust how it
|
||||
locates and executes third party executables. For example, when using the
|
||||
VirtualBox provider Vagrant will interact with VirtualBox installed on
|
||||
the Windows system, not within the WSL. It is important to ensure that
|
||||
any required Windows executable is available within your `PATH` to allow
|
||||
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:
|
||||
|
||||
```
|
||||
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...
|
||||
```
|
||||
|
||||
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.
|
||||
|
||||
## Using Docker
|
||||
|
||||
The docker daemon cannot be run inside the Windows Subsystem for Linux. However,
|
||||
the daemon _can_ be run on Windows and accessed by Vagrant while running in the
|
||||
WSL. Once docker is installed and running on Windows, export the following
|
||||
environment variable to give Vagrant access:
|
||||
|
||||
```
|
||||
$ vagrant@vagrant-10:/mnt/c/Users/vagrant$ export DOCKER_HOST=tcp://127.0.0.1:2375
|
||||
```
|
|
@ -211,6 +211,7 @@
|
|||
<ul class="nav">
|
||||
<li<%= sidebar_current("other-debugging") %>><a href="/docs/other/debugging.html">Debugging</a></li>
|
||||
<li<%= sidebar_current("other-envvars") %>><a href="/docs/other/environmental-variables.html">Environmental Variables</a></li>
|
||||
<li<%= sidebar_current("other-wsl") %>><a href="/docs/other/wsl.html">WSL</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
Loading…
Reference in New Issue