【検索して】WSL1とWSL2の共存【なぞっただけ】

# 概要
本稿では以下のことが出来るまでを概説する。
基本的に人の投稿を検索してなぞっただけです。

- メインOSはWindows 10
- WSL1でUbuntu20を調子良く使っていた
- Seleniumの案件でLinuxでPython、Chrome、Seleniumを入れたくなった
- WSL1を壊さずにWSL2をインストールした
- WSL1のUbuntu20はそのまま、WSL2の方に"Ubuntu"をインストールした
- WSL2でGUIプログラムを動かせるようにVcXsrvの設定をいじった

なお、このあと以下のことを行うが、それは次回書く予定である。

- WSL2にLinux用のChromeをインストールした
- さらにSeleniumとChromeDriverをインストールした
- Seleniumが無事に動いてハッピー

# 対象読者
- WSL1を使っているが、WSL1の環境を壊さずにWSL2をインストールし、Xまで設定したい
- WSL2をいきなり使う人にもまあまあ参考になるかも？

# 前書き
浮世の義理でWindowsをメインOSとして使用しているが、Linuxも使いたいので、WSLでUbuntu 20を使っている。
WSLの最新バージョンはWSL2だが、愛用しているのはWSL1だ。
WSL1環境を構築するのにずいぶん手間取ったし、いろいろハックしてもう手放せなくなっているので、できればこのまま運用したい。
WSL2は2019年の出始めの頃にインストールしようとして苦労したので触っていなかった。

そんなある日、Seleniumを使ってChromeによるWeb検索、ファイル取得を自動化する用事があった。
WSL1を使ってみたが、ブラウザーが入っていない。
これも、インストールしようとしてなぜかうまくいかなかったし、どうせWindowsのブラウザーが使えるので放っておいていた。
個人的な話が多くてスミマセン。

そこで、WSL1を壊さずにWSL2をインストールし、そっちにも別のUbuntuをインストールしてみることにした。
快調に動いているWSL1のUbuntu 20を壊したくなかったのである。
じつはWSL1とWSL2で同じLinuxを共用してもいいのかもしれない。これも良く知らない。スミマセン。
でも、同様のことをしたい人多いんじゃないだろうか。
そう思って書く。

# BIOSから仮想化を有効にする
WSL2を動かすには、まずPCのBIOSに入って仮想化技術を有効化する必要がある。
ぼくは「ASUSTek Intel H370 搭載 マザーボード LGA1151 対応 PRIME H370M-PLUS/CSM 【 mATX 】 統合マネージメントシステム搭載」（Amazon販売ページより）というマザーボードを使っている。
リブートしてASUSというロゴが表示している間にDELキーを連打して、BIOS画面に行く。

以下の記事を参考にした。

https://variable.jp/2020/06/06/wsl1%E3%81%8B%E3%82%89wsl2%E3%81%B8%E3%81%AE%E6%9B%B4%E6%96%B0/

同記事に以下のオプションの両方を有効化するとあったが、ぼくの環境では下の方しかなかった。
それだけで大丈夫っぽい。
- Advanced > CPU Configuration >  Execute Disable Bit > [Enabled]
- Advanced > CPU Configuration >  Intel(R) VirtualizationTechnology > [Enabled]***＜＝こっちを有効化しました。***

# WSL2のインストール
以下、だいたい以下の記事を参考にした。

https://www.tekwind.co.jp/ASU/faq/entry_134.php

## PowerShellコマンドラインを管理者として開く
まず、PowerShellのコマンドラインを開く。
Windowsボタン（田ボタン）をクリックして検索窓にpowersとタイプすると最上位に表示される。
（powerだけだとPowerPointが最上位）
ここで右クリックして「管理者として実行」を選択（盾のアイコン）。
チャララーンと警告されるが「はい」を選択。

## 仮想化マシンの有効化
PowerShellコンソールで、以下のコマンドを入力する。

```PowerShell
> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
```

「正常に完了しました。」と言われたら先に進む。

**（2021-07-02追記）** dism.exeを使うのであればPowerShellではなくコマンドプロンプトで十分で、PowerShellを使うなら```Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -All -NoRestart```でいけるというコメントをいただきました。なるほどー

## WSL2 Linux カーネルの更新
以下のページにアクセスからインストーラーを取得する。

