Hatena::ブログ(Diary)

kk_Atakaの日記 RSSフィード

 →kk_Atakaの日記@GitHub Pages(同一内容)

2013-06-05

Over-the-Airという形式でiOSアプリのインストールを試みるが失敗する場合がある

あらすじ

iOSアプリサーバに置いてそこからインストールできるようにしたかった。

  • 結果、Over-the-Airという方式でインストール環境を作り、インストールできるようなったので手順のメモ
  • と、なぜか失敗する端末もあるので、後半にその調査メモ(とりあえず、インストールはできたが、根本原因がわからん)

インストール環境構築手順

参考サイト

前提

まだよくわかってないところもあるので、以下は必要ない手順、ファイルも多いかも。。。

別の作業と混同している可能性も。

前準備

CertificateSigningRequest.certSigningRequest 準備

はじめに CertificateSigningRequest.certSigningRequestMac上で作成する

Destribution用Certificates 作成

実機にインストールできるという事は、Developer用のCertificateは作成済のはず。今回はDestribution用を作る。

  • Apple Developer から iOS Apps へ
  • Certificates -> All(なんでもいい) -> +アイコン で新しくCertificatesを作る
  • Select Type : App Store and Ad Hoc を選択
    • 1個作ったらそれ以上作れない? 改めて見に行ったらdisable状態で選択できなかったので、以降は記憶で
  • CertificateSigningRequest.certSigningRequest を選択
  • 作成されたDistribution Certificateをダウンロードしておく: ios_distribution.cer

Destribution用Provisioning Profile 作成

実機にインストールできるという事は、Developer用の以下略。

  • 引き続き Apple DeveloperiOS Apps
  • Provisioning Profiles -> All(なんでもいい) -> +アイコン で新しくProvisioning Profileを作る
  • Select Type : Ad Hoc を選択
  • Configure : Select App ID App ID を選択するが、前提で使っている実機にインストールする時に使っているProvisioning Profileと同じ App ID を選択
  • Configure : Select certificates 上で作成した時のDestribution用のCertificateファイルがあるはずなのでそれを選ぶ
  • Configure : Select devices インストールしたいデバイスを選ぶ
  • Generate : Profile Nameを入力
  • 作成されたDestribution Provisioning Profile をダウンロードしておく: PROJECT_NAME.mobileprovision

ここまでで作ったファイルは、なんかうまくいかない時に使う かも

アプリ側準備

Provisioning Profileインストール

※ ここは、サーバPROJECT_NAME.mobileprovision を配備し、サーバ経由でインストールする方法もあるっぽい。

  • Xcodeからビルドしたいプロジェクトを起動する
  • Organizer -> Devices -> LIBRARY -> Provisioning Profiles に上で作った PROJECT_NAME のProvisioning Profileがある事を確認する
    • また、status が Valid profile になっている事を確認する
    • キーチェインへの登録とかがうまくいってないと、statusが 〜not found〜 みたいになる場合がある
  • インストールしたい端末と Xcode を接続する
  • Organizer -> Devices -> 接続した端末 -> Provisioning ProfilesPROJECT_NAME がある事を確認する
    • なければ、LIBRARYのProvisioning Profileからドラッグ&ドロップしたりして持ってくる

ipaファイル作成

  • 引き続きXcode
  • Organizerからプロジェクトに戻りBuild Settingsへ
    • Code Signing Identity を iPhone Distribution: へ変更(必要?)
  • Product -> Archive を選択
  • アーカイブ化が成功したら Organizer -> Archives 画面が起動する
    • 作成されたアーカイブを選択し Distribute... 選択
    • Select the method of distribution : Save for Enterprise or Ad-Hoc Deployment 選択
    • Choose an Identity to sign with : https://developer.apple.com で作成した iOS Distribution が存在するはずなので、それを選択
    • Save as : 保存場所とファイル名を選択、 Save for Enterprise Distribution にチェックを入れる
  • helloworld.ipahelloworld.plist が作成される

ダウンロードページ準備

※ 作らなくても、Safari等から決められたUrlを直叩きすればインストールできる。…が、長くて直叩きはめんどい

