FreeBSDにRiakをインストールしてみた

NoSQLの本命かと期待しているRiakをインストールしてみました.
まずは普通にダウンロードしてビルドを試みる.

> wget http://downloads.basho.com/riak/CURRENT/riak-0.14.0-1.tar.gz
> tar xvf riak-0.14.0-1.tar.gz
> cd riak-0.14.0
> make rel
"Makefile", line 141: Need an operator
make: fatal errors encountered -- cannot continue

おっと,gmakeじゃないとダメなんですね.

> gmake rel
gmake: git: コマンドが見つかりませんでした
./rebar get-deps
gmake: git: コマンドが見つかりませんでした
gmake: git: コマンドが見つかりませんでした
gmake: git: コマンドが見つかりませんでした
env: escript: No such file or directory
gmake: *** [deps] エラー 127

gitを入れておかないとダメなのか...portsから入れます.
あと,erlangも入れておかないとダメですね.
rebarってerlangの実行ファイルみたいなので.

> su
# cd /usr/ports/devel/git
# make
# make install
# cd /usr/ports/lang/erlang
# make
# make install

改めまして

> gmake rel
fatal: Not a git repository (or any parent up to mount parent )
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
./rebar get-deps
fatal: Not a git repository (or any parent up to mount parent )
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
fatal: Not a git repository (or any parent up to mount parent )
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
fatal: Not a git repository (or any parent up to mount parent )
Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set).
==> cluster_info (get-deps)
==> skerl (get-deps)
==> protobuffs (get-deps)
(中略)
Running make -C c_src
gunzip -c nsprpub-4.8.tar.gz | tar xf -
(cd /nsprpub &&  ./configure --disable-debug --enable-optimize  --prefix=/system --disable-64bit &&  make all install)
cd: can't cd to /nsprpub
*** Error code 2

Stop in /home/hoge/riak-0.14.2/deps/erlang_js/c_src.
ERROR: make -C c_src failed with error: 1
gmake: *** [rel] ??? 1

んーーー???
あーーーー!!!
トップディレクトリでgmakeコマンドを叩いても,下位ディレクトリでmakeを呼んでしまうんですね...

しゃーないんで,強引に

> su
# 
# cd /usr/bin/
# mv make make-freebsd
# ln -s /usr/local/bin/gmake make
# exit
exit

gmakeでmakeコマンドを置き換えて,再度チャレンジ.

> make rel
make[2]: ディレクトリ `/home/hoge/riak-0.14.2/deps/erlang_js/c_src/js/src' に入ります
config.mk:161: config/FreeBSD8.2-RELEASE.mk: そのようなファイルまたはディレクトリはありません
cat: ../../dist/FreeBSD8.2-RELEASE_OPT.OBJ/nspr/Version: No such file or directory
make[2]: *** ターゲット `config/FreeBSD8.2-RELEASE.mk' を make するルールがありません.  中止.
make[2]: ディレクトリ `/home/hoge/riak-0.14.2/deps/erlang_js/c_src/js/src' から出ます
make[1]: *** [/home/hoge/riak-0.14.2/deps/erlang_js/c_src/system/lib/libjs.a] エラー 2
make[1]: ディレクトリ `/home/hoge/riak-0.14.2/deps/erlang_js/c_src' から出ます
ERROR: make -C c_src failed with error: 2
gmake: *** [rel] エラー 1

あぁ...そりゃFreeBSD8.2-RELEASE.mkなんてファイルは無いですわな...
作ります.

> cp -v deps/erlang_js/c_src/js/src/config/Linux_All.mk ./FreeBSD8.2-RELEASE.mk
> emacs FreeBSD8.2-RELEASE.mk

フラグの行だけ書き換えて...

# OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R
OS_CFLAGS = -DXP_UNIX -DSVR4 -DSYSV -D_BSD_SOURCE -DPOSIX_SOURCE -DHAVE_LOCALTIME_R -fPIC -lstdc++

再チャレンジ.

> make rel
src/riakc_pb_socket.erl:62: type ip_address() undefined
make: *** [rel] Error 1

ああ,これはerlangバージョン依存のネームスペースの話ですよ...修正します.

> emacs deps/riakc/src/riakc_pb_socket.erl
%-type address() :: string() | atom() | ip_address().
-type address() :: string() | atom() | inet:ip_address().

またまたちゃれんじ.

