production.log

株式会社リブセンスでエンジニアをやっている星直史のブログです。

Solr 4.10.4でレプリケーション(master-slave構成)を試してみました。

ピクスタの開発部で開発合宿を開催したので、
そのネタとして、Solr4.10.4でのレプリケーション(master-slave構成)を今更ながら試してみることにしました。
前回の記事はこちらです。

また参考にした書籍は↓こちらです

レプリケーションの設定(master)

$ cp -R solr-4.10.4/example/ solr-4.10.4/master1
$ cd ~/solr-4.10.4/master1
$ vim solr/collection1/conf/solrconfig.xml

上記ファイルを開いたら、下記のように編集します。

  <requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="master">
      <str name="replicateAfter">commit</str>
      <str name="replicateAfter">optimize</str>
      <str name="replicateAfter">startup</str>
      <str name="confFiles">schema.xml,stopwords.txt</str>
    </lst>
  </requestHandler>

こちらの設定はcommit, optimize, 起動直後にslaveに対してレプリケーションを実行するという設定です。

続いて、Slave側の修正もしましょう。

レプリケーションの設定(slave)

$ cp -R solr-4.10.4/example/ solr-4.10.4/slave1
$ cd ~/solr-4.10.4/slave1
$ vim solr/collection1/conf/solrconfig.xml

上記ファイルを開いたら、下記のように編集します。

  <requestHandler name="/replication" class="solr.ReplicationHandler" >
    <lst name="slave">
      <str name="masterUrl">http://localhost:8983/solr/collection1</str>
      <str name="pollInterval">00:00:30</str>
    </lst>
  </requestHandler>

こちらは、masterURLを指定しており、ポーリング間隔を30秒にしています。

これでレプリケーション(master-slave構成)設定は完了です。
それぞれ起動してみましょう。

$ cd ~/solr-4.10.4/master1
$ java -jar start.jar
$ cd ~/solr-4.10.4/slave1
$ java -Djetty.port=8985 -jar start.jar

http://locahost:8983/solr/#/にアクセスし、
collection1のreplicationタブを確認すると、Disable Replicationというボタンが表示されていることが確認できます。
f:id:watasihasitujidesu:20160124001449p:plain

続いてslaveの確認をしてみましょう。
http://locahost:8985/solr/#/にアクセスし、
collection1のreplicationタブを確認すると、Replication Nowボタン、Disable Polingボタンが表示されていることが確認できます。
f:id:watasihasitujidesu:20160124001453p:plain

これらのボタンを押すと、ボタンのキャプションの通り、下記の動作ができます。

GUIでサクッとレプリケーションの確認ができるなんて3系のadmin画面を知っている身からすると、
なんだか嬉しいような切ないような気持ちになりますね。
甥っ子がいつの間にか大人になっていた的な。
(個人的には3系の無骨な画面も好きだったりします。)

今回で分散インデクシングレプリケーション(master-slave構成)を学んだので、
お次は待望のSolrCloudを試してみましょ〜!

Solr 4.10.4で分散インデクシングを試してみました。

ピクスタの開発部で開発合宿を開催したので、
日頃からお世話になっているCloudSearchの内部を少しでも知るべく、
Solr 4から登場した分散インデクシングを今更ながら試してみることにしました。

参考にした書籍は↓こちらです

合宿中に検証したことは下記の通りです。

今回の記事では

  • 分散インデクシング(Sharding)

この部分について触れようと思います。

Solr 4.10.4を配置

$ wget http://ftp.jaist.ac.jp/pub/apache/lucene/solr/4.10.4/solr-4.10.4.tgz 
$ tar zxvf solr-4.10.4.tgz

分散インデクシング(Sharding)

$ cp -R solr-4.10.4/example/ solr-4.10.4/master1
$ cp -R solr-4.10.4/example/ solr-4.10.4/master2
$ cd ~/solr-4.10.4/master1/
$ java -jar start.jar &
$ cd ~/solr-4.10.4/master2/
$ java -Djetty.port=8985 -jar start.jar &
$ cd ~/solr-4.10.4/master1/exampledocs
$ java -Durl=http://localhost:8983/solr/collection1/update -jar post.jar [a-m]*.xml # master1 にインデクシング
$ cd ~/solr-4.10.4/master2/exampledocs
$ java -Durl=http://localhost:8985/solr/collection1/update -jar post.jar [n-z]*.xml # master2 にインデクシング

結果

# ipad solrという文字列を検索
$ curl "http://localhost:8983/solr/collection1/select?shards=localhost:8983/solr/collection1,localhost:8985/solr/collection1&indent=true&q=ipod+solr" | grep '<str name="id">'
    <str name="id">IW-02</str>
    <str name="id">F8V7067-APL-KIT</str>
    <str name="id">SOLR1000</str>
    <str name="id">MA147LL/A</str>

良い感じに4件取得できました。
query stringのshards=localhost:8983/solr/collection1,localhost:8985/solr/collection1という部分で、
分散インデクシングされたdocumentをまとめて取得しています。

念のため本当にまとめて取得してきているか確認してみましょう。

$ curl "http://localhost:8983/solr/collection1/select?indent=true&q=ipod+solr" | grep '<str name="id">'
    <str name="id">IW-02</str>
    <str name="id">F8V7067-APL-KIT</str>
    <str name="id">MA147LL/A</str>

$ curl "http://localhost:8985/solr/collection1/select?indent=true&q=ipod+solr" | grep '<str name="id">'
    <str name="id">SOLR1000</str>

port番号8983と8985に同一のクエリを投げた結果です。
8983からは3件, 8985からは1件取れてきたので、合計4件となり、分散インデクシングに成功しています。

Solr3時代ではレプリケーションしてLBで振り分けなければいけなかったものが、
シャーディングすることによってサーバーあたりのindex容量が下げられるのはだいぶ大きいと思いました。

注意すべき点

ただし、documentをindexに登録する際に、サーバーによって偏りがあると、
システム全体の検索応答速度は、最もレスポンスが遅いサーバーに引っ張られます。
そのため登録の際は、ラウンドロビン / ハッシュの剰余による分配など検討する必要があります。

また、リクエスト数上限によるデッドロック、URL(getリクエスト時)制限やエラーによる単一障害によるシステム全体のダウンもあるので、
十分に注意して構築していく必要があります。

「ついていきたい」と思われるリーダーになる51の考え方 を読みました。

ひょんなことから、リーダーポジションになり、色々勉強してきたのですが、
いわゆる"理想の上司"的な人物像について書かれている本が多く、少し懐疑的になっていました。
そんな時に「ついていきたい」と思われるリーダーになる51の考え方という本を読んだので、
その感想を書きます。

リーダーは完璧でなければいけないのか?

この本の読者層は、マネージャー / リーダーなど、部下が一人でもいる方です。

先のエントリでも書きましたが、やはりリーダー像って、
(だいぶ抽象的ですが)

  • 仕事ができる
  • リーダーシップがある
  • プレゼンとか話がうまい
  • カリスマ性がある

などなど、完全無欠のビジネスパーソンが頭に浮かぶのですが、
この本は、「いやいや、そんなことないよ〜。頑張れば誰でもリーダーになれるよ〜」
っと、全てのリーダーが上記のようなリーダーではないということについて書かれています。

この本を読むと、人間力を高める(磨く)ことがリーダーの最低条件だなということが学べました。

  • 誠実
  • 信頼できる
  • 責任感がある
  • 人に優しい
  • 気配りができる

などなど、著者のエピソードを基に、いかに人間力が重要かについて書かれています。

この本を読んで、理想のリーダーになったる!!!!!!!といった感じで、
鼻息を荒くして行動していたのですが、こういうリーダーもいるということが学べました。

これまで、自分のことばかり考えていたなぁと反省したのと、
自分一人ではなく、メンバーと協力して大きな仕事をしていくのが重要だと気付きが得られました。

上司のルール を読みました。

ひょんなことから、リーダーポジションについたので、
まずは、理想のリーダー像を学ぶことを目的に 上司のルールという本を読みました。

今回はその感想を書きます。

理想の上司がとる行動とは?

この本の対象読者は、"1人でも部下ができた人"です。

この本は、2部構成です。

  1. 部下を育てる時のルール
  2. 上司力を磨くルール

全100ルールが1ルールごとに見開きで書かれているのと、 あまり前後関係がないので、隙間時間に読むのに最適です。

内容としては、リーダーはどのような人格の人なのか? という点について、それをルールとして書かれています。

例えば、下記のルールがあります。

  • 褒め、励ます
  • チームのために戦う
  • 懸命に働く
  • 会社の目的を忘れない

おそらく誰しも、ぼやっとした"理想の上司像"があると思いますが、 その人物像の行動や思想を全て明文化したのがこの本です。

ここに書かれているルールを全て実践できている人は、圧倒的な信頼を得ているんだろうなと想像できます。

一定の期間で、この本のルールを鑑みて、振り返りをしていけば、 おのずと、模範となるマネージャー / リーダーになれるのではないのかと思います。

人を動かす を読みました。

色々な人と接する機会が増えたので、今更ながら
人を動かすを読みました。
今回はその感想を書きます。

人と接するときの基本思想が学べる一冊

対象読者は読者は人類全員です。

この本は、人と接するときの基本思想が学べる一冊です。 議論の最中に相手を論破しにいく行為は愚の骨頂であり、なんの価値も生まないことや、
傾聴力を上げるための方法論が書かれています。
また、タイトルの通り、人を動かす(やる気にさせる / 交渉する / 結婚生活をうまくいかせる / 人に頼み事をする)ときに有効な接し方も書かれているので、
会話の場面ごとに接し方を考えて行動するとうまく物事を運ぶことができるでしょう。

社会人であれば必読の一冊であることは間違いありません。

CircleCIで回しているRspecのテストを40%高速化しました

タイトルの通り、CirclCIで回しているテストを40%高速化した話をします。

うちの会社では、342files, 27300examples強を回しており、テスト時間が肥大化傾向にありました。
そこで、テスト高速化を図ろうと試行錯誤したので、その過程を書きます。
RRRSpec使えよ!というツッコミはなしで。CircleCI上で試行錯誤の記録を残すために書きます。

