diff --git a/lib/vagrant/errors.rb b/lib/vagrant/errors.rb index 3be2aae84..95fae400d 100644 --- a/lib/vagrant/errors.rb +++ b/lib/vagrant/errors.rb @@ -947,5 +947,9 @@ module Vagrant class WSLVirtualBoxWindowsAccessError < VagrantError error_key(:wsl_virtualbox_windows_access) end + + class WSLRootFsNotFoundError < VagrantError + error_key(:wsl_rootfs_not_found_error) + end end end diff --git a/lib/vagrant/util/platform.rb b/lib/vagrant/util/platform.rb index 5ecb01220..0402b6b00 100644 --- a/lib/vagrant/util/platform.rb +++ b/lib/vagrant/util/platform.rb @@ -282,27 +282,6 @@ module Vagrant return @_platform end - def linux_distro - return @_linux_distro if defined?(@_linux_distro) - - @_linux_distro = nil - - if linux? - # A simplest way to get the Linux distribution name. - result = Subprocess.execute( - "python", - "-c", - "import platform;print(platform.linux_distribution()[0].split(' ')[0])" - ) - - if result.exit_code.zero? - @_linux_distro = result.stdout.chomp - end - end - - @_linux_distro - end - # Determine if given path is within the WSL rootfs. Returns # true if within the subsystem, or false if outside the subsystem. # @@ -321,17 +300,33 @@ module Vagrant @_wsl_rootfs = nil if wsl? - # Handle WSL installation from Microsoft Store. - @_wsl_rootfs = PowerShell.execute_cmd('(Get-ChildItem "HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss" -Recurse | ForEach-Object { Get-ItemProperty $_.pspath } | Where-Object { $_.PackageFamilyName -eq ($(get-appxpackage).PackageFamilyName | findstr ' + linux_distro + ') }).BasePath') + PowerShell.execute_cmd('(Get-ChildItem HKCU:\Software\Microsoft\Windows\CurrentVersion\Lxss | ForEach-Object {Get-ItemProperty $_.PSPath}).BasePath').split(" ").each do |path| + # Lowercase the drive letter, skip the next symbol (which is a + # colon from a Windows path) and convert path to UNIX style. + path = "/mnt/" + path[0, 1].downcase + path[2..-1].tr('\\', '/') + "/rootfs" + + begin + fs = Dir.open(path) + rescue Errno::EACCES + # Current WSL instance doesn't have an access to its mount from + # within itself despite all others are available. That's the + # hacky way we're using to determine current instance. + @_wsl_rootfs = path + # You can create and simultaneously run multiple WSL instances, + # comment out the "break", run this script within each one and + # it'll return only single value. + break + else + fs.close + end + end + + if @_wsl_rootfs.nil? + raise Vagrant::Errors::WSLRootFsNotFoundError + end end - if @_wsl_rootfs.nil? - # Looks like WSL has been installed via "lxrun /install" which is deprecated. - @_wsl_rootfs = wsl_windows_appdata_local + '\\lxss' - else - # The path has been found in the registry, so append the directory with FS. - @_wsl_rootfs += '\\rootfs' - end + @_wsl_rootfs end # Convert a WSL path to the local Windows path. This is useful diff --git a/templates/locales/en.yml b/templates/locales/en.yml index aefee43aa..63295a30a 100644 --- a/templates/locales/en.yml +++ b/templates/locales/en.yml @@ -1629,6 +1629,10 @@ en: Linux, please refer to the Vagrant documentation: https://www.vagrantup.com/docs/other/wsl.html + + wsl_rootfs_not_found_error: |- + Vagrant is unable to determine WSL instance it is currently in. If you see this + error then your WSL installation is incorrect. #------------------------------------------------------------------------------- # Translations for config validation errors #-------------------------------------------------------------------------------