VSCodeがWSL上で起動しなくなった

VSCodeをアップグレードしてWSL上で起動しようと思ったら

$ code .
/mnt/c/Program Files/Microsoft VS Code/bin/code: 61: /mnt/c/Program Files/Microsoft VS Code/Code.exe: Exec format error

といったエラーが表示されて起動しなくなりました。

ググったところでsystemdを有効にしていると問題が発生するようで、githubに以下の解決法が載ってました。

まずWSL上で以下のコマンドを実行します。

$ sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf'

その後、WSLを終了させて再起動するとVSCodeが起動できるようになりました。

PS > wsl --shutdown

参考:[WSL2][systemd][interop] Unable to Execute Windows Binary when systemd enabled #8843

Hyper-V上のUbuntuにLIS(Linux Integration Services)をインストールする。

UbuntuをHyper-Vで実行していると遅いなと感じる場合はMicrosoftが提供するLinux Integration Services(LIS)をインストールすると改善する可能性があります。

最初に、/etc/initramfs-tools/modules に次の行を追加します。

$ sudo vi /etc/initramfs-tools/modules
hv_vmbus   # 追加
hv_storvsc # 追加
hv_blkvsc  # 追加
hv_netvsc  # 追加

次のコマンドを実行して modules ファイルを再初期化し、仮想ツールをインストールしてマシンを再起動します。

$ sudo apt install linux-virtual linux-cloud-tools-virtual linux-tools-virtual
$ sudo update-initramfs -u
$ sudo reboot

再起動されると、LISがシステムに登録されます。 インストールされているかを確認するには、ターミナルで lsmod を実行し、hid_hyperv、hv_netvsc、hv_utils、hv_storvc、hv_vmbus が存在する場合、LISのインストールは成功しています。

Docker for Windows を WSLで使う

Docker for Windowsをインストールする

まずは、Docker for Windowsをインストールします。
インストールが終わったら、画面右下のシステムトレイにあるDockerアイコンから設定画面を開きます。

下記項目にチェックを入れて、TLSなしでデーモンに接続できるようにします。
これにより、ローカルのWSLインスタンスが、Docker for Windows内で実行されているDockerデーモンに接続できるようになります。 デーモンはlocalhostにのみバインドされているため、ネットワーク上の他のマシンは接続できません。

## Dockerのインストール

Docker公式HPに記載のあるとおりDockerをインストールします。

$ sudo apt update
$ sudo apt install \
    apt-transport-https \
    ca-certificates \
    curl \
    gnupg-agent \
    software-properties-common
$ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
$ sudo apt-key fingerprint 0EBFCD88
$ sudo add-apt-repository \
   deb [arch=amd64] https://download.docker.com/linux/ubuntu \
   $(lsb_release -cs) \
   stable
$ sudo apt update
$ sudo apt install docker-ce docker-ce-cli containerd.io

docker-composeもインストールします。

$ sudo curl -L https://github.com/docker/compose/releases/download/1.25.0/docker-compose-`uname -s`-`uname -m` -o /usr/local/bin/docker-compose
$ sudo chmod +x /usr/local/bin/docker-compose

sudoしなくてもdockerコマンドを実行できるようにdockerグループにユーザーを追加します。

$ sudo usermod -aG docker $USER

Docker for Windowsに接続するために以下の設定を.bashrcに追加します。

$ echo export DOCKER_HOST=tcp://localhost:2375 >> ~/.bashrc && source ~/.bashrc 

dockerが動くようになっていることを確認します。

$ docker info
$ docker-compose --version

ボリュームマウントのための設定

WSL上ではドライブは /mnt/d にマウントされるのに対して、Docker for Windowsでは内部で /d にマウントされているため、そのままで空のボリュームをマウントしてしまいます。

この対策として、/etc/wsl.conf に root=/ の設定を追加することで /mnt ではなく / にマウントされるようになります。

$ vi /etc/wsl.conf
[automount]
root = /
options = metadata,umask=22,fmask=11

設定した後、一旦ログアウト/ログインするか、以下のコマンドをコマンドプロンプトで実行してWSLを再起動すると / に各ドライブがマウントされるようになります。

C:\> net stop LxssManager
LxssManager サービスを停止中です.
LxssManager サービスは正常に停止されました。
C:\> net start LxssManager
LxssManager サービスを開始します.
LxssManager サービスは正常に開始されました。 

また、別の方法として、/mnt/d を /d にマウントする方法があります。

$ sudo mkdir /d
$ sudo mount --bind /mnt/d /d

ただし、この方法だと.bashrcに以下のようにコマンドを追加しておく必要があります。

$ echo sudo mount --bind /mnt/c /c >> ~/.bashrc && source ~/.bashrc

$ # パスワードなしでマウント出来るようにしたい場合は以下の設定を追加する
$ sudo visudo
$ username ALL=(root) NOPASSWD: /bin/mount

Windows10(WSL)にHomebrewを入れる

WSLには開発用ツールが入っていませんので、まずはbuild-essentialをインストールします(あとでもいいかも?)。

$ sudo apt install build-essential

Homebrewの公式HPにも記載のある次のコマンドを実行します。

$ sh -c "$(curl -fsSL https://raw.githubusercontent.com/Linuxbrew/install/master/install.sh)"

次の変数を~/.profileに追加します。

export HOMEBREW_PREFIX="/home/linuxbrew/.linuxbrew"
export HOMEBREW_CELLAR="/home/linuxbrew/.linuxbrew/Cellar"
export HOMEBREW_REPOSITORY="/home/linuxbrew/.linuxbrew/Homebrew"
export PATH="/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:$PATH"
export MANPATH="/home/linuxbrew/.linuxbrew/share/man:$MANPATH"
export INFOPATH="/home/linuxbrew/.linuxbrew/share/info:$INFOPATH"