https://docs.microsoft.com/ja-jp/windows/wsl/wsl2-kernel

インストーラーはwsl_update_x64.msiという名前。ダウンロードして実行する。
ペンギンの絵が書いたウィンドウが表示されて、うまくいったヨ的なことを言われたら先に進む。

## WSL2を既定のバージョンとして設定
ここで、ぼくのようにWSL1をすでに使っている場合は、やはりPowerShellコンソールから以下のコマンドを使ってWSLの既定のバージョンを2に設定する。

```PowerShellコマンド画面
> wsl --set-default-version 2
```

「WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください」と言われたら完了。
リンク先のページは英語。読んでない。

これを行ってからWindows StoreでLinuxをインストールすると、WSL2側にインストールされる。

## WSLとインストールされているLinuxをリスト表示

PowerShellコンソールで以下のコマンドを使う。

```PowerShellコマンド画面
> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         1
```

上では、WSL1にUbuntu 20.04がインストールされていて、現在停止中であると分かる。

# WSL2に"Ubuntu"をインストール
WSL2が準備できたので、Linuxをインストールする。
ぼくはWSL1にUbuntu20をインストールしているので、それをあえて壊さず、別のUbuntuをインストールした。

Microsoft Storeには、次の３つのUbuntuがある。

- "Ubuntu"
- "Ubuntu 20.04 LTS"＜＝WSL1で使用中
- "Ubuntu 18.04 LTS"

最初Ubuntu 18.04をインストールしてテストしたが、Python3のバージョンが古くて、Seleniumがうまく使えなかったので、あらためて"Ubuntu"に挑戦した。
"Ubuntu"は、最新のUbuntuが入るもので（？）現在は20.04.02 LTSが入るみたいだ。
つまり、WSL1で使用中のと同じバージョンになるが、それでも名前で区別された別のUbuntuとしてWindowsに認識されているっぽい？

田ボタンをクリックし、StoreとタイプするとMicrosoft Storeが起動するので、Ubuntuで検索した。
「Ubuntu」「Ubuntu 18」「Ubuntu 20」の３つが表示されたので、"Ubuntu"をインストールした。

ここではどのWSLにインストールしますか的なことを***聞かれない***。
上記の通り、「wsl --set-default-version 2」というコマンドが効いているから、WSL2にインストールされる。
PowerShellコンソールで、あらためてリスト表示してみる。

```PowerShellコマンド画面
> wsl --list --verbose
  NAME            STATE           VERSION
* Ubuntu-20.04    Stopped         1
  Ubuntu          Installing      2
```

WSL1にUbuntu20がインストールされていて休止中、WSL2にUbuntuが***インストール中***ということが分かる。
まだインストールは終了していない。
***ここでユーザー名とパスワードを考えておいたほうがいい。***

## Ubuntuを削除するには
ここでは行わなかったが、もしインストールしたUbuntuを削除するには、Windowsの機能である「プログラムの追加と削除」を使う。
田ボタンの付近の検索ボックスで"puro"と入力すると「⚙プログラムの追加と削除」というのが表示されるのでクリック起動する。
で、「アプリと機能」の下の検索ボックスに"Ubu"と入力すると、インストールしたUbuntuが一覧表示されるので、アンインストールしたいUbuntuをクリックする。
「アンインストール」ボタンを押すとアンインストールされる。

## なぜかインストール出来ないとき
何回もインストールしたり、削除したりしていると、たまにMicrosoft Storeが異常動作して、確実に削除したUbuntuであっても「この製品はすでに取得されています」または「すでにインストールされています」と表示されるだけで、「インストール」ボタンをクリックしても何も起きないことがある。
これはハマった。

よくわからないのだが、以下の方法でしのげるようだ。

- Microsoft Storeの右横の「・・・」アイコンをクリックする
- 「マイ ライブラリ」をクリックする
- たぶん目的のUbuntuが表示されていて（取得は終わっており）たぶん「インストール」ボタンが表示されている
- ここで「インストール」ボタンを押す

これでインストールされるようだ。
なぜかはよく知らない。
（この情報はざっと検索したところ見当たらなかったのでお値打ちだよ！

## 初起動と初期設定
ここで田ボタンをクリックして「ubu」とタイプすると、Ubuntu20とUbuntuの２つのアイコンが検索される。
Ubuntuの方をクリックする。
コンソールが表示されてbashが起動する。