index.htmlとして、以下のようなリンクを持つページを作成する。

(略)
<body>
<a href="itms-services://?action=download-manifest&url=PLIST_FULL_PATH">Download !!</a>
</body>

サーバ配備

  $ cp index.html DOCUMENT_ROOT/
  $ cp helloworld.ipa DOCUMENT_ROOT/ipa/
  $ chmod 755 DOCUMENT_ROOT/ipa/helloworld.ipa 
  $ cp helloworld.plist DOCUMENT_ROOT/ipa/
  $ chmod 755 DOCUMENT_ROOT/ipa/helloworld.plist

ダウンロードするのでアクセス権限を変更しておく。

アクセスインストール

うまくいかない場合

ここからが本題。

大体うまくいくんだけど、一部うまく場合がある。なんでかがわからない。

パターン1

iOS Deployment Target のバージョンより低いバージョンの端末でインストールしようとした場合、エラーダイアログとともに失敗する。

これは凡ミスなので、TargetのiOSバージョンを下げてやればよい。

パターン2

未遭遇だが、Provisioning Profileが正常にインストールされていない場合などもこけるはず。

設定アプリの一般からプロファイルを確認。

パターン3(未解決)

これで困った。

  • Safariにて、index.htmlに記載されたリンクを叩きインストール開始
  • 端末の画面がSafariからホーム画面に遷移
  • アイコンが現れ、 待機中… と表示される
  • そこで止まる!
    • エラーなし、警告なしでずっと待機中のまま

iOSのバージョンとかにもよるのかと思ったが、違うっぽい。インストールできてる端末もあるし、Provisioning Profileも入ってるから端末の問題と思われる。

内部のログとか見れないかと調べていると、2通りの方法で調べられた。

  1. XcodeOrganizer -> 端末 -> Console
  2. Appleから iPhone 構成ユーティリティ アプリダウンロード

どっちも端末とMacを接続すれば使える。

…で、確認してみたら以下のようなログが延々と出ていた。

May xx xx:xx:xx iOS端末名 com.apple.launchd[1] (com.apple.ubd) <Notice>: (com.apple.ubd) Throttling respawn: Will start in 1 seconds
May xx xx:xx:xx iOS端末名 com.apple.launchd[1] (com.apple.ubd) <Notice>: (com.apple.ubd) Throttling respawn: Will start in 1 seconds
May xx xx:xx:xx iOS端末名 com.apple.launchd[1] (com.apple.ubd) <Notice>: (com.apple.ubd) Throttling respawn: Will start in 1 seconds
May xx xx:xx:xx iOS端末名 com.apple.launchd[1] (com.apple.ubd) <Notice>: (com.apple.ubd) Throttling respawn: Will start in 1 seconds
May xx xx:xx:xx iOS端末名 com.apple.launchd[1] (com.apple.ubd) <Notice>: (com.apple.ubd) Throttling respawn: Will start in 1 seconds
(略)

うーん、なんだろうこれ。

とりあえずエラーメッセージでググってみた。

launchdはプロセスの起動を制御するデーモンプロセス

こやつがubdを1秒毎に呼ぼうとしてる?

ubdとはなんぞや…。

“ubd” is the Ubiquity Server Process.

何者なんだ…。OSXの方でなにやらエラーログを出しまくるという現象あり。

iCloud関係なの?確かにログインはした事あるけど、今はログアウト済なんだよなあ。

また、iPhone5バッテリー持ちが4よりもひどいという所ではまったく同じログを吐いている人も。

ただし、決定打ではない…。

困り果てているところへこんな情報。(OSXっぽいけど)

This message would repeat in the logs every 10 seconds.

And would continue to repeat even after the offending application had been force quit.

A quick search for com.apple.ubd shows it is the iCloud synchronization daemon.

しかも

正常にインストールできるようになってからも、インストール失敗した端末だけは依然として

May xx xx:xx:xx iOS端末名 com.apple.launchd[1] (com.apple.ubd) <Notice>: (com.apple.ubd) Throttling respawn: Will start in 1 seconds

