VirtualBox用のCentOS base boxを作ってGitHub Releasesで共有する

# 動機

[A list of base boxes for Vagrant - Vagrantbox.es](http://www.vagrantbox.es/)でVirtualBox用のbase boxが配布されていますが、中身がよくわからないという不安もありますし、必要な物だけを組み込んだbase boxを自作したいと思いますよね。

自作したら他の人にも共有したいところです。GitHub Releasesを使えばPacker用のtemplateファイルと対応して管理しておけるのでbase boxの内容の確認もしやすくて便利です。

# base boxの作成

base boxを自作するには[Packer](http://www.packer.io/)が便利です。
Packerのインストールは[OSXでpackerでCentOS6.4のVirtualBox VMを作成する - Qiita \[キータ\]](http://qiita.com/hnakamur/items/da0ed14192a18405f704)を参照してください。

ここでは[株式会社 時雨堂](http://shiguredo.jp/)さんが公開してくれている[shiguredo/packer-templates](https://github.com/shiguredo/packer-templates)を使ってCentOS 6.5のVMを作ります。minimalな構成になっていて素晴らしいです。ありがとうございます。

GitHubでReleaseを作るためには自分のレポジトリである必要があるので、GitHubのページで[shiguredo/packer-templates](https://github.com/shiguredo/packer-templates)をforkします。私の場合は、[hnakamur/packer-templates](https://github.com/hnakamur/packer-templates)にforkしました。

packerを使ってbase boxをビルドします。

```shell-session
$ git clone git@github.com:hnakamur/packer-templates.git
$ cd packer-templates/centos-6.5
$ packer build -only=virtualbox template.json
```

centos-6-5-x64-virtualbox.boxというファイル名でbase boxが作成されます。

ビルドが完了したら、タグを打ってpushします。ここではv1.0.1とします。

```shell-session
$ git tag v1.0.1
$ git push --tag
```

# GitHub Releaseの作成

## GitHubウェブページにて手動作成

[Release Your Software](https://github.com/blog/1547-release-your-software)や[Creating Releases · GitHub Help](https://help.github.com/articles/creating-releases)にGitHub Releasesの説明があります。

レポジトリのトップページで、commits, branch, release, contributorと並んでいるところのreleaseをクリックして、[Draft a new release]ボタンを押します。Tag Version, Release Title, Describe this releaseの欄に適宜説明を記入します。Attach binaries for this release by dropping them thereと書かれた欄に上記で作成したcentos-6-5-x64-virtualbox.boxをドロップします。[Publish release]ボタンを押すとreleaseが作成されます。

base boxのファイルは以下のURLでダウンロードできるようになります。
https://github.com/hnakamur/packer-templates/releases/download/v1.0.1/centos-6-5-x64-virtualbox.box

## curlコマンドでWeb APIを利用して作成

またWeb APIでReleaseを作成したり、Releaseにファイルを添付することもできます。

* [Create a release](http://developer.github.com/v3/repos/releases/#create-a-release)
* [Upload a release asset](http://developer.github.com/v3/repos/releases/#upload-a-release-asset)

APIのユーザ認証については[Other Authentication Methods | GitHub API](http://developer.github.com/v3/auth/#basic-authentication)に説明があります。

### APIトークン生成

[Personal API tokens](https://github.com/blog/1509-personal-api-tokens)の手順に従ってAPIトークンを作成します。

GitHubのページの右上のAccount Settingsのアイコンをクリックしてprofileページに進み、画面左のメニューのApplicationsをクリックします。

画面右のPersonal Access Tokensのセクションの[Create new token]ボタンを押します。Token descriptionにtoken for creating GitHub releasesなどと説明を入力し[Create token]ボタンを押すとトークンが生成されます。
トークンの値は流出しないよう気をつけてください。

### releaseの作成

```shell-session
$ GITHUB_TOKEN=上で作成したトークンの値
$ curl -v -H "Authorization: token "$GITHUB_TOKEN \
  -H "Accept: application/json" -H "Content-type: application/json" -X POST -d '
{
  "tag_name": "v1.0.1",
  "name": "CentOS 6.5 x86_64 for VirtualBox 4.3.6",
  "body": "CentOS 6.5 x86_64 minimal VM for VirtualBox 4.3.6",
  "draft": false,
  "prerelease": false
}' https://api.github.com/repos/hnakamur/packer-templates/releases
```

上記のJSONに"target_commitish": "master"というのを追加しておけば事前にgitでタグを生成してpushしなくてもよいです。詳しくは[Create a release](http://developer.github.com/v3/repos/releases/#create-a-release)を参照してください。

すると以下の様なレスポンスが返ります。

```json
{
  "url": "https://api.github.com/repos/hnakamur/packer-templates/releases/129188",
  "assets_url": "https://api.github.com/repos/hnakamur/packer-templates/releases/129188/assets",
  "upload_url": "https://uploads.github.com/repos/hnakamur/packer-templates/releases/129188/assets{?name}",
  "html_url": "https://github.com/hnakamur/packer-templates/releases/v1.0.1",
  "id": 129188,
  "tag_name": "v1.0.1",
  "target_commitish": "develop",
  "name": "CentOS 6.5 x86_64 for VirtualBox 4.3.6",
  "body": "CentOS 6.5 x86_64 minimal VM for VirtualBox 4.3.6",
  "draft": false,
  "prerelease": false,
  "created_at": "2013-12-04T02:15:10Z",
  "published_at": "2013-12-21T17:00:10Z",
  "assets": [

  ],
  "tarball_url": "https://api.github.com/repos/hnakamur/packer-templates/tarball/v1.0.1",
  "zipball_url": "https://api.github.com/repos/hnakamur/packer-templates/zipball/v1.0.1"
}
```

### releaseに添付するファイルをアップロード

ファイルをアップロードします。releaseを作成したときのレスポンスのupload_uriを使いnameパラメータにファイル名を指定してPOSTします。

```shell-session
$ curl -v -H "Authorization: token "$GITHUB_TOKEN \
  -H "Accept: application/json" -H "Content-type: application/octet-stream" -X POST \
  --data-binary @centos-6-5-x64-virtualbox.box \
  'https://uploads.github.com/repos/hnakamur/packer-templates/releases/129188/assets?name=centos-6-5-x64-virtualbox.box'
```

centos-6-5-x64-virtualbox.boxは564MBとかなりサイズが大きいのでアップロードにはかなり時間がかかりますが気長に待ちます。OS Xの場合はアクティビティモニタでプロセス名、% CPUのヘッダでポップアップメニューを開いて送信バイト数にチェックを付けて、curlのプロセスを見ていれば進み具合がわかります。

自宅だと上り回線が細くて時間がかかりすぎたせいか以下のようにエラーになってしまいました。

```
...
> Expect: 100-continue
> 
< HTTP/1.1 100 Continue
< HTTP/1.1 502 Bad Gateway
< Cache-Control: no-cache
< Content-Length: 92
< Content-Type: application/json; charset=utf-8
< Strict-Transport-Security: max-age=2592000
< X-Github-Request-Id: 45afa34d-6a65-11e3-8593-dd0f7c7a03df
< Date: Sat, 21 Dec 2013 18:42:30 GMT
* HTTP error before end of send, stop sending
< 
* Closing connection 0
{"message":"Error uploading to S3: 403","request_id":"45afa34d-6a65-11e3-8593-dd0f7c7a03df"}
```

諦めてブラウザからreleaseの編集画面でファイルをドロップしてアップロードしました。

# base boxの利用

base boxを作成したマシンではローカルのcentos-6-5-x64-virtualbox.boxファイルを登録します。

```shell-session
$ vagrant box add centos6.5 centos-6-5-x64-virtualbox.box
```

他のマシンではGitHub releaseにアップロードしたbase boxのURLを指定してboxを登録します。

```shell-session
$ vagrant box add centos6.5 https://github.com/hnakamur/packer-templates/releases/download/v1.0.1/centos-6-5-x64-virtualbox.box
```