> gmake rel
Compiling c_src/ebloom_nifs.cpp
c_src/ebloom_nifs.cpp: In function 'ERL_NIF_TERM ebloom_new_filter(ErlNifEnv*, int, const ERL_NIF_TERM*)':
c_src/ebloom_nifs.cpp:85: error: 'enif_alloc_resource_compat' was not declared in this scope
c_src/ebloom_nifs.cpp:90: error: 'enif_release_resource_compat' was not declared in this scope
c_src/ebloom_nifs.cpp: In function 'ERL_NIF_TERM ebloom_serialize(ErlNifEnv*, int, const ERL_NIF_TERM*)':
c_src/ebloom_nifs.cpp:247: error: 'enif_alloc_binary_compat' was not declared in this scope
c_src/ebloom_nifs.cpp: In function 'ERL_NIF_TERM ebloom_deserialize(ErlNifEnv*, int, const ERL_NIF_TERM*)':
c_src/ebloom_nifs.cpp:263: error: 'enif_alloc_resource_compat' was not declared in this scope
c_src/ebloom_nifs.cpp:266: error: 'enif_release_resource_compat' was not declared in this scope
c_src/ebloom_nifs.cpp: In function 'int on_load(ErlNifEnv*, void**, ERL_NIF_TERM)':
c_src/ebloom_nifs.cpp:287: error: 'enif_open_resource_type_compat' was not declared in this scope
ERROR: $CXX -c $CXXFLAGS $DRV_CFLAGS c_src/ebloom_nifs.cpp -o c_src/ebloom_nifs.o failed with error: 1
make: *** [compile] Error 1

あーーーー....これもerlangバージョン依存の話.
チェックしてるRiakのファイルの方を書き換えます.

> emacs deps/ebloom/c_src/erl_nif_compat.h
/* #if ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION == 0 */
#if ERL_NIF_MAJOR_VERSION == 2 && ERL_NIF_MINOR_VERSION == 2

チャレンジ!

> make rel
(中略)
Compiled src/riak_err_app.erl
Compiled src/trunc_io.erl
Compiled src/riak_err_monitor.erl
Compiled src/riak_err_sup.erl
Compiled src/riak_err_stdlib.erl
Compiled src/riak_err_handler.erl
==> rel (compile)
==> riak-0.14.2 (compile)
==> rel (generate)
> ./rel/riak/bin/riak start
> ./rel/riak/bin/riak-admin status | grep nodename
nodename : 'riak@127.0.0.1'

OK!

データのPUTにチャレンジ.

> curl -v -X PUT -d '{"bar":"baz"}' -H "Content-Type: application/json" http://127.0.0.1:8098/riak/test/doc
> curl -v 'http://127.0.0.1:8098/riak/test/doc
{"bar":"baz"}

OK!
じゃ,全キー取得にチャンレンジ.
あれ?

> curl -v 'http://127.0.0.1:8098/riak/test?keys=true'
* About to connect() to 127.0.0.1 port 8098 (#0)
*   Trying 127.0.0.1... connected
* Connected to 127.0.0.1 (127.0.0.1) port 8098 (#0)
> GET /riak/test?keys=true HTTP/1.1
> User-Agent: curl/7.21.3 (i386-portbld-freebsd8.2) libcurl/7.21.3 OpenSSL/0.9.8q zlib/1.2.3 libidn/1.16 libssh2/1.2.7
> Host: 127.0.0.1:8098
> Accept: */*   
>
* Empty reply from server
* Connection #0 to host 127.0.0.1 left intact
curl: (52) Empty reply from server
* Closing connection #0

ダメポ.
ログを見ると,

less ./rel/riak/log/erlang.log.1

=ERROR REPORT==== 27-Jul-2011::17:36:46 ===
The on_load function for module ebloom returned {error,
                                                 {load_failed,"Failed to load NIF library: '/home/hoge/riak-0.14.2/rel/riak/lib/ebloom-1.0.2/priv/ebloom_nifs.so: Undefined symbol \"_ZTVN10__cxxabiv117__class_type_infoE\"'"}}

なるほど,class_type_infoが入っているlibstdc++がリンクされてねー感じ.
なんでか探すと,このエラーのebloom_nifs.soを作っているところがサボってるっぽい.
なので書き換えます.

emacs deps/ebloom/rebar.config
%             {"(linux|solaris)", "LDFLAGS", "$LDFLAGS -lstdc++"},
             {"(linux|solaris|freebsd)", "LDFLAGS", "$LDFLAGS -lstdc++"},

結構苦労して何度目かのチャレンジ.

> make clean
> make rel
> cp -v FreeBSD8.2-RELEASE.mk deps/erlang_js/c_src/js/src/config/FreeBSD8.2-RELEASE.mk
> make rel
> ./rel/riak/bin/riak start
> curl -X PUT -d '{"bar":"baz"}' -H "Content-Type: application/json" http://127.0.0.1:8098/riak/test/doc
> curl -X PUT -d '{"bar":"baz"}' -H "Content-Type: application/json" http://127.0.0.1:8098/riak/test/doc2
> curl 'http://127.0.0.1:8098/riak/test?keys=true'
{"props":{"name":"test","n_val":3,"allow_mult":false,"last_write_wins":false,"precommit":[],"postcommit":[],"chash_keyfun":{"mod":"riak_core_util","fun":"chash_std_keyfun"},"linkfun":{"mod":"riak_kv_wm_link_walker","fun":"mapreduce_linkfun"},"old_vclock":86400,"young_vclock":20,"big_vclock":50,"small_vclock":10,"r":"quorum","w":"quorum","dw":"quorum","rw":"quorum"},"keys":["doc2","doc"]}

OK!!!
キーのリスト(二つしか登録していませんが)の「doc」「doc2」が取れました.
ログにエラーも出ていません.