Raspberry Pi 4 + Ubuntu 18.04 (arm64) + Docker + FOSSology

*この記事は、[OpenChain Japan WG Advent Calendar 2019](https://qiita.com/advent-calendar/2019/openchainjapanswg) の [12/24公開記事](https://qiita.com/TakashiNinjouji/items/04316e62ab056bce1572)の番外編について、Raspberry Pi 4 (4GB) + Ubuntu 18.04 (arm64) で改めてやり直し、補筆したものです*

#概要
- Raspberry Pi 4 に Ubuntu 18.04 (arm64) の環境を構築し、そこの Docker 上で [FOSSology](https://github.com/fossology/fossology) を動かす。
  - 実行させるまでの手順は、通常よく知られているもので問題なかった。
    -  参考として docker hub にイメージをあげた。Raspberry Pi 4 に Ubuntu 18.04 (arm64) と docker を導入済みで動作を試してみたい方はどうぞ ： [taknin/fossology-arm64](https://hub.docker.com/r/taknin/fossology-arm64)
 - 使い込みたい場合はチューニングなど検討されたし。

# 実施環境
* Ubuntu Server 18.04 (arm64)
* Raspberry Pi 4 Model B, 4GB (以下、"RPi4")
* microSDHC 64GB (Toshiba M203, THN-M203K0640, UHS-I, CLASS 10. 以下、"microSD")
* Mac機 (機種を晒すまでのものではないので... 以下、"母艦") 

備考
- RPi4 は有線で LAN に、USB でキーボードとマウスを、HDMI でモニターに接続した。インストール後は、有線LANのみを残し、母艦からSSHを介して作業した。
- microSDの選定は用途に応じて留意することもあるだろうが、今回は動作検証なので手元にあったものを流用した。


# 手順
## microSD にインストールイメージを用意する

CANONICAL が提供する Ubuntu公式サイトの [Ubuntu 18.04.4 LTS (Bionic Beaver)](http://cdimage.ubuntu.com/releases/18.04/release/) から(\*1)、RPi4のarm64イメージを入手する(\*2)。

- ※1: 18.04 を選定した理由は、本件とは別に Windows Subsystem for Linux (WSL) の Ubuntu 18.04 LTS の docker 上で FOSSology を利用していることから、build 及び実行に問題が起きた時に対処しやすいと考えたため。
- ※2: 僕は誤って Raspberry Pi 3 用のイメージを利用したことを告白する。続くコマンド実施例はその名残。Rapsberry Pi 4 用の本来のイメージは"ubuntu-18.04.4-preinstalled-server-arm64+raspi4.img.xz" である。なお、20.04 のイメージであれば ("[Install Ubuntu Server on a Raspberry Pi 2, 3 or 4] (https://ubuntu.com/download/raspberry-pi)" からも入手可能である。

イメージを microSD に書き込むのは、母艦 で microSD を exFAT でフォーマットし、[手引きのページ](https://ubuntu.com/tutorials/create-an-ubuntu-image-for-a-raspberry-pi-on-windows#1-overview)で紹介されている通りに実施すればよい。僕は dd コマンドを利用したのだけど、僕の母艦にインストール済みの dd コマンドは status をサポートしていないため、進捗を確認するには "sudo killall -INFO dd" を利用した。


```
$ diskutil list
(microSDのカードスロットが/dev/disk1だったので...)
$ diskutil unmountDisk /dev/disk1
$ sudo sh -c 'gunzip -c ~/Downloads/ubuntu-18.04.4-preinstalled-server-arm64+raspi3.img.xz | sudo dd of=/dev/disk1 bs=32m'
```

## Ubuntu のインストールから初回起動まで
イメージを書き込んだ microSD を RPi4 に挿して起動させる。
初回起動時にログイン(ubuntu/ubuntu)後に、パスワードを再設定する。


### [寄り道] IPアドレスを割り当てる

以下、Windows Subsystem for Linux (WSL) 以外で ubunbu 18.04 を使うのが初めてだったので自分の備忘録。

初回起動では dhcp が有効になっており、とくに設定せずに SSH 経由で接続できる。再起動を繰り返したり常用の可能性があるので、IP アドレスを割り当てた。

ネットワーク周りは cloud-init で設定されるため、読み込みが後になりそうな名前を付けた自分用の設定ファイルを用意する。これは /etc/netplan ディレクトリ配下の yaml ファイルをスキャンして、後に読み出される値で上書きされることからの措置。

```shell-session:/etc/netplanに自環境用のyamlファイルを用意して反映させる
$ cd /etc/netplan
$ sudo cp 50-cloud-init.yaml  99-mySetting-init.yaml
$ sudo vi 99-mySetting-init.yaml
$ cat /etc/netplan/99-mySetting-init.yaml 
(snipped)
network:
    ethernets:
        eth0:
            dhcp4: false
            addresses: [<割り当てたいIPv4アドレス>/マスク長]
            gateway4: <default gatewayのIPv4アドレス>
            nameservers:
                    addresses: [<default gatewayのIPv4アドレス>, 8.8.8.8, 8.8.4.4]
            optional: true
    version: 2
$ sudo netplan apply
```

## Docker のインストール

"curl https://get.docker.com | sh" でインストールできる。
あわせて、自分の利用したいユーザアカウント（例では \<MY_USER> ）を docker グループに設定する。

```shell-session:Dockerのインストール
$ curl https://get.docker.com | sh
$ sudo groupadd docker
$ sudo usermod -aG docker <MY_USER>
(ここで再ログイン)
$ docker -v
Docker version 19.03.8, build afacb8b
```

定番の hello-world を実行してみる。

```
$ docker run hello-world
Unable to find image 'hello-world:latest' locally
latest: Pulling from library/hello-world
256ab8fe8778: Pull complete 
Digest: sha256:8e3114318a995a1ee497790535e7b88365222a21771ae7e53687ad76563e8e76
Status: Downloaded newer image for hello-world:latest

Hello from Docker!
This message shows that your installation appears to be working correctly.

To generate this message, Docker took the following steps:
 1. The Docker client contacted the Docker daemon.
 2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
    (arm64v8)
 3. The Docker daemon created a new container from that image which runs the
    executable that produces the output you are currently reading.
 4. The Docker daemon streamed that output to the Docker client, which sent it
    to your terminal.

To try something more ambitious, you can run an Ubuntu container with:
 $ docker run -it ubuntu bash

Share images, automate workflows, and more with a free Docker ID:
 https://hub.docker.com/

For more examples and ideas, visit:
 https://docs.docker.com/get-started/
```

Manifest を生成して dockerhub に push したいので、experimental を enable する。

```shell-session:Dockerでexperimentalをenableする
$ vi ~/.docker/config/json
$ cat ~/.docker/config/json 
{
    "experimental": "enabled"
}
```

## FOSSology の docker image を build する

FOSSology が dockerhub で提供しているイメージ "[fossology/fossology](https://hub.docker.com/r/fossology/fossology)" は linux/AMD64 のみである。したがって、Ubuntu 18.04 (amr64) で動かすには、arｍ64 のものを build する必要がある。

RPi4 に fossology の repository を clone して、ローカルで build してみた。

以下、同様の手順を実施される場合は、イメージ名、タグ、dockerhubのアカウントなどはご自身の環境に合わせて修正されたい。

```shell-session:FOSSologyをローカルでbuildする
$ git clone https://github.com/fossology/fossology
$ cd fossology
$ $ date
Sun May 10 03:57:09 UTC 2020
$ docker build -t taknin/fossology-arm64:local-build-latest .
(snipped)
Successfully built 319cde2f400f
Successfully tagged taknin/fossology-arm64:local-build-latest
ubuntu@ubuntu:~/temp/fossology$ date
Sun May 10 05:52:43 UTC 2020
```

約2時間程度で終了した。

manifest もあわせて push する。


```shell-session:imageをdockerhubにpushする
$ docker login -u=taknin --password-stdin
$ docker push taknin/fossology-arm64:local-build-latest
$ docker manifest create taknin/fossology-arm64:local-build-latest --amend taknin/fossology-arm64:local-build-latest 
$ docker manifest push taknin/fossology-arm64:local-build-latest
```

manifest の内容は次の通り。

```
$ docker manifest inspect taknin/fossology-arm64:local-build-latest
{
   "schemaVersion": 2,
   "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json",
   "manifests": [
      {
         "mediaType": "application/vnd.docker.distribution.manifest.v2+json",
         "size": 2829,
         "digest": "sha256:da14d7e324b8bf4bb3eb496750ce6a27771c1d102f88d89e4268c9d6a705910e",
         "platform": {
            "architecture": "arm64",
            "os": "linux"
         }
      }
   ]
}
```

# 動作確認

docker にて fossology を起動させる。

```shell-session:
$ docker run -p 8081:80 taknin/fossology-arm64:local-build-latest
```

母艦の browser から次のアドレスにアクセスする。

```
http://<IPアドレス>:8081/repo/
```

初期画面が表示される。

<img width="75%" alt="1_start.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74496/63ea1ea8-2508-700b-9b2f-2dbca88e8a79.jpeg">

fossy/fossy でログインする。

<img width="75%" alt="2_startLogin.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74496/5e53165d-4326-22a4-1c5e-e3ee1b19de5b.jpeg">


本稿では、国内での OSS 活用事例として話題の一つである「[東京都 新型コロナウイルス感染症対策サイト](https://stopcovid19.metro.tokyo.lg.jp)」について、その Github リポジトリ [tokyo-metropolitan-gov/covid19](https://github.com/tokyo-metropolitan-gov/covid19) から本稿執筆時点で最新の[リリース](https://github.com/tokyo-metropolitan-gov/covid19/releases)である "1.5.192" について見てみることにする。

アーカイブをダウンロードして、fossology に upload する。

<img width="75%" alt="3_upload_file.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74496/a489daeb-0ba9-76ff-ed3f-dfa6e31dbc07.jpeg">

解析のジョブが "#2" として、処理を開始した。

<img width="75%" alt="4_start_job.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74496/a9be585c-eabb-44fb-3179-1bd25bd62d69.jpeg">

およそ4−5分程度でほとんど終了した。

<img width="75%" alt="5_jobFinished.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74496/e9b9148a-49d7-2752-d497-3b6d38c4c590.jpeg">

結果の概要は次の通り。

<img width="75%" alt="6_License_Browser.jpg" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/74496/aad9a8b7-8e2b-764c-2d87-d8247a909a80.jpeg">

概ね動作しているようである。
本稿ではここまで。


# おわり

Ubuntu 18.04 (arm64) + docker でも FOSSology の実行は可能である。
パフォーマンスについては、操作方法も含めてチューニングの必要がある。
手持ちの PC に FOSSology の環境を用意できない時、ポータブルな環境として用意する手段にはなりそう。

機会があれば次を試してみたいところだ。
- Ubuntu 20.04 (arm64) での動作
- クロスビルド (amd64環境でarm64向けをビルドする)
- [SW360](https://github.com/eclipse/sw360) on docker 

以上