SONiC VS版をビルドしてみた。

# TL;DR
こちらの手順でSONiCのVM imageが作れます。
```bash
#!/bin/bash -xe

# pre-install
sudo apt install -y docker-ce
sudo apt install -y python3-pip
sudo pip3 install j2cli

# Ensure the 'overlay' module is loaded on your development system
sudo modprobe overlay

# Enter the source directory
git clone https://github.com/Azure/sonic-buildimage.git
cp ./config.user sonic-buildimage/rules/
cd sonic-buildimage

# (Optional) Checkout a specific branch. By default, it uses master branch. For example, to checkout the branch 201911, use "git checkout 201911"

# Check this list !!!
# https://sonic-build.azurewebsites.net/ui/sonic/pipelines/142/builds?branchName=master
# https://sonic-build.azurewebsites.net/ui/sonic/pipelines/142/builds?branchName=202205
git checkout b0c9013ea1

# Execute make init once after cloning the repo, or after fetching remote repo with submodule updates
make init

# Execute make configure once to configure ASIC
make configure PLATFORM=vs

# Build SONiC image with 4 jobs in parallel.
# Note: You can set this higher, but 4 is a good number for most cases and is well-tested.
make SONIC_BUILD_JOBS=4 target/sonic-vs.img.gz
```
ただ、折角なので少し解説していきたいと思います。
お付き合いよろしくお願いします。

# SONiC OS image build
### SONiC OS image色々
SONiCのOSビルド方法はこちらにまとまっています。

https://github.com/sonic-net/sonic-buildimage

SONiCは動作させたいプラットフォーム（各ベンダーのswtich/ASIC、またはソフトウェア）に合わせて、OSをビルドする必要があります。
本エントリではターゲットプラットフォームをVS版として、KVM上で動くVMイメージを作ってみます。
VS版以外にもdocker版（コンテナイメージ）もあり、実際のSONiC開発ではこちらの方がより手軽かもしれません。


