Yocto環境にmeta-spdxscannerを適用し、SPDX出力環境を構築する（fossdriver利用編）

# はじめに
OSSライセンス スキャナーであるFOSSologyを利用すると、OSSパッケージ毎のソース コード解析→SPDXファイルの出力が可能です。
しかし、ソース コードをパッケージ毎にWeb UIからFOSSologyへ送るのは手間がかかるため、meta-spdxscannerを利用して、Yoctoでビルドしながら、FOSSologyへソース コードを送信、解析、SPDXファイルを出力する環境の構築方法をまとめてみました。

今回、構築する環境は、以下のような感じです。
![output_spdx_environment.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/531316/3010ade1-964a-e559-6c2b-424bce8fab26.png)

ホスト環境は、Ubuntu 18.04やAWS（Amazon Linux）など、dockerが使えれば何でもよいです。
青枠がdockerコンテナです。
FOSSologyやYoctoビルド環境をdockerコンテナで構築し、Yoctoビルド環境のdocker上にFOSSologyとアクセスするためのfossdriverをインストールします。
※FOSSologyやYoctoビルド環境についての説明は割愛します。

# FOSSology環境の構築
FOSSology のdockerイメージを取得します。
最新版は3.6.0版ですが、fossdriver経由で動作しないので、3.5.0版を取得します。
追記：fossdriverが、FOSSology-3.6.0に対応したようです。（https://github.com/fossology/fossdriver/commit/efbbd51ae407e78cd8f969b2cdc3c243b31ade2a）

```
$ sudo docker pull fossology/fossology:3.5.0
```

FOSSology dockerを起動します。

```
$ sudo docker run -d -p 8081:80 --name fossology-3.5.0 fossology/fossology:3.5.0
```

```-p 8081:80```は、外部アクセスされるポート番号:dockerコンテナ側のポート番号を指定します。
```-d ```は、バックグラウンド実行です。

```docker ps```で、dockerコンテナが起動したことは確認できますが、念の為、```docker logs```で起動状況（```--tail=20 ```で、最新ログ20行だけ）を表示します。

```
$ sudo docker logs --tail=20 fossology-3.5.0
　：
YYYY-MM-DD hh:mm:ss scheduler [PID1] :: NOTE: ********************************************
YYYY-MM-DD hh:mm:ss scheduler [PID1] :: NOTE: ***   FOSSology scheduler started        ***
YYYY-MM-DD hh:mm:ss scheduler [PID1] :: NOTE: ***   pid:      PID1                     ***
YYYY-MM-DD hh:mm:ss scheduler [PID1] :: NOTE: ***   verbose:  3                        ***
YYYY-MM-DD hh:mm:ss scheduler [PID1] :: NOTE: ***   config:   /usr/local/etc/fossology ***
YYYY-MM-DD hh:mm:ss scheduler [PID1] :: NOTE: ********************************************
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.X. Set the …
AH00558: apache2: Could not reliably determine the server's fully qualified domain name, using 172.17.0.X. Set the …
[………] [mpm_prefork:notice] [pid PID2] AH00163: Apache/2.4.25 (Debian) configured …
[………] [core:notice] [pid PID2] AH00094: Command line: '/usr/sbin/apache2 -D FOREGROUND'
```

※```YYYY-MM-DD```⇒年-月-日、```hh:mm:ss```⇒時:分:秒、```PID1```⇒FOSSologyスケジューラのpid番号
 ```[………]```⇒apacheの起動年月日と時間、```PID2```⇒apacheのpid番号

最後の```apache2 -D FOREGROUND```のログが出ていれば、起動できています。

# fossdriverのインストール
Yoctoビルド環境のdockerコンテナ上にインストールします。
今回、Yoctoビルド環境のベースとなったdockerコンテナは、Ubuntu 16.04のdockerイメージより作成しており、そのdockerイメージにはPython3.5をインストールしましたが、Python3.6でも動作可能なことは確認済です。
以下、dockerコンテナにyoctoユーザを作成し、ホーム ディレクトリ上で作業します。

```
$ git clone https://github.com/fossology/fossdriver.git
$ pip3 install -e /home/yocto/fossdriver
```

インストールされたか確認します。


```
$ pip3 list
beautifulsoup4 (4.7.1)
bs4 (0.0.1)
certifi (2019.6.16)
chardet (3.0.4)
command-not-found (0.3)
fossdriver (0.0.2, /home/yocto/fossdriver)　★インストールできている
：
```

fossdriverの設定ファイルを作成します。
冒頭で説明した環境の通り、dockerホストのポート8081経由でFOSSologyにアクセスできるので、そのように設定します。

```
$ vi ~/.fossdriverrc
{
        "serverUrl": "http://172.17.0.1:8081",
        "username": "fossy",
        "password": "fossy"
}
```