ログは出続けている…。

インストールできない問題と、このエラーメッセージは関係ないの!?

数ある内の一台だけ…なぜ。

2013-05-27

Jekyll@GitHub Pagesの運用形態を変えたのでAnalyticsの設定が効かなくなっていた

あらすじ

Jekyllで指定していたGoogle Analyticsの設定が効かなくなっていた。

他のGitHub Pages@Jekyllでは正しくGoogle Analyticsが動いているのに…。

結論

おぉ…。

参考サイト

ハマり

前提: GitHub Pagesの運用形態

指定のブランチに以下のようなファイル群を置いておく事で、GitHub Pagesができる。

  1. Jekyllのコンテンツ
    • Jekyllに必要なファイルをpushしておけば、GitHubがよろしくデプロイしておいてくれる
  2. 静的ファイル
    • そのまま表示される

Jekyllのコンテンツをpushして、後はおまかせするだけの運用は便利だけど、 自作プラグインが動かない という問題がある。

プラグインを動作させるためには、以下のように、あらかじめローカルでビルドした静的ファイルをpushしなければならない。

  • master 以外の別ブランチ(仮に source ブランチ)を作成し、そこでJekyllのコンテンツを管理する
  • ローカルの source ブランチで編集を終えたら、 jekyll build
  • 生成された成果物を master ブランチにpushする
    • ローカルでbuildしているので、プラグインが動作した状態で静的ファイルが出来ている
    • こんな感じの手法をとっているのがOctopress

この情報をもとに、Rakefileにdeployコマンドを作った。

https://github.com/gosyujin/gosyujin.github.com/blob/source/Rakefile

# Usage: rake deploy
desc "Begin a push static file to GitHub"
task :deploy do
  sh "jekyll build"
  puts "! Push to source branch of GitHub"
  sh "git push origin source:source"
()

analyticsの設定はどう読み込まれているのか

_includes/JB/analytics を見ると、analyticsを読み込むには以下の条件を満たす必要がある。

{% if site.safe and site.JB.analytics.provider and page.JB.analytics != false %}

{% case site.JB.analytics.provider %}
{% when %}
  {% include JB/analytics-providers/google %}
()

大事なのは、 site.safe がtrue である事。

このsafeオプションがtrueになっている条件を見落としてた。trueじゃないとanalytics読み込みはなされない。

しかし…。

※ safeはデフォルトではfalse

$ bundle exec jekyll --help
    jekyll
(略)
    --safe 
        Safe mode (defaults to false)

https://help.github.com/articles/pages-don-t-build-unable-to-run-jekyll 本家のhelpでも --safe オプションよろしく!とのこと。

GitHubがJekyllのコンテンツをデプロイする際は、必ず --safe がつけられる。(そのため、自作プラグインが動かなくなる)

しかし、safeがfalseじゃないと自作のプラグインを動かせないので、 _includes/JB/analytics から if site.safe の条件を削除する事で対応。

ローカルで埋め込んだ後で、pushすればいい。


以下、どこが原因かわからなかったので、Jekyll Bootstrapのデフォルトファイルを読んでいった結果。

蛇足

ディレクトリ構成

Jekyll Bootstrapを落としてくるとファイル構成はこう。

その中の _layouts ディレクトリの中にテンプレート的なファイルがある。

htmlを見てみると…。

$ cat _layouts/default.html
---
theme :
  name : twitter
---
{% include JB/setup %}
{% include themes/twitter/default.html %}

$ cat _layouts/page.html 
---
layout: default
---
{% include JB/setup %}
{% include themes/twitter/page.html %}

$ cat _layouts/post.html 
---
layout: default
---
{% include JB/setup %}
{% include themes/twitter/post.html %}

こんな感じ。はじめのハイフンで囲まれたエリアはyaml front matter? http://jekyllrb.com/docs/frontmatter/

続いて、JB/setupthemes/twitter/default.html page.html post.html をインクルードしている。

layout: default と書かれている page.html と post.html は default.html を親にしている事がわかる。

include JB/setup

