- 更新
2014-05-29
- バージョン
0.2.0
- 作者
@voluntas
- URL
rebar generate と node_package についてまとめました。
- Erlang/OTP
17.0
- OS
Mac OS X 10.9.3
- rebar
rebar 2.3.1 17 20140524_080240 git 2.3.1-5-g755c602-dirty
Erlang/OTP コンパイルオプション:
./configure --prefix=/opt/erlang/17.0 \
--enable-smp-support \
--enable-threads \
--enable-darwin-64bit \
--enable-vm-probes \
--enable-kernel-poll \
--enable-hipe \
--with-dynamic-trace=dtrace \
--without-javac \
--enable-dirty-schedulers \
--disable-native-libs \
--disable-sctp
詳細については Erlang/OTP 17.0 コンパイルオプションについて を参照する事をお勧めする。
- Ubuntu 14.04 でのサンプル
- eunit_formatters や reloader などを有効にしていた場合に package に含めない方法
reltool を頑張っていた時代から rebar generate の時代が来て、そして node_package の時代へ
Erlang のパッケージングは基本的に Erlang/OTP ランタイム自身も含んでパッケージングする手段が基本だ。
そのため、Erlang/OTP がインストールされている環境を用意する必要は特にない。
ここでは Erlagn/OTP で開発されたシステムをパッケージングする方法を提供する。
Erlang/VM は OS 事にビルドをするという一般の手法が使われる。残念ながらクロスビルドは無い。
さらに、Erlang/OTP のコンパイル設定もそのまま引き継がれるため、SCTP 等ライブラリが必要なものを有効にしていた場合は 起動しない 、または 使用時にエラーがでる といった影響がある。
その辺りに注意して使用する必要がある。
パッケージングの手段は基本的に reltool を使った方法しかない。
ただ reltool だけだと色々つらいので、 rebar のサポートを使う。 さらに node_package という basho が公開しているツールを使うことで rpm や deb ファイルを簡単に作る事ができるようになる。
最初に rebar を使ったパッケージング方法を学んだ後、 rpm などのパッケージングが作りたいのであれば node_package を覚えればいい。
パッケージングの基本である rebar generate の機能を紹介したい。
rebar generate は Erlang/OTP に最初から入っている reltool の機能をわかりやすくラッピングし、誰もが簡単に使えるようなコマンドに落とし込んで提供してくれている。
さらに reltool にはないテンプレートの機能を使うことで様々なパッケージングに対応することが出来る。
rebar の generate で重要な機能の一つに overlay 機能がある。
overlay 機能は app.config や sys.config 等に対して template 的な役割が出来る。
overlay_vas の値で上書きしたい部分を "{{spam}}" の用にしておくと rebar generate overlay_vars=vars.config で rel/vars.config で値を指定しておくことが出来る。
rel/vars.config の例
{spam, "egg"}.
これを使う事で app.config の設定を上書きすることが出来る用になる。
ファイルを overlay_vars 対象とする場合は reltool.config の overlay 部分で template を定義する必要がある。
例えば app.config 、デフォルトは copy にすることが多いが template に変更することで、overlay_vars にて上書きすることが可能になる。
あとは rebar generate overlay_vars=vars.config とし、rel 以下にアプリ名でフォルダが出来る。そのフォルダを tar.gz で固めれば良い。
もしフォルダの場所などを変更したい場合は target_dir を使う事が出来る。
$ rebar generate target_dir=...
target_dir を使う事で指定したフォルダにパッケージされたデータをまとめてくれる。
開発用や本番用などで target_dir を分けると良いだろう。
app.config の値を vars.config にて上書きする例
reltool.config:
{overlay, [{template, "files/app.config"}, "etc/app.config"}]}.
vars.config:
{lager_async_threhold, 20}.
app.config
{lager, [
{colored, true},
{error_logger_hwm, 3000},
{async_threshold, {{lager_async_threhold}}},
{handlers, [
{lager_console_backend, info},
{lager_file_backend, [{file, "log/info.log"}, {level, info}, {date, "$D0"}, {count, 7}]},
{lager_file_backend, [{file, "log/warning.log"}, {level, warning}, {date, "$D0"}]},
{lager_file_backend, [{file, "log/error.log"}, {level, error}, {date, "$D0"}]}
]}
]},
コマンドの実行
$ rebar generate overlay_vars=var.config target_dir=/tmp
生成されたフォルダをそのままデプロイすれば良い。
https://github.com/basho/node_package
node_packege は basho が開発した rpm や deb さらには dmg を生成してくれる仕組みである。
このライブラリを使う事で rpm などのパッケージを簡単に作れるようになる。
これ自体は rebar と reltool を使っている。
ただし、ほぼドキュメントが無い事もあり、かなり使いこなすのにはコストがかかる。 上手く付けばかなり便利なため、以下にサンプルを示す。
このパッケージ手法は Git とかなり密接に連携しているため、Git 側の動作にも影響する。
以下に例を用意した、これをベースに解説していく
まず、rebar の create-app や create-node は終わった状態である前提とする。
rebar.config の deps に node_package を追加する。ここでは最新版を使用している。
https://github.com/voluntas/pkgex/blob/develop/rebar.config#L25
{deps, [
{node_package,
".*", {git, "git@github.com:basho/node_package.git", {branch, "develop"}}},
{lager,
".*", {git, "git@github.com:basho/lager.git", {branch, "master"}}}
]}.
Makefile は node_package 専用の Makefile を使用する。
Makefile 自体は以下を参照する事。
https://github.com/voluntas/pkgex/blob/develop/Makefile
パッケージング関連の設定は以下を参照する事。
https://github.com/voluntas/pkgex/blob/develop/Makefile#L54
pkg 自体の情報を設定する pkg.vars.config を用意する必要がある。
https://github.com/voluntas/pkgex/blob/develop/pkg.vars.config
pkg.vars.config に使える項目は node_package のドキュメントに書いてある
https://github.com/basho/node_package#required-variables-1
必須は全て記載し、オプションは基本的に記載する必要は無い。
この値が RPM や DEB ファイルなどのパッケージング情報として使われる。
reltool.config や他の files 以下のテンプレート用の設定をする vars.config を用意する必要がある。
https://github.com/voluntas/pkgex/blob/develop/rel/vars.config
デフォルトでは ulimit を 4096 以上に設定するしないとワーニングが出るため、あえて runner_ulimit_warn を 256 に設定してる
rebar.config で注意する必要があるのは sub_dirs の rel を対象にする必要がある。
https://github.com/voluntas/pkgex/blob/develop/rebar.config#L3
OS 事の vars.config を上書きするために overlay_vars を指定する必要がある。
https://github.com/voluntas/pkgex/blob/develop/rel/reltool.config#L33
reltool.config では erl や nodetool を node_package と置き換える必要がある。
https://github.com/voluntas/pkgex/blob/develop/rel/reltool.config#L36
またバージョン自体を明確にしておくとよい。
https://github.com/voluntas/pkgex/blob/develop/rel/reltool.config#L7
vm.args の node 名部分を {{node}} に変更する必要がある。
https://github.com/voluntas/pkgex/blob/develop/rel/files/vm.args#L2
今回は files 以下は app.config と vm.args のみとした。
https://github.com/voluntas/pkgex/tree/develop/rel/files
それ以外は削除して問題無い。
以上で準備は整った。
node_package は Git と連動しているため tag が何も打たれていない状態だと動作しない。
そのため、ここまでを git で commit し、 git tag でタグを打とう。
ここでは git tag 0.0.0 としている。
$ git commit
$ git tag 0.0.0
$ make package
上記コマンドを打つと package ディレクトリが生成され、その中に tag のバージョンのパッケージが自動で作成されていく。
長いが全てののログを貼り付けておく。Warning は消してある。
$ make package
==> node_package (get-deps)
==> goldrush (get-deps)
==> lager (get-deps)
==> rel (get-deps)
==> pkgex (get-deps)
mkdir -p package
rm -rf package/pkgex-0.0.0
git archive --format=tar --prefix=pkgex-0.0.0/ 0.0.0| (cd package && tar -xf -)
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C package/pkgex-0.0.0 deps
==> rel (get-deps)
==> pkgex-0.0.0 (get-deps)
Pulling node_package from {git,"git@github.com:basho/node_package.git",
{branch,"develop"}}
Cloning into 'node_package'...
Pulling lager from {git,"git@github.com:basho/lager.git",{branch,"master"}}
Cloning into 'lager'...
==> node_package (get-deps)
==> lager (get-deps)
Pulling goldrush from {git,"git://github.com/DeadZen/goldrush.git",
{tag,"0.1.6"}}
Cloning into 'goldrush'...
==> goldrush (get-deps)
mkdir -p package/pkgex-0.0.0/priv
git --git-dir=.git describe --tags >package/pkgex-0.0.0/priv/vsn.git
for dep in package/pkgex-0.0.0/deps/*; do \
echo "Processing dep: ${dep}"; \
mkdir -p ${dep}/priv; \
git --git-dir=${dep}/.git describe --tags >${dep}/priv/vsn.git; \
done
Processing dep: package/pkgex-0.0.0/deps/goldrush
Processing dep: package/pkgex-0.0.0/deps/lager
Processing dep: package/pkgex-0.0.0/deps/node_package
find package/pkgex-0.0.0 -depth -name ".git" -exec rm -rf {} \;
tar -C package -czf package/pkgex-0.0.0.tar.gz pkgex-0.0.0
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C package -f pkgex-0.0.0/deps/node_package/Makefile
echo "{app_version, \"0.0.0\"}." >> pkgex-0.0.0/deps/node_package/priv/templates/osx/vars.config
/Applications/Xcode.app/Contents/Developer/usr/bin/make -f pkgex-0.0.0/deps/node_package/priv/templates/osx/Makefile.bootstrap
/Users/voluntas/work/pkgex/rebar -v create \
template_dir=pkgex-0.0.0/deps/node_package/priv/templates \
template_vars=pkgex-0.0.0/pkg.vars.config template=osx
==> package (create)
ERROR: One or more files already exist on disk and were not generated:
* "Makefile"
* "vars.config"
To force overwriting, specify -f/--force/force=1 on the command line.
make -f Makefile
cd pkgex-0.0.0 && \
OVERLAY_VARS="overlay_vars=../../vars.config" /Applications/Xcode.app/Contents/Developer/usr/bin/make rel
==> node_package (get-deps)
==> goldrush (get-deps)
==> lager (get-deps)
==> rel (get-deps)
==> pkgex-0.0.0 (get-deps)
==> node_package (compile)
==> goldrush (compile)
Compiled src/gr_param_sup.erl
Compiled src/gr_sup.erl
Compiled src/gre.erl
Compiled src/gr_manager_sup.erl
Compiled src/gr_counter_sup.erl
Compiled src/gr_manager.erl
Compiled src/gr_context.erl
Compiled src/gr_app.erl
Compiled src/gr_param.erl
Compiled src/gr_counter.erl
Compiled src/glc_ops.erl
Compiled src/glc.erl
Compiled src/glc_lib.erl
Compiled src/glc_code.erl
==> lager (compile)
Compiled src/lager_util.erl
Compiled src/lager_transform.erl
Compiled src/lager_sup.erl
Compiled src/lager_msg.erl
Compiled src/lager_handler_watcher_sup.erl
Compiled src/lager_handler_watcher.erl
Compiled src/lager_stdlib.erl
Compiled src/lager_trunc_io.erl
Compiled src/lager_default_formatter.erl
Compiled src/lager_format.erl
Compiled src/lager_console_backend.erl
Compiled src/lager_crash_log.erl
Compiled src/lager_file_backend.erl
Compiled src/lager_config.erl
Compiled src/lager_backend_throttle.erl
Compiled src/lager_app.erl
Compiled src/lager.erl
Compiled src/error_logger_lager_h.erl
==> rel (compile)
==> pkgex-0.0.0 (compile)
Compiled src/pkgex_app.erl
Compiled src/pkgex_sup.erl
==> node_package (compile)
==> goldrush (compile)
==> lager (compile)
==> rel (compile)
==> pkgex-0.0.0 (compile)
==> rel (generate)
mkdir -p packages
mkdir -p osxbuild
cd pkgex-0.0.0 && \
cp -R rel/pkgex \
../osxbuild/pkgex-0.0.0
cd osxbuild && \
tar -czf ../packages/pkgex-0.0.0-OSX-i386.tar.gz \
pkgex-0.0.0
cd packages && \
for tarfile in *.gz; do \
shasum -a 256 ${tarfile} > ${tarfile}.sha \
; done
package 以下のディレクトリ構成は以下のようになっているはずだ。
Makefile
osxbuild/
packages/
pkgex-0.0.0-OSX-i386.tar.gz
pkgex-0.0.0-OSX-i386.tar.gz.sha
pkgex-0.0.0/
pkgex-0.0.0.tar.gz
vars.config
packages 以下の pkgex-0.0.0-OSX-i386.tar.gz が生成された Mac OS X 向けのバイナリファイルだ。
環境によってパッケージの生成を変えてくれる。これを CentOS でやれば rpm が Debian でやれば deb が生成される。
毎回タグを打つわけにも行かないだろう。 node_package はタグ以外のパッケージングも対応している。
かなり高機能だ。0.0.0 の後ろの 1 というのはタグを打ってからのコミット数だ。 さらにその後ろにショートハッシュが付く。
それでパッケージングが生成されようになる。
$ make package
... 省略
mkdir -p package
rm -rf package/pkgex-0.0.0.1.g7fad516
git archive --format=tar --prefix=pkgex-0.0.0.1.g7fad516/ 0.0.0-1-g7fad516| (cd package && tar -xf -)
/Applications/Xcode.app/Contents/Developer/usr/bin/make -C package/pkgex-0.0.0.1.g7fad516 deps
この状態で生成された Mac OS X 用のパッケージ。
pkgex-0.0.0.1.g7fad516-OSX-i386.tar.gz
pkgex-0.0.0.1.g7fad516-OSX-i386.tar.gz.sha
package ディレクトリの package にバイナリが出来ていますのでそれをコピーすれば動作する。
/tmp にファイルを持っていって起動する例:
$ tar xvfz pkgex-0.0.0.8.g6351c09-OSX-i386.tar.gz
$ cd pkgex-0.0.0.8.g6351c09/
$ ./bin/pkgex console
config is OK
-config /tmp/pkgex-0.0.0.8.g6351c09/bin/../etc/app.config -args_file /tmp/pkgex-0.0.0.8.g6351c09/bin/../etc/vm.args -vm_args /tmp/pkgex-0.0.0.8.g6351c09/bin/../etc/vm.args
Exec: /tmp/pkgex-0.0.0.8.g6351c09/bin/../erts-6.0/bin/erlexec -boot /tmp/pkgex-0.0.0.8.g6351c09/bin/../releases/0.0.0/pkgex -config /tmp/pkgex-0.0.0.8.g6351c09/bin/../etc/app.config -args_file /tmp/pkgex-0.0.0.8.g6351c09/bin/../etc/vm.args -vm_args /tmp/pkgex-0.0.0.8.g6351c09/bin/../etc/vm.args -pa /tmp/pkgex-0.0.0.8.g6351c09/bin/../lib/pkgex-patches -- console
Root: /tmp/pkgex-0.0.0.8.g6351c09/bin/..
Erlang/OTP 17 [erts-6.0] [source] [64-bit] [smp:4:4] [ds:4:4:10] [async-threads:10] [hipe] [kernel-poll:false] [dtrace]
23:54:21.416 [info] Application lager started on node 'pkgex@127.0.0.1'
23:54:21.416 [info] Application pkgex started on node 'pkgex@127.0.0.1'
Eshell V6.0 (abort with ^G)
(pkgex@127.0.0.1)1>
起動コマンドには幾つか例が書いてあるので参考にされると良い
$ ./bin/pkgex
Usage: pkgex «command»
where «command» is one of the following:
{ help | start | stop | restart | ping | console | attach
attach-direct | ertspath | chkconfig | escript | version | getpid
top [-interval N] [-sort { reductions | memory | msg_q }] [-lines N] } |
config { generate | effective | describe VARIABLE } [-l debug]
Run `pkgex help` for more detailed information.
Erlang/VM 向けの top コマンドが使えるので start で起動した後に実行すると色々見ることが出来る。
$ ./bin/pkgex start
% ./bin/pkgex top
========================================================================================
'pkgex@127.0.0.1' 14:56:16
Load: cpu 0 Memory: total 17920 binary 688
procs 64 processes 4591 code 7485
runq 0 atom 331 ets 372
Pid Name or Initial Func Time Reds Memory MsgQ Current Function
----------------------------------------------------------------------------------------
<5816.3.0> erl_prim_loader '-' 341697 142736 0 erl_prim_loader:loop
<5816.25.0> code_server '-' 115471 101408 0 code_server:loop/1
<5816.11.0> kernel_sup '-' 54309 197424 0 gen_server:loop/6
<5816.0.0> init '-' 18383 42312 0 init:loop/1
<5816.6.0> error_logger '-' 6453 5920 0 gen_event:fetch_msg/
<5816.44.0> release_handler '-' 5825 58144 0 gen_server:loop/6
<5816.57.0> application_master:s '-' 5706 42272 0 application_master:l
<5816.7.0> application_controll '-' 4805 55328 0 gen_server:loop/6
<5816.32.0> erlang:apply/2 '-' 3412 142880 0 shell:get_command1/5
<5816.59.0> lager_event '-' 2712 12104 0 gen_event:fetch_msg/
========================================================================================
書きかけ
- Erlang/OTP 17.0 インストール済み
$ sudo aptitude install devscripts