VSCodeのRemote SSHでNixOS on WSL2に接続する

TL;DR

  1. flake.nixnixos-vscode-serverを追加
  2. Windows側の$HOME/.vscode/extensions/.../wslDaemon.js内の.push("sh","-c".push("sh","-l","-c"に一括置換

すでにWSLにNixOSがインストールされており、また、Nix Flakesで環境構築済みである前提で話を進めます。ちなみに、NixOS on WSLには以下を使うと楽でした。ありがたい。 github.com

nixos-vscode-server を追加

VSCodeのRemoteSSHでNixOS on WSLに接続を試みても失敗します。どのようなエラーメッセージが出ていたか、手元でメモしておくのを忘れました。

解消のため、以下を追加しましょう。

github.com

手順などは上記のReadme通りです。

VSCodeのwslDaemon.jsを書き換えてNixOSの環境変数が通るようにする

しかし、以下のエラーメッセージを受け取ります。

[2024-03-16 21:57:55.394] Extension version: 0.86.0
[2024-03-16 21:57:55.395] L10N bundle: file:///c%3A/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/l10n/bundle.l10n.ja.json
[2024-03-16 21:57:55.407] authorityHierarchy: wsl+NixOS
[2024-03-16 21:57:55.407] WSL extension activating for a local WSL instance
[2024-03-16 21:57:55.415] Resolving wsl+NixOS, resolveAttempt: 1
[2024-03-16 21:57:55.415] WSL feature installed: true (dll path)
[2024-03-16 21:57:55.415] NodeExecServer run: C:\Windows\System32\wsl.exe --list --verbose
[2024-03-16 21:57:55.575] 5 distros found
[2024-03-16 21:57:55.577] Starting VS Code Server inside WSL (wsl2)
[2024-03-16 21:57:55.577] Windows build: 19045. Multi distro support: available. WSL path support: enabled
[2024-03-16 21:57:55.577] Scriptless setup: false
[2024-03-16 21:57:55.577] No shell environment set or found for current distro.
[2024-03-16 21:57:55.829] WSL daemon log file: 
[2024-03-16 21:57:55.833] Probing if server is already installed: if [ -d ~/.vscode-server/bin/863d2581ecda6849923a2118d93a088b0745d9d6 ]; then printf 'install-found '; fi; if [ -f /etc/alpine-release ]; then printf alpine-; fi; uname -m
[2024-03-16 21:57:55.833] NodeExecServer run: C:\Windows\System32\wsl.exe -d NixOS -e sh -c if [ -d ~/.vscode-server/bin/863d2581ecda6849923a2118d93a088b0745d9d6 ]; then printf 'install-found '; fi; if [ -f /etc/alpine-release ]; then printf alpine-; fi; uname -m
[2024-03-16 21:57:57.677] Unable to detect if server is already installed: Error: Failed to probe if server is already installed: code: Failed to probe if server is already installed: code: 127, <3>WSL (37858) ERROR: CreateProcessParseCommon:748: getpwnam(nixos) failed 5
[2024-03-16 21:57:57.677] /nix/store/032wiarm65zp3bh9ak3dz2sqcr3n8g70-bash-interactive-5.2p26/bin/sh: line 1: uname: command not found
[2024-03-16 21:57:57.677] , 
[2024-03-16 21:57:57.678] NodeExecServer run: C:\Windows\System32\wsl.exe -d NixOS sh -c '"$VSCODE_WSL_EXT_LOCATION/scripts/wslServer.sh" 863d2581ecda6849923a2118d93a088b0745d9d6 stable code-server .vscode-server --host=127.0.0.1 --port=0 --connection-token=3310471485-982298393-618761714-2787472227 --use-host-proxy --without-browser-env-var --disable-websocket-compression --accept-server-license-terms --telemetry-level=all'
[2024-03-16 21:57:57.920] Setting up server environment: Looking for /root/.vscode-server/server-env-setup. Not found.
[2024-03-16 21:57:57.920] WSL version:  NixOS
[2024-03-16 21:57:57.921] <3>WSL (37861) ERROR: CreateProcessParseCommon:748: getpwnam(nixos) failed 5
[2024-03-16 21:57:57.921] /mnt/c/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/scripts/wslServer.sh: line 28: uname: command not found
[2024-03-16 21:57:57.921] /mnt/c/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/scripts/wslServer.sh: line 32: dirname: command not found
[2024-03-16 21:57:57.921] /mnt/c/Users/USERNAME/.vscode/extensions/ms-vscode-remote.remote-wsl-0.86.0/scripts/wslServer.sh: line 32: /wslDownload.sh: No such file or directory
[2024-03-16 21:57:57.921] スタートアップの問題のヘルプについては、https://code.visualstudio.com/docs/remote/troubleshooting#_wsl-tips にアクセスしてください
[2024-03-16 21:58:08.179] Download in background is enabled

パスが見つからないと言われます。それを解消するためにnixos-vscode-serverを導入したつもりでしたが、こまった。

https://nixos.wiki/wiki/Visual_Studio_Code#Remote_WSL ここを読むと、なんだかうまく参照できていなさそうなことがわかります。

Similar to SSH hosts, both nix-vscode-server and nix-ld solution allows a VSCode Windows client to connect a NixOS-WSL host. However, by default the VSCode Windows client uses wsl.exe --exec to start the code server, which bypasses NixOS environment variables required by nix-ld, resulting in failures.

とりあえず、当該の章にあるように、$HOME\.vscode\extensions\...\wslDaemon.js内の.push("sh","-c".push("sh","-l","-c"に置換します。力技です。2箇所ありました。

そして再度Remote SSHを試すと、無事に繋がりました。

NixOSでバイナリファイルを参照するときのつらみをあまり理解できていないので、また今度読みます。 blog.thalheim.io

NixOS on WSLを立ち上げると、rootユーザーでログインしてしまう

ところで、NixOS on WSLだとrootユーザーでログインしてしまう問題があります。以下のようなエラーメッセージを毎回受け取ることになっています。

<3>WSL (10563) ERROR: CreateProcessParseCommon:748: getpwnam(nixos) failed 5

discourse.nixos.org

ググると上記のディスカッションを発見しましたが、これだ!という解決策は見当たりませんでした。この件については、ログインするたびに su <username>で切り替えることで対応することにしました。