_layout/default.html 一つ目の include である JB/setup を見てみる。 include なだけあって、 _includes ディレクトリにある。

{% capture jbcache %}
  <!--
  - Dynamically set liquid variables for working with URLs/paths
  -->
  {% if site.JB.setup.provider == %}
    {% include custom/setup %}
  {% else %}
    {% if site.safe and site.JB.BASE_PATH and site.JB.BASE_PATH != '' %}
      {% assign BASE_PATH = site.JB.BASE_PATH %}
      {% assign HOME_PATH = site.JB.BASE_PATH %}
    {% else %}
      {% assign BASE_PATH = nil %}
      {% assign HOME_PATH = %}
    {% endif %}

    {% if site.JB.ASSET_PATH %}
      {% assign ASSET_PATH = site.JB.ASSET_PATH %}
    {% else %}
      {% capture ASSET_PATH %}/assets/themes/{% endcapture %}
    {% endif %}
  {% endif %}
{% endcapture %}{% assign jbcache = nil %}

site.JB.hogehogeの設定を確認して、パス設定などしているよう。

この site.JB.hogehoge っていうのは _config.yml に定義しているパラメータだよね。こんな感じで定義されている。

JB :
  version : 0.3.0
  BASE_PATH : false
  ASSET_PATH : false
  archive_path: /archive.html
  categories_path : /categories.html
  tags_path : /tags.html
  atom_path : /atom.xml
  rss_path : /rss.xml
  (略)

どんな値になっているのか確認のため、 JB/setup の先頭に以下のような出力を足してみる。

safe {{site.safe}} <br>
site.JB {{site.JB}} <br>
provider {{site.JB.setup.provider}} <br>
base {{site.JB.BASE_PATH}} <br>
asset {{site.JB.ASSET_PATH}} <br>
page name {{ page.theme.name }}
{% capture jbcache %}

で、実行結果。

safe false 
site.JB {"version"=>"0.3.0", "BASE_PATH"=>false, "ASSET_PATH"=>false, "archive_path"=>"/archive.html", "categories_path"=>"/categories.html", "tags_path"=>"/tags.html", "atom_path"=>"/atom.xml", "rss_path"=>"/rss.xml", "comments"=>{"provider"=>"disqus", "disqus"=>{"short_name"=>"jekyllbootstrap"}, "livefyre"=>{"site_id"=>123}, "intensedebate"=>{"account"=>"123abc"}, "facebook"=>{"appid"=>123, "num_posts"=>5, "width"=>580, "colorscheme"=>"light"}}, "analytics"=>{"provider"=>"google", "google"=>{"tracking_id"=>"UA-123-12"}, "getclicky"=>{"site_id"=>nil}, "mixpanel"=>{"token"=>"_MIXPANEL_TOKEN_"}}, "sharing"=>{"provider"=>false}} 
provider 
base false 
asset false 
page name twitter

なるほど。実行結果的にはifの最後を通っているようなので、 ASSET_PATH の設定をしている事になる。

ASSET_PATH = /assets/themes/twitter となった。

include themes/twitter/default.html

_layouts/default.html の二つ目の include。一部を除き、htmlがつらつらと…。

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>{{ page.title }}</title>
    {% if page.description %}<meta name="description" content="{{ page.description }}">{% endif %}
    <meta name="author" content="kk_Ataka">

    <!-- Enable responsive viewport -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
(略)
    <div class="container-narrow">

      <div class="content">
        {{ content }}
      </div>
      <hr>

動的に表示させたい部分はliquidで埋め込んでいる。{{ }} とか {% %} で始まる部分がそう。

で、 content 部分に子?の内容が埋め込まれるのか。

まとめ

rake post title=hoge として作った _posts/2013-xx-yy-hoge.md を表示するためには、こんな風に埋め込みしていっている?

jekyll-page

2013-05-23

記事の目次を出力するJekyllプラグインの改良

前回までのあらすじ

Jekyll(Liquid)で記事の目次を出力するプラグインを作ってみた

これの続き。昔の話すぎて、忘れないようにメモ。

前回の疑問

