AWS S3をdebパッケージリポジトリとして使う

## はじめに
Dockerの登場で、アプリケーションの配信が非常に手軽になりました。
一方で、Dockerでは動作しないようなorできないようなファームウェア層は当たり前ですが多く残っています。（dkmsなどのハード絡みの部分など特に。）
モジュールの重要性に応じて、この部分を塩漬けするのも、一つの戦略としてはありだとは思いますが、開発周期の高速化も相まって必ずしも完全なファームウェアを作るのも難しいのもまた事実。
本ページでは、debパッケージリポジトリをAWS S3を使って実現する方法を記します。何が嬉しいか？


1. HTTPSが使える
   - さすがS3
2. LambdaEdgeを使ってBasic認証をかけることができる!!
   - [Lambda \+ CloudFront \+ S3でBasic認証する \- Qiita](https://qiita.com/takahashi-kazuki/items/688f5f736bd76682483c)
3. 独自ドメインを設定できる
   - [独自ドメインを使ってAmazon S3で静的Webサイトをホストする \- Qiita](https://qiita.com/Ichiro_Tsuji/items/c174d580587a622d3358)


他にも機能面以外では、小規模であれば安い（商用のdebパッケージリポジトリの多くが$200/monthぐらい）などのメリットもあります。
ここでは、2,3についてはほかサイトの解説に譲るとして、基礎となる「公開debパッケージリポジトリ」を[aptly \- Debian repository management tool](https://www.aptly.info/)を使って実現します。aptlyはDebパッケージリポジトリを管理するためのツールです。
なお、あとから、3,4を追加するのは簡単です。


## aptlyインストール
* apt-getでデフォルトで取れるのは古いので、公式リポジトリからのダウンロードとする。

```bash
$ wget -qO - https://www.aptly.info/pubkey.txt | sudo apt-key add -
$ echo "deb http://repo.aptly.info/ squeeze main" | sudo tee /etc/apt/sources.list.d/aptly.list
$ sudo apt update
$ sudo apt install aptly
```

## aptly用ユーザを作成する
* 必須では無いが、本ページでは専用ユーザを作って権限を管理することとする。

```bash
$ sudo adduser aptly
[sudo] password for intec: 
Adding user `aptly' ...
Adding new group `aptly' (1001) ...
Adding new user `aptly' (1001) with group `aptly' ...
Creating home directory `/home/aptly' ...
Copying files from `/etc/skel' ...
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
Changing the user information for aptly
Enter the new value, or press ENTER for the default
	Full Name []: 
	Room Number []: 
	Work Phone []: 
	Home Phone []: 
	Other []: 
Is the information correct? [Y/n]
```

## aptlyユーザに切り替える
ユーザを切り替えて、鍵をインポートする。

```sh
$ sudo -iu aptly
$ gpg --gen-key
```

## 公開鍵を作る
* リポジトリを使う時は、これを`apt-key add`して信頼してもらう必要がある。
```sh
$ gpg --export --armor > princess.pub
```

## ローカルパッケージのリポジトリを作る
* リポジトリを作る

```bash
aptly repo create -distribution=stretch -component=main rdbox_firmware
```

* リポジトリにdebファイルを追加する
   - dbgsymは除く

```bash
$ ls *.deb | grep -v "dbgsym" | xargs -l aptly repo add rdbox_firmware
```

* 中身を確認してみる

```bash
$ aptly repo show -with-packages rdbox_firmware
Name: rdbox_firmware
Comment: 
Default Distribution: stretch
Default Component: main
Number of packages: 1
Packages:
  rdbox_0.0.3_armhf
```

### スナップショットを活用する
* スナップショットとして管理することで、いろんなリポジトリをマージして一つのリポジトリを作ることが可能になる。
   - 以下の例では、rdbox_firmware-0.0.3のみをマージしているが、いろんなスナップショットをマージして一つのリポジトリにすることも可能。

```bash
$ aptly snapshot create rdbox_firmware-0.0.3 from repo rdbox_firmware
$ aptly snapshot merge -latest rdbox_release-0.0.3 rdbox_firmware-0.0.3
```


## S3の設定をする
今回は直接S3からダウンロードさせていますが、CloudFrontの使用も検討しましょう。

* バケットを作る
   - 作り方は省略。多分ググれば山のように出てくる。`静的Webサイト`としてホスティングします。
      - [AWS S3で静的Webページをホスティングする \- Qiita](https://qiita.com/dogwood008/items/a92abae789f4b0466f38)
   - 本ページでは`repo.rdbox.com`とします。

* aws_cliをインストールする
   - 権限のあるユーザで実施。

```
$ sudo pip install awscli
```

* 環境変数として、`AWS_ACCESS_KEY_ID`と`AWS_SECRET_ACCESS_KEY`を宣言する。
   - IAMでユーザを払い出す。S3の権限があれば良い。

```sh
$ vim ~/.bashrc

export AWS_ACCESS_KEY_ID="AKIA++++++++++++++++++++++++"
export AWS_SECRET_ACCESS_KEY="hogeeeeeeeeeeeeeee"
```

* ~/.aptly.confを作る
   - S3PublishEndpointsは次の通り。バケット名に応じて、適宜変更すること。
   - regionも同様

```json

{
  "rootDir": "/home/aptly/.aptly",
  "downloadConcurrency": 4,
  "downloadSpeedLimit": 0,
  "architectures": [],
  "dependencyFollowSuggests": false,
  "dependencyFollowRecommends": false,
  "dependencyFollowAllVariants": false,
  "dependencyFollowSource": false,
  "dependencyVerboseResolve": false,
  "gpgDisableSign": false,
  "gpgDisableVerify": false,
  "gpgProvider": "gpg",
  "downloadSourcePackages": false,
  "skipLegacyPool": true,
  "ppaDistributorID": "ubuntu",
  "ppaCodename": "",
  "skipContentsPublishing": false,
  "FileSystemPublishEndpoints": {},
  "S3PublishEndpoints": {
      "repo.rdbox.com":{
         "region":"ap-northeast-1",
         "bucket":"repo.rdbox.com",
         "acl":"public-read"
      } 
   },
  "SwiftPublishEndpoints": {}
}
```

* S3に対してPublishする。

```bash
$ aptly publish snapshot rdbox_release-0.0.3 s3:repo.rdbox.com:
```


## クライアント側の設定
* 今回作った、「HTTPSサーバレスaptリポジトリ」は、`/etc/apt/sources.list.d/yoursite.list`に対して記載する。
   - 冒頭にもあるように`apt-key add`をやることを忘れずに。
   - `sudo apt-get install apt-transport-https`も必要に応じて追加しよう。

```bash:/etc/apt/sources.list.d/yoursite.list
deb https://バケット名.s3-website-リージョン名.amazonaws.com stretch main
```

* 【補足】パスワードかけるときはこんな感じ。

```bash:/etc/apt/sources.list.d/yoursite.list
deb http://user:pass@バケット名.s3-website-リージョン名.amazonaws.com stretch main
```

## 参考
[aptly \- Debian repository management tool](https://www.aptly.info/)
[第485回　aptlyで本格的なパッケージリポジトリを作る：Ubuntu Weekly Recipe｜gihyo\.jp … 技術評論社](http://gihyo.jp/admin/serial/01/ubuntu-recipe/0485)
[第489回　ARM向けバックポートリポジトリをaptlyで作る：Ubuntu Weekly Recipe｜gihyo\.jp … 技術評論社](http://gihyo.jp/admin/serial/01/ubuntu-recipe/0489)