はじめてのToaster@YoctoPJ: Windows11からWSL2/Docker環境上のToasterに触ってみる

# はじめに
以前Qiitaで書いた「[前回Qiita記事: WSL2とDockerを用いた、Windows環境におけるYocto環境構築の入門](https://qiita.com/namanamaallegg/items/9bfea34212586ba7b677)」で構築したYocto環境ですが、本環境でToaster(※1)を使えるのか？と考えるようになりました。
※1: [Toaster](https://www.yoctoproject.org/software-item/toaster/): YoctoのBitbake作業の支援を目的としたWebインタフェースで、Bitbake前後の作業をWebブラウザベースのGUIでできるようになる
Toaster環境を構築することで下記のメリットがあると考えています。

- はじめてYocto/Bitbakeを触る人がとっかかりやすい(Yoctoの迷宮のように入り組んだmetaディレクトリやbuild/tmp/workディレクトリの階層構造に頭を抱えずに済む!!)
- ビルド後イメージの情報(内包パッケージやOSSライセンスなど)をGUIで確認でき、Yoctoを知らない人に組み込みLinux情報を提供しやすい(サプライチェーン間での情報共有に役立つイメージ!!)

# 本記事読者のターゲット
 - Windows環境でToasterを用いたYocto環境を構築してみたい人
 - WindowsからDockerまでの仮想環境のパケット転送(ポートフォワーディング)について知らない人/試してみたい人

# [入門:ポートフォワーディングを知らない人向け] 仮想環境のネットワークの概要説明
タイトルのDocker/WSL2/Windows11へのToaster環境構築方法と直接は関係話ですので、構築方法を知りたいという方は飛ばしてください。

ここでは、今回Windows11からDocker内のToasterへアクセスするにあたり、必要なネットワーク知識を少し解説します。
コンテナ環境のコンセプトは「ユーザランドの隔離」であり、コンテナの中からは他コンテナやホスト上の情報はわかりません。例えば特定のコンテナ内で`ps`コマンドを打っても、コンテナ外で動いているプロセスは見れません。

コンテナのソフトウェア間の分離は主にNamespace(名前空間)で実現されており、ネットワークはその中のNetwork Namespace(ネットワーク名前空間)で分離されています。ホスト環境で`localhost:8000`を使っているときにコンテナ環境上で`localhost:8000`が使えるのはそのためです。

そのため、今回は各種環境間のネットワークの特定ポート間をつなげる(特定ポートに届いたパケットを他のポートへ転送する)作業、すなわちポートフォワーディングが必要になります。

# 今回構築する環境の概要
WSL2でLinux GUI環境を実現する[WSLg](https://github.com/microsoft/wslg)があるそうですが、動作が重いという話もあるので、今回はポートフォワーディングを用いてWindows11側にToasterの画面を表示する方法を試してみます。
前回記事と同様のハードウェア/Dockerイメージ環境に対して、下記の流れで作業を進めていきます。

   1. Docker環境上でToasterを立ち上げ
   1. WSL2⇔Dockerのポートフォワーディングを設定
   1. Windows11⇔WSL2のポートフォワーディングを設定
   1. 操作感の検証

# 1. Docker環境上でToaster立ち上げ
下記の流れでToasterのインストールと起動をします。
 
```bash
pip3 install --user -r /home/work/poky/bitbake/toaster-requirements.txt
source oe-init-build-env -b build
source toaster start
```

Toasterの起動には5分弱かかるので、コーヒーでも飲んで待ちましょう。正常に立ち上がると下記のような出力がでます。

```bash:実行出力末尾の抜粋
Updating distros 100%
2022-02-03 20:54:02,205 INFO Fetching machine information
Updating machines 100%
2022-02-03 20:54:13,677 INFO Fetching recipe information
Updating recipes 100%
Starting webserver...
Toaster development webserver started at http://localhost:8000

You can now run 'bitbake <target>' on the command line and monitor your build in Toaster.
You can also use a Toaster project to configure and run a build.
```

`source toaster start`だとデフォルトで`8000`ポートになっているみたいです。
今回はポートフォワーディング対象にミスって`8080`ポートを指定してしまっていたので、Tosterを一度落として、ポートを変更して立ち上げ直します。
その際、出力で赤文字でエラーが生じされますが、気にしなくて大丈夫です。

```bash
source toaster stop
source toaster start webport=127.0.0.1:8080
```

その後、`curl http://localhost:8080`を実行して何も出力されなければ成功です。


# 2. WSL2⇔Dockerのポートフォワーディング設定

作業した後にdocker-composeでやればよかったと後悔しましたが、Dockerfileべた書きでひとまず作業を進めていきます。まずはポートフォワーディングできているかを確認しやすいようにDockerfileに下記を追加し、今回使うポートを公開設定します。

````
EXPOSE 8080
```

その後、`docker build`した後に下記でWSL⇔Docker間のポートフォワーディングしてコンテナを起動します。

```bash
docker run -itd -p 8081:8080 --name="container-yocto" docker-yocto
```
 <img width="800" alt="02_01_PORTS_Check.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/cebcbf4e-dd0a-30aa-a8e4-8afc3d6bd822.png">

動作確認としては下記になります。

 - ポートフォワーディングが確認できているかの確認方法: `docker ps`コマンド出力で対象コンテナのPORTS項目をチェック

```bash
docker ps
CONTAINER ID   IMAGE                COMMAND       CREATED        STATUS        PORTS                                       NAMES
7e9d5f15ee37   build-yocto:latest   "/bin/bash"   13 hours ago   Up 13 hours   0.0.0.0:9000->8080/tcp, :::9000->8080/tcp   container-yocto
```
 - `curl`を用いてToasterへアクセスし、レスポンスが返ってくればOK

```bash
curl http://localhost:9000
curl: (56) Recv failure: Connection reset by peer
```
Toasterを`localhost`ではなく、`0.0.0.0`に変更して解決できました。

```bash
source toaster start webport=0.0.0.0:8080
```

これでホスト環境で`curl http://localhost:9000`すれば、何も出てこなくなるので接続完了です。ただまだWSL2で今回はGUI設定していないので、Toaster操作はできない状況です。

※ `0.0.0.0`にするのセキュリティ的にどうかちょっと懸念あります...自身のPCなら良いですが、会社への導入でこの設定はちょっと厳しそうと思っています。
ここら辺はもう少し勉強して、今後ちゃんとやっていきたいです(い良いやり方があったら更新させてもらいます)。

# 3. Windows11⇔WSL2のポートフォワーディング設定
WSL2の場合、ホスト環境から`localhost`を直接たたきにいけるみたいです(結構衝撃的でした)。
ポートフォワーディング設定は不要だったみたいです。
任意のブラウザのアドレスバーに`http://localhost:9000`でToasterの画面が表示されました。

![02_02_Toaster_Home.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/2bfac00e-3c0a-859b-8374-be5872af3e56.png)

# 4. 操作感検証(感想)
少し触ってみます。
ホーム画面の右上のNew Projectで`Test`プロジェクトを作成すると、`local.conf`と`bblayers.conf`相当の情報がでてきました。

 - 組み込み対象のターゲットボード(あるいはqemu)種類 | 標準:qemux86
 - 作成する(bitbakeでビルドする)Linuxディストリビューションの種類 | 標準:poky
 - ビルド対象のレイヤー | 標準:openembedded-core,mata-poky,meta-yocto-bsp
 
 <img width="600" alt="02_03_Toaster_Project.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/925da18a-f42f-2a47-dbd5-d2dc1d3f34b1.png">


Machine内の"Viwe compatible distors"を押すと、使用可能なターゲットボードレイヤー(BSPレイヤー)の一覧が出てきます。使いたいBSPをadd layerしてProject画面に戻ると、Layerに追加されています。通常のCUI操作の場合、この作業は必要なBSPレイヤーを`clone`して、bblayers.confを修正してと結構面倒だったので、ボタン一つでできるのは正直衝撃的でした。これはすごい...。
一覧はおそらくPokyの公式リポジトリにマージ済みのものが表示されているのですが、ものすごい出ますし検索も簡単にできるので思った以上に使いやすいです。

 <img width="800" alt="02_03_Toaster_Machine.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/63ed4422-7812-560b-b66f-af18872422fc.png">

 <img width="300" alt="02_04_Toaster_AddMachine.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/9b23945d-3fbb-644d-1d25-a9fbe81c60aa.png">


ディストリビューション側も試してみましたみましたが、`meta-debian`や`meta-ros2`もあったのでこれは思っていた以上に実用的です。
また、Most built recipes使えば、追加したいパッケージ関連のmetaレイヤがたくさんありました。AGL(Automotive Grade Linux)やAWS、他にもdocker関連のレイヤーなど無数にレイヤが準備されていました。

 <img width="800" alt="02_05_Toaster_RecipeAGL.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/303b8d24-6e7b-2d10-61a7-3d0d869b6760.png">

 <img width="800" alt="02_05_Toaster_Recipeaws.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2490986/363a2331-f408-815c-4bf9-de63dc7c33a8.png">

Toaster単にBitbake周りの操作をGUI化しただけだろうと思っていたのですが、かなり自動化されている機能が多く正直かなり感動しました。OSSで公開されているレイヤーをそのまま使うとかほんの少しだけ編集して使う際にToasterの力が発揮されそうです。
とはいってもYoctoを触るときは細かい独自レシピやパッチ追加が主だと思うので、そういう作業はなんだかんだCUIの方がやりやすいのかな？と思います。

# 課題

試しに`core-image-minimal`のビルドを試してみたのですが、`Build queued: This build is waiting for the build directory to become available`になってしまい、ビルド作業が進みませんでした。
また、追加したレイヤーがdocker内の`poky`ディレクトリに追加されているか直接みてみましたが増えていませんでした。
これは単にToasterでBuildボタンを押した際に必要レイヤーを引っ張ってからビルドするという仕様ならよいのですが、Toaster上でadd layerを押した時点で追加されるはずの仕様だとしたら、これもまた問題です。

ToasterからDocker上のBitbakeに指示を投げられていなさそうなので、今後の課題とさせてください。