SONiCにdebパッケージを追加する

# はじめに
SONiCはDebian/GNU Linuxをベースに、ホワイトボックススイッチに必要な機能を追加したものです。オープンソースソフトウェアとして提供されていますので、ユーザが必要に応じてソフトウェアをインストールすることができます。本稿では、debパッケージを追加する方法を紹介します。

# 起動後にdebパッケージを追加する
SONiCを起動してログインすれば、PC用のDebian系ディストリビューションと同様に、`sudo apt-get install` を使って様々なパッケージをインストールすることができます。

<details><summary>実行例</summary><div>

```
admin@sonic:~$ sudo apt-get update
Get:1 http://debian-archive.trafficmanager.net/debian buster InRelease [121 kB]
Get:2 http://debian-archive.trafficmanager.net/debian-security buster/updates InRelease [65.4 kB]
Get:3 http://debian-archive.trafficmanager.net/debian buster-backports InRelease [46.7 kB]
Get:4 http://debian-archive.trafficmanager.net/debian buster/contrib amd64 Packages [60.4 kB]
Get:5 http://debian-archive.trafficmanager.net/debian buster/main amd64 Packages
Get:6 http://debian-archive.trafficmanager.net/debian buster/non-free amd64 Packages [107 kB]
Get:7 http://debian-archive.trafficmanager.net/debian-security buster/updates/non-free amd64 Packages [486 B]
Get:8 http://debian-archive.trafficmanager.net/debian-security buster/updates/main amd64 Packages [318 kB]
Get:9 http://debian-archive.trafficmanager.net/debian buster-backports/non-free amd64 Packages [27.2 kB]
Get:10 http://debian-archive.trafficmanager.net/debian buster-backports/main amd64 Packages [391 kB]
Get:11 http://debian-archive.trafficmanager.net/debian buster-backports/contrib amd64 Packages [7,824 B]
Fetched 11.9 MB in 7min 28s (26.5 kB/s)                                        
Reading package lists... Done
admin@sonic:~$ sudo apt-get install -y htop
Reading package lists... Done
Building dependency tree       
Reading state information... Done
Suggested packages:
  lsof strace
The following NEW packages will be installed:
  htop
0 upgraded, 1 newly installed, 0 to remove and 35 not upgraded.
Need to get 92.8 kB of archives.
After this operation, 230 kB of additional disk space will be used.
Get:1 http://debian-archive.trafficmanager.net/debian buster/main amd64 htop amd64 2.2.0-1+b1 [92.8 kB]
Fetched 92.8 kB in 2s (59.9 kB/s)
debconf: delaying package configuration, since apt-utils is not installed
Selecting previously unselected package htop.
(Reading database ... 29799 files and directories currently installed.)
Preparing to unpack .../htop_2.2.0-1+b1_amd64.deb ...
Unpacking htop (2.2.0-1+b1) ...
Setting up htop (2.2.0-1+b1) ...
Processing triggers for mime-support (3.62) ...
admin@sonic:~$ 
```

</div></details>


# インストールイメージにdebパッケージを追加する

自分でSONiCのインストールイメージをビルドするのであれば、`build_debian.sh`の下記部分にパッケージ名を追加してビルドすることで、あらかじめパッケージがインストールされたインストールイメージを作成することができます。

```
## Pre-install the fundamental packages
## Note: gdisk is needed for sgdisk in install.sh
## Note: parted is needed for partprobe in install.sh
## Note: ca-certificates is needed for easy_install
## Note: don't install python-apt by pip, older than Debian repo one
sudo LANG=C DEBIAN_FRONTEND=noninteractive chroot $FILESYSTEM_ROOT apt-get -y install      \
    file                    \
    ifmetric                \
    iproute2                \
    bridge-utils            \
    isc-dhcp-client         \
    sudo                    \
```

# Dockerコンテナにdebパッケージを追加する

SONiCは主要な機能をDockerコンテナの中で動かしています。その機能に関連してコンテナ内でソフトウェアを追加して動かしたいケースもあるかと思いますので、コンテナ(正確にはコンテナを動かすためのDockerイメージ)にパッケージを追加する方法を紹介します。