…あれ? 別の環境でやったら hタグに section , section-1 , section-2 … って連番が振られてる!? なんで!

これは原因がわかった。 使っているMarkdownパーサが違うだけだった。

  • rdiscount … idなし
  • kramdown … idにsection-xが振られる

今回やったこと

  • kramdownで動くようにkramdownいじったりtree_list.rbいじったり
  • プラスバグ修正

目次から記事へのリンク

(略) めんどいので自動で振ってほしい

kramdownのidの振り方

kramdownがhタグにidを振っている方法を調べてみると、

  • 半角文字はそれが そのままid になる
  • スペースは ハイフン になる
  • 全角文字は なくなる
  • 全部全角文字だった場合 section と振られる
  • 2度目以降のsectionは順に section-x と振られる

こんな感じになっているっぽい。以下は一例。

見出しの内容 hタグのid
ほげいち <h4 id=”section”>ほげ
ほげに <h4 id=”section-2”>ほげに
ほげさん <h4 id=”section-3”>ほげさん
hoge <h4 id=”hoge”>hoge
piyoとは <h4 id=”piyo”>piyoとは
ほげよん <h4 id=”section-4”>ほげよん

ソース

実際にソースを見てみよう。 kramdown-0.14.0\lib\kramdown\converter\base.rb に書いてあった。めんどくさいので 今回は全ての見出しがsectionとなってほしいので、以下の行をコメントアウトした。

# Generate an unique alpha-numeric ID from the the string +str+ for use as a header ID.
#
# Uses the option +auto_id_prefix+: the value of this option is prepended to every generated
# ID.
def generate_id(str)
  gen_id = str.gsub(/^[^a-zA-Z]+/, '')         # コメントアウト
  gen_id.tr!('^a-zA-Z0-9 -', '')               # コメントアウト
  gen_id.tr!(' ', '-')                         # コメントアウト
  gen_id.downcase!                             # コメントアウト
  gen_id = 'section' if gen_id.length == 0     # if 以降をコメントアウト
  @used_ids ||= {}
  if @used_ids.has_key?(gen_id)
    gen_id += '-' << (@used_ids[gen_id] += 1).to_s
  else
    @used_ids[gen_id] = 0
  end
  @options[:auto_id_prefix] + gen_id
end

これで半角だろうが全部section-xと振られるようになった。

…が、よく考えたら自分のプラグインでこれと同じ処理をしたら良かったんじゃ…。

tree_list.rbのバグ修正

目次に貼ったリンクが正しい見出しに飛んでいるか確認してたら、一個バグ見つけた。

  • 引用部分の見出しにもidが振られるが、tree_listでは文頭にある見出ししか集めてなかった
    • でも、正直引用部分の見出しは目次にはいらない…
      • 集めるだけ集めて捨てるか…

2013-05-21

GitHub PagesでJekyllプラグインを使えるようにするには…

あらすじ

Jekyll@GitHub Pagesの場合、Liquidで(自分で)作ったプラグインは使えないという事が判明した。(ローカルで起動した場合/safeモードじゃない場合は関係ない)

これを回避するには

する方法がありそう。今回はGitHub Pagesを使い続けたいので後者で頑張ってみる。

参考サイト

そもそもGitHub Pagesとはなんぞや

User & Organization Pages

User & Organization Pages はPagesファイル専用のスペシャルリポジトリとして生きている。このリポジトリはaccount nameを使用する。例えば、defunkt/defunkt.github.com

  • このリポジトリusername/username.github.com というnaming schemeを使わなければならない
  • master ブランチからのコンテンツはビルドとパブリッシュに使用される

Project Pages

Project Pages は同じリポジトリからプロジェクトとして維持される。これらのページはUser PageとOrg Pagesほとんど正確に同じである。いくつかのわずかな違いはある。

  • gh-pages ブランチはビルドとパブリッシュに使用される
  • カスタムドメインを使っていないなら、Project PagesはUser Pageのサブパスの下で使われる。 username.github.com/projectname

ということは

