WSL2の導入とGUI環境の構築とsshfsしたものもgnome-openしたい!! [Ubuntu18.04/20.04]

2020年春の大型アップデート以降、Linuxがまともに使える(正確にはLinuxカーネルを載せる)ようになるWindows Subsystem for Linux 2が正式リリースされます。wsl2のインストール方法のほか、wslとGUIの導入方法がやや異なるので紹介していきます。

なお、本記事は2020年春のアップデート以前に、Windows Insider Programに参加し、Windows2004をインストールしてwsl2を導入できるのでそれを基に書かれたものです。**ただし変わっていないので問題ないです**。（一応補足しておくと、2021年の大型アップデート以降?ならpowershellで `wsl --install`と打つだけでインストールできるようになるはずなのでそのときには状況は変わります。Insiderプログラムには降りてきてるので春にはさらに楽になるかもしれないです。既にだいぶ楽ですが。）

2020/6/18
Build 20150以降、 `wsl.exe -–install` でwslのインストールが、 `wsl --update` でwsl2で使用するLinuxカーネルのアップデートができるようになりました。また、CUDAの公式サポートも始まりました。GPUが使える時代になりましたね…。
https://blogs.windows.com/windowsexperience/2020/06/17/announcing-windows-10-insider-preview-build-20150/

2020/10/29
Build 20246以降， `wsl --install` で設定がすべて終わるようになりました。べんりです。Insider Program未参加者は春まで待ちましょう！

2020/11/13
筆者の都合でUbuntu20.04でも試してみましたが、そのまま使えました。ご活用ください。

