简体   繁体   中英

running powershell inside VS Code from docker on WSL2

I am trying to use the "remote container"-functionality of VS Code, but parts of the build-script needs to run as a windows-process.

So the setup gets kind of complicated:

windows 10 -> WSL2 -> docker -> VS Code (server) -> bash -> powershell

Without docker, this works great (windows running WSL2 starting a windows-executable), through some kind of magic. Inside docker, some of the magic is not present...

I figured out that I need to run docker in privileged mode to be able to mount /proc/sys/fs/binfmt_misc where I find the WSLInterop -file, but this is apparently not enough.

What other magic do I need in order to get WSL2 to execute a windows process?

root@ea31e9627f7a:/# mount -t binfmt_misc binfmt_misc /proc/sys/fs/binfmt_misc/
root@ea31e9627f7a:/# cat /proc/sys/fs/binfmt_misc/WSLInterop 
enabled
interpreter /tools/init
flags: F
offset 0
magic 4d5a
root@ea31e9627f7a:/# powershell.exe
root@ea31e9627f7a:/# which powershell.exe
/opt/windows/System32/WindowsPowerShell/v1.0//powershell.exe
root@ea31e9627f7a:/# 

The reference to interpreter /tools/init is some kind of magic I havent figured out. In WSL2 I have:

$ mount | grep /init
tools on /init type 9p (ro,relatime,dirsync,aname=tools;fmask=022,loose,access=client,trans=fd,rfd=6,wfd=6)

But I have not been able to figure out how to replicate this inside docker (or if it will matter)

My development environment is here: https://github.com/rolfrander/smarthome

(I guess one could argue that this setup is just too complicated, but the experience of developing inside a docker container is really nice)

Ok, I think I figured this out. In WSL /init acts as a bridge between linux and windows. $WSL_INTEROP points to a socket in /run/WSL for communicating with init. Privileged mode is not needed.

compare

$ docker run --rm -i -t --volume /mnt/c/Windows/:/opt/windows alpine sh
/ # /opt/windows/System32/WindowsPowerShell/v1.0/powershell.exe -c '$PSVersionTable'
/ #

with

$ docker run --rm -i -t --volume /mnt/c/Windows/:/opt/windows --volume /run/WSL:/run/WSL --env WSL_INTEROP=$WSL_INTEROP alpine sh
/ # /opt/windows/System32/WindowsPowerShell/v1.0/powershell.exe -c '$PSVersionTable'

Name                           Value
----                           -----
PSVersion                      5.1.19041.906
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.906
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


/ #

(Running windows commands directly from the docker command line doesn't work, not sure why)

Don't do this unless you understand the implications. This basically breaks a hole in the container enabling processes inside the container to speak directly with the windows host.

Also note that the current directory of the process starting is set to the windows equivalent of the current linux directory, and if the command is started from some directory which isn't available (or if WSL can't determine the correct windows directory), the command will fail with "Invalid argument".

Now, for the VSCode part, it seems I need to first start VSCode remote in WSL, then start the remote container from there, this enables docker mounts to refer to linux directories and not windows directories. I've had succes with a devcontainer.json like this:

{
    "build": {"dockerfile": "Dockerfile"},
    "extensions": ["ms-vscode.cpptools"],
    "mounts": [
        "source=/mnt/c/Windows,target=/opt/windows,type=bind,ro=true",
        "source=/run/WSL/,target=/run/WSL,type=bind,ro=true"
    ],
    "remoteEnv": {
        "PATH": "${containerEnv:PATH}:/opt/windows/System32/WindowsPowerShell/v1.0/"
    }
}

Regarding WSL_INTEROP, see this discussion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM