普段はQiitaにまとめてるのですが、今回は成功しなかった系なのでブログに書きます。

http://qiita.com/tienlen/items

まずはじめに

経緯

Dockerで構築してた環境で全部をAlpineLinuxで構築していたので、CouchbaseもAlpineLinuxで立てることができないのかやってみました。

Couchbaseってなぁに?

公式: http://www.couchbase.com/

Couchbaseはドキュメント指向でスキーマフリーなDBいわゆるNoSQLという種類のDBですが、Version4以降(投稿時は4.5)ではSQL準拠のN1QLが使えることになったことで、NotOnlySQLとかNewSQLとかっていう分類の仲間入りをしました。
特徴としてはマルチマスターで単一障害点がないことやmembaseやcouchdbをベースにしているため、キャッシュ機構が最適化されており、もちろん速度も早いこと。 モバイルアプリと連携する場合にオフライン設計ができていたり、DBとの同期処理もsync gatewayという関連パッケージを使うことでデータの競合解決をほぼ自動で行ってくれることなどがあげられます。 (いいところがありすぎて書ききれない...)

やってみた

dockerは使うけど、Dockerfileを書いて実行だと時間がかかりすぎるので、shellに入って試していきます。
imageはalpineの最新を使いました。(検証時は3.4)

Makeまでの流れは以下の手順となります。

  1. 必要なパッケージをインストールする
  2. repoをインストールする
    • repoはgitを拡張したようなツールで予めmanifestで定義されているリポジトリたちから一度にgit clone/updateしてくれるものです。
  3. repoを使って関連パッケージを落とす
  4. makeを実行する
docker run -it alpine sh  

以降 dockerコンテナの中での作業

とりあえず必要なパッケージを入れます。

apk update  
apk upgrade

# とりあえずgitはつかうので、必要なパッケージを入れます
apk --no-cache add git musl-dev

# 今後必要になるパッケージをインストールしておきます。
# curl: repoをダウンロードするのに使います
# alpine-sdk: makeと関連パッケージが内包されています
# cmake: makefileからcmakeを参照するので必要です。
# openssl: とちゅうでssl通信が発生するため必要です。
# python: repo実行途中でpythonがないと怒られます。
apk --no-cache add alpine-sdk curl cmake openssl python  

repoを落として、使えるようにします。

# curlでrepoを落とす
curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo  
# repoが実行できるようにモードを修正
chmod a+x ~/bin/repo

# repoを使ってるとユーザ情報がないと怒られるので、gitに適当に登録しておきます
git config --global user.name "FooBar"  
git config --global user.email "foo@bar.com"  

repoを実行します。
github.com/couchbase/manifestのreleasedディレクトリにmanifestのファイルがあるので、好きなのを選びます。
今回は最新版がよかったので、released/4.5.1.xmlにしました。

実行すると、合計71個のリポジトリからファイルを落ちてきます。 途中で止まるかもしれないので、止まったら再実行してください。

# 作業するための適当なディレクトリを作成します。
makedir /var/couchbase  
cd /var/couchbase

# repo initを実行し、各リポジトリからファイルを落とす
repo init -u git://github.com/couchbase/manifest.git -m released/4.5.1.xml

# 実際に使うファイルを同期する
# repo initをしただけだと、.repo配下にファイルがダウンロードされるだけで使えません。
# 途中で対話式で何回か聞かれるのでわからなかったらenter押しとけば大丈夫です
repo sync  

これで、makeが実行できるようになりました。 実行します。

$ make
(cd build && cmake -G "Unix Makefiles" -D PRODUCT_VERSION= -D BUILD_ENTERPRISE=  ..)
-- The C compiler identification is GNU 5.3.0
-- The CXX compiler identification is GNU 5.3.0
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Detecting C compile features
-- Detecting C compile features - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- Third-party dependencies will be cached in /root/.cbdepscache
-- *** Installing binary dependencies ***
CMake Warning at tlm/cmake/Modules/PlatformIntrospection.cmake:74 (MESSAGE):  
  Can't determine Linux platform without lsb_release
Call Stack (most recent call first):  
  tlm/deps/CMakeLists.txt:10 (_DETERMINE_PLATFORM)


