QNAP TS-239 ProにSubversion+Tracを入れた記録
昨日付けでQNAP製のNASをセットアップしたときの記録を書きました。それだけでも結構手間だったんですが、実はその後、バージョン管理システムのSubversionと連携できるWebインタフェースTracを入れるのに大変苦労したので、別に記録として残しておきます。
見ての通りかなりアドホックで汚いやり方なので、スマートな解決法をご存知の方いらっしゃいましたらご教示ください…。
2010/04/14追記; ファームウェアを更新したらApacheが上書きされ、mod_wsgiのインストール時に置換したビルドパス(/root/daily_build/云々)が新しくなっていたので、該当箇所の記述(sedコマンドの引数)をより一般的なものに修正しました。QNAPの中の人はユーザの手でプリインストールされたApacheに新しくモジュールを追加させる気がないようだ…。
Subversionのインストール
root権限を持つadminユーザで ipkg install svn すればSubversionがインストールされます。
ただし、Tracと連携させる前提でSubversionをインストールする場合、TracのエンジンであるPythonがSubversionにアクセスできるようにSWIGという仕組みを有効にしておく必要があります。ipkgコマンドを使ってインストールした素のSubversionではSWIGが有効になっていないため、このままでは後々エラーが出ます。
では、どうすればいいのでしょうか。
結論から言えば、Subversion用のPython SWIG bindingパッケージ svn-py というものが用意されており、ipkg install svn-py すればSWIGを有効にしてSubversionをビルドしたのと同じ状態になります。(はじめ、Subversionをソースからビルドし直さないといけないものと思い込んで四苦八苦しました。)
このとき、依存関係でPython 2.5がインストールされます。
PythonについてはQPKGでインストールすることもできますが、svn-pyと連携が取れないうえ、後で試してみたら mod_wsgi の ./configure で以下のようなエラーを吐いてしまうので使えなさそうです。機能の絞られたビルドなのかな?
mod_wsgi.c:135:20: error: Python.h: No such file or directory mod_wsgi.c:138:2: error: #error Sorry, Python developer package does not appear to be installed. mod_wsgi.c:142:2: error: #error Sorry, mod_wsgi requires at least Python 2.3.0 for Python 2.X. mod_wsgi.c:150:2: error: #error Sorry, mod_wsgi requires that Python supporting thread.
Tracのインストール
これは本当に簡単で、 ipkg install py25-trac すればいいだけです。
ちなみにPython 2.6用に py26-trac パッケージもありますが、先ほど svn-py のため強制的にPython 2.5をインストールさせられたのでこちらは使えません。
mod_wsgiのインストール
QNAPのNASについてくるApacheは、標準状態でPythonをCGIとして動かせないので、mod_pythonやmod_wsgiをインストールする必要があります。ApacheとPythonを繋げる方法には色々ありますが、mod_wsgiが一番速そうなのでこれを使うことにしました。
コンパイル済みの mod_wsgi 自体は ipkg install mod-wsgi で入手できますが、これは apache パッケージに依存しています。QNAPのNASに最初から入っているApacheを使い続けることを考えると、 mod-wsgi パッケージではなく、ソースからコンパイルしたほうがよさそうです。
まずGoogle Codeのプロジェクトサイトから最新のtar.gzをwgetしてtar -zxvfで展開します。
その後、ディレクトリに入ってapxsとpython2.6のパスを指定して ./configure しようとするとエラーが出ます。
[admin@kitten mod_wsgi-3.2]# ./configure --with-apxs=/usr/local/apache/bin/apxs --with-python=/opt/bin/python2.5
apxsの先頭で指定しているPerlのパス /usr/bin/perl が存在しないようです。 ipkg install perl して /opt/bin/perl に置換します。このとき、同じ画面内に $installbuilddir へ存在しないディレクトリ /root/daily_build/NasX86/Model/TS-259/../../NasMgmt/HTTP/apache_install_tmp/build を代入している行が見えたので /usr/local/apache/build に置き換えておきました。
改めて ./configure するとやはりエラーが出ます。apxsが内部で呼び出している /usr/local/apache/build/config_vars.mk というファイル内でやはりおかしなApacheのパスを指定しているようです。置換します。
[admin@kitten mod_wsgi-3.2]# cd /usr/local/apache/build [admin@kitten build]# cat config_vars.mk | /bin/sed -e 's@/root/daily_build/.*/apache_install_tmp@/usr/local/apache@g' > config_vars.new [admin@kitten build]# mv config_vars.mk config_vars.backup [admin@kitten build]# mv config_vars.new config_vars.mk [admin@kitten build]# cd /share/MD0_DATA/home/httpdusr/mod_wsgi-3.2 [admin@kitten mod_wsgi-3.2]# ./configure --with-apxs=/usr/local/apache/bin/apxs --with-python=/opt/bin/python2.5 (失敗)
同じようなエラーが出ます。どうやらQNAPのNASにインストールされているApacheは中の人の環境でビルドされたものをコピーしてきたもののようで、ことごとくパスの指定がおかしいです。
原因らしき /usr/local/apache/bin/apr-1-config のパス指定を置換します。
[admin@kitten mod_wsgi-3.2]# cd /usr/local/apache/bin [admin@kitten bin]# cat apr-1-config | /bin/sed -e 's@/root/daily_build/.*/apache_install_tmp@/usr/local/apache@g' > apr-1-config.new [admin@kitten bin]# mv apr-1-config apr-1-config.backup [admin@kitten bin]# mv apr-1-config.new apr-1-config [admin@kitten bin]# chmod 755 apr-1-config [admin@kitten bin]# cd /share/MD0_DATA/home/httpdusr/mod_wsgi-3.2 [admin@kitten mod_wsgi-3.2]# ./configure --with-apxs=/usr/local/apache/bin/apxs --with-python=/opt/bin/python2.5 checking Apache version... 2.2.14 configure: creating ./config.status config.status: creating Makefile [admin@kitten mod_wsgi-3.2]# make (失敗)
./configureはうまくいきましたが、makeできません。
今度は /usr/local/apache/build/libtool がおかしいようです。置換します。また、途中 /bin/bash を見に行っていますが、これはQNAPのNASでは /bin/sh として存在しているようなのでシンボリックリンクを張ります。
[admin@kitten mod_wsgi-3.2]# cd /usr/local/apache/build [admin@kitten build]# cat libtool | /bin/sed -e 's@/opt/cross-project/x86/sys-root/bin@/bin@g' > libtool.new [admin@kitten build]# ln -s /bin/sh /bin/bash [admin@kitten build]# mv libtool libtool.backup [admin@kitten build]# mv libtool.new libtool [admin@kitten build]# chmod 755 libtool [admin@kitten build]# cd /share/MD0_DATA/home/httpdusr/mod_wsgi-3.2 [admin@kitten mod_wsgi-3.2]# make /usr/local/apache/bin/apxs -c -I/opt/include/python2.5 -DNDEBUG mod_wsgi.c -L/opt/lib -L/opt/lib/python2.5/config -lpython2.5 -lpthread -ldl -lpthread -lutil -lm /usr/local/apache/build/libtool --silent --mode=compile gcc -prefer-pic -DLINUX=2 -D_REENTRANT -D_GNU_SOURCE -D_LARGEFILE64_SOURCE -g -O2 -pthread -I/usr/local/apache/include -I/usr/local/apache/include -I/root/daily_build/NasX86/Model/TS-259/../../NasMgmt/HTTP/apache_install_tmp/include -I/opt/include/python2.5 -DNDEBUG -c -o mod_wsgi.lo mod_wsgi.c && touch mod_wsgi.slo /usr/local/apache/build/libtool --silent --mode=link gcc -o mod_wsgi.la -rpath /usr/local/apache/modules -module -avoid-version mod_wsgi.lo -L/opt/lib -L/opt/lib/python2.5/config -lpython2.5 -lpthread -ldl -lpthread -lutil -lm copying selected object files to avoid basename conflicts...
うまくいきました。インクルードパスが若干おかしいですが、何とかなっていてほしい。
[admin@kitten mod_wsgi-3.2]# make install /usr/local/apache/bin/apxs -i -S LIBEXECDIR=/usr/local/apache/modules -n 'mod_wsgi' mod_wsgi.la /usr/local/apache/build/instdso.sh SH_LIBTOOL='/usr/local/apache/build/libtool' mod_wsgi.la /usr/local/apache/modules /usr/local/apache/build/libtool --mode=install cp mod_wsgi.la /usr/local/apache/modules/ cp .libs/mod_wsgi.so /usr/local/apache/modules/mod_wsgi.so cp .libs/mod_wsgi.lai /usr/local/apache/modules/mod_wsgi.la cp .libs/mod_wsgi.a /usr/local/apache/modules/mod_wsgi.a chmod 644 /usr/local/apache/modules/mod_wsgi.a ranlib /usr/local/apache/modules/mod_wsgi.a PATH="$PATH:/sbin" ldconfig -n /usr/local/apache/modules ---------------------------------------------------------------------- Libraries have been installed in: /usr/local/apache/modules If you ever happen to want to link against installed libraries in a given directory, LIBDIR, you must either use libtool, and specify the full pathname of the library, or use the `-LLIBDIR' flag during linking and do at least one of the following: - add LIBDIR to the `LD_LIBRARY_PATH' environment variable during execution - add LIBDIR to the `LD_RUN_PATH' environment variable during linking - use the `-Wl,--rpath -Wl,LIBDIR' linker flag - have your system administrator add LIBDIR to `/etc/ld.so.conf' See any operating system documentation about shared libraries for more information, such as the ld(1) and ld.so(8) manual pages. ---------------------------------------------------------------------- chmod 755 /usr/local/apache/modules/mod_wsgi.so
いよいよ /usr/local/apache/modules/mod_wsgi.so が作成されました。
/usr/local/apache/conf/apache.conf に LoadModule wsgi_module modules/mod_wsgi.so という行を足してサーバを停止します。
[admin@kitten mod_wsgi-3.2]# cd /usr/local/apache/bin [admin@kitten bin]# ./apachectl stop apache: Syntax error on line 46 of /etc/config/apache/apache.conf: Cannot load /usr/local/apache/modules/mod_wsgi.so into server: libpython2.5.so.1.0: cannot open shared object file: No such file or directory
mod_wsgi.so が libpython2.5.so.1.0 が見つからなくて落ちている旨のエラーが表示されます。
/opt/lib にあるので、これが /usr/lib からも見えるようシンボリックリンクを張ります。
[admin@kitten bin]# ln -s /opt/lib/libpython2.6.so.1.0 /usr/lib/libpython2.6.so [admin@kitten bin]# ./apachectl restart
いけました。
プロジェクト リポジトリの初期化
[httpdusr@kitten httpdusr]$ mkdir svn [httpdusr@kitten httpdusr]$ cd svn [httpdusr@kitten svn]$ svnadmin create test [httpdusr@kitten svn]$ cd ../ [httpdusr@kitten httpdusr]$ mkdir trac [httpdusr@kitten httpdusr]$ cd trac [httpdusr@kitten trac]$ trac-admin test initenv Traceback (most recent call last): File "/opt/bin/trac-admin", line 5, in <module> from pkg_resources import load_entry_point ImportError: No module named pkg_resources
Subversionのリポジトリは作れましたが、Tracのほうでpkg_resources が見つからないと怒られます。
調べてみるとsetuptoolsをインストールしたらいいらしいことが分かりました。
[admin@kitten httpdusr]# wget http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c11-py2.5.egg#md5=64c94f3bf7a72a13ec83e0b24f2749b2 --2010-04-04 02:25:22-- http://pypi.python.org/packages/2.5/s/setuptools/setuptools-0.6c11-py2.5.egg Resolving pypi.python.org... 82.94.164.163 Connecting to pypi.python.org|82.94.164.163|:80... connected. HTTP request sent, awaiting response... 200 OK Length: 333390 (326K) [application/octet-stream] Saving to: `setuptools-0.6c11-py2.5.egg' 100%[===================================================================================>] 333,390 147K/s in 2.2s 2010-04-04 02:25:25 (147 KB/s) - `setuptools-0.6c11-py2.5.egg' saved [333390/333390] [admin@kitten httpdusr]# sh ./setuptools-0.6c11-py2.5.egg Processing setuptools-0.6c11-py2.5.egg Copying setuptools-0.6c11-py2.5.egg to /share/MD0_DATA/.qpkg/Optware/local/lib/python2.5/site-packages Adding setuptools 0.6c11 to easy-install.pth file Installing easy_install script to /opt/local/bin Installing easy_install-2.5 script to /opt/local/bin Installed /share/MD0_DATA/.qpkg/Optware/local/lib/python2.5/site-packages/setuptools-0.6c11-py2.5.egg Processing dependencies for setuptools==0.6c11 Finished processing dependencies for setuptools==0.6c11
このときは setuptools のスクリプトを公式サイトからダウンロードしてきましたが ipkg install py-setuptools でも入るようです。まぁ、同じこと。
では、再チャレンジします。
[httpdusr@kitten trac]$ trac-admin test initenv Creating a new Trac environment at /share/MD0_DATA/home/httpdusr/trac/test Trac will first ask a few questions about your environment in order to initialize and prepare the project database. Please enter the name of your project. This name will be used in page titles and descriptions. Project Name [My Project]> Test Project Please specify the connection string for the database to use. By default, a local SQLite database is created in the environment directory. It is also possible to use an already existing PostgreSQL database (check the Trac documentation for the exact connection string syntax). Database connection string [sqlite:db/trac.db]> Please specify the type of version control system, By default, it will be svn. If you don't want to use Trac with version control integration, choose the default here and don't specify a repository directory. in the next question. Repository type [svn]> Please specify the absolute path to the version control repository, or leave it blank to use Trac without a repository. You can also set the repository location later. Path to repository [/path/to/repos]> /share/MD0_DATA/home/httpdusr/svn/test Creating and Initializing Project Installing default wiki pages (略) Indexing repository --------------------------------------------------------------------- Project environment for 'Test Project' created. You may now configure the environment by editing the file: /share/MD0_DATA/home/httpdusr/trac/test/conf/trac.ini If you'd like to take this new project environment for a test drive, try running the Trac standalone web server `tracd`: tracd --port 8000 /share/MD0_DATA/home/httpdusr/trac/test Then point your browser to http://localhost:8000/test. There you can also browse the documentation for your installed version of Trac, including information on further setup (such as deploying Trac to a real web server). The latest documentation can also always be found on the project website: http://trac.edgewall.org/ Congratulations!
きました。指示に従ってtracdを試してみます。
[httpdusr@kitten trac]$ tracd --port 8000 /share/MD0_DATA/home/httpdusr/trac/test Server starting in PID 13675. Serving on 0.0.0.0:8000 view at http://127.0.0.1:8000/ 127.0.0.1 - - [04/Apr/2010 02:29:43] "GET / HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:43] "GET /favicon.ico HTTP/1.1" 404 - 127.0.0.1 - - [04/Apr/2010 02:29:46] "GET /test HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:47] "GET /test/chrome/common/topbar_gradient2.png HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:47] "GET /test/chrome/site/your_project_logo.png HTTP/1.1" 404 - 127.0.0.1 - - [04/Apr/2010 02:29:51] "GET /test/browser HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:51] "GET /test/chrome/common/css/browser.css HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:51] "GET /test/chrome/common/js/expand_dir.js HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:51] "GET /test/chrome/common/js/keyboard_nav.js HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:51] "GET /test/chrome/site/your_project_logo.png HTTP/1.1" 404 - 127.0.0.1 - - [04/Apr/2010 02:29:51] "GET /test/chrome/common/asc.png HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:55] "GET /test/wiki HTTP/1.1" 200 - 127.0.0.1 - - [04/Apr/2010 02:29:55] "GET /test/chrome/site/your_project_logo.png HTTP/1.1" 404 -
ブラウザからアクセスしたら確かにアクセスできました。プロジェクトのロゴがないのでそこだけ404エラー。間違いなくちゃんと動いています。
Apacheの設定
以下のページに従って設定を終えました。
Google Code Archive - Long-term storage for Google Code Project Hosting.
サーバを再起動したところ、Tracのサイトが表示されました。しかし、次のエラーメッセージを吐いています。
Warning: Can't synchronize with the repository (Couldn't open Subversion repository /share/MD0_DATA/home/httpdusr/svn/test: SubversionException: ('SQLite compiled for 3.6.22, but running with 3.3.7', 200030)). Look in the Trac log for more information.
調べたところ、これはPHP用のSQLite(3.3.7)とSubversion用のSQLite(3.6.22)が衝突して起きるエラーのようです。
PHPを再コンパイルしたら直るといった情報が見つかりましたが、phpinfo();で現行PHPのビルドオプションを確認すると例によってApacheの変なパスを見ていたりして、再コンパイルは難航が予想されます。
そこでもう少し調べを進めていると、ApacheのLoadFileディレクティブで必要なライブラリを読むという解決策が見つかりました。
あまり期待せず、 libphp5 を読む前に libsqlite を読むように /usr/local/apache/conf/apache.conf を修正します。
LoadFile /opt/lib/libsqlite3.so.0 LoadModule php5_module modules/libphp5.so
果たして、サーバを再起動するとTracがうまく動くではありませんか。PHP版のSQLiteはどうなったんだ、等と少し不安も残りますが、とりあえずPHPでSQLiteを使う予定もないのでよしとしましょう。
2011/12/20 追記; 本件に関して別の解決策を見つけました。Fixing an SQLite version mismatch between Subversion and PHP5によれば、Subversionリポジトリを古いフォーマットで作っておけばこの問題自体が生じないそうです。
途中、 /usr/lib にシンボリックリンクを作成したりしましたが、これは恐らくNASを再起動したときに消えます。したがって、別途対策を講じる必要があります。まぁ、それはおいおい。