## 全コンテナに追加

`dockers/docker-base/Dockerfile.j2` の下記部分にパッケージ名を追加します。

```
# Pre-install fundamental packages
RUN apt-get -y install \
    vim-tiny           \
    perl               \
    python             \
    python-pip         \
    rsyslog            \
```

## 特定コンテナに追加

syncd dockerを除くコンテナについては、`dockers`ディレクトリの下にある、パッケージを追加したいDockerコンテナの`Dockerfile.j2` を編集し、全コンテナのときと同じように `apt-get install`でインストールされるパッケージ名のリストに追加します。

SONiCを実行しているときに見えるコンテナ名とビルド時に参照されるディレクトリ名が異なるので、対応表を下記に掲載します。

|コンテナ名             |ファイル                                                              |
|:--------------------|--------------------------------------------------------------------:|
|snmp docker          |`dockers/docker-snmp/Dockerfile.j2`                                  |
|mgmt-framework docker|`dockers/docker-sonic-mgmt-framework/Dockerfile.j2`                  |
|telemetry docker     |`dockers/docker-telemetry/Dockerfile.j2`                             |
|sflow docker         |`dockers/docker-sflow/Dockerfile.j2`                                 |
|radv docker          |`dockers/docker-router-advertiser/Dockerfile.j2`                     |
|lldp docker          |`dockers/docker-lldp/Dockerfile.j2`                                  |
|dhcp_relay docker    |`dockers/docker-dhcp-relay/Dockerfile.j2`                            |
|nat docker           |`dockers/docker-nat/Dockerfile.j2`                                   |
|teamd docker         |`dockers/docker-teamd/Dockerfile.j2`                                  |
|swss docker          |`dockers/docker-orchagent/Dockerfile.j2`                              |
|bgp docker           |`dockers/docker-fpm-frr/Dockerfile.j2` (quaggaやgobgpを使う場合は適宜変更)|
|pmon docker          |`dockers/docker-platform-monitor/Dockerfile.j2`                       |
|database docker      |`dockers/docker-database/Dockerfile.j2`                               |

syncd dockerに追加する場合は`Dockerfile.j2`がターゲットプラットフォームの下にあるのでそれを変更します。(`rules/config`を変更してRPCを利用している場合は`docker-syncd-どれか-rpc`になります)

見ればわかるとは思いますが、いちおうプラットフォームごとのファイルの在り処を示します。

|プラットフォーム |ファイル                                                  |
|:-------------|--------------------------------------------------------:|
|Barefoot      |`platform/barefoot/docker-syncd-bfn/Dockerfile.j2`       |
|Broadcom      |`platform/broadcom/docker-syncd-brcm/Dockerfile.j2`      |
|Cavium        |`platform/cavium/docker-syncd-cavm/Dockerfile.j2`        |
|Centec        |`platform/centec/docker-syncd-centec/Dockerfile.j2`      |
|Centec(ARM64) |`platform/centec-arm64/docker-syncd-centec/Dockerfile.j2`|
|Innovium      |`platform/innovium/docker-syncd-invm/Dockerfile.j2`      |
|Marvell       |`platform/marvell/docker-syncd-mrvl/Dockerfile.j2`       |
|Marvell(ARM64)|`platform/marvell-arm64/docker-syncd-mrvl/Dockerfile.j2` |
|Marvell(ARM)  |`platform/marvell-armhf/docker-syncd-mrvl/Dockerfile.j2` |
|Mellanox      |`platform/mellanox/docker-syncd-mlnx/Dockerfile.j2`      |
|Nephos        |`platform/nephos/docker-syncd-nephos/Dockerfile.j2`      |
|P4            |`platform/p4/docker-sonic-p4/Dockerfile.j2`              |
|VS            |`platform/vs/docker-syncd-vs/Dockerfile.j2`              |

# おわりに
SONiCのカスタマイズには、今回紹介したdebパッケージの追加以外にも、dockerコンテナの追加やソースコードの追加などがあります。機会があれば紹介してみようと思います。