itamae 生活 5日目

前回 itamae-plugin-recipe-rbenv に Pull Request 出して終わった。

今日はその後どうなったかを


当初

EC2(Amazon Linux) の環境下で itamae 実行したときに dependency.rbelse 節の3つしか install されてなかったので、 node[:platform] に値の設定が必要なのでは?

と考えていた。

なので、 node.ymlplatform: redhat を追記することで対処していた。

んで、 README に追記するような Pull Request を出した。

github.com

k0kubun さんからレス

https://github.com/k0kubun/itamae-plugin-recipe-rbenv/pull/16#issuecomment-267210349

レシピのバグで、AmazonLinux 使った際に node[:platform] = amazon という値が入ってくるのだけど、 case when の判定の漏れてるという内容。

修正コミット→マージ

この修正 を加えて手元で試したところ、無事 install されたので Pull Request の内容を修正して Push して無事マージされた。


itamae-pluglin を使った rbenv の install は、環境変数などの設定含めてこんな感じにしてみた。

include_recipe 'rbenv::system'

file '/home/ec2-user/.bashrc' do
  action :create
end

file '/home/ec2-user/.bashrc' do
  action :edit
  block do |content|
    next if content.match %r{export RBENV_ROOT=/usr/local/rbenv}
    appendix = <<~EOS
      # rbenv
      export RBENV_ROOT=/usr/local/rbenv
      export PATH="${RBENV_ROOT}/bin:${PATH}"
      eval "$(rbenv init -)"
    EOS
    content << appendix
  end
end

itamae 生活 4日目

itamae 生活4日目

前回 謎エラーの暫定対処ができたので、本線に戻る。

Today's Goal

  • rbenv で ruby を入れる

bundler 環境に切り替える

ここまで itamae はグローバルな gem に入れていたが、 rbenv は plugin で入れようを思うので、この際 bundler 環境に移行する。

itamae init で Gemfile も併せて作られているので、そちらに前回のエラー暫定対処を踏まえて thor のバージョンを v 0.19.1 を上限に指定する。

source 'https://rubygems.org'

gem 'itamae'
gem 'itamae-plugin-recipe-rbenv'
gem 'thor', '<= 0.19.1'

んで、 bundle install お好みで --path オプションもどーぞ

rails ロール作成

今回は rails という role を作った

$ bundle exec itamae g role rails
      create
      create  default.rb
      create  files/.keep
      create  templates/.keep

roles/rails/default.rb

まずは、 roles/rails/default.rb に以下1行だけ

include_recipe 'rbenv::system'

node.yml

どこに置くのが適切か判断つかなかったので、 roles/rails/node.yml とした

README にはオプション設定含めつらつらと書いてあるが、Ruby v2.3.3 を入れる最小は以下なのかな。

scheme も default git になるので削れそうではある

rbenv:
  global:
    2.3.3
  versions:
    - 2.3.3

  scheme: https

Execution

しかしエラー...

$ bundle exec itamae ssh -h xx.xx.xx.xx -i ~/.ssh/hogepiyo.pem -u ec2-user -y roles/rails/node.yml roles/rails/default.rb

 INFO : Starting Itamae...
 INFO : Loading node data from /Users/kawakubox/Workspace/generic-recipe/roles/rails/node.yml...
 INFO : Recipe: /Users/kawakubox/Workspace/generic-recipe/roles/rails/default.rb
 INFO :   Recipe: /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-plugin-recipe-rbenv-0.6.3/lib/itamae/plugin/recipe/rbenv/system.rb
 INFO :     Recipe: /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-plugin-recipe-rbenv-0.6.3/lib/itamae/plugin/recipe/rbenv/install.rb
 INFO :       Recipe: /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-plugin-recipe-rbenv-0.6.3/lib/itamae/plugin/recipe/rbenv/dependency.rb
 INFO :       execute[rbenv install 2.3.3] executed will change from 'false' to 'true'