するとユーザー名とパスワードを聞かれるので好きなのをタイプ入力すると、ワーといろいろ出てきてインストールが終わる。
（ひどくてスミマセン）

Ubuntuのバージョン確認はbashコンソールから「cat /etc/lsb-release」が簡単だ。

```bashコンソール
$ cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=20.04
DISTRIB_CODENAME=focal
DISTRIB_DESCRIPTION="Ubuntu 20.04.2 LTS"
```
## この時点で出来ること（2021-07-01追記)
ここまででも、コンソールからCUIで使うだけなら使える。
Emacsも、インストールして「emacs -nw」で（ノー・ウィンドウの略であろう）と入力すれば使える。

WSL1とWSL2の「共存」という意味だが、完全な共存であって、WSL1のコンソールを起動するとWSL1のコンソールが、WSL2のコンソールを起動するとWSL2のコンソールが、2つ同時に別々に使える。前者から起動するとWSL1のホームディレクトリが、後者から起動するとWSL2のホームディレクトリが見え、両者は別のディレクトリである。

本文書ではまだインストールしていないが、もしインストールすると、前者でEmacsを起動するとWSL1にインストールしたEmacsが、後者でEmacsを起動すると別々のEmacsが起動する。バージョン、設定を別々にすることも出来る。2つ同時に起動して別々のウィンドウ間でコピペも出来る。

くだくだしくなったが、要するに、2つのWSLを独立して使用でき、特に切り替えとかそういう作業は必要ない。

