はじめに
近年、OSS(Open Source Software、オープンソースソフトウェア)が個人や企業問わずさまざまな場面で利用されています。OSSを活用することで開発のスピード向上や費用の削減が見込めるのですが、ライセンスのリスク(OSS利用に伴う責務など)も発生します。
このようなOSSのライセンスの管理を行うにあたって利用できるツールは多々ありますが、無料で利用できるものとしてFOSSologyがあります。Dockerコンテナを使うと簡単に利用環境を構築でき、またブラウザーから簡単に利用することができるのですが、ここでは一歩踏み込んで、自動化を念頭に置いたREST APIの利用についてお話ししたいと思います。
この記事でお伝えしたいこと
- FOSSologyでREST APIを使うためのFirst Step。
以下のような方が読まれることを想定しています。
- FOSSologyを構築し、利用されている方。
- FOSSologyをもっと効率よく利用したい方。
また、以下の知識を必要とします。
- HTTP(Hypertext Transfer Protocol)に関する知識。
- REST APIに関する知識。
環境・準備
検証環境
本記事では以下の環境にて操作を行っています。
サーバー
- FOSSology v3.11.0 (Docker image)
- Docker version 20.10.7
クライアント
- WSL2(Kernel v5.10.60.1 / Ubuntu-20.04)
以下のコマンドを使用します。事前にインストールしておいてください。
- jq
- curl
事前準備
REST APIを利用するには認証のためのトークンが必要になります。事前にFOSSologyにブラウザーでアクセスして、トークンを生成する必要があります。
-
FOSSologyにログインし、メニューの [Admin] > [Users] > [Edit User Account] を選択します。
-
[Create a new token]で必要事項(Name / Expire at)を設定します。Access scope は Read/Write accessを選択してください。
-
"Create new token"ボタンを押してトークンを生成します。
-
認証に必要なトークンが表示されるので、メモしてください。
画面をリロードすると、トークンが非表示になります。その場合は、Active access tokensリストに表示される対象トークンの"Reveal"ボタンにて再表示してください。
Let's get started!
REST API呼び出しの基本
FOSSologyでは、Bearer認証が利用されています。具体的には、取得したトークンをHTTPのAuthorizationヘッダに指定して対象のURLにアクセスします。
例えば、curlでAPIを呼び出すにはリクエストヘッダ(-H オプション)に "Authorization: Bearer トークン" を指定してコマンドを実行します。
- ※以降の例では、見栄えのために改行を入れていますが1行で入力してください。
例:フォルダ一覧取得
$ curl -sS -X GET http://10.0.11.1/repo/api/v1/folders
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJl
eHAiOjE2NjgyOTc1OTksIm5iZiI6MTYzNjY3NTIwMCwianRpIjoiTWk0eiIsInN
jb3BlIjoid3JpdGUifQ.vr1duV6c13TFlQ2Nh20VUgw0EHeSpjhrZXLhJpvVs5c" | jq
結果
[
{
"id": 1,
"name": "Software Repository",
"description": "Top Folder",
"parent": null
}
]
例ではFOSSologyサーバー(http://10.0.11.1)にアクセスし、取得したjsonをjqコマンドで整形しています。サーバー上にはトップフォルダのみ存在していることがわかります。
REST APIの利用方法ですが、以下のように実際に解析に適用しやすいケースを想定して説明します。
-
格納先フォルダ作成
-
ファイルアップロード
-
ファイルアップロードの結果確認
-
解析実行
-
解析実行の結果確認
1. 格納先フォルダ作成
フォルダを作成するには、リクエストヘッダの parentFolder に親フォルダのId、 folderName にフォルダ名を指定して実行します。次の例では、親にトップフォルダ、フォルダ名に rest を指定しています。
$ curl -sS -X POST http://10.0.11.1/repo/api/v1/folders
-H "parentFolder: 1"
-H "folderName: rest"
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJl
eHAiOjE2NjgyOTc1OTksIm5iZiI6MTYzNjY3NTIwMCwianRpIjoiTWk0eiIsInN
jb3BlIjoid3JpdGUifQ.vr1duV6c13TFlQ2Nh20VUgw0EHeSpjhrZXLhJpvVs5c" | jq
結果
{
"code": 201,
"message": 3,
"type": "INFO"
}
実行が成功した場合には、codeに200番台の値が格納されます。 また、messageに新規作成したフォルダのIdが格納されます。次のアップロードにはフォルダのIdが必要になります。
2. ファイルアップロード
ファイルをアップロードするには、リクエストヘッダの folderId にファイルを格納するフォルダのId、uploadDescription にファイルの説明、public にファイルの公開設定、リクエストボディにアップロードするファイル(例ではsample.tar.gz)を指定して実行しています。この例ではマルチパートでファイル送信するため、Content-Typeにmultipart/form-dataを設定しています。
$ curl -sS -X POST http://10.0.11.1/repo/api/v1/uploads
-H "folderId: 3"
-H "uploadDescription: created by REST"
-H "public: public"
-H "Content-Type: multipart/form-data"
-F 'fileInput=@"sample.tar.gz";type=application/octet-stream'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJl
eHAiOjE2NjgyOTc1OTksIm5iZiI6MTYzNjY3NTIwMCwianRpIjoiTWk0eiIsInN
jb3BlIjoid3JpdGUifQ.vr1duV6c13TFlQ2Nh20VUgw0EHeSpjhrZXLhJpvVs5c" | jq
結果
{
"code": 201,
"message": 2,
"type": "INFO"
}
実行が成功した場合には、codeに200番台の値が格納されます。 また、messageにアップロードしたファイルのIdが格納されます。
3. ファイルアップロードの結果確認
ファイルをアップロードの結果を確認するには、対象ファイルのIdをクエリパラメータuploadに指定してステータスを取得します。
$ curl -sS -X GET http://10.0.11.1/repo/api/v1/jobs?upload=2
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJl
eHAiOjE2NjgyOTc1OTksIm5iZiI6MTYzNjY3NTIwMCwianRpIjoiTWk0eiIsInN
jb3BlIjoid3JpdGUifQ.vr1duV6c13TFlQ2Nh20VUgw0EHeSpjhrZXLhJpvVs5c" | jq
結果
[
{
"id": 2,
"name": "sample.tar.gz",
"queueDate": "2021-11-12 10:04:44.435339+00",
"uploadId": "2",
"userId": "3",
"groupId": "3",
"eta": 0,
"status": "Processing"
}
]
ファイルのアップロード処理中は、statusが"Processing"となります。しばらく待って再度ステータスを取得しましょう。処理が完了すると、statusが"Completed"となります。次の解析実行は、処理が完了してから実行してください。
4. 解析実行
解析は、リクエストヘッダの uploadId に対象ファイルのId、 folderId にファイルが格納されているフォルダのId、リクエストボディに解析のオプションのjsonデータを指定して実行します。Content-Typeはapplication/jsonとしてください。
$ curl -sS -X POST http://10.0.11.1/repo/api/v1/jobs
-H "folderId: 3"
-H "uploadId: 2"
-H 'Content-Type: application/json'
--data '{
"analysis": {
"bucket": false,
"copyright_email_author": false,
"ecc": false,
"keyword": false,
"mime": false,
"monk": true,
"nomos": true,
"ojo": true,
"package": true
},
"decider": {
"nomos_monk": true,
"bulk_reused": true,
"new_scanner": true,
"ojo_decider": true
}
}'
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJl
eHAiOjE2NjgyOTc1OTksIm5iZiI6MTYzNjY3NTIwMCwianRpIjoiTWk0eiIsInN
jb3BlIjoid3JpdGUifQ.vr1duV6c13TFlQ2Nh20VUgw0EHeSpjhrZXLhJpvVs5c" | jq
結果
{
"code": 201,
"message": 3,
"type": "INFO"
}
実行が成功した場合には、codeに200番台の値が格納されます。 また、messageに解析のジョブのIdが格納されます。
5. 解析実行の結果確認
解析が正常に終了したか確認するには、対象ジョブのIdをパスパラメータに指定してステータスを取得します。
$ curl -sS -X GET http://10.0.11.1/repo/api/v1/jobs/3
-H "Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJl
eHAiOjE2NjgyOTc1OTksIm5iZiI6MTYzNjY3NTIwMCwianRpIjoiTWk0eiIsInN
jb3BlIjoid3JpdGUifQ.vr1duV6c13TFlQ2Nh20VUgw0EHeSpjhrZXLhJpvVs5c" | jq
結果
{
"id": 3,
"name": "sample.tar.gz",
"queueDate": "2021-11-12 10:44:52.069541+00",
"uploadId": "2",
"userId": "3",
"groupId": "3",
"eta": 0,
"status": "Processing"
}
解析処理中は、statusが"Processing"となります。しばらく待って再度ステータスを取得しましょう。処理が完了すると、statusが"Completed"となります。
ブラウザーで確認してみましょう
今までのREST API実行結果をブラウザーでも確認してみましょう。
メニューの[Browse]を開くと、"Software Repository"の直下に"rest"フォルダが作成されていることが分かります。"rest"フォルダには、"sample.tar.gz"ファイルの結果が格納されています。
また、メニューの[Jobs] > [My Recent Jobs]では、解析のジョブが正常に終了していることが分かります。
最後に
FOSSologyで解析を行う際、対象のOSSの数が多くなるとzipなどで纏めるなど、解析の実行に工夫が必要になります。
ただ、実際に大量のソースファイルをアップロードすると、アップロードに失敗したり、次のアップロードを実行するため定期的にブラウザーで終了を確認する必要があったりと、思いのほか手間がかかることに気が付きます。今回は1つのOSSを対象としましたが、シェルスクリプトなどで"ファイルアップロード"~"解析実行の結果確認"を繰り返すことで、複数のOSSにも対応できます。
長くなりましたが、今後のFOSSology活用の手助けになれば幸いです。