まず、GitHub Pagesは2種類ある。

  1. ユーザ、組織用 のページ
  2. プロジェクト のページ

という事でよろしい?

かぶった場合どうなる?

ところで、こうなるとユーザのGitHub Pagesにプロジェクト名と同じ階層でファイルを作ったらどっちが呼ばれるの?

=> あーありがち - github pagesとjekyllを今さら練習 , 夏だ によると、

  1. github.com/wtnabe/wtnabe.github.com 内に /ical2gcal/index.html を作成
    • 作った /ical2gcal/index.html が wtnabe.github.com/ical2gcal/ に表示される
  2. github.com/wtnabe/ical2gcal に gh-pages branch を作る
    • 作った gh-pages が wtnabe.github.com/ical2gcal/ に表示される
  3. github.com/wtnabe/wtnabe.github.com/ical2gcal/index.html を編集
    • 今編集したファイルが表示される。つまり 1 に戻る。

ちょっと気をつけないといけない。

GitHub Pagesの作り方

プロジェクト用のGitHub Pagesの場合。

既に master が少し育っているとして gh-pages ブランチを作成してみる。とりあえず、GitHubから以下のようなコマンド例が提示される。

$ cd /path/to/repo-name
$ git symbolic-ref HEAD refs/heads/gh-pages
$ rm .git/index
$ git clean -fdx
$ echo "My GitHub Page" > index.html
$ git add .
$ git commit -a -m "First pages commit"
$ git push origin gh-pages

何をやっているのかというと… master ブランチ(というか、ソースとかがある本流のブランチ?)と 独立した空っぽのブランチ を作り、そこにindex.htmlをpushしている。

コマンド、オプションのメモ

$ cd /path/to/repo-name
$ git symbolic-ref HEAD refs/heads/gh-pages

HEAD(.git/HEAD)ファイル には最終コミットの参照が入っている。例えば…

$ cat .git/HEAD
ref: refs/heads/master

こんなん。で、checkoutとかすると変わる。このHEADファイルを変更するためのコマンドが symbolic-ref

移動した後は、Gitで管理していたファイルはインデックスに移っている。

$ rm .git/index
$ git clean -fdx

ので、まず index ファイルを削除してインデックスにあったファイルを追跡対象から除外。

そして clean コマンドで追跡対象外のファイルを掃除。 -f 実行(このオプションを指定しないと実行されない)、 -d ディレクトリも含める。 -x 無視ファイルも削除

$ echo "My GitHub Page" > index.html
$ git add .
$ git commit -a -m "First pages commit"
$ git push origin gh-pages

奇麗さっぱりしたらindex.htmlを作ってFirst commit…。

これで master ブランチ(ソース)とは完全に独立した gh-pages ブランチが作成できた。

JekylプラグインGitHub Pagesで使えるようにするには

さてようやく本題。

今までの情報からわかった事は以下。

  • 自分が使っているのは ユーザ用のGitHub Pages
    • つまり、 master ブランチのファイルがビルドされる
  • 今の master ブランチにはJekyll用のソースがある

この状況を以下のように変更する。

  • source ブランチ: 現在の master ブランチのソースをそのまま持ってくる
    • エントリなどはこちらで書いていく事になる
  • master ブランチ: 一旦からっぽにして、 source ブランチのソースから生成した 静的ファイル を持ってきてプッシュする
    • ローカルで一旦生成しちゃった後でGitHub Pagesにpushしているから、プラグインが動かないという問題も起こらない

そうすると

  • source ブランチでファイルを生成する(_site/直下)
  • これを master にコピーする
  • push

を毎回やらなければならない…それはめんどくさい!

これはrakeでやればいいかな。

こんな感じ。

# Usage: rake deploy
desc "Begin a push static file to GitHub"
task :deploy do
  puts "! Copy static file from _site to _deploy"
  sh "cp -r _site/* _deploy/"
  puts "! Change directory _deplay"
  cd "_deploy" do
    puts "! Push to master branch of GitHub"
    sh "git add *"
    message = "deploy at #{Time.now}"
    begin
      sh "git commit -m \"#{message}\""
      sh "git push origin master:master"
    rescue Exception => e
      puts "! Error - git command abort"
      exit -1
    end
  end