-- Set platform to unknown for dependency downloads
-- Set arch to x86_64 for dependency downloads
-- NOTE: The dependencies for unsupported platforms may not be available.
--       Downloads may fail. You may build dependencies from from
--       tlm/deps/packages and store then in ~/.cbdepscache
-- -----------------------------------------
-- Reading global third-party dependencies manifest...
-- Dependency breakpad (1e455b5-cb10) not declared for platform unknown, skipping...
-- Dependency curl (7.49.1-cb1) not declared for platform unknown, skipping...
-- Dependency erlang (R16B03-1-couchbase-cb1) not declared for platform unknown, skipping...
-- Dependency erlang (R16B03-couchbase-cb2) not declared for platform unknown, skipping...
-- Dependency flatbuffers (1.2.0-cb1) not declared for platform unknown, skipping...
-- Dependency gperftools (2.4-cb3) not declared for platform unknown, skipping...
-- Dependency icu4c (54.1.0) not declared for platform unknown, skipping...
-- Dependency icu4c (54.1-cb7) not declared for platform unknown, skipping...
-- Dependency jemalloc (4.1.0-cb2) not declared for platform unknown, skipping...
-- Dependency jemalloc (4.0.4-cb2) not declared for platform unknown, skipping...
-- Dependency jemalloc (4.1.1-couchbase-cb1) not declared for platform unknown, skipping...
-- Dependency libevent (2.1.4-alpha-dev) not declared for platform unknown, skipping...
-- Dependency libevent (2.0.22-cb1) not declared for platform unknown, skipping...
-- Dependency libevent (2.0.22-cb2) not declared for platform unknown, skipping...
-- Dependency openssl (1.0.1h) not declared for platform unknown, skipping...
-- Dependency pysqlite2 (0ff6e32-cb1) not declared for platform unknown, skipping...
-- Dependency python-snappy (c97d633) not declared for platform unknown, skipping...
-- Dependency python-snappy (c97d633-cb1) not declared for platform unknown, skipping...
-- Dependency snappy (1.1.1) not declared for platform unknown, skipping...
-- Dependency snappy (1.1.1-cb2) not declared for platform unknown, skipping...
-- Dependency v8 (4.8-cb4) not declared for platform unknown, skipping...
-- Dependency v8 (b08066f-cb1) not declared for platform unknown, skipping...
-- Global third-party dependencies manifest complete
-- -----------------------------------------
-- Using cmake version: 3.5.2
-- Installing to /var/lib/couchbase/install
-- Build type: RelWithDebInfo (Community Edition)
-- Using system-supplied malloc
CMake Error at tlm/cmake/Modules/FindCouchbaseOpenSSL.cmake:58 (MESSAGE):  
  Can't build Couchbase without openssl
Call Stack (most recent call first):  
  CMakeLists.txt:92 (INCLUDE)


-- Configuring incomplete, errors occurred!
See also "/var/lib/couchbase/build/CMakeFiles/CMakeOutput.log".  
Makefile:45: recipe for target 'build/Makefile' failed  
make[1]: *** [build/Makefile] Error 1  
GNUmakefile:14: recipe for target 'all' failed  
make: *** [all] Error 2  