fossdriver経由で、FOSSologyへソース コードを送信してSPDXファイルを出力する[テスト コード](https://github.com/y-ashiduka/fossdriver-test)を置いたので、動作確認用にご利用ください。
使用例：

```
$ ./fossdriver-test.py <source-code.tar.gz> <SPDXファイル出力パス>
```

# meta-spdxscannerレイヤ追加と設定ファイル更新
Yoctoビルド環境に、meta-spdxscannerレイヤを追加します。
以降、pokyディレクトリ以下での作業を想定しています。

```
$ git clone https://github.com/dl9pf/meta-spdxscanner
```

Yoctoのリリース版数にマッチするブランチがありますが、Sumo以降であれば、masterブランチで動作することを確認済です。
（MortyやPyroなど、古いYocto環境だと、動作しない可能性があります）

ビルド ディレクトリ配下のレイヤ設定ファイル（conf/bblayers.conf）に、meta-spdxscannerを追加します。（xxxは任意のパス）

```
　：
BBLAYERS ?= "\
　：
    /xxx/poky/meta \
    /xxx/poky/meta-poky \
　：
    /xxx/poky/meta-spdxscanner \　　★追加
```

ビルド ディレクトリ配下のYocto設定ファイル（conf/local.conf）に、fossdriverを経由して、ソース コードのスキャン＆SPDXファイル出力できるよう、記述を追加します。（xxxは任意のパス）

```
　：
# Use spdxscanner
INHERIT += "fossdriver-host"
SPDX_DEPLOY_DIR = "/xxx/SPDX"　　★事前に作成しておいたディレクトリをfull-pathで指定
```

パッケージングされないOSSパッケージ（*-nativeパッケージなど）をソース コードのスキャン＆SPDXファイル出力対象外にする場合は、meta/classes/nopackages.bbclass に以下を追加します。

```
　：
deltask do_spdx　　　★最下行に追加
```

ここまで設定が終わったら、あとは```bitbake```すると、パッチ適用されたソース コードがFOSSologyへ送信され、スキャン＆SPDXファイル出力まで自動で行われます。
出力ディレクトリを確認すると、以下のようにSPDXファイルが出力されます。

```
$ ls -l /xxx/SPDX/
total 232200
-rw-rw-r-- 1 <user> <group>    <size> <MM DD xxxx> acl-<version>.spdx
　：
-rw-rw-r-- 1 <user> <group>    <size> <MM DD xxxx> zip-<version>.spdx
-rw-rw-r-- 1 <user> <group>    <size> <MM DD xxxx> zlib-<version>.spdx
```

※```<user> <group>```ファイル所有のユーザ/グループ属性、※```<size>```⇒ファイル サイズ、
　```<MM DD xxxx>```⇒年月日/月日時、```<version>```⇒ソース スキャンしたパッケージ版数

一例ですが、出力されるSPDXファイル（zlib-1.2.11）は以下の通りです。
<details><summary>zlib-1.2.11.spdx</summary><div>

```
SPDXVersion: SPDX-2.1
DataLicense: CC0-1.0

〜略〜

##-------------------------
## Creation Information
##-------------------------

Creator: fossdriver-host.bbclass in meta-spdxscanner
Creator: fossdriver-host.bbclass in meta-spdxscanner
CreatorComment: <text>
This document was created using license information and a generator from Fossology.
</text>
Created: 2019-10-25T13:51:02Z
LicenseListVersion: 2.6

##-------------------------
## Package Information
##-------------------------


PackageName: zlib
PackageVersion: 1.2.11
PackageFileName: zlib-1.2.11-r0-patched.tar.gz
SPDXID: SPDXRef-upload12
PackageDownloadLocation: http://downloads.sourceforge.net/libpng/zlib/1.2.11/zlib-1.2.11.tar.xz
PackageHomePage: http://zlib.net/
PackageSummary: <text>Zlib Compression Library</text>
modification record : true
PackageVerificationCode: da39a3ee5e6b4b0d3255bfef95601890afd80709
PackageDescription: <text>zlib version 1.2.11</text>
PackageChecksum: SHA1: 52c1cca78a84d64c2d9fbfe2f02f8ba16c8d7405
PackageChecksum: MD5: 604e2d2a555b7df2650e59e72785a540
PackageLicenseConcluded: NOASSERTION
PackageLicenseDeclared: NOASSERTION
PackageLicenseComments: <text> licenseInfoInFile determined by Scanners:
 - nomos ("3.5.0".aacf0d)
 - monk ("3.5.0".aacf0d) </text>
PackageLicenseInfoFromFiles: NOASSERTION
PackageCopyrightText: NOASSERTION

Relationship: SPDXRef-DOCUMENT DESCRIBES SPDXRef-upload12

##--------------------------
## File Information
##--------------------------

〜略〜

##File

FileName: spdx_temp/zlib-1.2.11/contrib/dotzlib/DotZLib/Inflater.cs
SPDXID: SPDXRef-item13875
FileChecksum: SHA1: 25f788ff0015c08fcd74d6e4552e01792c559350
FileChecksum: MD5: 6071d8412268ff9765540c491a26de1a
LicenseConcluded: NOASSERTION
LicenseInfoInFile: BSL-1.0
FileCopyrightText: <text> © Copyright Henrik Ravn 2004
 </text>

〜略〜

##-------------------------
## License Information
##-------------------------

LicenseID: LicenseRef-Zlib-possibility
LicenseName: Zlib-possibility
ExtractedText: <text> License by Nomos. </text>

LicenseID: LicenseRef-GPL
LicenseName: GNU General Public License
ExtractedText: <text> GPL is referenced without a version number. Please look up GPL in the License Admin to view the different versions. </text>

〜略〜
```

</div></details>

今回は、fossdriverを利用する方法について記述しましたが、REST API（fossdriver無し）経由でFOSSologyへソース コードを送信することが可能です。こちらについては、REST API利用編で記述します。

また、FOSSologyの問題（大きいサイズのソース コードを送ると応答がなくなる、出力されるSPDXファイルのPackage License Declaredフィールドが"NOASSERTION"になる、etc...）に関する回避策なども、別記事で記述します。