また、spec自体の高速化ではなく、CircleCIの仕様に合わせた高速化の方法についてのみを書きます。

やり方

なんと、この2つだけです!
シンプル!なんてシンプル!
並列実行して、遅いテストを特定するだけです。
そもそも技術力なんていりません。気合と根性*1で速くできます。

並列実行する

並列数を変更

CircleCIで並列実行数を増やすオプションがあります。

Project Settings => Tweaks => Adjust Parallelism
から設定ができます。

f:id:watasihasitujidesu:20150924222541p:plain

並列数増やせば(金で解決すれば)高速化できるんじゃね?っと、頭がよぎりましたが、
今回の話は、並列数は据え置きのまま(6並列)という縛りプレイでいきます。

もちろん、並列数は多いほど高速になります。

並列で実行するときに理解しておきたいこと

並列で実行する際、CircleCI上では複数コンテナを使ってテストを実行します。
理解しておきたいのは、複数コンテナ上実行されるテストはファイル単位となることです。
example単位ではないので、注意が必要です。

また、並列化した場合、テスト完了は、最も遅く終わったコンテナに引っ張られます。

  • コンテナA: 10分
  • コンテナB: 20分

この場合、CircleCI上では、テスト完了時間が20分になります。
要は、1コンテナあたりの実行時間限りなく、全コンテナの平均時間に近づけたいのです。

で、分散させる方法は下記の通りです。
1. まずはcircle.ymlを修正

この設定では、テスト実行を上書きしており、parallel: true (並列実行モード)にしています。

test:
  override:
    - ./script/parallel_for_circle.sh:
        parallel: true

では、parallel_for_circle.shを見ていきましょう。
2. 各コンテナで実行するテストは指定する方法

#!/bin/bash
set -xe

i=0
files=()
for file in $(find ./spec -name "*_spec.rb" | sort)
do
  if [ $(($i % $CIRCLE_NODE_TOTAL)) -eq $CIRCLE_NODE_INDEX ];then
    files+=" $file"
  fi  
  i=$((i+1))
done

echo $files
bundle exec parallel_rspec ${files[@]} -n 2
exit $?

CircleCIでは、並列実行時、各コンテナにCIRCLE_NODE_INDEXという、何個目のコンテナか?というインデックスが振られます。
また、CIRCLE_NODE_TOTAL全部で何並列か?という数値も取れます。
CircleCIではテストコマンドを上書きすることができるので、1ファイルごとにループを回し、
どのコンテナに割り当てるかをゴリゴリ書いていけば、均等に割り当てることができます。

もちろん、*1_spec.rbなどとすれば、コンテナを指定することができます。
が、全実行時にコンテナを指定するメリットがあまりないので、今回は上記のスクリプトで並列化します。*2

遅いテストファイルを特定する

次のステップは遅いファイルを特定して、そのファイルを分割することです。
6並列でテストを回すとこのような結果になります。
f:id:watasihasitujidesu:20150924224914p:plain f:id:watasihasitujidesu:20150924224935p:plain f:id:watasihasitujidesu:20150924224952p:plain f:id:watasihasitujidesu:20150924225039p:plain f:id:watasihasitujidesu:20150924225051p:plain f:id:watasihasitujidesu:20150924225103p:plain

見にくくて申し訳ないですが、実行時間は
- 1台目:14:03
- 2台目:15:55
- 3台目:16:29
- 4台目:38:46
- 5台目:13:13
- 6台目:12:06
合計96分。平均16分で終わるはずなので、それ以上かかっているコンテナに遅いファイルが存在する可能性が高いです。
この中ではダントツで4台目が遅いので、4台目に時間がかかっているテストファイルが存在するだろうと推測できます。

次に、並列数はそのままで、4台目の実行されたテストファイルを実行していきます。
さきほどのスクリプトではecho $filesと書いているので、CircleCI上のダッシュボードから実行されているテストファイルが確認できますのでメモっておきましょう。

メモっておいたテストファイルの絞り込みは、単純に