# 目次
- [wsl2のインストール](#wsl2のインストール)
- [wsl2でGUIを使う](#wsl2でGUIを使う)
- [wsl2にもChromeをインストールする](#wsl2にもChromeをインストールする)
- [guiで日本語フォントを使えるようにする](#guiで日本語フォントを使えるようにする)
- [gnome-openを使えるようにする](#gnome-openを使えるようにする)
- [wsl配下のディレクトリをネットワークドライブのように扱う](#wsl配下のディレクトリをネットワークドライブのように扱う)
- [sshfsを使ってマウントする](#sshfsを使ってマウントする)
- [sshfsしたものもgnome-openできるようにする](#sshfsしたものもgnome-openできるようにする)
- [windows側からwslのgitを使う（おまけ）](#windows側からwslのgitを使う（おまけ）)

WSL2でsshfsしたものをエクスプローラーなどのWindowsのプログラムを用いて開く方法はあまり紹介されていないのでぜひご参照ください。

また、GUI関係は2021年ごろに正式に搭載され、もっと楽になりそうです。それまではがんばりましょう。

#WSL2のインストール
参考: https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-install
ここに書いてある通りです。また、`wsl -–install` などが使えるようになったら最初にwsl入れるというようなまどろっこしいことはしなくていいかもしれないですね。

## Windows Insider Programへの参加とWindowsのバージョンアップ(~2020年春のアップデートまで)
設定->更新とセキュリティ-> Windows Insider Program から参加できます。Insiderの設定はスローでよいです。

登録ができたら、設定->更新とセキュリティ-> Windows Update からアップデートができるはずなのでします。

## WSLのインストール
注: Build 20246以降であれば `wsl -–install`でいけます。2020/10/29にWindows Insider ProgramのDev channel(旧Fast Ring)に登録している人はできるようになりました！

まず、"仮想マシン プラットフォーム" のオプション コンポーネントを有効にし、wslが有効であることを確認します。これはGUIからもできますが、PowerShellからでもできます。管理者権限が必要。

```powershell:PowerShell
dism.exe /online /enable-feature /featurename:Microsoft-Windows-Subsystem-Linux /all /norestart
dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

終わったらコンピュータを再起動します。

## Linuxカーネル更新プログラムパッケージをダウンロードする
[公式サイト](https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#step-4---download-the-linux-kernel-update-package)から最新のLinuxカーネル更新パッケージをダウンロードします。ARM64パッケージの場合にはARM64用のパッケージをいれることに注意。同じページにあります。

参考:

- https://docs.microsoft.com/ja-jp/windows/wsl/install-win10#install-your-linux-distribution-of-choice
- https://docs.microsoft.com/ja-jp/windows/wsl/initialize-distro

## WSL2のインストール
wslをバージョン2にアップデートします。
起動済みのインスタンスを触りたい場合にはいったん終了してください。

ディストリビューションを設定するには

```powershell:PowerShell
wsl --set-version <Distro> 2
```
を実行します。`<Distro>`はUbuntuならUbuntu、Ubuntu18.04ならそれなど。
このときにLinuxカーネルを更新しろ、 https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel を見ろ、と言われるかもしれませんが、そしたらこのページの通り、 https://wslstorestorage.blob.core.windows.net/wslblob/wsl_update_x64.msi をダウンロードして実行すればOKです。実行して終わったら再び上記のコマンドをたたいてください。

最後に、デフォルトのwslを2にしたければ

```powershell:PowerShell
wsl --set-default-version 2
```
を叩いて終わりです。

## Linuxディストリビューションのインストール
もしもLinuxディストリビューションを入れていなければいれます。Microsoft Storeから好きなものをいれます。その後起動し、ユーザー登録を済ませます。パスワードはsudoに必要なので忘れないようにしてください。

#WSL2でGUIを使う
以降はUbuntu 18.04/20.04を想定します。また、デスクトップ環境を作るというよりはwsl内のChromeやwslで実行したプログラムに起因するGUIの表示などのためという用途のものになります。

いろいろなページに書いてありますが、VcXsrvをダウンロードして使えばよいです。また、これまたいろいろなページに書いてありますがwslと異なって、VcXsrvを立ち上げるときにコマンドラインオプションをつけてやる必要、ファイアウォールに気を付ける必要、`export DISPLAY` の書き方に気を付ける必要があります。

参考

- https://github.com/microsoft/WSL/issues/4106
  - これが大元の議論。以下はそれを利用した説明
- https://qiita.com/baibai25/items/5841b0592727893d960f
- https://odaryo.hatenablog.com/entry/2020/01/08/114846

## Ubuntu側でのGUIの導入

```bash
 sudo apt install libgl1-mesa-dev xorg-dev
```

これで最低限はできるはずです。いろいろなGUI環境があると思うので自由に選んで下さい。

## Windows側の設定
### X Serverの導入
https://sourceforge.net/projects/vcxsrv/ からVcXsrvをダウンロードします。チェックはそのままでよいのでインストールします。

### X Serverの起動
VcXsrvをダウンロードして起動します。基本的にはそのままで大丈夫ですが、"Additional parameters for VcXsrv"に `-ac` を記述する必要があります。

(参考: その他の設定)

- Select display settings: Multiple Display
- Select how to start clients: Start no client
- Extra settings: デフォ+最後の欄に -ac を追加。

ただし、自身の環境ではOpenGLのバージョンが1.4であり、これより新しいバージョンが必要な場合にはNative openglというような設定のチェックを外し、Disable access controlにチェック、さらに

```bash:~/.bashrc
unset LIBGL_ALWAYS_INDIRECT
```
などして`LIBGL_ALWAYS_INDIRECT`変数を消す必要があります。

参考: https://superuser.com/questions/1487555/how-to-troubleshoot-opengl-on-ubuntu-under-windows-10-wsl

### ファイアウォールの設定
VcXsrvの初回起動時にファイアウォールを聞かれたらパブリック側を解除しておきましょう。し損ねたら「セキュリティで強化されたWindows Defender ファイアウォール」から「Windows Defender ファイアウォールのプロパティ->パブリック プロファイル->保護されているネットワーク接続: カスタマイズ」からWSLを外します。

##`~/.bashrc`の設定
`~/.bashrc`でDISPLAY変数の設定をしないといけないのはwslと同様ですが、バグによりlocalhostではだめで、WSLのIPアドレスを入れてやる必要があります。`export DISPLAY=:0`というwslの書き方はだめです。

```bash
$ export DISPLAY=:0
$ GUI apps command
Error: Can't open display: :0
```
たぶんこうなります。

自力で頑張るのであれば、PowerShellから `ipconfig` で `イーサネット アダプター vEthernet (WSL):`を探し、そのIPv4アドレス(aaa.bbb.ccc.dddとおきます)をコピーし、

```bash
export DISPLAY=aaa.bbb.ccc.ddd:0.0
```
すればOKです。ここで、0.0はDisplay番号ですが、VcXsrvのアイコンにカーソルをかざしたときに`(hoge):0.0`などとあるこの番号に対応させます。まれに1.0などということもあるかと思いますが、そのときは1.0にします。

また、この番号はwslのインスタンスを再起動するたびに代わってしまうので、

```bash:~/.bashrc
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0.0
```
を`~/.bashrc`に記述する方法が提案されています。


##検証
これで動くはずです。有名なテストなら、

```bash
sudo apt install x11-apps
```
をして

```bash
xeyes
```
が動けばOKです。

ここまでくれば下記に示した[wsl2にもChromeをインストールする](#wsl2にもChromeをインストールする)のようにするとChromeも開けます。実用的にはChromeでテストしてもいいかもしれません。

##GUIのポイント

1. UbuntuにGUI環境を入れる
2. VcXsrvを入れる
3. VcXsrvの起動時に-acオプションを忘れない
4. ファイアウォールの設定は大丈夫か気にする
5. `export DISPLAY=:0`というwslの書き方はだめ。ipアドレスを指定した書き方にする。
6. もしもOpenGLのバージョンが合わないならVcXsrvの起動時の設定でnative openglというような設定のチェックを外し、Disable access controlにチェック、さらに`unset LIBGL_ALWAYS_INDIRECT`などし`LIBGL_ALWAYS_INDIRECT`変数を削除する。

## OpenGL のバージョンについて
デフォルトのOpenGLはバージョンがとても古いです。これが原因で開けない場合の解決方法も紹介しています。
[WSL(2)上でMuJoCoを動かす(GUIも)](https://qiita.com/momomo_rimoto/items/2841f1f15d364c2377a1#gui%E3%81%A7%E6%8F%8F%E7%94%BB%E3%81%99%E3%82%8B)
こちらも併せてご覧ください。

#WSL2にもChromeをインストールする
なにかと便利なので。やることは公開鍵の登録とリポジトリの追加、そして `apt install`です。

```bash
sudo apt install wget
sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> 
/etc/apt/sources.list.d/google-chrome.list'
sudo wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -
sudo apt update
sudo apt install google-chrome-stable
```

これによって

```bash
google-chrome
```
でChromeも開けます。お疲れ様でした。

参考: https://qiita.com/develop/items/350f5487b4825d716d9d

## おまけ: アップデート方法

```bash
sudo apt update
sudo apt --only-upgrade install google-chrome-stable
```

#GUIで日本語フォントを使えるようにする
[wsl2でGUIを使う](#wsl2でGUIを使う)の状態ではChromeを導入しても日本語が表示されません。これはデフォルトでは日本語フォントが入っていないためです。これを解決するには主に2つの方法があります。

1. 日本語フォントをダウンロードする
2. Windows側のフォントを利用する

ここではWindows側のフォントを利用する方法を記載します。やりかたはいくつかあります。

1つめは、Windows側のフォントからシンボリックリンクをはる方法です。

```bash
sudo ln -s /mnt/c/Windows/Fonts /usr/share/fonts/windows
sudo fc-cache -fv
```

参考: https://nakomii.hatenablog.com/entry/wsl_ubuntu

2つ目は、フォントの参照先を教えてあげる方法です。デフォルトでは`/etc/fonts/local.conf`はないので作ってあげます。`/etc/fonts/fonts.conf`は編集してはいけません。

```bash
sudo vim /etc/fonts/local.conf

###内容###
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
    <dir>/mnt/c/Windows/Fonts</dir>
</fontconfig>
##########
```

参考: https://www.atmarkit.co.jp/ait/articles/1812/27/news033.html


#gnome-openを使えるようにする
Windows Subsystem for Linux 2 ではWindows側からLinux側のファイルを `\\wsl$\(ディストリビューション名)` でアクセスできますし、デフォルトではLinux側からWindows側も `/mnt/c` などでアクセスできます。

これと PowerShell の機能であって拡張子に紐づけられたアプリ・ソフトを実行する `Invoke-Item` を利用して Ubuntu の `gnome-open` と同じことをします。

## 書き方
これを `~/.bashrc` に書きました。

```bash:~/.bashrc
alias gnome-open="powershell.exe Invoke-Item"
```
`powershell.exe` にはデフォルトではパスがwsl上で通っていると思います。powershell.exeの引数にコマンドを書けばそれが実行できるのでこう書けます。
ただしこれだけだとwslでマウントしたものは開けない可能性があります。例えばsshfsでrootユーザー以外でマウントするとallow_userができないからです。これはwslのユーザーとwindows側のユーザーが異なるからです。解決策は下記参照ください。

#WSL配下のディレクトリをネットワークドライブのように扱う
エクスプローラで`\\wsl$`にアクセスするとwsl側のファイルを見ることができます。例えばUbuntu20.04を入れた場合、`\\wsl$Ubuntu-20.04\home\(username)`がUbuntu20.04におけるホームディレクトリになります。

#sshfsを使ってマウントする
## sshfs導入
2019年末に、wsl2でsshfsが使えるようになったようです。

```bash
sudo apt install sshfs
```
してやればsshfsできます！

これで端末からはアクセスできますが、Windows標準のエクスプローラー (explorer.exe) を用いて表示することはできません（アクセス許可がないと怒られます）。

なお、

```bash
$ sudo apt install sshfs
[sudo] password for morimoto:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Package sshfs is not available, but is referred to by another package.
This may mean that the package is missing, has been obsoleted, or
is only available from another source

E: Package 'sshfs' has no installation candidate
```

となった場合、`sudo apt update`や`sudo apt upgrade`をしてください。

#sshfsしたものもgnome-openできるようにする
そこで、 `/etc/fuse.conf` を書き換え、管理者以外がallow_otherオプションを用いて自分以外のユーザーからのアクセスを許可するようにします。

GitHubのissue: https://github.com/Microsoft/WSL/issues/4172

デフォルトでは次のようになっています。

```bash:/etc/fuse.conf
# /etc/fuse.conf - Configuration file for Filesystem in Userspace (FUSE)

# Set the maximum number of FUSE mounts allowed to non-root users.
# The default is 1000.
#mount_max = 1000

# Allow non-root users to specify the allow_other or allow_root mount options.
#user_allow_other
```

この部分のうち、 `user_allow_other` のコメントアウトを外します。

```bash:/etc/fuse.conf
# Allow non-root users to specify the allow_other or allow_root mount options.
user_allow_other
```

やっていることは管理者以外がマウントさせたときに他のユーザーからのアクセスを許容することです。

さらに、sshfsする際に `allow_other ` オプションを追加します。

```bash
sshfs -o allow_user test@test:/target /path/to/mount
```

これでエクスプローラーで開けるようになりました。

#Windows側からwslのgitを使う（おまけ）
[Windows10からWSL 2のgitを使う](https://qiita.com/momomo_rimoto/items/5a113dba3a6d0978a906)

別の記事を書いています。けっこうややこしくてStack Overflowでも議論されがちです。よければご覧ください。