ERROR :         stdout | Installing ruby-2.3.3...
ERROR :         stdout |
ERROR :         stdout | [1mBUILD FAILED[m (Amazon Linux AMI 2016.09 using ruby-build 20161121-14-gd799bdd)
ERROR :         stdout |
ERROR :         stdout | Inspect or clean up the working tree at /tmp/ruby-build.20161214144733.28704
ERROR :         stdout | [33mResults logged to /tmp/ruby-build.20161214144733.28704.log[m
ERROR :         stdout |
ERROR :         stdout | Last 10 log lines:
ERROR :         stdout | config.sub already exists
ERROR :         stdout | checking build system type... x86_64-pc-linux-gnu
ERROR :         stdout | checking host system type... x86_64-pc-linux-gnu
ERROR :         stdout | checking target system type... x86_64-pc-linux-gnu
ERROR :         stdout | checking for gcc... no
ERROR :         stdout | checking for cc... no
ERROR :         stdout | checking for cl.exe... no
ERROR :         stdout | configure: error: in `/tmp/ruby-build.20161214144733.28704/ruby-2.3.3':
ERROR :         stdout | configure: error: no acceptable C compiler found in $PATH
ERROR :         stdout | See `config.log' for more details
ERROR :         Command `  export RBENV_ROOT=/usr/local/rbenv
  export PATH="/usr/local/rbenv/bin:${PATH}"
  eval "$(rbenv init --no-rehash -)"
  rbenv install 2.3.3` failed. (exit status: 1)
ERROR :       execute[rbenv install 2.3.3] Failed.

README をまるっとコピペしても動かなかったので、うんうん唸ってたんですが rbenv::dipendency を眺めていてハッと思いついた。

platform: redhat   # <-- 追記

rbenv:
  global:
    2.3.3
  versions:
    - 2.3.3

  scheme: https

再度実行

$ bundle exec itamae ssh -h xx.xx.xx.xx -i ~/.ssh/hogepiyo.pem -u ec2-user -y roles/rails/node.yml roles/rails/default.rb

 INFO : Starting Itamae...
 INFO : Loading node data from /Users/kawakubox/Workspace/generic-recipe/roles/rails/node.yml...
 INFO : Recipe: /Users/kawakubox/Workspace/generic-recipe/roles/rails/default.rb
 INFO :   Recipe: /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-plugin-recipe-rbenv-0.6.3/lib/itamae/plugin/recipe/rbenv/system.rb
 INFO :     Recipe: /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-plugin-recipe-rbenv-0.6.3/lib/itamae/plugin/recipe/rbenv/install.rb
 INFO :       Recipe: /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-plugin-recipe-rbenv-0.6.3/lib/itamae/plugin/recipe/rbenv/dependency.rb
 INFO :         package[gcc] installed will change from 'false' to 'true'
 INFO :         package[gdbm-devel] installed will change from 'false' to 'true'
 INFO :         package[libyaml-devel] installed will change from 'false' to 'true'
 INFO :       execute[rbenv install 2.3.3] executed will change from 'false' to 'true'
 INFO :       execute[rbenv global 2.3.3] executed will change from 'false' to 'true'

やったね♪


同じミスが減るように README にプルリク投げてみた。 どうなるかな〜

github.com

itamae 生活3日目

引き続き itamae です。

kawakubox.hatenablog.com

kawakubox.hatenablog.com

Today's Goal

前回は眠さに負けたので、 Rails環境構築までを目指す。

Result

突然 itamae の help コマンドが動かなくなるという状況に陥り、2日ほど進展せず。

itamae が依存する gem を疑い始め、エラーログにも出てる thor あたりから追いかけ始める

bundler: failed to load command: itamae (/Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/bin/itamae)
NoMethodError: undefined method `upcase' for nil:NilClass
  /Users/kawakubox/Workspace/generic-recipe/vndor/bundle/ruby/2.3.0/gems/itamae-1.9.10/lib/itamae/cli.rb:15:in `initialize'
  /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/thor-0.19.4/lib/thor.rb:365:in `new'
  /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/thor-0.19.4/lib/thor.rb:365:in `dispatch'
  /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/thor-0.19.4/lib/thor/base.rb:444:in `start'
  /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/gems/itamae-1.9.10/bin/itamae:4:in `<top (required)>'
  /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/bin/itamae:22:in `load'
  /Users/kawakubox/Workspace/generic-recipe/vendor/bundle/ruby/2.3.0/bin/itamae:22:in `<top (required)>'

pry などで、ブレークポイント打ちつつ見てみると、 log_level のオプションの値が空っぽでコケてる様子。

この時点で使っている thor は 0.19.4。

順繰りに version を戻していったところ 0.19.1 でエラーが出なくなった。

CHANGELOG を見てると、それっぽいものが見つかった。

Fix support for subcommand-specific "help"s

関連する PR はこれっぽい

github.com


ひとまず、 thor のバージョン下げれば動くことはわかったので、 itamae に issue 作ったところで今日は打ち止め。 ねむねむ。

github.com

itamae 生活 2日目

昨日 に引き続き今日も itamae

Today's Goal

  • itamae の BestPractice の沿った構成で Nginx x Unicorn x Rails の構成を作る
  • Ruby は rbenv 環境下で入れたい

Premise

  • itamae が global に install されている

Let's Try

BestPractice をみながらディレクトリ構築

ディレクトリ構成

ココ にある通り

.
├── cookbooks
│   └── nginx
│       ├── default.rb
│       ├── files
│       │   └── etc
│       │       └── nginx
│       │           └── conf.d
│       │               └── static.conf
│       └── templates
│           └── etc
│               └── nginx
│                   └── conf.d
│                       └── dynamic.conf
└── roles
    └── web.rb

手でペチペチ作るのもなんだなぁと思ってたら、それっぽいのがあった

itamae help

$ itamae -h
Commands:
  itamae destroy [cookbook|role] [NAME]   # Undo role or cookbook (short-cut alias: "d")
  itamae docker RECIPE [RECIPE...]        # Create Docker image
  itamae generate [cookbook|role] [NAME]  # Initialize role or cookbook (short-cut alias: "g")
  itamae help [COMMAND]                   # Describe available commands or one specific command
  itamae init NAME                        # Create a new project
  itamae local RECIPE [RECIPE...]         # Run Itamae locally
  itamae ssh RECIPE [RECIPE...]           # Run Itamae via ssh
  itamae version                          # Print version

itamae inititamae gemenate が使えそう

itamae init

$ itamae init itamae-labo
      create
      create  Gemfile
      create  cookbooks/.keep
      create  roles/.keep
         run  bundle install from "."
Could not locate Gemfile or .bundle/ directory

$ cd itamae-labo
$ ls -la
total 8
drwxr-xr-x   5 kawakubox  staff   170 12 10 00:51 .
drwxr-xr-x  47 kawakubox  staff  1598 12 10 00:51 ..
-rw-r--r--   1 kawakubox  staff    63 12 10 00:51 Gemfile
drwxr-xr-x   3 kawakubox  staff   102 12 10 00:51 cookbooks
drwxr-xr-x   3 kawakubox  staff   102 12 10 00:51 roles

ルートディレクトリと Gemfile, 空ディレクトリ(cookbook, roles)作ってくれる。

cookbook

ミドルウェアやライブラリを取り回しやすい単位でまとめたもの

role

cookbook の利用者。 アプリサーバ、DBサーバなどで構成がガラッと変わるのでそれぞれ app, db といった role を用意してあげる

itamae generate

create cookbook

nginx の cookbook 作ってみる

$ itamae g cookbook nginx
      create
      create  default.rb
      create  files/.keep
      create  templates/.keep

g は generate のエイリアスrails っぽい

create role

続いて role を作る

$ itamae g role web
      create
      create  default.rb
      create  files/.keep
      create  templates/.keep

Recipe for nginx

昨日のまんまなので省略

Role for web

include_recipe '../../cookbooks/nginx/default.rb'

Execution

$ itamae ssh -i ~/.ssh/hogepiyo.pem -h xx.xx.xx.xx -u ec2-user roles/web/default.rb

 INFO : Starting Itamae...
 INFO : Recipe: /../itamae-labo/roles/web/default.rb
 INFO :   Recipe: /../itamae-labo/cookbooks/nginx/default.rb
 INFO :     package[nginx] installed will change from 'false' to 'true'
 INFO :     service[nginx] enabled will change from 'false' to 'true'
 INFO :     service[nginx] running will change from 'false' to 'true'

※動かす前に既に入っていた nginx を削除してから実行した


眠くなったので今日はここまで

Summary

BesstPractice の構成に則って作るには、 itamae init, itamae generate を使うのがよい

itamae はじめました

itamae はじめました

Today's Goal

ローカルの recipe.rb を使って、 EC2 インスタンスに Nginx 立てる

Install into local machine

まず itamae をローカルマシンにインストール

$ gem install itamae

bundler なんかは使わず、 global に入れてしまうのがよいのかな。

Create recipe

てきとうな場所に recipe.rb を作る

package 'nginx' do
  action :install
end

DSLは、操作したいパッケージの block に書いていく。

action メソッドに symbol を渡すという書式。

Execution

ローカルの recipe を使って EC2 インスタンスに対して dry-run で実行してみる。

$ itamae ssh -u ec2-user -i ~/.ssh/your_keypari.pem -h xx.xx.xx.xx -n recipe.rb
 INFO : Starting Itamae...
 INFO : Recipe: /~~/recipe.rb
 INFO :   package[nginx] installed will change from 'false' to 'true'

nginx のインストール状態は false → true になるよって言われる。

-n を取って実際に動かしてみる。

   ・    ・    ・

EC2 インスタンスに接続して確認。

$ ssh -i ~/.ssh/your_keypair.pem ec2-user@xx.xx.xx.xx

$ which nginx
/usr/sbin/nginx

この時点でサービスとして登録されていない。

service 'nginx' do
  action [:enable, :start]
end
$ itamae ssh -u ec2-user -i ~/.ssh/your_keypair.pem -h xx.xx.xx.xx recipe.rb
 INFO : Starting Itamae...
 INFO : Recipe: /xx/recipe.rb
 INFO :   service[nginx] enabled will change from 'false' to 'true'
 INFO :   service[nginx] running will change from 'false' to 'true'

すでに package 'nginx' は済んでるので実行されていない。

$ ps aux | grep nginx
root     23685  0.0  0.0  58084  1016 ?        Ss   15:46   0:00 nginx: master process /usr/sbin
/nginx -c /etc/nginx/nginx.conf
nginx    23687  0.0  0.3  58456  3924 ?        S    15:46   0:00 nginx: worker process

プロセスもしっかり立ってる

f:id:kawakubox:20161209005955p:plain


Wiki みると、 BestPractice ってのがあるので、もう少し触ったら BestPractice に沿って書いてみよう。

社内でぷちLT大会があったので、Neo4jの話をしてきた

2016年8月17日に、社内でソニックガーデンさんを招いてのぷちLT大会があったので、エントリーしました。

最近、Neo4j がお気に入りで業務でも社内向けツールに導入を図るなどをしたので、今回のLTでもNeo4jをテーマにしたものを用意しました

スライドの最後にもありますが、サービスへの本格導入などをするに向けて、クラスタ構成やHA構成なんかを抑えておくと強力な説得材料になるので、触れていこうと思います。

コードリーディングの効能

この記事はSpeee Advent Calendar 20日目の記事です。

前日の記事はコチラ ハリネズミと暮らすエンジニアライフ | CTO.Works


こんにちは、ミドルサーティーエンジニアのkawakuboxです。

2015年もあと残すところ10日ちょい。

あらためて2015年を振り返ると

などと、直近5,6年の中で最も変化の大きかった年だった。

今日は、10年近くJavaで食ってきた自分が、Rubyへとシフトチェンジした際にコードリーディングを通じて感じた効能を書いていく。

文法が覚えられる

代入系の演算子が多く定義(||= etc)されていて、初見で??となったり。

<=> を見て「ナニコレ?」となったりした。

そっから調べてみると「便利!」といったこともあった。

また、繰り返し処理にも学びがあった。

一昔前のプログラム言語だと、while, for あたりを押さえていれば事足りた*1けども、Ruby は更に表現力が増していて、 while と対になる until があったり、 イテレーション系のメソッド(each, map, times etc...)が豊富に用意されている。

こんな標準メソッドあったんだという感動

先の繰り返し処理each するのにインデックス用のカウンタ欲しいなと思ったら、 each_with_index ってのがあったりと至れり尽くせり。

そんなこんなで、カウンタ用の変数が広めのスコープに定義されていたら、あれっ?と思う感性はついた。

初日に suthio も書いてるとおりで、自分の知っている範疇のメソッドしか使えないので、いくらコード書いてアプリ作れるようにはなっても、いっこうに中身は洗練されてない、、、なんてことになりかねない。

やっぱり他人のコードやリファレンスを読む数をこなさないと身につかないなぁ〜と感じるわけっす。

命名やコメントのセンスを磨ける

英単語語彙や英分作成能力の乏しい自分にとっては、ここを伸ばそうと思ったら他人のコードを見るのが手っ取り早いと思っている。

命名のお作法まとめや、commitコメント検索サービスもあるけど、ロジックの背景を汲んだ活きた単語やコメントに触れるのも大事なんじゃないの? と思う次第。

標準のディレクトリ構成を知れる

Java であれば、maven で標準的なディレクトリ構成が提示されるよねってのと同じで、 Ruby であれば、rails newbundle gem によって基本となるディレクトリ構成が生成される。

さらには初期生成されるディレクトリに加えて、サービスはテストデータ、デコレーション用のクラスなんかはどこに入れるんだろう?? ってのことも色んなコード見ることでどの辺に置くのが一般的かは見えてくると思う。

例えばRails だと、サービスクラスは app/services だし、テストデータは spec(or test)/fixtures に入れましょうといったお作法があったり。

まとめ

リーディングが大事ってのはプログラムに特化した話ではなく、英語・ドイツ語といったような、一般的に言語と呼ばれる学習にも通じることだと思う。

アプリケーションを作るというのはアウトプットする場なので、それの良し悪しを左右するのはインプットの質と量ということになる。

ではそのインプットって何なの? と考えると、コードリーディングがその筆頭になるじゃないかなと考えてる。

追伸

巷にあふれている外国語のすぐれた勉強法を適用するのはとてもよい戦術だと思う。

 最短ルートで英語をマスターする現実的かつ効率的な勉強法をまとめてみる

 これなんかも、 s/英語/Ruby/g, s/英語/Go/g で脳内置換すると、あぁそうだよねぇ とすごく腹落ちする感じ。


明日(12/21)、は Tei1988Pebble Watchでmrubyを試す(まだ動かせて無いよ編)です。

*1:Java もバージョン重ねるごとに、 Iterator や 拡張 for が導入されたりした