SONiCのビルドオプション解説

# はじめに: SONiCビルドしてますか?

SONiCはホワイトボックススイッチ用のOSです。ホワイトボックススイッチはOSをあとからインストールして動かすネットワーク機器(L3スイッチ)で、OS別売りのショップブランドPCみたいなものです。ホワイトボックススイッチ用のOSには商用・OSS含めていろいろありますが、OSSでいま勢いがあるのはSONiCだけかな? といったような状況です。

SONiCですが、公式やベンダー提供のビルド済みバイナリを使っている方もたくさんいらっしゃると思います。でも、使いたい機能が標準で無効になっていたり、逆に使わない機能なので無効化したい場合には、ソースコードを入手して自前でビルドする必要がでてきます。

がんばりましょう。

# まず一度、ビルドしてみましょう

ビルド環境を整えて、変更せずにビルドできることを一度確認してみましょう。`master`ブランチだとときおりビルドできないことがありますが、いったんそこはおいといて。

[公式の説明](https://github.com/sonic-net/sonic-buildimage/blob/master/README.md)によると、必要なリソースは

- 最低8GBのメモリ
- 300GB以上のディスクスペース
- KVMサポート

とありますが、VS(Virtial Switch)以外だとKVMサポートはたぶん不要です。

公式の説明に書かれてる通り、事前にいくつかのソフトウェアを入れておく必要があります。

- `sudo apt install -y python3-pip`
- `pip3 install --user j2cli`
- [docker](https://docs.docker.com/engine/install/)

でもってビルドします。下記は仮想マシン用ディスクイメージのビルド例になります。

```shell-session
git clone https://github.com/sonic-net/sonic-buildimage
cd sonic-buildimage
make init
make configure PLATFORM=vs
make all
```

BroadcomのスイッチASICを使っている機器であれば`PLATFORM=broadcom`、NVIDIAのであれば`PLATFORM=mellanox`といったふうに`make configure`の後ろに指定します。

SONiCを入れようとしている機器の中身がよくわからない場合は、[Supported Platforms](https://github.com/sonic-net/SONiC/blob/sonic_image_md_update/supported_devices_platforms.md)のページから探してみるといいでしょう。載ってない場合は、おそらくその機器でSONiCは動きません。ハードウェアベンダー側で独自に対応しているケースもありますが、その場合手元でビルドできるかは不明です(バイナリ提供だけかもしれません)。

なお、ビルドするマシンの性能によってビルド時間は前後するのですが、早くても数時間は見ておいたほうがいいでしょう。(参考: とあるXeon E5-2650マシンでbroadcom,mellanox,vsをまとめてビルドして5時間程度)

# ビルドの注意点

`master`ブランチは日々変更が入るのですが、検証不十分でビルドエラーとなることがあります。数日間ビルド失敗が続いて、そのうち修正されてビルドできるようになったりします。身に覚えのないビルドエラーが発生した場合、気長に修正されるのを待ちましょう。

一度ビルドが終わった後`make configure`で別プラットフォームに切り替えると、ビルドが途中で失敗することがあります。たとえばBroadcomスイッチ用にビルドした後、仮想スイッチ(VS)をビルドするようなケースです。`make clean`しても無意味。というか`make clean`が失敗することもあります。これは、公式がCI/CD環境でクリーンビルドしているため、`make configure`での上書き変更や`make clean`でのクリーンアップの検証が不十分なのが理由です。

`make reset`を実行すると完全にきれいになるはずなので、しくじったら`make reset`しましょう。あるいは`git clone`からやりなおしです。

# コマンドラインでの指定いろいろ

## ターゲット指定

`make all`ではなく、ターゲットを明示することでビルド時間の短縮を図ります。

```shell
# Arista EOS用イメージ(sonic-broadcom.swi)の作成をスキップする
make target/sonic-broadcom.bin
```

## ユーザ、パスワード指定

`ps`なんかで見えるので、いろんな人が使うマシンで実行するとバレますが、ファイルにいちいち書かずにお手軽に変更できる方法です。

- `USERNAME=username`
- `PASSWORD=password`

実行例は下記です。

```shell-session
make USERNAME=sonic PASSWORD=soncuser all
```

## その他

ユーザ、パスワードについて書きましたが、これは以降で説明するビルドオプションそのものです。`make`のパラメータに書くことで上書きできます。

# ビルドオプションの記述場所

下記のテキストファイルに

```
オプション変数=パラメータ
```

という形式で記述されています。パラメータは`y`や`n`だったり数値だったり文字列だったりです。`#`から始まる行はコメントです。

- `rules/config`
- `rules/config.user`

前者を直接書き換えてもいいのですが、本家が更新されたときconflictすると扱いが面倒なので、`config.user`に書いて設定を上書きさせるのがいいでしょう。

```Makefile:config.user
# ユーザ名とパスワードを上書きする設定
USERNAME=sonic
PASSEORD=sonicuser

# REST APIを有効化する設定
INCLUDE_RESTAPI=y
```

# ビルドオプション個別解説

実のところ`rules/config`のコメントとして英語で書かれているので、それ読めよで終わっていい感じではあります。下手すると中身全部コピペしたうえで日本語に置き換えて。じゃ芸がないので、自分チョイスで使いそうなものだけピックアップします。

## `SONIC_CONFIG_BUILD_JOBS`と`SONIC_CONFIG_MAKE_JOBS`

なんだか似ていて、どっちがどうなの? と悩んじゃいそうですが。SONiCのビルドは、基本的にたくさんの`deb`パッケージをビルドして、仮想的なルートディレクトリ上にインストールしてディスクイメージ化するという流れになるのですが、

- `SONIC_CONFIG_BUILD_JOBS`は同時にいくつパッケージをビルドするか。(デフォルト: 1)
- `SONIC_CONFIG_MAKE_JOBS`はひとつのパッケージをビルドするのにどれだけ並列化するか。(デフォルト: `nproc`コマンドの実行結果)

というふうな違いになります。コア数とストレージの速度上限次第で効果が変わります。

## `CHANGE_DEFAULT_PASSWORD`

最初にログインした時、パスワード変更を強制するかを指定します。デフォルト: `n`

## `ENABLE_ZTP`

ゼロタッチプロビジョニングを有効にします。デフォルト: `n`

SONiCのゼロタッチプロビジョニングは、SONiCが動いているスイッチがDHCPクライアントとなって、DHCPサーバからIPアドレス等のネットワーク情報以外の設定情報も受け取って自動的に設定完了する技術です。各機器にログインして設定などやる必要がなくなります。CLOSのように同じ設定のスイッチを横にずらっと並べて使うようなケースで威力を発揮します。

## `INSTALL_DEBUG_TOOLS`

デバッグツール(`gdb`等)を組み込みます。デフォルト: `n`

## `SONIC_DEBUGGING_ON`と`SONIC_PROFILING_ON`

最適化を抑止し、デバッグシンボルをつけることでデバッグしやすくするオプション。デフォルト: `n`

なお、デバッグ情報を組み込んで最適化を抑止するとイメージがいるのサイズがとても大きくなります。具体的には2GBを超えます。

## `SONIC_DPKG_CACHE_METHOD`

SONiCのビルドは`deb`パッケージをたくさんビルドしてインストールすると書きましたが、この`deb`パッケージを一度ビルドしたらキャッシュしてビルド時間を短縮することができるオプションです。指定は下記のいずれか。

- `none` キャッシュしない(デフォルト)
- `rwcache` キャッシュされた`deb`があれば使い、なければビルドしてキャッシュに入れる
- `wcache` ビルドしてキャッシュに入れる
- `rcache` キャッシュがあれば使うが、なければ使わないだけ
- `cache` `rwcache`と同じ

## `INCLUDE_SYSTEM_GNMI`

gNMIを有効にします (デフォルト: `n`)

## `INCLUDE_SYSTEM_TELEMETRY`

テレメトリサポートを有効にします (デフォルト: `n`)

## `INCLUDE_MGMT_FRAMEWORK`

マネジメントフレームワークを有効にします (デフォルト: `y`)

標準CLIでしか使わない場合、`n`指定することでイメージサイズとビルド時間を節約できます。

## `INCLUDE_RESTAPI`

OpenConfig準拠のREST APIを有効にします (デフォルト: `n`)

## `INCLUDE_P4RT`

P4Runtimeを有効にします (デフォルト: `n`)

SONiCの本来のCLIとは別に、P4Runtimeによる遠隔制御を可能とします。
なお、読み書きするテーブルはAPPL_DBの中にありますが、もともとの各機能と関係なくSAIのパラメータ相当のテーブルをこしらえてあって`syncd`に流し込むような作りになってるので、P4Runtimeで制御する場合はCLIでの制御を併用すると設定が破綻するのでご注意を。(各種ユーザプロセスとの連動が考慮されてないので、そういうのはP4Runtimeを呼ぶ側の仕事ということになりそうです)

## 他

もしかしたらここを解説したほうがいいのかもしれませんが、

- Kubernets関連
- セキュアブート関連
- バージョン管理関連

などあったりします。だらだら書いてもしかたないので、すみませんが`rules/config`を読んでください。

# まとめ

- `rules/config`にオプションが書かれている
- `rules/config`を直接いじってもいいけど、`rules/config.user`に設定すれば上書きできる

レッツビルド!