end

とやれば、手間はそれほど変わらずにGitHub PagesでJekyllプラグインが使えるか。

2013-04-28

BPStudy#68に参加しました #bpstudy

詳細

テーマはChef。

入門からChefの実運用例まで。

所感

第1部 明日からはじめる Chef 入門

http://www.slideshare.net/slideshow/embed_code/20014957

サーバ、どうやって構築している?

手順書?Wikiを見て?職人がやってる?

よくある話

  • 手順書通りにやってもうごかない
  • サーバごとに設定がちがう
  • 手順を飛ばしちゃって事故る
    • 手作業で複数だいは辛い
    • クロスチェック欄など…

自動化しよう!

どうやってやる?

環境構築について、継続的デリバリーにはこう書かれている。

本番環境と同じ方法で開発環境を構築する

自動化ツールについて

アプローチの違い

  • 手順ベース
    • 手順を意識する必要
    • 手作業と混ぜやすい
  • 定義ベース
    • あるべき姿を定義(例: nginxが入っているべき)
    • 何度実行してもよい = 冪等性 を持つ
    • 定義の仕方は覚えないといけない
    • 大抵は 、状態を意識しなくてよい

インストールが必要か

他の構成ツール

こんなにあるとは…fabricpuppetくらいしか聞いた事なかった。

Chef

Chefができること

  • OS、ファイル、パッケージの操作
  • サービス起動/停止
  • ユーザ作成
  • gemなどのインストール

Chef特徴

Chefの種類

  • Chef-Server Chef-Client
  • Hosted Chef(ASP)
    • サーバが大量にある場合有効かも
  • Chef-solo
    • 練習用 / サーバが少ない場合これでも回せる
    • 20台以下くらいならこれで

インストール

の前に

は準備必要。

  • Rubyが入っていなくてもcurlでいける

環境構築

  • 設定対象を決める
  • Community siteでクックブックで探す
  • 試す
  • だめだったら自分で書く

はじめにCommunityからクックブックを探してみるとよいという話。

ただし、固執し過ぎるとハマる。

必要なファイル

  • solo.rb
    • 設定ファイル
  • sodo.json
    • run_list 実行するクックブックを列挙
      • file_cache_path
      • cookbook_path
    • attributes 設定情報、クックブックのREADMEを見てみるとよい

自分でクックブックを作ってみる

knifeコマンドで。

利用事例

周辺ツール

  • vagrant
    • vmを使い捨てられる
  • librarian-chef berkshelf
    • Ruby のbundlerのようなもの
      • Jenkinsクックブック入れようとしたらJavaが必要などの依存を解消してくれる
  • knife-solo paratrooper-chef
    • chef-soloをリモート実行するツール

Chefのデメリット

  • community cookbookの不備
  • 全員がChefを覚える必要がある
    • 手動で書き換えたところにChefで流し込むと、手動の部分が消えてしまう
  • まだ定石がない
  • テストが難しい
    • serverspec, chefspecが候補
  • はじめるにはコストが掛かる

第2部 Chefで構築するBP-Redmine環境

実際の導入事例の紹介。

  1. BeProudのRedmine環境
  2. Webサービスサーバ構成(10台)

BP-Redmine

Redmineの管理

  • メンテナンスが大変
  • 構築手順が残っていない or 残っていても集めるのが大変(Wikiとかに散らばってる)

それならChefでまとめる。

セットアップ内容

Apache, Redmine, Ldapなどを入れていく方針…。

しかし、一部GUI必須のインストール(Skypeなど)がある。

GUIインストールもChefでできるかもしれないが、今回は切り離して考える。

使用ツール

Webサービス

セットアップ内容

サーバの役割

役割ごとにRoleでグルーピング

環境別にenvironment的に分け。(Chef 11.4.0ではenvironmentをサポートしていないため)

クックブック

  • opscodeとgithubから持ってきたもの
  • 案件に依存するものは自作

課題など

  • 鍵とかはどう管理するか