rm -rf ./spec/*
cat output_file | awk '{print "git checkout "$1""}'
....

などとしていけば4台目で実行されたものだけが残り、
実行することができます*3
理論的には6分ほどで終わるでしょう。

これを繰り返していけば、実行時間が長いファイルが特定できます。

遅いテストファイルを分割する

遅いファイルが特定できたら、あとはファイルを分割するだけです。
おそらく遅いファイルでは複数describeブロックやcotextブロックが存在すると思います。

# coding: utf-8
require 'spec_helper'

describe 'Hoge.fuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fuga? }

  it{should be_true}
end

describe 'Hoge.fugafuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fugafuga? }

  it{should be_false}
end

例えば、このテストファイルが実行完了まで10分かかっていたとします。
このファイルをhogehoge_fuga_rspec.rbとhogehoge_fugafuga_rspec.rbの2ファイルに分割した場合

# coding: utf-8
require 'spec_helper'

describe 'Hoge.fuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fuga? }

  it{should be_true}
end
# coding: utf-8
require 'spec_helper'

describe 'Hoge.fugafuga?' do
  let(:hoge) { FactoryGirl.create(:hoge)}
  
  subject{ hoge.fugafuga? }

  it{should be_false}
end

並列で実行すると、最高で5分に短縮できます。

このような泥臭いことを続けていきます。
ファイルを特定 => ファイル分割 => ファイルを特定 => ファイル分割 => ....................

ただし、分割するのはいいのだけれど、間違った分割の仕方をしたら、死罪に値するかもしれません。
たとえば、
hoge_controller_get_action_spec.rb hoge_controller_post_action_spec.rb とかだったら中身を見なくとも、どのようなテストが書かれているか予測ができると思うのですが、

hoge_controller_1_spec.rb hoge_controller_2_spec.rb

などとした場合、いちいちファイルを開かねばならず、苦労しそうですので気をつけましょう。

まとめ

テクニカルなことは一つもやっていないのですが、簡単なことでテスト時間を40%も高速化することができました。*4

また、CircleCIの挙動に合わせた高速化ではなく、spec自体の高速化は、
下記のエントリが参考になりますので、お試しください。

ruby-rails.hatenadiary.com

*1:うちの会社の裏行動指針です

*2:もっと簡単な方法もあります。Qiitaで探してみてください

*3:かならず違うブランチでやりましょう

*4:これを自動化すれば良いって話ですが

スクラムのプランニングで見積もりと計画がうまくいかなかった時に参考になった本を紹介します

スクラム導入の目的の一つとして、進捗の可視化という点*1が挙げられたのですが、
うまく説明できなかったので、 「アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~
という本を読んだら、見積もり、計画、スケジューリング、他者への説明も以前よりはできるようになったので、
紹介しようと思います。

見積もりってどうやれば効果的なのだろう

アジャイルな見積りと計画づくり ~価値あるソフトウェアを育てる概念と技法~

まず、前書きの時点で震えるような言葉が書いていました。

アジャイル界隈に出かけていくと、私はいつも次のような質問を受ける。

  • 大規模チームの計画はどうやって立てれば良い?

  • イテレーションの長さはどれぐらいにすべき?

  • マネージャへの進捗報告はどうすれば?

  • ストーリーの優先順位づけの方法は?

  • プロジェクトの全体像をどう把握するのか?

ここに挙げたような疑問(と、その他多くの疑問)への見事な回答が本書だ。

読み終わってから思ったのが、「まさに、前書きに書かれていた通りだ」でした。

内容としては大きく下記のように構成されています。

  • (見積もりと計画においての)問題とゴール
  • 規模を見積もる
  • 価値のための計画づくり
  • スケジュールを立てる
  • ラッキングと情報共有
  • なぜアジャイルな計画づくりがうまくいくのか
  • ケーススタディ

計画と見積もりにフォーカスしているだけに、その内容はとても濃いです。
おそらく、スプリントを進めていると、ものすごく小さな疑問にぶつかると思います。
例えば、

  • 再見積もりはどのタイミングで行うか?
    • そもそも再見積もりして良いのか?
  • 部分的に完了した状態でスプリントが終わった場合は完了したストーリーポイントに加算するか?
  • 優先順位はどのようにつければ良いのか?
  • ユーザーストーリーは分割するのか?できるのか?
    • いつ分割するのか?
  • プランニング時に担当は決めるものなのか?
  • プランニング時に設計が始まっちゃうんだけで良いのか?
  • ベロシティにバッファは必要か?
    • どれくらい必要か?
  • バーンダウンチャートのうまい書き方はあるのか?
  • 個人のベロシティを計測したいのだが・・・

"プランニング"だけでも疑問を挙げ出せば切りがないのですが、
この本を読むと自分が感じた疑問は全て解決しました。

また、内容についても、深く書かれています。

なぜ必要なのか?いつ実行すべきか?実行すべきタイミングではないのはいつか?
誰が実行するのか?どう実行すれば良いのか?

それぞれ、明確に書かれており、疑問を残す余地がないほどです。

なぜ?の部分に関しては、学術的にも書かれていますので納得度も高いです。

優先度の決め方、知ってますか?

プロダクトオーナーは優先度を決める役割を担うわけですが、
優先度はどのように決めれば良いのでしょうか。

えいやで決めることもあれば、Aと比較してBは優先度は高いといった二分木探索的に決めるかもしれません。

この本では、優先度のつけ方についても詳細に書かれています。
ただ、その決め方がやや難解です。

具体的には下記項目を指標にします。

  • 金銭価値
  • コスト
  • 新しい知識を得られるか
  • リスク

収益を増加させることができるか、新しい収益を生むか、コストを抑えるか、業務効率化できるか、
実装にかかるコスト、理解するのにかかるコスト
ハイリスクのものから取り組むか、ローリスクのものから取り組みナレッジを積み上げるか
などが書かれています。

また、財務指標(内部収益率、回収期間、割引回収期間)を判断基準に用いるので、
より納得できる優先順位をつけることができると思いますし、
対外的にも納得感のある優先順位になると思います。*2

この本を買うべきだと思ったポイント

ポイントは2つあります。

1点目は、なんといっても見積もりと計画づくりにおいての網羅率と詳細度だと思います。
この本を読めば、切りが晴れたような感覚になると思います。
疑問点はなくなるでしょうし、納得感もあります。

また、"アジャイルな"と書いてありますが、見積もりと計画づくりを"アジャイルに"(「すばやい」「俊敏な」という意味)運ぶための本です。
本の中では、アジャイル開発中心として進められていますが、本を読んだ後振り返ると、
学んだことの肝は、ウォターフォール開発の中でも活きると思います。

2点目は、ソフトウェア開発(全体)についても学ぶことが多かった点です。
TDD, CI, ペアプロなど、技術者だけでアジャイルなプラクティスを回すことはできますが、
計画や見積もりなどといったビジネスサイドのプロセスがうまく回っていなければ、ソフトウェア開発がうまくいってると言えないと思います。

この本では、ビジネスサイド(計画や見積もり)のプラクティスを学び、技術とビジネスを調和を図るための一冊になると思います。

ビジネスサイドと技術サイドの人間は、決して相反するような関係であってはなりませんし、
互いに強調しながら価値のあるプロダクトを提供しなければならないと思います。
この本は、主にプラクティスについて書かれているのですが、それを実行するだけでは、"信頼のおける"見積もりと計画づくりにはできないと思います。
信頼のおける見積もりと計画づくりは、両サイドの人間が強調し合いながら、一つのプロダクトを磨くプロセスを共に歩んでこそ生まれるものなのだと学べます。

315ページ程度なのですが、1ページあたりの文字量と難しい言葉がやや多いので、気合を入れて読まないと挫折します。
(業務の合間にですが)気合を入れて読んだので、1週間程度で全て読む事ができました。

*1:要は、いつ終わるの?に答えられること

*2:とはいえ、だいぶパワーのいる作業なので、実際やれていない...orz

スクラムのレトロスペクティブをもっと掘り下げて学ぶときに参考になった本を紹介します

スクラムを導入して3ヶ月が経ち、チーム全体にスクラムが浸透してきましたが、
なんとなく、レトロスペクティブ(振り返り)がマンネリ化してきたので、
アジャイルレトロスペクティブズ 強いチームを育てる「ふりかえり」の手引き
という本を読んだら、フリカエリのバリエーションと手法が増えたので、 紹介しようと思います。

レトロスペクティブ(振り返り)にマンネリ化を感じたら読むべき本

アジャイルレトロスペクティブズ 強いチームを育てる「ふりかえり」の手引き

この書籍では、レトロスペクティブを5つのステップに分け、
それぞれのステップにおけるプラクティスを説明しています。

  • 場を設定する
  • データ(意見)を収集する
  • イデアを出す
  • 何をすべきかを決定する
  • レトロスペクティブを終了する

また、スプリント毎のレトロスペクティブだけではなく、
ある大きなプロジェクトが終わった際に行うレトロスペクティブの方法についても記載しています。

各プラクティスは、一定のフォーマット(目的、所要時間、概要、ステップ、材料と準備、使用例)
で書かれているので、理解も用意でした。

リーダーとしてのレトロスペクティブ

この本は、主にレトロスペクティブをリードしていく層に向けての本だと感じました。

本の冒頭には、振り返りの目的はもちろん、フォシリテーションについても書かれています。
レトロスペクティブだけでなく、議論を前に進めるというスキルも学べると思います。 具体的には*1

  • レトロスペクティブの準備の仕方
  • リード(ファシリテーションの仕方)
  • 議論へ参加させる方法
    • 口数が少なく、あまり話さない人
    • 口数が多く、喋りすぎてしまう人
    • 上位職の人が圧力をかけてきた時の対処
    • メンバーにイレギュラーな出来事が発生したときの対応
      • 泣いた時
      • 怒った時
      • 部屋を出て行った時
      • 不適切に笑いが起こった時
      • 静寂に包まれたとき
      • 表面化で何かしている時(内職をしている時)
  • 自分を落ち着かせ、頭を整理する方法

上記のような事についても書かれています。

この本を買うべきだと思ったポイント

先述の通り、レトロスペクティブを5つのステップに分け、それぞれのステップにおけるプラクティスを説明しています。
買うべきだと思ったポイントは、その手法の多さです。
量だけ説明すると

  • 場を設定する => 6件
  • データ(意見)を収集する => 8件
  • イデアを出す => 9件
  • 何をすべきかを決定する => 6件
  • レトロスペクティブを終了する => 9件

合計 38件の手法をこの一冊で学ぶことができます。
一度のレトロスペクティブで使える手法は5つかもしれませんが、
知識として自分のツールボックスに入れておくには十分すぎる量だと思います。

また、各ステップにおいて、どのプラクティスが有効かについても、書かれていますので、
逆引き的にも使えます。

レトロスペクティブを進めるリーダーにはオススメな書籍です。

160ページ程度なので、3~4時間程度で全て読む事ができました。

*1:一部抜粋

Xcode7 で Buildしたときにyou must rebuild it with bitcode enabledと 出てしまう場合の回避方法

概要

Xcode7 で Buildした際に f:id:watasihasitujidesu:20150919173334p:plain

does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture armv7

といわれてしまい、Failしてしまったので、その対応方法を書きます。

手順

  1. プロジェクトのルートフォルダをクリック
  2. Build Settingsタブを選択
  3. Allを選択(Basicではない方)
  4. Enable BitcodeNoに設定
  5. Product => Clean
  6. Buildする

こちらを参考にしました。 qiita.com

rbenvを使用したrubyのバージョン管理と最新状態に保つ方法

概要

  • rbenvのインストールと設定
  • rubyのバージョンの最新を取得

rbenv インストール

$ git clone git://github.com/sstephenson/rbenv.git ~/.rbenv
$ mkdir -p ~/.rbenv/plugins
$ git clone https://github.com/sstephenson/ruby-build.git ~/.rbenv/plugins/ruby-build
$ echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bash_profile
$ echo 'eval "$(rbenv init -)"' >> ~/.bash_profile

rbenvを入れているが、rbenv install -lので最新のrubyバージョンが出てこない場合

$ cd ~/.rbenv
$ git pull origin master
$ cd ~/.rbenv/plugins/ruby-build
$ git pull origin master

Amazon CloudSearch における適切なスケーリングオプション(Scaling Options)を紹介します

概要

Amazon CloudSearch における適切なスケーリングオプションの設定を紹介します。 設定できる項目は下記の通りです。

以下、公式ドキュメントより引用

ドメインのスケーリングオプションを設定するときは、コストとパフォーマンスのトレードオフが生じます。望ましいインスタンスタイプ、レプリケーション数、パーティション数を変更すると、ドメインを実行するコストに大きな影響があります。

また、各項目の変更はそれぞれ下記の通り影響があります。

設定項目 期待できる効果
インスタンスタイプ アップロードキャパシティの増加
パーティションカウント 検索リクエストの応答速度の向上
レプリケーションカウント 検索キャパシティの増加および耐障害性の改善

インスタンスタイプ

インスタンスタイプは格納するIndexサイズ(データ総容量)とドキュメント数の目安から決定しましょう。

インスタンスタイプ Indexサイズ ドキュメント数
m1.small 1GB未満 625,000
m3.medium 1GB ~ 8GB 1,250,000
m3.large 8GB ~ 16GB 2,500,000
m3.xlarge 16GB ~ 32GB 5,000,000
m3.2xlarge 32GB ~ 64GB 10,000,000

※Indexサイズが64GBを超える場合は、後述のパーティションカウントの設定変更を検討します。

Indexサイズ(データ総容量)について

容量はindexing optionsの設定により増加していきます。 indexing optionsで設定できる項目は下記の通りです。

  • Highlight
  • Return
  • Sort
  • Facet

これらはそれぞれ、次のようにIndexサイズを肥大化させます。

設定項目 増加するIndexサイズ(%)
全て指定しなかった場合 0%
全て指定した場合 243%
Highlight 220.8%
Return 153.2%
Sort 12.7%
Facet 0.3%

不要なindexing optionsの設定をしないことで、コスト削減と応答速度向上が見込めるため、 indexingする際には注意する必要があります。

パーティションカウント

インスタンスタイプが2xlargeの場合、パーティション数を指定できます。
また、インスタンスタイプを決定する際に、格納するIndexサイズ(データ総容量)を確認したと思いますが、
この容量が64GBを超える場合はパーティションカウントの上限を上げることを検討をします。
具体的なパーティション数は
(Indexサイズ / インスタンスタイプの容量上限) + 1
が望ましいパーティション数です。

例) Indexサイズが150GBの場合
インスタンスタイプ: m3.2xlarge
パーティションカウント: (150GB / 64) + 1 = 3

レプリケーションカウント

レプリケーションカウントはリクエストするクエリの複雑度と、トラフィックに応じてレプリケーションカウントを調整します。
現状CloudSearchでは応答速度のメトリクスは取れませんので、
NewRelicのWeb externalを確認し、調整するしかないようです。

または、下記の表を目安にしても良いでしょう。

インスタンスタイプ JMeterの設定 スループット
m3.medium 2 hosts 10threads 48.3 qps / 206 ms
m3.large 4 hosts 20threads 291.5 qps / 68 ms
m3.xlarge 8 hosts 40threads 665.9 qps / 59 ms
m3.2xlarge 16 hosts 80threads 985.3 qps / 80ms

その他スケーリングについてのtips

  1. スケーリングオプションではレプリケーションカウントの変更はIndex再構築が必要ない(変更自体は無料で変更できる)ですが、
    インスタンスタイプとパーティションカウントの変更にはIndex再構築費用がかかるため、十分に検討する必要があります。
    Index再構築費用は下記の通り
    Indexサイズ 1GB あたり 0.98 USD

  2. 上記より、Webサイトのピークタイムがわかる場合は、AWS CLIより自動で設定します。
    例) 10 ~ 18時のピークタイムに合わせてレプリケーションカウントを2 => 3に変更する場合

0 10 * * * /usr/bin/aws --region ap-northeast-1 cloudsearch update-scaling-parameters --domain-name hogehoge-production --scaling-parameters DesiredReplicationCount=3,DesiredInstanceType=search.m3.2xlarge,DesiredPartitionCount=4
0 18 * * * /usr/bin/aws --region ap-northeast-1 cloudsearch update-scaling-parameters --domain-name hogehoge-production --scaling-parameters DesiredReplicationCount=2,DesiredInstanceType=search.m3.2xlarge,DesiredPartitionCount=4

まとめ

CloudSearchはフルマネージドと謳いつつも、AutoScalingの検知やスケールが遅かったり、
メトリクスが貧弱なため、トライ&エラーで知見を得ていくしかありません。
また、障害が発生した場合の問題を自分達で調べることができない上、サポートに問い合わせをしても腑に落ちない回答になる場合が多いです。
(レプリケーションカウントとパーティションカウントを増やして対応してくださいで終わる、など…)

ただ、経験が溜まっていくと、オンプレでSolrやElasticSearchを運用するよりは楽だと感じています。

スクラムのレトロスペクティブをKPTで振り返りするときに参考になった本を紹介します

スクラムを導入してなんとか1スプリントが終わったばかりなのですが、
レトロスペクティブ(振り返り)の具体的な進め方がわからなかったので、
「これだけ!KPT」という本を読んだらスムーズに進行できたので、
紹介しようと思います。

KPTをするの時のバイブル

これだけ!KPT

全6章立てで、1,2章はよくある問題とか、KPTの効能とかが書かれています。
KPTが何なのかを既に知っている方は、ここは正直読み飛ばしてしまってもよいかと思います。

3~6章にかけては、ハウツーについて書かれています。
KPTを使った振り返りについて、時間配分が分単位で書かれています。
また、時間配分された項目ごとに、実際に

  • 何を話すか
  • ポイントとコツは何か

についても書かれています。

そのほか、後半の章になると、下記のことについても掘り下げて書かれています。

  • KPTの応用編と称した、慣れてきたチーム向けに時間圧縮バージョンの進め方
  • Keep, Problem, Tryそれぞを引き出すための質問例
  • 意見が多く出た場合の情報分類術
  • KPTの結果からチーム状態の分析
  • ファシテーションの方法

これまで、KPTを体系的に学ばず、普通のメンバーとしてダラダラ振り返っていると感じる人や、
KPTを使った振り返りでのファシテーションをします!

って人まで、KPTに関わる人全員におすすめだと思います。

ページ数が少なく、文字も比較的多く、イラストを使って説明もされているので、
1.5時間くらいでサクッと読めました。

これからスクラムを始める人へのお勧め本を紹介します

ひょんなことから、会社でスクラムを使って開発をすることになり、スクラム関連の本を読み漁ったので、 これを機会にお勧め書籍を紹介します。

アジャイル手法

アジャイルサムライ

アジャイル開発手法についてまとめた本。
これを読んだ時は、スクラムの存在を知らなかった状態で読んだが、
アジャイル開発の思想は理解できる内容。
ただし、ハウツー本ではなく、思想の解説本であるため、実際にチームが
いつ、なにをするかという具体的な内容は文面から想像ができませんでした。
一度読んで理解すればそれだけで良い本かなと思います。

また、この本を読んだ後にスクラム本を読み始めたが、前提となる知識はこの本で理解していたので、
後続のアジャイル系の本をサクサク読んでいくことができました。

文字数が多く、すべて読むのに6時間くらいかかりました。

スクラム

SCRUM BOOT CAMP THE BOOK

読んだ直後は、後に紹介するスクラム実践入門と比較して内容が薄い。と思ったのですが、
スクラムはただの開発手法でありフレームワークにしかすぎないので、
フレームワークを実践する組織なり、チームに合わせた内容にアレンジする必要があると考えさせられました。

ベースとなるストーリはマンガで書かれているので、とても読みやすいので、
サクッとスクラムの概要をサクッと理解するには良い本です。
2時間ほどで読める内容なので、はじめの一冊にオススメです。

スクラム実践入門

体系的にまとまった一冊。
SCRUM BOOT CAMP THE BOOKとは違う種類の書籍で、参考書的に使いたいです。
今、机の上においてあるのはこの一冊だけです。それほどよくまとまっています。

スクラムで登場する役割、成果物、イベントなどを説明のほかに、オススメできる内容として

  • パターンプラクティス
  • スクラムを使っている会社の導入事例3社分
  • スクラム運用における、よくある問題と解決集

が掲載されているので、何か不穏な空気を感じた時とはこの本を参考にすると、だいたい解決するのではないかと思います。
実際、救われたことが何度かありました。

4時間ほどで読める内容ですが、何度も何度も読んで理解を深めるのに最適です。
もしかしたらSCRUM BOOT CAMP THE BOOKはいらないかも?

まとめ

振り返ると、スクラム実践入門だけあれば、文字通り実践までできるのではないかと思います。
スクラム勉強会などでも、スクラムマスターとして、様々な人と対等に話せるレベルになります。
(スクラムが、理解'は'容易だからってのもありますが・・・)

チームのメンバーに対してスクラムに興味を持ってもらうには、
SCRUM BOOT CAMP THE BOOKのマンガ部分をサクッと読んでもらう程度で良いかと思います。
それくらいライトな本です。

それでは、よいスクラムライフを!

Red Hatにberkshelfを入れようとした際に発生するエラー回避方法

背景

こちらを参考にchef, knife-solo, berkshelfをインストールしようとしたときに、berkshelfがエラーでインストールできなかったので、
その回避方法を書く。

対象サーバー

AWS EC2インスタンスRHEL-6.5_GA-x86_64-4-Hourly2 (ami-35106f34)

実行コマンド

gem install berkshelf --no-ri --no-rdoc

原因

gem installした時に内部でmakeが呼ばれるんですが、その途中でなぜかエラーで落ちてしまう。

Building native extensions.  This could take a while...
Successfully installed nio4r-1.1.0
Fetching: hitimes-1.2.2.gem (100%)
Building native extensions.  This could take a while...
Successfully installed hitimes-1.2.2
Fetching: timers-4.0.1.gem (100%)
Successfully installed timers-4.0.1
Fetching: celluloid-0.16.0.gem (100%)
Successfully installed celluloid-0.16.0
Fetching: celluloid-io-0.16.2.gem (100%)
Successfully installed celluloid-io-0.16.2
Fetching: addressable-2.3.8.gem (100%)
Successfully installed addressable-2.3.8
Fetching: multipart-post-2.0.0.gem (100%)
Successfully installed multipart-post-2.0.0
Fetching: faraday-0.9.1.gem (100%)
Successfully installed faraday-0.9.1
Fetching: sawyer-0.6.0.gem (100%)
Successfully installed sawyer-0.6.0
Fetching: octokit-3.8.0.gem (100%)
Successfully installed octokit-3.8.0
Fetching: dep-selector-libgecode-1.0.2.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing berkshelf:
    ERROR: Failed to build gem native extension.

    /opt/rbenv/versions/2.2.2/bin/ruby -r ./siteconf20150425-4486-1uunsyf.rb extconf.rb
-> sh /opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2/ext/libgecode3/vendor/gecode-3.7.3/configure --prefix=/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2/lib/dep-selector-libgecode/vendored-gecode --disable-doc-dot --disable-doc-search --disable-doc-tagfile --disable-doc-chm --disable-doc-docset --disable-qt --disable-examples --disable-flatzinc
checking for the host operating system... Linux
checking for g++... g++
checking whether the C++ compiler works... yes
checking for C++ compiler default output file name... a.out
checking for suffix of executables... 
checking whether we are cross compiling... no
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for ranlib... ranlib
checking for diff... ok
checking for tar... ok
checking for make... ok
checking for sed... ok
checking for perl... ok
checking how to run the C++ preprocessor... g++ -E
checking for rc.exe... no
checking whether to build with Visual Studio resource files... no
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking ext/hash_map usability... yes
checking ext/hash_map presence... yes
checking for ext/hash_map... yes
checking Whether to build for different architectures... no
checking for user-defined library name prefix... no
checking for user-defined library name suffix... no
checking whether to build static libraries... no
checking whether to build shared libraries... yes
checking whether to build with debug symbols and assertions... no
checking whether to optimize for code size... no
checking whether to build with support for finding memory leaks... no
checking whether to build with auditing code... no
checking whether to build with profiling information... no
checking whether to build with gcov support... no
checking size of int... 4
checking if int has at least 32 bit... yes
checking if doubles have a big enough mantissa... yes
checking for unistd.h... (cached) yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking whether g++ accepts -fPIC... yes
checking whether gcc accepts -fPIC... yes
checking whether g++ accepts -Wextra... yes
checking whether gcc accepts -Wextra... yes
checking whether g++ accepts -Wall... yes
checking whether gcc accepts -Wall... yes
checking whether g++ accepts -pipe... yes
checking whether gcc accepts -pipe... yes
checking whether g++ accepts -ggdb... yes
checking for __builtin_ffsl... yes
checking whether to use gcc visibility attributes... yes
checking whether g++ accepts -fvisibility=hidden... yes
checking if compiler supports forced inlining... yes
checking whether g++ accepts -O3... yes
checking whether gcc accepts -O3... yes
checking whether g++ accepts -fno-strict-aliasing... yes
checking whether gcc accepts -fno-strict-aliasing... yes
checking whether g++ accepts -ffast-math... yes
checking whether gcc accepts -ffast-math... yes
checking whether g++ accepts -mthreads... no
checking whether gcc accepts -mthreads... no
checking whether g++ accepts -Qunused-arguments... no
checking whether gcc accepts -Qunused-arguments... no
checking for dot... no
checking whether to enable graphs in the documentation... no
checking whether to enable the documentation search engine... no
checking whether to generate a doxygen tagfile... no
checking whether to build compressed html documentation... no
checking whether to build docset documentation for XCode... no
checking whether to build the set variables library... yes
checking whether to build the int variables library... yes
checking for qmake-qt4... no
checking for qmake... no
checking for moc-qt4... no
checking for moc... no
checking whether to build with Qt support... no
checking whether to build Gist... no
checking for flex... no
checking whether we have at least flex 2.5.33... no
checking for stdlib.h... (cached) yes
checking for unistd.h... (cached) yes
checking for sys/param.h... yes
checking for getpagesize... yes
checking for working mmap... yes
checking whether to build driver... yes
checking whether to build flatzinc... no
checking whether to build driver... yes
checking whether to build examples... no
checking whether to build minimodel... yes
checking whether to build search... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating tools/flatzinc/mzn-gecode
config.status: creating doxygen.conf
config.status: creating doxygen.hh
config.status: creating gecode/support/config.hpp
-> make clean
(cd . && autoconf)
./config.status --recheck
running CONFIG_SHELL=/bin/sh /bin/sh /opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2/ext/libgecode3/vendor/gecode-3.7.3/configure --prefix=/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2/lib/dep-selector-libgecode/vendored-gecode --disable-doc-dot --disable-doc-search --disable-doc-tagfile --disable-doc-chm --disable-doc-docset --disable-qt --disable-examples --disable-flatzinc --no-create --no-recursion
checking for the host operating system... Linux
checking for C++ compiler default output file name... a.out
checking whether the C++ compiler works... yes
checking whether we are cross compiling... no
checking for suffix of executables... 
checking for suffix of object files... o
checking whether we are using the GNU C++ compiler... yes
checking whether g++ accepts -g... yes
checking for gcc... gcc
checking whether we are using the GNU C compiler... yes
checking whether gcc accepts -g... yes
checking for gcc option to accept ISO C89... none needed
checking for ranlib... ranlib
checking for diff... ok
checking for tar... ok
checking for make... ok
checking for sed... ok
checking for perl... ok
checking how to run the C++ preprocessor... g++ -E
checking for rc.exe... no
checking whether to build with Visual Studio resource files... no
checking for grep that handles long lines and -e... /bin/grep
checking for egrep... /bin/grep -E
checking for ANSI C header files... yes
checking for sys/types.h... yes
checking for sys/stat.h... yes
checking for stdlib.h... yes
checking for string.h... yes
checking for memory.h... yes
checking for strings.h... yes
checking for inttypes.h... yes
checking for stdint.h... yes
checking for unistd.h... yes
checking ext/hash_map usability... yes
checking ext/hash_map presence... yes
checking for ext/hash_map... yes
checking Whether to build for different architectures... no
checking for user-defined library name prefix... no
checking for user-defined library name suffix... no
checking whether to build static libraries... no
checking whether to build shared libraries... yes
checking whether to build with debug symbols and assertions... no
checking whether to optimize for code size... no
checking whether to build with support for finding memory leaks... no
checking whether to build with auditing code... no
checking whether to build with profiling information... no
checking whether to build with gcov support... no
checking size of int... 4
checking if int has at least 32 bit... yes
checking if doubles have a big enough mantissa... yes
checking for unistd.h... (cached) yes
checking pthread.h usability... yes
checking pthread.h presence... yes
checking for pthread.h... yes
checking sys/time.h usability... yes
checking sys/time.h presence... yes
checking for sys/time.h... yes
checking whether g++ accepts -fPIC... yes
checking whether gcc accepts -fPIC... yes
checking whether g++ accepts -Wextra... yes
checking whether gcc accepts -Wextra... yes
checking whether g++ accepts -Wall... yes
checking whether gcc accepts -Wall... yes
checking whether g++ accepts -pipe... yes
checking whether gcc accepts -pipe... yes
checking whether g++ accepts -ggdb... yes
checking for __builtin_ffsl... yes
checking whether to use gcc visibility attributes... yes
checking whether g++ accepts -fvisibility=hidden... yes
checking if compiler supports forced inlining... yes
checking whether g++ accepts -O3... yes
checking whether gcc accepts -O3... yes
checking whether g++ accepts -fno-strict-aliasing... yes
checking whether gcc accepts -fno-strict-aliasing... yes
checking whether g++ accepts -ffast-math... yes
checking whether gcc accepts -ffast-math... yes
checking whether g++ accepts -mthreads... no
checking whether gcc accepts -mthreads... no
checking whether g++ accepts -Qunused-arguments... no
checking whether gcc accepts -Qunused-arguments... no
checking for dot... no
checking whether to enable graphs in the documentation... no
checking whether to enable the documentation search engine... no
checking whether to generate a doxygen tagfile... no
checking whether to build compressed html documentation... no
checking whether to build docset documentation for XCode... no
checking whether to build the set variables library... yes
checking whether to build the int variables library... yes
checking for qmake-qt4... no
checking for qmake... no
checking for moc-qt4... no
checking for moc... no
checking whether to build with Qt support... no
checking whether to build Gist... no
checking for flex... no
checking whether we have at least flex 2.5.33... no
checking for stdlib.h... (cached) yes
checking for unistd.h... (cached) yes
checking for getpagesize... yes
checking for working mmap... yes
checking whether to build driver... yes
checking whether to build flatzinc... no
checking whether to build driver... yes
checking whether to build examples... no
checking whether to build minimodel... yes
checking whether to build search... yes
configure: creating ./config.status
./config.status --file Makefile:Makefile.in
config.status: creating Makefile
rm -rf *.stackdump core gmon.out \
        vc70.pdb vc80.pdb vc90.pdb vc100.pdb
rm -rf doxygen.log doxygen.hh doxygen.conf.use stat.hh \
         changelog.hh doxygen.hh license.hh header.html
rm -rf gecode/support/exception.o gecode/support/heap.o gecode/support/thread/thread.o gecode/support/thread/windows.o gecode/support/thread/pthreads.o gecode/kernel/archive.o gecode/kernel/core.o gecode/kernel/memory-manager.o gecode/kernel/branch.o gecode/kernel/region.o gecode/search/stop.o gecode/search/options.o gecode/search/parallel/engine.o gecode/search/dfs.o gecode/search/parallel/dfs.o gecode/search/bab.o gecode/search/parallel/bab.o gecode/search/restart.o gecode/search/parallel/restart.o gecode/int/int-set.o gecode/int/var-imp/int.o gecode/int/var-imp/bool.o gecode/int/var/int.o gecode/int/var/bool.o gecode/int/array.o gecode/int/bool.o gecode/int/bool/eqv.o gecode/int/extensional/dfa.o gecode/int/extensional/tuple-set.o gecode/int/extensional.o gecode/int/dom.o gecode/int/rel.o gecode/int/precede.o gecode/int/element.o gecode/int/count.o gecode/int/arithmetic.o gecode/int/exec.o gecode/int/exec/when.o gecode/int/element/pair.o gecode/int/linear/int-post.o gecode/int/linear-int.o gecode/int/linear/bool-post.o gecode/int/linear-bool.o gecode/int/branch.o gecode/int/distinct.o gecode/int/sorted.o gecode/int/gcc.o gecode/int/channel.o gecode/int/channel/link-single.o gecode/int/channel/link-multi.o gecode/int/unshare.o gecode/int/sequence.o gecode/int/bin-packing.o gecode/int/bin-packing/propagate.o gecode/int/unary.o gecode/int/cumulative.o gecode/int/cumulatives.o gecode/int/circuit.o gecode/int/no-overlap.o gecode/int/nvalues.o gecode/int/member.o gecode/int/branch/post-view-int.o gecode/int/branch/post-view-bool.o gecode/set/branch.o gecode/set/cardinality.o gecode/set/convex.o gecode/set/convex/conv.o gecode/set/convex/hull.o gecode/set/dom.o gecode/set/rel.o gecode/set/rel-op.o gecode/set/rel-op-ternary.o gecode/set/rel-op-singleton.o gecode/set/rel-op/post-compl.o gecode/set/rel-op/post-nocompl.o gecode/set/rel-op/post-compl-cvv.o gecode/set/rel-op/post-nocompl-cvv.o gecode/set/rel-op/post-compl-vvc.o gecode/set/rel-op/post-nocompl-vvc.o gecode/set/rel-op/post-compl-cvc.o gecode/set/rel-op/post-nocompl-cvc.o gecode/set/rel-op-const-vvc.o gecode/set/rel-op-const-vcv.o gecode/set/rel-op-const-vcc.o gecode/set/rel-op-const-cvc.o gecode/set/rel-op-const-cvv.o gecode/set/int.o gecode/set/element.o gecode/set/sequence.o gecode/set/distinct.o gecode/set/distinct/atmostOne.o gecode/set/precede.o gecode/set/sequence/seq.o gecode/set/sequence/seq-u.o gecode/set/array.o gecode/set/var-imp/set.o gecode/set/var-imp/integerset.o gecode/set/var/set.o gecode/set/exec.o gecode/set/branch/post-view.o gecode/minimodel/lin-expr.o gecode/minimodel/lin-rel.o gecode/minimodel/bool-expr.o gecode/minimodel/set-expr.o gecode/minimodel/set-rel.o gecode/minimodel/reg.o gecode/minimodel/arithmetic.o gecode/driver/options.o gecode/driver/script.o examples/alpha.o examples/bacp.o examples/bibd.o examples/donald.o examples/efpa.o examples/eq20.o examples/golomb-ruler.o examples/graph-color.o examples/grocery.o examples/ind-set.o examples/magic-sequence.o examples/magic-square.o examples/money.o examples/ortho-latin.o examples/partition.o examples/photo.o examples/queens.o examples/sudoku.o examples/kakuro.o examples/nonogram.o examples/pentominoes.o examples/crowded-chess.o examples/black-hole.o examples/minesweeper.o examples/domino.o examples/steel-mill.o examples/sports-league.o examples/all-interval.o examples/langford-number.o examples/warehouses.o examples/radiotherapy.o examples/word-square.o examples/crossword.o examples/open-shop.o examples/car-sequencing.o examples/sat.o examples/bin-packing.o examples/knights.o examples/tsp.o examples/perfect-square.o examples/schurs-lemma.o examples/dominating-queens.o examples/crew.o examples/golf.o examples/hamming.o examples/steiner.o examples/queen-armies.o gecode/gist/drawingcursor.o gecode/gist/gist.o gecode/gist/gecodelogo.o gecode/gist/node.o gecode/gist/spacenode.o gecode/gist/textoutput.o gecode/gist/treecanvas.o gecode/gist/qtgist.o gecode/gist/visualnode.o gecode/gist/nodestats.o gecode/gist/nodewidget.o gecode/gist/mainwindow.o gecode/gist/preferences.o gecode/gist/stopbrancher.o gecode/flatzinc/flatzinc.o gecode/flatzinc/registry.o tools/flatzinc/fz.o gecode/gist/moc_treecanvas.o gecode/gist/moc_qtgist.o gecode/gist/moc_mainwindow.o gecode/gist/moc_textoutput.o gecode/gist/moc_preferences.o gecode/gist/moc_nodestats.o gecode/flatzinc/parser.tab.o gecode/flatzinc/lexer.yy.o gecode/support/exception.s gecode/support/heap.s gecode/support/thread/thread.s gecode/support/thread/windows.s gecode/support/thread/pthreads.s gecode/kernel/archive.s gecode/kernel/core.s gecode/kernel/memory-manager.s gecode/kernel/branch.s gecode/kernel/region.s gecode/search/stop.s gecode/search/options.s gecode/search/parallel/engine.s gecode/search/dfs.s gecode/search/parallel/dfs.s gecode/search/bab.s gecode/search/parallel/bab.s gecode/search/restart.s gecode/search/parallel/restart.s gecode/int/int-set.s gecode/int/var-imp/int.s gecode/int/var-imp/bool.s gecode/int/var/int.s gecode/int/var/bool.s gecode/int/array.s gecode/int/bool.s gecode/int/bool/eqv.s gecode/int/extensional/dfa.s gecode/int/extensional/tuple-set.s gecode/int/extensional.s gecode/int/dom.s gecode/int/rel.s gecode/int/precede.s gecode/int/element.s gecode/int/count.s gecode/int/arithmetic.s gecode/int/exec.s gecode/int/exec/when.s gecode/int/element/pair.s gecode/int/linear/int-post.s gecode/int/linear-int.s gecode/int/linear/bool-post.s gecode/int/linear-bool.s gecode/int/branch.s gecode/int/distinct.s gecode/int/sorted.s gecode/int/gcc.s gecode/int/channel.s gecode/int/channel/link-single.s gecode/int/channel/link-multi.s gecode/int/unshare.s gecode/int/sequence.s gecode/int/bin-packing.s gecode/int/bin-packing/propagate.s gecode/int/unary.s gecode/int/cumulative.s gecode/int/cumulatives.s gecode/int/circuit.s gecode/int/no-overlap.s gecode/int/nvalues.s gecode/int/member.s gecode/int/branch/post-view-int.s gecode/int/branch/post-view-bool.s gecode/set/branch.s gecode/set/cardinality.s gecode/set/convex.s gecode/set/convex/conv.s gecode/set/convex/hull.s gecode/set/dom.s gecode/set/rel.s gecode/set/rel-op.s gecode/set/rel-op-ternary.s gecode/set/rel-op-singleton.s gecode/set/rel-op/post-compl.s gecode/set/rel-op/post-nocompl.s gecode/set/rel-op/post-compl-cvv.s gecode/set/rel-op/post-nocompl-cvv.s gecode/set/rel-op/post-compl-vvc.s gecode/set/rel-op/post-nocompl-vvc.s gecode/set/rel-op/post-compl-cvc.s gecode/set/rel-op/post-nocompl-cvc.s gecode/set/rel-op-const-vvc.s gecode/set/rel-op-const-vcv.s gecode/set/rel-op-const-vcc.s gecode/set/rel-op-const-cvc.s gecode/set/rel-op-const-cvv.s gecode/set/int.s gecode/set/element.s gecode/set/sequence.s gecode/set/distinct.s gecode/set/distinct/atmostOne.s gecode/set/precede.s gecode/set/sequence/seq.s gecode/set/sequence/seq-u.s gecode/set/array.s gecode/set/var-imp/set.s gecode/set/var-imp/integerset.s gecode/set/var/set.s gecode/set/exec.s gecode/set/branch/post-view.s gecode/minimodel/lin-expr.s gecode/minimodel/lin-rel.s gecode/minimodel/bool-expr.s gecode/minimodel/set-expr.s gecode/minimodel/set-rel.s gecode/minimodel/reg.s gecode/minimodel/arithmetic.s gecode/driver/options.s gecode/driver/script.s examples/alpha.s examples/bacp.s examples/bibd.s examples/donald.s examples/efpa.s examples/eq20.s examples/golomb-ruler.s examples/graph-color.s examples/grocery.s examples/ind-set.s examples/magic-sequence.s examples/magic-square.s examples/money.s examples/ortho-latin.s examples/partition.s examples/photo.s examples/queens.s examples/sudoku.s examples/kakuro.s examples/nonogram.s examples/pentominoes.s examples/crowded-chess.s examples/black-hole.s examples/minesweeper.s examples/domino.s examples/steel-mill.s examples/sports-league.s examples/all-interval.s examples/langford-number.s examples/warehouses.s examples/radiotherapy.s examples/word-square.s examples/crossword.s examples/open-shop.s examples/car-sequencing.s examples/sat.s examples/bin-packing.s examples/knights.s examples/tsp.s examples/perfect-square.s examples/schurs-lemma.s examples/dominating-queens.s examples/crew.s examples/golf.s examples/hamming.s examples/steiner.s examples/queen-armies.s gecode/gist/drawingcursor.s gecode/gist/gist.s gecode/gist/gecodelogo.s gecode/gist/node.s gecode/gist/spacenode.s gecode/gist/textoutput.s gecode/gist/treecanvas.s gecode/gist/qtgist.s gecode/gist/visualnode.s gecode/gist/nodestats.s gecode/gist/nodewidget.s gecode/gist/mainwindow.s gecode/gist/preferences.s gecode/gist/stopbrancher.s gecode/flatzinc/flatzinc.s gecode/flatzinc/registry.s tools/flatzinc/fz.s gecode/support/exception.pdb gecode/support/heap.pdb gecode/support/thread/thread.pdb gecode/support/thread/windows.pdb gecode/support/thread/pthreads.pdb gecode/kernel/archive.pdb gecode/kernel/core.pdb gecode/kernel/memory-manager.pdb gecode/kernel/branch.pdb gecode/kernel/region.pdb gecode/search/stop.pdb gecode/search/options.pdb gecode/search/parallel/engine.pdb gecode/search/dfs.pdb gecode/search/parallel/dfs.pdb gecode/search/bab.pdb gecode/search/parallel/bab.pdb gecode/search/restart.pdb gecode/search/parallel/restart.pdb gecode/int/int-set.pdb gecode/int/var-imp/int.pdb gecode/int/var-imp/bool.pdb gecode/int/var/int.pdb gecode/int/var/bool.pdb gecode/int/array.pdb gecode/int/bool.pdb gecode/int/bool/eqv.pdb gecode/int/extensional/dfa.pdb gecode/int/extensional/tuple-set.pdb gecode/int/extensional.pdb gecode/int/dom.pdb gecode/int/rel.pdb gecode/int/precede.pdb gecode/int/element.pdb gecode/int/count.pdb gecode/int/arithmetic.pdb gecode/int/exec.pdb gecode/int/exec/when.pdb gecode/int/element/pair.pdb gecode/int/linear/int-post.pdb gecode/int/linear-int.pdb gecode/int/linear/bool-post.pdb gecode/int/linear-bool.pdb gecode/int/branch.pdb gecode/int/distinct.pdb gecode/int/sorted.pdb gecode/int/gcc.pdb gecode/int/channel.pdb gecode/int/channel/link-single.pdb gecode/int/channel/link-multi.pdb gecode/int/unshare.pdb gecode/int/sequence.pdb gecode/int/bin-packing.pdb gecode/int/bin-packing/propagate.pdb gecode/int/unary.pdb gecode/int/cumulative.pdb gecode/int/cumulatives.pdb gecode/int/circuit.pdb gecode/int/no-overlap.pdb gecode/int/nvalues.pdb gecode/int/member.pdb gecode/int/branch/post-view-int.pdb gecode/int/branch/post-view-bool.pdb gecode/set/branch.pdb gecode/set/cardinality.pdb gecode/set/convex.pdb gecode/set/convex/conv.pdb gecode/set/convex/hull.pdb gecode/set/dom.pdb gecode/set/rel.pdb gecode/set/rel-op.pdb gecode/set/rel-op-ternary.pdb gecode/set/rel-op-singleton.pdb gecode/set/rel-op/post-compl.pdb gecode/set/rel-op/post-nocompl.pdb gecode/set/rel-op/post-compl-cvv.pdb gecode/set/rel-op/post-nocompl-cvv.pdb gecode/set/rel-op/post-compl-vvc.pdb gecode/set/rel-op/post-nocompl-vvc.pdb gecode/set/rel-op/post-compl-cvc.pdb gecode/set/rel-op/post-nocompl-cvc.pdb gecode/set/rel-op-const-vvc.pdb gecode/set/rel-op-const-vcv.pdb gecode/set/rel-op-const-vcc.pdb gecode/set/rel-op-const-cvc.pdb gecode/set/rel-op-const-cvv.pdb gecode/set/int.pdb gecode/set/element.pdb gecode/set/sequence.pdb gecode/set/distinct.pdb gecode/set/distinct/atmostOne.pdb gecode/set/precede.pdb gecode/set/sequence/seq.pdb gecode/set/sequence/seq-u.pdb gecode/set/array.pdb gecode/set/var-imp/set.pdb gecode/set/var-imp/integerset.pdb gecode/set/var/set.pdb gecode/set/exec.pdb gecode/set/branch/post-view.pdb gecode/minimodel/lin-expr.pdb gecode/minimodel/lin-rel.pdb gecode/minimodel/bool-expr.pdb gecode/minimodel/set-expr.pdb gecode/minimodel/set-rel.pdb gecode/minimodel/reg.pdb gecode/minimodel/arithmetic.pdb gecode/driver/options.pdb gecode/driver/script.pdb examples/alpha.pdb examples/bacp.pdb examples/bibd.pdb examples/donald.pdb examples/efpa.pdb examples/eq20.pdb examples/golomb-ruler.pdb examples/graph-color.pdb examples/grocery.pdb examples/ind-set.pdb examples/magic-sequence.pdb examples/magic-square.pdb examples/money.pdb examples/ortho-latin.pdb examples/partition.pdb examples/photo.pdb examples/queens.pdb examples/sudoku.pdb examples/kakuro.pdb examples/nonogram.pdb examples/pentominoes.pdb examples/crowded-chess.pdb examples/black-hole.pdb examples/minesweeper.pdb examples/domino.pdb examples/steel-mill.pdb examples/sports-league.pdb examples/all-interval.pdb examples/langford-number.pdb examples/warehouses.pdb examples/radiotherapy.pdb examples/word-square.pdb examples/crossword.pdb examples/open-shop.pdb examples/car-sequencing.pdb examples/sat.pdb examples/bin-packing.pdb examples/knights.pdb examples/tsp.pdb examples/perfect-square.pdb examples/schurs-lemma.pdb examples/dominating-queens.pdb examples/crew.pdb examples/golf.pdb examples/hamming.pdb examples/steiner.pdb examples/queen-armies.pdb gecode/gist/drawingcursor.pdb gecode/gist/gist.pdb gecode/gist/gecodelogo.pdb gecode/gist/node.pdb gecode/gist/spacenode.pdb gecode/gist/textoutput.pdb gecode/gist/treecanvas.pdb gecode/gist/qtgist.pdb gecode/gist/visualnode.pdb gecode/gist/nodestats.pdb gecode/gist/nodewidget.pdb gecode/gist/mainwindow.pdb gecode/gist/preferences.pdb gecode/gist/stopbrancher.pdb gecode/flatzinc/flatzinc.pdb gecode/flatzinc/registry.pdb tools/flatzinc/fz.pdb gecode/gist/moc_treecanvas.pdb gecode/gist/moc_qtgist.pdb gecode/gist/moc_mainwindow.pdb gecode/gist/moc_textoutput.pdb gecode/gist/moc_preferences.pdb gecode/gist/moc_nodestats.pdb gecode/flatzinc/parser.tab.pdb gecode/flatzinc/lexer.yy.pdb
rm -rf test/int.o test/int/channel.o test/int/arithmetic.o test/int/basic.o test/int/bool.o test/int/count.o test/int/dom.o test/int/distinct.o test/int/element.o test/int/extensional.o test/int/rel.o test/int/linear.o test/int/gcc.o test/int/sorted.o test/int/unshare.o test/int/exec.o test/int/sequence.o test/int/mm-arithmetic.o test/int/mm-bool.o test/int/mm-lin.o test/int/mm-count.o test/int/mm-rel.o test/int/bin-packing.o test/int/unary.o test/int/cumulative.o test/int/cumulatives.o test/int/circuit.o test/int/no-overlap.o test/int/precede.o test/int/nvalues.o test/int/member.o test/set.o test/set/construct.o test/set/dom.o test/set/rel.o test/set/rel-op.o test/set/rel-op-const.o test/set/convex.o test/set/sequence.o test/set/int.o test/set/element.o test/set/precede.o test/set/distinct.o test/set/exec.o test/set/mm-set.o test/branch.o test/branch/int.o test/branch/bool.o test/branch/set.o test/assign.o test/assign/int.o test/assign/bool.o test/assign/set.o test/search.o test/array.o test/test.o test/afc.o test/int.s test/int/channel.s test/int/arithmetic.s test/int/basic.s test/int/bool.s test/int/count.s test/int/dom.s test/int/distinct.s test/int/element.s test/int/extensional.s test/int/rel.s test/int/linear.s test/int/gcc.s test/int/sorted.s test/int/unshare.s test/int/exec.s test/int/sequence.s test/int/mm-arithmetic.s test/int/mm-bool.s test/int/mm-lin.s test/int/mm-count.s test/int/mm-rel.s test/int/bin-packing.s test/int/unary.s test/int/cumulative.s test/int/cumulatives.s test/int/circuit.s test/int/no-overlap.s test/int/precede.s test/int/nvalues.s test/int/member.s test/set.s test/set/construct.s test/set/dom.s test/set/rel.s test/set/rel-op.s test/set/rel-op-const.s test/set/convex.s test/set/sequence.s test/set/int.s test/set/element.s test/set/precede.s test/set/distinct.s test/set/exec.s test/set/mm-set.s test/branch.s test/branch/int.s test/branch/bool.s test/branch/set.s test/assign.s test/assign/int.s test/assign/bool.s test/assign/set.s test/search.s test/array.s test/test.s test/afc.s test/int.pdb test/int/channel.pdb test/int/arithmetic.pdb test/int/basic.pdb test/int/bool.pdb test/int/count.pdb test/int/dom.pdb test/int/distinct.pdb test/int/element.pdb test/int/extensional.pdb test/int/rel.pdb test/int/linear.pdb test/int/gcc.pdb test/int/sorted.pdb test/int/unshare.pdb test/int/exec.pdb test/int/sequence.pdb test/int/mm-arithmetic.pdb test/int/mm-bool.pdb test/int/mm-lin.pdb test/int/mm-count.pdb test/int/mm-rel.pdb test/int/bin-packing.pdb test/int/unary.pdb test/int/cumulative.pdb test/int/cumulatives.pdb test/int/circuit.pdb test/int/no-overlap.pdb test/int/precede.pdb test/int/nvalues.pdb test/int/member.pdb test/set.pdb test/set/construct.pdb test/set/dom.pdb test/set/rel.pdb test/set/rel-op.pdb test/set/rel-op-const.pdb test/set/convex.pdb test/set/sequence.pdb test/set/int.pdb test/set/element.pdb test/set/precede.pdb test/set/distinct.pdb test/set/exec.pdb test/set/mm-set.pdb test/branch.pdb test/branch/int.pdb test/branch/bool.pdb test/branch/set.pdb test/assign.pdb test/assign/int.pdb test/assign/bool.pdb test/assign/set.pdb test/search.pdb test/array.pdb test/test.pdb test/afc.pdb
rm -rf gecode/gist/moc_treecanvas.cpp gecode/gist/moc_qtgist.cpp gecode/gist/moc_mainwindow.cpp gecode/gist/moc_textoutput.cpp gecode/gist/moc_preferences.cpp gecode/gist/moc_nodestats.cpp
rm -rf libgecodesupport.so.32.0.manifest libgecodekernel.so.32.0.manifest libgecodesearch.so.32.0.manifest libgecodeint.so.32.0.manifest libgecodeset.so.32.0.manifest libgecodeminimodel.so.32.0.manifest libgecodedriver.so.32.0.manifest \
        libgecodesupport.so.32.0.rc libgecodekernel.so.32.0.rc libgecodesearch.so.32.0.rc libgecodeint.so.32.0.rc libgecodeset.so.32.0.rc libgecodeminimodel.so.32.0.rc libgecodedriver.so.32.0.rc \
        libgecodesupport.so.32.0.res libgecodekernel.so.32.0.res libgecodesearch.so.32.0.res libgecodeint.so.32.0.res libgecodeset.so.32.0.res libgecodeminimodel.so.32.0.res libgecodedriver.so.32.0.res \
        libgecodesupport.exp libgecodekernel.exp libgecodesearch.exp libgecodeint.exp libgecodeset.exp libgecodeminimodel.exp libgecodedriver.exp
rm -rf examples/alpha examples/bacp examples/bibd examples/donald examples/efpa examples/eq20 examples/golomb-ruler examples/graph-color examples/grocery examples/ind-set examples/magic-sequence examples/magic-square examples/money examples/ortho-latin examples/partition examples/photo examples/queens examples/sudoku examples/kakuro examples/nonogram examples/pentominoes examples/crowded-chess examples/black-hole examples/minesweeper examples/domino examples/steel-mill examples/sports-league examples/all-interval examples/langford-number examples/warehouses examples/radiotherapy examples/word-square examples/crossword examples/open-shop examples/car-sequencing examples/sat examples/bin-packing examples/knights examples/tsp examples/perfect-square examples/schurs-lemma examples/dominating-queens examples/crew examples/golf examples/hamming examples/steiner examples/queen-armies examples/alpha.manifest examples/bacp.manifest examples/bibd.manifest examples/donald.manifest examples/efpa.manifest examples/eq20.manifest examples/golomb-ruler.manifest examples/graph-color.manifest examples/grocery.manifest examples/ind-set.manifest examples/magic-sequence.manifest examples/magic-square.manifest examples/money.manifest examples/ortho-latin.manifest examples/partition.manifest examples/photo.manifest examples/queens.manifest examples/sudoku.manifest examples/kakuro.manifest examples/nonogram.manifest examples/pentominoes.manifest examples/crowded-chess.manifest examples/black-hole.manifest examples/minesweeper.manifest examples/domino.manifest examples/steel-mill.manifest examples/sports-league.manifest examples/all-interval.manifest examples/langford-number.manifest examples/warehouses.manifest examples/radiotherapy.manifest examples/word-square.manifest examples/crossword.manifest examples/open-shop.manifest examples/car-sequencing.manifest examples/sat.manifest examples/bin-packing.manifest examples/knights.manifest examples/tsp.manifest examples/perfect-square.manifest examples/schurs-lemma.manifest examples/dominating-queens.manifest examples/crew.manifest examples/golf.manifest examples/hamming.manifest examples/steiner.manifest examples/queen-armies.manifest \
        examples/alpha.rc examples/bacp.rc examples/bibd.rc examples/donald.rc examples/efpa.rc examples/eq20.rc examples/golomb-ruler.rc examples/graph-color.rc examples/grocery.rc examples/ind-set.rc examples/magic-sequence.rc examples/magic-square.rc examples/money.rc examples/ortho-latin.rc examples/partition.rc examples/photo.rc examples/queens.rc examples/sudoku.rc examples/kakuro.rc examples/nonogram.rc examples/pentominoes.rc examples/crowded-chess.rc examples/black-hole.rc examples/minesweeper.rc examples/domino.rc examples/steel-mill.rc examples/sports-league.rc examples/all-interval.rc examples/langford-number.rc examples/warehouses.rc examples/radiotherapy.rc examples/word-square.rc examples/crossword.rc examples/open-shop.rc examples/car-sequencing.rc examples/sat.rc examples/bin-packing.rc examples/knights.rc examples/tsp.rc examples/perfect-square.rc examples/schurs-lemma.rc examples/dominating-queens.rc examples/crew.rc examples/golf.rc examples/hamming.rc examples/steiner.rc examples/queen-armies.rc examples/alpha.res examples/bacp.res examples/bibd.res examples/donald.res examples/efpa.res examples/eq20.res examples/golomb-ruler.res examples/graph-color.res examples/grocery.res examples/ind-set.res examples/magic-sequence.res examples/magic-square.res examples/money.res examples/ortho-latin.res examples/partition.res examples/photo.res examples/queens.res examples/sudoku.res examples/kakuro.res examples/nonogram.res examples/pentominoes.res examples/crowded-chess.res examples/black-hole.res examples/minesweeper.res examples/domino.res examples/steel-mill.res examples/sports-league.res examples/all-interval.res examples/langford-number.res examples/warehouses.res examples/radiotherapy.res examples/word-square.res examples/crossword.res examples/open-shop.res examples/car-sequencing.res examples/sat.res examples/bin-packing.res examples/knights.res examples/tsp.res examples/perfect-square.res examples/schurs-lemma.res examples/dominating-queens.res examples/crew.res examples/golf.res examples/hamming.res examples/steiner.res examples/queen-armies.res
rm -rf test/test test/test.manifest \
        test/test.rc test/test.res
rm -rf   \
         
-> make -j 5
make[1]: ディレクトリ `/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2/ext/libgecode3/vendor/gecode-3.7.3' に入ります
perl ./misc/genvarimp.perl -typehpp ./gecode/int/var-imp/int.vis ./gecode/int/var-imp/bool.vis ./gecode/set/var-imp/set.vis > gecode/kernel/var-type.hpp
perl ./misc/genvarimp.perl -header ./gecode/int/var-imp/int.vis ./gecode/int/var-imp/bool.vis ./gecode/set/var-imp/set.vis > gecode/kernel/var-imp.hpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/support/exception.o  gecode/support/exception.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/support/heap.o  gecode/support/heap.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/support/thread/thread.o  gecode/support/thread/thread.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/support/thread/windows.o  gecode/support/thread/windows.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/support/thread/pthreads.o  gecode/support/thread/pthreads.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG     \
    -c -o gecode/kernel/archive.o  gecode/kernel/archive.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG     \
    -c -o gecode/kernel/core.o  gecode/kernel/core.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG     \
    -c -o gecode/kernel/memory-manager.o  gecode/kernel/memory-manager.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG     \
    -c -o gecode/kernel/branch.o  gecode/kernel/branch.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG     \
    -c -o gecode/kernel/region.o  gecode/kernel/region.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/stop.o  gecode/search/stop.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/options.o  gecode/search/options.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/parallel/engine.o  gecode/search/parallel/engine.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/dfs.o  gecode/search/dfs.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/parallel/dfs.o  gecode/search/parallel/dfs.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/bab.o  gecode/search/bab.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/parallel/bab.o  gecode/search/parallel/bab.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/restart.o  gecode/search/restart.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/search/parallel/restart.o  gecode/search/parallel/restart.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/int-set.o  gecode/int/int-set.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/var-imp/int.o  gecode/int/var-imp/int.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/var-imp/bool.o  gecode/int/var-imp/bool.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/var/int.o  gecode/int/var/int.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/var/bool.o  gecode/int/var/bool.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/array.o  gecode/int/array.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/bool.o  gecode/int/bool.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/bool/eqv.o  gecode/int/bool/eqv.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/extensional/dfa.o  gecode/int/extensional/dfa.cpp
g++ -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG -I. -ffast-math -fno-strict-aliasing -O3 -fvisibility=hidden -ggdb -pipe -Wall -Wextra -fPIC -pthread -DNDEBUG    \
    -c -o gecode/int/extensional/tuple-set.o  gecode/int/extensional/tuple-set.cpp
g++: 内部エラー: 強制終了 (プログラム cc1plus)
完全なバグレポートを送ってください。
<http://bugzilla.redhat.com/bugzilla> に手順が書いてあります。
make[1]: *** [gecode/int/bool.o] エラー 1
make[1]: *** 未完了のジョブを待っています....
make[1]: ディレクトリ `/opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2/ext/libgecode3/vendor/gecode-3.7.3' から出ます
make: *** [compilelib] エラー 2
extconf.rb:98:in `block in run': Failed to build gecode library. (GecodeBuild::BuildError)
    from extconf.rb:97:in `chdir'
    from extconf.rb:97:in `run'
    from extconf.rb:104:in `<main>'

extconf failed, exit code 1

Gem files will remain installed in /opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/gems/dep-selector-libgecode-1.0.2 for inspection.
Results logged to /opt/rbenv/versions/2.2.2/lib/ruby/gems/2.2.0/extensions/x86_64-linux/2.2.0-static/dep-selector-libgecode-1.0.2/gem_make.out

こまけぇこたぁいいんだよ、回避方法はよ

EC2のinstance typem3.medium にあげる。

パワー不足で途中で落ちると、原因を探ろうにも探れないから苦労しますね。
Passenger入れたときもそうなんだけど、microインスタンスだと本当だめ。
Ruby入れるだけでも30分くらいかかっちゃうんで、何かインストール作業するときはおとなしくmediumくらいで実行するよろし

Railsアプリケーションにおいて、ファイルアップロードする際のウイルスチェックをClamAVで実装する

背景

手軽にファイルアップロード機能を実装するときにCarrierwaveをよく使うんですが、
ひょんなことから、アップロードされたファイルのウイルスチェックをする必要がでてきたので、
チェックするまでの手順を、ClamAVのインストールとチェック方法を主にまとめます。

ClamAVインストール手順

  1. ClamAVインストール
  2. ウイルス更新の設定ファイル修正
  3. ウイルスのパターンファイル更新
  4. ウイルスチェックの設定ファイル修正
  5. デーモン起動

上記手順のコマンド

$ sudo su -
$ yum remove -y clam*
$ yum install -y clamav clamav-scanner-sysvinit clamav-update

# 2. ウイルス更新の設定ファイル修正
$ sed -i -e "s/Example/#Example/" /etc/freshclam.conf
$ sed -i -e "s:#DatabaseDirectory /var/lib/clamav:DatabaseDirectory /var/lib/clamav:" /etc/freshclam.conf
$ sed -i -e "s:#UpdateLogFile /var/log/freshclam.log:UpdateLogFile /var/log/freshclam.log:" /etc/freshclam.conf
$ sed -i -e "s/#DatabaseOwner clamupdate/DatabaseOwner clamupdate/" /etc/freshclam.conf

# 3. ウイルスのパターンファイル更新
$ freshclam

# 4. ウイルスチェックの設定ファイル修正
$ sed -i -e "s/Example/#Example/" /etc/clamd.d/scan.conf
$ sed -i -e "s:#LocalSocket /var/run/clamd.scan/clamd.sock:LocalSocket /var/run/clamd.scan/clamd.sock:" /etc/clamd.d/scan.conf
$ sed -i -e "s/#FixStaleSocket yes/FixStaleSocket yes/" /etc/clamd.d/scan.conf
$ sed -i -e "s/#TCPSocket 3310/TCPSocket 3310/" /etc/clamd.d/scan.conf
$ sed -i -e "s/#TCPAddr 127.0.0.1/TCPAddr 127.0.0.1/" /etc/clamd.d/scan.conf
$ chown clamscan:clamscan /var/run/clamd.scan
$ ln -s /etc/clamd.d/scan.conf /etc/clamd.conf 

# 5. デーモン起動ついでにchkconfig設定
$ /etc/rc.d/init.d/clamd.scan start
$ /sbin/chkconfig clamd.scan on

# デーモンのソケットはclamscanユーザにしかrwがないので、その他ユーザも実行できるように権限設定
$ chmod 775 /var/run/clamd.scan/
  1. ウイルスのパターンファイル更新については、定期的に実行したいので、cronで仕込む必要があると思います。

Rails プロダクションコードからの呼び出し(アップロードファイルのウイルスチェック)

  1. gem インストール
  2. 環境変数設定
  3. コード組み込み

1. gem インストール(Rails.rootにて) && 2. 環境変数設定

$ echo "gem 'clamav-client', require: 'clamav/client'" >> Gemfile
$ bundle install
$ echo 'export CLAMD_UNIX_SOCKET="/var/run/clamd.scan/clamd.sock"' >> ~/.bash_profile
$ source ~/.bash_profile
  1. 環境変数設定 についてですが、clamav-clientはCLAMD_UNIX_SOCKETが設定されていると、そこをソケットパスとして参照しにいきます。
    clamav-clientがデフォルトで参照するソケットパスが/var/run/clamav/clamd.ctlであるため、yum でinstallしたClamAVの設定ファイルのソケットパスに合わせます。

3. コード組み込み

def upload_image
  client = ClamAV::Client.new
  io = StringIO.new(params["image"].tempfile.read)
  raise "detected virus" if client.execute(ClamAV::Commands::InstreamCommand.new(io)).virus_name.present?
end

プロダクションコードでやるというよりは、ウイルスチェック専用のサーバにpostして結果だけ受け取るような仕組みにしたいですね。

参考サイト

github.com www.agilegroup.co.jp ClamAV on Amazon Linux - ぬぞうWiki