### SONiC VS版のOS image buildの（心の）準備
公式にビルド方法が詳しく書いてあるので、その通りに進めればそれほど難しい所は少ないと思います。
ただし、ビルドにはそれなりのマシンパワーが必要になります。
[公式レポに説明](https://github.com/sonic-net/sonic-buildimage#hardware)によると下記のようなHW requirementの記載があり、特にdiskの空き容量には注意が必要かと思います。

> Hardware
> Any server can be a build image server as long as it has:
> - Multiple cores to increase build speed
> - Plenty of RAM (less than 8 GiB is likely to cause issues)
> - 300G of free disk space
> - KVM Virtualization Support.

また、ビルドマシンのスペックにも依りますが、一回ビルドするのに3時間程度掛かります。
つまり、一日に何度も細かくビルドを試す、ということは現状難しい点に注意です。
（なお私は、とあるSONiCビルドが中々通らず、一週間ほど苦しみました。時間が掛かるビルドはハマると大変ですね。。）
ビルド環境はOSはUbuntu 20.05が推奨されており、本エントリもこの環境でビルドしました。
参考までに、私の使ったビルド環境はCPU 24core/Memory 64GB/Disk 2TBとなります。

### SONiC VS版のOS image build
それではSONiCビルドをstep by stepで見ていきましょう。
今回のビルド対象はSONiC VS版の`202205`ブランチの`b0c9013ea1` (比較的新しいコミットID)になります。

### pre-install
まずは必要なパッケージをインストールしていきます。
SONiCのビルド自体は全てdocker内で実行されるため、dockerが必要になります。
```bash
$ sudo apt install docker-ce
$ sudo apt install -y python3-pip
$ sudo pip3 install j2cli
```

### git clone
SONiC本体のソースコードを取得します。
```bash
$ git clone https://github.com/Azure/sonic-buildimage.git
```
ここで、`config.user`というファイルを作成しておくと便利です。
SONiCはデフォルトユーザ名とパスワードが`admin/YourPaSsWoRd`なのですが、このパスワードが打ちにくく、打つたびに指がつるので、変えておくと楽です。
```bash
$ cat config.user
DEFAULT_PASSWORD = pass
$ cp ./config.user sonic-buildimage/rules/
```
https://github.com/sonic-net/SONiC/blob/master/doc/SONiC-User-Manual.md#2-login-username--password

### コミットID変更
SONiCは頻繁にコミットされており、実際のビルドパイプライン状況（下記）から活発な開発状況が見えてきます。
コミットの中にはビルドが`failed`なものもあるため、下記のResultが`succeeded`なものを狙ってビルドを進めていきます。

https://sonic-build.azurewebsites.net/ui/sonic/pipelines/142/builds?branchName=202205

今回は`b0c9013ea1`を使っていきます。
```bash
$ cd sonic-buildimage
$ git checkout b0c9013ea1
```

### ビルド
さて、これでビルドの準備が整いました。
実際にビルドをしてみましょう。っと言ってもコマンドを打つだけです。
ただし、ビルドにはかなり時間がかかる（特に最後のコマンドは時間がかかる）ので気長に待ちましょう。
```bash
$ make init
$ make configure PLATFORM=vs
$ make SONIC_BUILD_JOBS=4 target/sonic-vs.img.gz
```

参考までに私の環境でのビルド状況を共有します。
1\. 掛かった時間: 約3時間
```bash
time ./sonic-build-202205-vs-kvm.sh
...
./sonic-build-202205-vs-kvm.sh  280.29s user 125.36s system 3% cpu 3:08:49.53 total
```
2\. Disk使用率: 約200GB
ビルド処理内でdocker pullや各種アプリケーションのインストールが走るため、ビルド中にdisk容量を大きく消費している様子が分かります。
![out.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46231/7cef4d84-0fb8-4edc-1bff-ecb901197aa3.png)

### 生成されたOS imageの確認
SONiC VS版（VMイメージ）が確かに生成されていることが確認できます。
```bash
$ ls -lh sonic-buildimage/target/sonic-vs.img.gz
-rwxr-xr-x 1 cafenero cafenero 1003M Dec 11 02:02 sonic-buildimage/target/sonic-vs.img.gz
```

# 動かしてみる
せっかく作ったSONiC OS imageなので、実際にKVM上で動かしてみましょう。

### KVSセットアップ
KVMのセットアップ、およびVMの起動・ログインの以下のように進めます。
- 必要なパッケージのインストール
- OSイメージの配置
- XMLファイルを指定してVM起動
- telnetでログイン

各詳細については省略します。

```bash
#!/bin/bash

# install kvm packages
sudo apt update
sudo apt install -y cpu-checker
kvm-ok
sudo apt install -y qemu-kvm libvirt-daemon-system libvirt-clients bridge-utils virtinst virt-manager
sudo systemctl is-active libvirtd
sudo usermod -aG libvirt $USER
sudo usermod -aG kvm $USER
echo "================================"
echo "If you need, "
echo "newgrp libvirt"
echo "newgrp kvm"
echo "================================"

# copy your image here
sudo cp ../sonic-build/sonic-buildimage/target/sonic-vs.img.gz /var/lib/libvirt/images/
sudo gunzip -k /var/lib/libvirt/images/sonic-vs.img.gz

## create qemu
# reference xml
# wget https://raw.githubusercontent.com/sonic-net/sonic-buildimage/master/platform/vs/sonic.xml
wget https://raw.githubusercontent.com/cafenero/running-sonic/main/sonic-runing-on-kvm/sonic.xml
sudo virsh create sonic.xml

## check qmemu list
sudo virsh list --all

## login
echo "================================"
echo "SONiC login:"
echo "admin/pass"
echo "telnet localhost 7000"
echo "================================"
```

実際にVMを起動し、SONiCにログインした様子がこちらのスクリーンショットになります。
ビルド時に指定してユーザ名とパスワード(admin/pass)を用いてログインできることが確認できました。
また、`show version`で確認すると、指定したコミットIDになっていることやビルドしたアカウント（自分のアカウントだ！）が表示されていることが確認できました。
![Screenshot 2022-12-11 at 10.58.03 copy.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/46231/000eb0c9-fa53-b099-3e39-20bb2fe64ce3.png)

このように、手元の環境でSONiCをビルドし、動作確認まで行うことができました。

# 参考
- https://github.com/sonic-net/sonic-buildimage
- https://github.com/sonic-net/SONiC
- https://sonic-build.azurewebsites.net/ui/sonic/pipelines
- https://sonic-build.azurewebsites.net/ui/sonic/pipelines/142/builds?branchName=202205
- https://github.com/ebiken/nsdevnotes/tree/main/sonic
- https://github.com/cafenero/running-sonic