前回[2015-01-09-1] はBerksfileにGitリポジトリを直接書きましたが、レ
シピの依存関係の解決ができませんでした。

berkshelf-apiサーバを立てるとその問題が解消されるようなので、
Herokuにberkshelf-apiサーバを立てて検証してみました。

適当なOrganizationを作り

$ berks cookbook git .
などで作ったcookbookを用意します。gitのtagを振る必要がある点は注意です。

https://github.com/doramichan/git/releases
https://github.com/doramichan/hub/releases

berksコマンドは

$ gem install berkshelf
などでインストールできます。

hubレシピはgitレシピに依存させた ため、Berksfileに

cookbook ‘hub’
と書けばgitレシピもインストールされるはずです。
※適当なレシピなので動作は保証しません。

次にapiサーバを用意します。Heroku stackがcedar-14だと動かなかった
のでcedarに変更しています。LD_LIBRARY_PATHの追加はREADME.md の説明
のとおりです。

$ git clone [email protected]:berkshelf/api.berkshelf.com.git
$ cd api.berkshelf.com
$ heroku create -s cedar masutaka-api-berkshelf
$ heroku config:add LD_LIBRARY_PATH=/app/vendor/libarchive-3.1/lib
$ git push heroku master

続けてconfig.jsonを追加し、先ほどのdoramichan Organizationを参照さ
せます。

{
    "endpoints": [
        {
            "type": "github",
            "options": {
                "organization": "doramichan",
                "access_token": "YOUR GITHUB ACCESS TOKEN",
                "api_endpoint": "https://api.github.com",
                "web_endpoint": "https://github.com",
                "ssl_verify": true
            }
        }
    ],
    "build_interval": 180.0
}

access_tokenはGitHubのSettings->Applications から作成したものを指定
します。

build_intervalを指定しているのはデフォルトが5秒でend_point(GitHub)
にアクセスしに行く鬼畜仕様だったためです。180秒に変更しました。

Procfileも修正しcommit、$ git push heroku masterします。

web: bundle exec berks-api -p $PORT -c config.json

なんか取れたっぽい!

$ curl https://masutaka-api-berkshelf.herokuapp.com/universe | jq .
{
  "git": {
    "0.1.0": {
      "endpoint_priority": 0,
      "platforms": {},
      "dependencies": {},
      "location_type": "github",
      "location_path": "https://github.com/doramichan/git"
    }
  },
  "hub": {
    "0.2.0": {
      "endpoint_priority": 0,
      "platforms": {},
      "dependencies": {
        "git": ">= 0.1.0"
      },
      "location_type": "github",
      "location_path": "https://github.com/doramichan/hub"
    },
    "0.1.0": {
      "endpoint_priority": 0,
      "platforms": {},
      "dependencies": {
        "git": ">= 0.0.0"
      },
      "location_type": "github",
      "location_path": "https://github.com/doramichan/hub"
    }
  }
}

ではBerkshelfを使ってcookbookをインストールしてみましょう。まずは
Gemfileを作成し、$ bundle install --path vendor/bundleなどで
berkshelfをインストールします。

source 'http://rubygems.org/'
ruby '2.2.0'

gem 'berkshelf'

次にBerksfileを作成しhubレシピを指定します。前述のとおりgitレシピ
に依存するように作ったため、gitレシピもインストールされるはずです。

source 'https://masutaka-api-berkshelf.herokuapp.com'

cookbook 'hub'

$ berks vendor vendor/cookbooksで無事インストールされました。

vendor/cookbooks
├── git
│   ├── Berksfile
│   ├── Gemfile
│   ├── LICENSE
│   ├── README.md
│   ├── Thorfile
│   ├── chefignore
│   ├── metadata.json
│   └── recipes
│       └── default.rb
└── hub
    ├── Berksfile
    ├── Gemfile
    ├── LICENSE
    ├── README.md
    ├── Thorfile
    ├── chefignore
    ├── metadata.json
    └── recipes
        └── default.rb

chef-soloの場合.chef/knife.rbを以下のように変更すれば
vendor/cookbooks以下のレシピを参照できます。

cookbook_path [“cookbooks”, “site-cookbooks”]

cookbook_path [“cookbooks”, “site-cookbooks”, “vendor/cookbooks”]

◆解決できたこと

  • 前回[2015-01-09-1] レシピの依存関係を見てくれなかった問題

◆まだ困っていること

  • レシピをGitHubのOrganization直下に置く必要があるため、private
    repositoryの運用は現実的でない
  • berkshelf-apiサーバに認証を付けられるかは調べていない
  • cedar-14でも動くようにしないと

◆参考にした記事
chef - berkshelf-apiで自前のcookbookサーバを立てる - Qiita
github:eで管理しているChefのクックブックを、Berkshelf APIサーバーを立てていい感じに依存解決する方法 - (ひ)メモ