## シンボリックリンクを使うと便利（2021-07-12追記)
WSLを使っていて不便なのが、WSLとWindowsのファイルの受け渡しであるが、これはWSL側からWindowsにシンボリックリンクを張ると便利である。
```/mnt/c/``` というディレクトリが、Windows上での ```C:\``` になる。

```
$ cd
$ ln -s /mnt/c/Users/user_name/Desktop Desktop
```

これでWSL側の~/Desktopから、Windowsのデスクトップを参照できる。
ぼくは他にもDownloadsフォルダーやDropboxにもリンクを張っている。

# XサーバーをインストールするとGUIが使える
ということで、上記の通り、ここまででも、コンソールからCUIで使うだけなら使える。
しかし、ぼくの目的はブラウザーを起動してSeleniumを使うことであるし、EmacsもGUIモードで使いたいので、Xをインストールする。

ここでちょっと豆知識なのだが、Xサーバーという言葉について。
サーバーというと世間とか同僚に何かを供する（serveする）ものというイメージだが、Xサーバーというのはそういうノリではなくて、Linuxのカーネルとやり取りして（自分のために）GUIアプリを起動できるようにするプログラムのことらしい。
ここがちょっと分かりづらいのであえて贅言を弄した。

## VcXsrvの設定を変える
ここでちょっとハマったのだが、先に結論を言うと、WSL1の時とはちょっとVcXsrvの設定を変える必要がある。
以下の記事が参考になる。

https://minettyo.com/entry/wsl_xwindow_settings

以下引用。

> WSL１ではホストと同一のイーサネット用 IP アドレスを共有していましたが、WSL２では Hyper-V の上で仮想化された完全な Linux が独立して動きますので、IP アドレスも仮想化されて独立した物となります。

> 従って、WSL１では localhost (127.0.0.1) はホストと同じコンピュータを指して居ましたが、WSL２ではホストとは別の仮想化されたコンピュータとなります。

> つまり、Linux の DISPLAY 環境変数の値は、WSL１では localhost で問題無かったのが、WSL２ではホストの IP アドレスを指定する必用が有ります。これは、WSL１で「export  DISPLAY=:0」の指定をしていた人は、WSL２では「export DISPLAY="ホストのIPアドレス”:0」への変更が必用になるという事です。

なるほど。。
ということで、以下の作業が必要であった。

> *1. Windows ホスト側での起動時に、アクセス コントロールを無効化する*
> XLaunch 起動時に、3画面目で「Disable access control」にチェックを入れます。
この指定は、localhost (127.0.0.1) 以外からの全てのアクセスを許可する事になります (一般的な Unix 環境での「xhost +」と同一) 。

ぼくの場合、WSL1をインストールしたときに行ったVcXsrvの設定によって、Xのプログラムを起動するとタスクバーにVcSrvのアイコンが出てくるようになっていた。
（どうやって設定したかは忘れました。。ゴメンネ。。

これを以下のように設定した。

1. WSL1でEmacsなどのGUIアプリを起動すると、タスクバーの中にXっぽいアイコンが入る。右クリックしてAbout...を選択すると、About "VcXsrv"と表示されたら、それがVcXsrvである。
2. このアイコンを右クリックしてExit...を選択し、ExitをクリックしてVcXsrvを終了する
3. 田ボタンを押して、テキストボックスに「XLaunch」とタイプしてEnterし、XLaunchを起動する
4. 次へ >>を2回クリックして画面を遷移する
5. 3画面目で「Disable access control」がアンチェックだったのでチェックを入れる。
6. 次へをクリックする
7. Save Configurationをクリックすると、config.xlaunchというファイルを保存する場所を聞かれる（ぼくはデフォルトを受け入れてドキュメントにした
8. 完了をクリックする

これでVcXsrvが再起動し、WSL2でGUIアプリが使える準備が出来ている。

ただし、一度VcXsrvをシャットダウンしてしまうと、「Disable access control」が無効になってしまうので、XLaunchを起動するショートカットに、上で保存したconfig.xlaunchを渡す。以下の設定を行う。

1. ぼくの場合C:\ProgramData\Microsoft\Windows\Start Menu\Programs\VcXsrvに、XLaunch.lnkというショートカットファイルが入っていた
2. 右クリックして「プロパティ」を選択する
3. 「リンク先」を以下のように変える　"C:\Program Files\VcXsrv\xlaunch.exe" -run config.xlaunch
4. さっき作ったconfig.xlaunchをxlaunch.exeと同じ場所（ぼくの場合はC:\Program Files\VcXsrv）に移動する

XLaunch.lnk、xlaunch.exeの場所は人によって違うかもしれないので、その場合は各自読み替えてください。
なお、Windowsでのファイルの検索は、everything.exeというフリーウェアが速いのでオススメ。

## UbuntuのXの設定
Ubuntuのコンソールで、Xの設定を続けていく。
以下の記事を参考にした。

https://astherier.com/blog/2020/08/run-gui-apps-on-wsl2/

まず、WSL2のbashからGUI関連のソフトをインストールする。

```bashコンソール
$ sudo apt install libgl1-mesa-dev xorg-dev
```

sudoはスーパー・ユーザーDOみたいな感じで、コマンド（上の場合はapt）を管理者権限で実行する。
パスワードを求められるが、最初に決めた自分用のパスワードで構わない。
何か聞かれたらすべてy（YES）と答える。

次にホームディレクトリにあるドットファイルの1つ、.profileを編集してDISPLAY変数を設定する。
ぼくはEmacsをインストールして「emacs -nw」でしのいだが、viが使える人はviでも構わないし、どちらも使いたくなければnanoでも構わない。
nanoはどんな初心者でもなんとか使えるエディターなの。

.profileの末尾に以下の1行を追加して保存終了する。

```.profile
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0.0
```

これがWSL1では必要なかった設定だ。
WSL1ではlocalhostで構わなかったのがWSL2では動的なIPアドレスになったので？それに対応するものらしい？（良く知らない？
設定が終わったらsourceコマンドで.profileを読み込む。

```bash
$ source .profile
```

テスト用にサンプルアプリをインストールする。

```bash
$ sudo apt install x11-apps
```

質問にyと答える。

インストールが終わったらxeyesを起動してみる。

```bash
$ xeyes&
```

&はバックグラウンド実行という意味で、xeyesが起動しても連続でCUI操作が出来る。

ここでvcXsrvが起動するのだが、最初の1回はWindows Defenderファイアウォールでブロックされましたと言われる。
「アクセスを許可する」をクリックする。

すると、なんか２つの目を表示するアプリが起動し、マウスカーソルを追従して目線が動く。
アハハ。
これでXが使えた。
xeyesのクローズは普通に閉じるボタンで出来る。

*

以上、Xが起動するまで書いた。
現状は、EmacsとChromeとSeleniumなどを入れ、快調に使っている。
WSL2に移行しても生きていける気がする（この記事もWSL2で書いている）。
でも、まあWSL1はいざというときのためにしばらく生かしておこうと思う。

***（この項終わり）***