本文接續上一篇對 rebar 的簡介,說明有關取得相依套件, 建構 release package 以及程式不關機直接升級的問題。
Templates
如果要使用自己的 template,就把 mytemplate.template 放到 templates 目錄中,並執行以下指令
rebar create template=mytemplate
rebar 提供了幾個內建的 templates
Template | Variables | Command | Alias Command |
---|---|---|---|
simplesrv | srvid | rebar create template=simplesrv | X |
simplenode | nodeid | rebar create template=simplenode | rebar create-node |
simplemod | modid | rebar create template=simplemod | X |
simplelib | libid | rebar create template=simplelib | rebar create-lib |
simplefsm | fsmid | rebar create template=simplefsm | X |
simpleapp | appid | rebar create template=simpleapp | rebar create-app |
ctsuite | testmod | rebar create template=ctsuite | X |
basicnif | module | rebar create template=basicnif | X |
管理發行版本
rebar 利用 reltool.config 建立執行的節點。
如果一個專案中,包含了多個 OTP applicaitons,我們可以建立一個 app 目錄,並把 otp application 移到 app 目錄中。
mkdir apps
cd apps
mkdir myapp
cd myapp
rebar create-app appid=myapp
cd ../../
編輯檔案 rebar.config
{sub_dirs, ["apps/myapp", "rel"]}.
然後就可以編譯專案
rebar compile
建立 release 目錄與檔案
mkdir rel
cd rel
rebar create-node
修改 reltool.config
line 4
{lib_dirs, ["../apps"]},
line 12 mynode 改為 myapp
[
kernel,
stdlib,
sasl,
myapp
]},
line 27 改為
{app, myapp, [{mod_cond, app}, {incl_cond, include}, {lib_dir, ".."}]}
產生 build release
cd ..
rebar -v generate
使用 rel/mynode/bin/mynode 啟動與停止節點
> rel/mynode/bin/mynode
Usage: mynode {start|start_boot <file>|foreground|stop|restart|reboot|ping|console|getpid|console_clean|console_boot <file>|attach|remote_console|upgrade}
啟動 app 後,進入 console 互動
> rel/mynode/bin/mynode console
(mynode@127.0.0.1)1> application:which_applications().
[{sasl,"SASL CXC 138 11","2.3.4"},
{myapp,[],"1"},
{stdlib,"ERTS CXC 138 10","1.19.4"},
{kernel,"ERTS CXC 138 10","2.16.4"}]
在背景啟動或停止 app
> rel/mynode/bin/mynode start
> rel/mynode/bin/mynode stop
增加 deps
專案通常會使用一些第三方的專業套件,我們必須要先修改 rebar.config。
必須增加 deps tuple 如下
{deps, [Dependency1, dependency2, ...]}
每一個 Dependency1 內容如下
{App, VsnRegex, Source}
Source 指定該 library 的來源,有以下幾種選擇。
- {hg, Url, Rev}
mercury repository - {git, Url}
- {git, Url, {branch, Branch}}
- {git, Url, ""} 等同於 {git, Url, {branch, "HEAD"}}
- {git, Url, {tag, Tag}}
- {git, Url, Rev}
- {bzr, Url, Rev}
bazaar repository
以下這個例子,使用了 cowboy。
{deps, [
{cowboy, "",
{git, "git://github.com/extend/cowboy.git",{branch, "master"}}}
]}.
{sub_dirs, ["apps/myapp", "rel"]}.
我們可以在 command line 用以下指令,從 git 取得 cowboy 相關的 libraries,包含了 cowlib, ranch與cowboy,程式碼都會 clone 到 deps。
rebar get-deps
rebar update-deps
如果專案 app 裡的程式碼使用了 cowboy,編譯時,也必須把 deps 相關的 libs 包含進去。
修改 reltool.config
line 4 增加 ../deps
{lib_dirs, ["../apps", "../deps"]},
line 12 mynode 改為 myapp
[
kernel,
stdlib,
sasl,
myapp
]},
line 27
{app, mynode, [{incl_cond, include}]},
{app, cowboy, [{incl_cond, include}]}
Makefile
可以做個簡單的 Makefile,簡化重複輸入指令的麻煩。
all: compile
deps:
rebar get-deps
rebar update-deps
compile:
rebar compile
clean:
rebar clean
test: compile
rebar eunit skip_deps=true
release: compile
rebar -v generate
mkdir -p ./rel/mynode/priv
cp -r ./apps/myapp/priv/ ./rel/mynode/priv/
.PHONY: all deps compile
Upgrades
把 apps/myapp/src/myapp.app.src and rel/reltool.conf 兩個檔案的版本號碼 vsn 都從 1 改為 2
在 rebar 有個測試的 dummy project 可用來驗證 OTP 程式線上直接升級的程序。
在取得 dummy project source code 時,一開始是設定為 0.1 版,所以先編譯然後就啟動 dummy server。
rebar compile
rebar generate
mv rel/dummy rel/dummy_0.1
rebar clean
啟動 dummy server
cd rel/dummy_0.1
bin/dummy console
(dummy@127.0.0.1)1> dummy_server:get_state().
0
(dummy@127.0.0.1)2> dummy_server:set_state(123).
{ok,123}
(dummy@127.0.0.1)3> dummy_server:get_state().
123
在另一個 terminal,進行 0.2 版的編譯
先將版本號碼從 0.1 版改為 0.2
vi apps/dummy/src/dummy.app.src
vi rel/reltool.config
編譯並封裝 0.2 版
rebar compile
rebar generate
rebar generate-appups previous_release=dummy_0.1
rebar generate-upgrade previous_release=dummy_0.1
這一行是一個測試 dummy_0.2.tar.gz 的壓縮檔
tar -zvtf rel/dummy_0.2.tar.gz
將 0.1 版 升級到 0.2 版
mv rel/dummy_0.2.tar.gz rel/dummy_0.1/releases/
回到剛剛 0.1 版的 console
(dummy@127.0.0.1)6> release_handler:unpack_release("dummy_0.2").
{ok,"0.2"}
(dummy@127.0.0.1)7> release_handler:install_release("0.2").
{ok,"0.1",[]}
(dummy@127.0.0.1)8> release_handler:make_permanent("0.2").
ok
(dummy@127.0.0.1)9> release_handler:which_releases().
[{"dummy","0.2",
["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","dummy-0.2",
"asn1-2.0.4","compiler-4.9.4","crypto-3.2","et-1.4.4.5",
"gs-1.5.15.2","inets-5.9.8","mnesia-4.11",
"observer-1.3.1.2","public_key-0.21","runtime_tools-1.8.13",
"ssl-5.3.3","tools-2.6.13","webtool-0.8.9.2","wx-1.1.2"],
permanent},
{"dummy","0.1",
["kernel-2.16.4","stdlib-1.19.4","sasl-2.3.4","dummy-0.1",
"asn1-2.0.4","compiler-4.9.4","crypto-3.2","et-1.4.4.5",
"gs-1.5.15.2","inets-5.9.8","mnesia-4.11",
"observer-1.3.1.2","public_key-0.21","runtime_tools-1.8.13",
"ssl-5.3.3","tools-2.6.13","webtool-0.8.9.2","wx-1.1.2"],
old}]
(dummy@127.0.0.1)10> dummy_server:get_state().
123