失敗しました!!(´・ω・`)

エラーメッセージを辿って原因を追求します。

Can't build Couchbase without openssl  

opensslは入れたはずなのにこのメッセージはおかしいです。
もう少し遡ります。

-- Dependency openssl (1.0.1h) not declared for platform unknown, skipping...

独自に入れようとしてるけど、Platformがわからなくてスキップされてるようですね。なぜ判別できてないのでしょう?

CMake Warning at tlm/cmake/Modules/PlatformIntrospection.cmake:74 (MESSAGE):  
  Can't determine Linux platform without lsb_release
Call Stack (most recent call first):  

ありました。ここですね。 lsb_releaseがなくて判別ができないっていわれてます。 AlpineLinuxはlsb_releaseがないので、困りました。
でも他のLinux OSでもminimumで入れたりしたらlsb_releaseない場合があった気がする。そこんところどうなんだろう?

とりあえず該当箇所を確認します。

tlm/cmake/Modules/PlatformIntrospection.cmake:74
tlmはTop-level Makefileの略らしく、makefileを管理してるリポジトリです。

該当ファイルの74行目付近を確認してみます。

# Returns a simple string describing the current platform. Possible      
# return values currently include: windows_msvc; macosx; or any value    
# from _DETERMINE_LINUX_DISTRO.                                          
MACRO (_DETERMINE_PLATFORM var)  
  IF (DEFINED CB_DOWNLOAD_DEPS_PLATFORM)                                 
    SET (_plat ${CB_DOWNLOAD_DEPS_PLATFORM})                             
  ELSE (DEFINED CB_DOWNLOAD_DEPS_PLATFORM)                               
    SET (_plat ${CMAKE_SYSTEM_NAME})                                     
    IF (_plat STREQUAL "Windows")                                        
      SET (_plat "windows_msvc")                                         
    ELSEIF (_plat STREQUAL "Darwin")                                     
      SET (_plat "macosx")                                               
    ELSEIF (_plat STREQUAL "Linux")                                      
      FIND_PROGRAM(LSB_RELEASE lsb_release)                              
      IF (LSB_RELEASE)                                                   
        _DETERMINE_LINUX_DISTRO (_plat)                                  
      ELSE (LSB_RELEASE)                                                 
        MESSAGE (WARNING "Can't determine Linux platform without lsb_release")
        SET (_plat "unknown")                                                 
      ENDIF (LSB_RELEASE)                                                     
    ELSEIF (_plat STREQUAL "SunOS")                                           
      SET (_plat "sunos")                                                     
    ELSEIF (_plat STREQUAL "FreeBSD")                                         
      SET (_plat "freebsd")                                                   
    ELSE (_plat STREQUAL "Windows")                                           
      MESSAGE (WARNING "Sorry, don't recognize your system ${_plat}. ")       
      SET (_plat "unknown")                                                   
    ENDIF (_plat STREQUAL "Windows")                                          
    SET (CB_DOWNLOAD_DEPS_PLATFORM ${_plat} CACHE STRING                      
      "Platform for downloaded dependencies")                                 
    MARK_AS_ADVANCED (CB_DOWNLOAD_DEPS_PLATFORM)                              
  ENDIF (DEFINED CB_DOWNLOAD_DEPS_PLATFORM)                                   
  SET (${var} ${_plat})                                                       
ENDMACRO (_DETERMINE_PLATFORM)  

Linuxの判定箇所( (_plat STREQUAL "Linux") )を確認すると、lsb_releaseを参照してないと即時にエラーを返してます。
これは動くわけない (;´д`)トホホ…

ここだけ直せば大丈夫なのかと関連箇所を確認すると、

MACRO (_DETERMINE_LINUX_DISTRO _distro)  
  _LSB_RELEASE (id _id)                                                       
  _LSB_RELEASE (release _rel)                                                 
  IF (_id STREQUAL "linuxmint")                                               
    # Linux Mint is an Ubuntu derivative; estimate nearest Ubuntu equivalent  
    SET (_id "ubuntu")                                                        
    IF (_rel VERSION_LESS 13)                                                 
      SET (_rel 10.04)                                                        
    ELSEIF (_rel VERSION_LESS 17)                                             
      SET (_rel 12.02)                                                        
    ELSE (_rel VERSION_LESS 13)                                               
      SET (_rel 14.04)                                                        
    ENDIF (_rel VERSION_LESS 13)                                              
  ELSEIF (_id STREQUAL "debian" OR _id STREQUAL "centos" )                    
    # Just use the major version from the CentOS/Debian identifier - we don't 
    # need different builds for different minor versions.                     
    STRING (REGEX MATCH "[0-9]+" _rel "${_rel}")                              
  ELSEIF (_id STREQUAL "fedora")                                              
    SET (_id "centos")                                                        
    SET (_rel "7")                                                            
  ELSEIF (_id STREQUAL "opensuse project" OR _id STREQUAL "suse linux")       
    SET(_id "suse")                                                           
  ELSEIF (_id STREQUAL "ubuntu")                                              
    # For Ubuntu 16.04 use the 14.04 cbdeps for now.                          
    IF (_rel STREQUAL "16.04")                                                
      SET (_rel "14.04")                                                      
    ENDIF ()                                                                  
  ENDIF (_id STREQUAL "linuxmint")                                            
  SET (${_distro} "${_id}${_rel}")                                            
ENDMACRO (_DETERMINE_LINUX_DISTRO)  

OSのディストリビューションが直書きされてる Σ( ̄ロ ̄lll) ガーン
しかもなんだろう? fedoraだったらCentOS7とみなすって... 古いfedoraだったらどうなるんだろう?

結論

  • 現行のままだと、lsb_releaseがないとMakeが動かない
  • cmakeファイルに対象となるOSの種類やバージョンがべた書きされていて、修正が大変そう
  • 仮に通ったとしても動くかどうかはまだわからない
  • Red Hat対応してるって公式では書いてるけど実態はCentOS対応だった

(´ε`;)ウーン… 仮に自分がやるとしても直すところがたくさんありそう。