Hatena::ブログ(Diary)

Lazy Technology

2008-02-12

[]リンクするaprのバージョンを0.9xから1.2xに

WebDAV(=Apache)でリポジトリにアクセスすると、500が返ってきてログにも何も残らないと言う現象に遭遇する。で、色々調べていくうちのSubversionApacheのaprのバージョンの不整合が原因と言う事が分かった。

なお、Apache HTTP Server 2.0系で利用されているAPR 0.9系と、Apache HTTP Server 2.2系で利用されているAPR 1.2系では、互換性がないことに注意されたい。

http://builder.japan.zdnet.com/news/story/0,3800079086,20361867,00.htm

トラブルシューティングの手順を残しておく。


まず、Apacheのログに何も残っていないので、telnetから直接WebDAVのリクエストを投げる。参考: Subversionによるバージョン管理 (2/3):Apache 2.0でWebDAV(後編) - @IT

$ telnet localhost 80
OPTIONS /svn/ HTTP/1.1
Host: hostname
Authorization: Basic ===============

すると、xmlでエラーの詳細が返ってくる。

HTTP/1.1 500 Internal Server Error
Date: Fri, 08 Feb 2008 02:43:28 GMT
Server: Apache
Content-Length: 290
Connection: close
Content-Type: text/xml; charset="utf-8"

<?xml version="1.0" encoding="utf-8"?>
<D:error xmlns:D="DAV:" xmlns:m="http://apache.org/dav/xmlns" xmlns:C="svn:">
<C:error/>
<m:human-readable errcode="22">
Can't set position pointer in file '/path/to/repos/db/revs/2406': Invalid argument
</m:human-readable>
</D:error>
Connection closed by foreign host.

ポイントは以下。

Can't set position pointer in file '/path/to/repos/db/revs/2406': Invalid argument

これでググる401 Unauthorizedでaprのバージョンが原因と書いてある。

Subversionはそのままだと同梱のAPR(0.9.7)を使ってしまうので、Apache 2.2.0に同梱のAPR(1.0)を使わせるため「--with-apr」と「--with-apr-util」を指定する。

指定しなくてもコンパイルもできてApacheもしっかり起動するが、アクセスするときに

Can't set position pointer in file '/var/lib/svn-repos/db/revs/0': Invalid argument

みたいなこと言われてハマる

http://saikyoline.jp/wiki/index.php?%A5%E1%A5%E2%2FWebDAV%A4%C7Subversion


aprのバージョンを確認するにはlddを使う。まずはSubversion(mod_dav_svn)。

$ ldd /usr/local/apache2/modules/mod_dav_svn.so
        libaprutil-0.so.0 => /usr/lib/libaprutil-0.so.0 (0x008f9000)
        libapr-0.so.0 => /usr/lib/libapr-0.so.0 (0x00270000)
        (snip)

$ ll /usr/lib/libapr*.0
lrwxrwxrwx  1 root root 18  1月 25 14:57 /usr/lib/libapr-0.so.0 -> libapr-0.so.0.9.17
lrwxrwxrwx  1 root root 22  1月 25 14:57 /usr/lib/libaprutil-0.so.0 -> libaprutil-0.so.0.9.17


恐らく0.9.17。次にApache

$ ldd /usr/local/apache2/bin/httpd
        libaprutil-1.so.0 => /usr/local/apache228/lib/libaprutil-1.so.0 (0x0078a000)
        libapr-1.so.0 => /usr/local/apache228/lib/libapr-1.so.0 (0x00b5d000)


$ ll /usr/local/apache228/lib/libapr*.0
lrwxrwxrwx  1 root root 18  2月  6 16:03 /usr/local/apache228/lib/libapr-1.so.0 -> libapr-1.so.0.2.12
lrwxrwxrwx  1 root root 22  2月  6 16:03 /usr/local/apache228/lib/libaprutil-1.so.0 -> libaprutil-1.so.0.2.12


恐らく1.2.12。確かにバージョンが違う。

と言うわけで、再々度Subversionコンパイル。この際なので色々オプションを調べて自分なりのconfigureを作る事に。

./configure \
--with-apr=/usr/local/apache2 \
--with-apr-util=/usr/local/apache2 \
--with-apxs=/usr/local/apache2/bin/apxs \
--with-swig=/usr/local/bin/swig \
--with-neon=/usr/local/ \
PERL=/usr/local/bin/perl \
PYTHON=/usr/local/bin/python \
RUBY=/usr/local/bin/ruby \
--with-ssl \
--without-berkeley-db

これでインストールしたらWebDAVで無事アクセスできた。いい加減これで全部かなー。

2008-01-24

[] Subversionでhttp(s)のURLスキームを認識しない問題を解決する。

RetrospectivaのtrunkをGoogle Codeからcoしようとしたらエラーが出る。

$ svn co -q http://retrospectiva.googlecode.com/svn/trunk/ retrospectiva
svn: 'http://retrospectiva.googlecode.com/svn/trunk' 用の URL スキームを認識できません

色々調べてみたものの分からなかったので、エラーメッセージググるとあっさり原因が見つかった。svnコマンドでhttp(s)系のリポジトリにアクセスする場合には、neonと言うライブラリが必要になるらしい。subversionのINSTALLファイルには以下のように書かれている。

4.  Neon library 0.25.x or 0.26.x (http://www.webdav.org/neon/)

The Neon library allows a Subversion client to interact with remote
repositories over the Internet via a WebDAV based protocol.  If you
want to use Subversion to connect to a server over ra_dav (via a
http:// or https:// url), you will require Neon.  (See also section
I.11 for information about "serf", an experimental alternative to
Neon for accessing servers over WebDAV.)

まず既存環境にNeonがあるか確認する。

$ rpm -qa | grep -i neon
neon-0.24.7-4

あった。でも要件を満たしていないようだ。と言うわけでNeonを含めてSubversionを再コンパイルする。NeonNeon公式からダウンロードするか、Subversionの依存ファイルを一括してパッケージしたtarファイルに含まれている。今回は後者を利用する。インストール方法も同様にINSTALLファイルに書かれているのでこれを参考に。

The source code is included with the Subversion dependencies package,
and it can also be obtained from:

  http://www.webdav.org/neon/neon-0.25.5.tar.gz
    -or-
  http://www.webdav.org/neon/neon-0.26.1.tar.gz

Building Neon inside the subversion build:

The Neon library source code can be placed in "./neon" if you
want Subversion to build it as part of the Subversion build process.

Unpack the archive using tar/gunzip.  Rename the resulting
directory from ./neon-0.XX.Y to just "./neon", inside the top
level of your Subversion source tree.  (This is what unpacking the
Subversion dependencies package does, too.)

手順は以下の通り。

$ wget http://subversion.tigris.org/downloads/subversion-1.4.6.tar.gz
$ tar zxf subversion-1.4.6.tar.gz
$ wget http://subversion.tigris.org/downloads/subversion-deps-1.4.6.tar.gz
$ tar zxf subversion-deps-1.4.6.tar.gz
$ cd subversion-1.4.6
$ ./configure
$ make
$ sudo make install

特に問題なく終了。configure時には以下の出力を確認した。

#
#configure: Configured to build neon 0.25.5:
#
#  Install prefix:  /usr/local
#  Compiler:        gcc
#  XML Parser:      expat
#  SSL library:     SSL support is not enabled
#  zlib support:    zlib support enabled, using -lz
#  Build libraries: Shared=no, Static=yes

再度チェックアウトし、無事チェックアウト出来る事を確認。


2008/1/29 追記

上記の手順でコンパイルした後、svkが動作しなくなったり、rubySubversionバインディングが動かなくなったりした。バインディングはバージョンが古いだけだったのだけれど、svkは原因がよく分からなかった。

以前とconfigureのオプションが違っていたりする事はあったのだが、Subvresionの依存パッケージにはNeon以外にapr,apr-util,zlibが入っていたので、それが問題になったのかもしれない。復旧した際にはNeon単体のみをソースツリーに含めるようにした。


2008/1/29 追記 その2

configureに--with-sslオプションを追加しないとhttpsでチェックアウトが出来なかったので、再度コンパイルし直し。

$ ./configure \
  PERL=/usr/local/bin/perl \
  PYTHON=/usr/local/bin/python \
  --with-swig=/usr/local/bin/swig \
  --with-ssl
$ make
$ sudo make install

コンパイル前。

$ svn --version
(snip)
以下のリポジトリアクセス (RA) モジュールが利用できます:

* ra_dav : WebDAV (DeltaV) プロトコルを使ってリポジトリにアクセスするモジュール。
  - 'http' スキームを操作します
* ra_svn : svn ネットワークプロトコルを使ってリポジトリにアクセスするモジュール。
  - 'svn' スキームを操作します
* ra_local : ローカルディスク上のリポジトリにアクセスするモジュール。
  - 'file' スキームを操作します

コンパイル後。

$ svn --version
(snip)
以下のリポジトリアクセス (RA) モジュールが利用できます:

* ra_dav : WebDAV (DeltaV) プロトコルを使ってリポジトリにアクセスするモジュール。
  - 'http' スキームを操作します
  - 'https' スキームを操作します
* ra_svn : svn ネットワークプロトコルを使ってリポジトリにアクセスするモジュール。
  - 'svn' スキームを操作します
* ra_local : ローカルディスク上のリポジトリにアクセスするモジュール。
  - 'file' スキームを操作します

2007-11-08

[][]Rubyでの正規表現についての覚書

Rubyで正規表現オブジェクトを作る方法は以下の三通り。

  1. /pattern/option
  2. %r{pattern}option
  3. Regexp.new('pattern', option)

通常扱うのは/pattern/option。所謂正規表現リテラルで、リテラル内には式展開を含める事ができる。

/hoge#{"foo"}/
# => /hogefoo/

ただし、optionには式展開を適用することができない。これはコンパイルエラーにもならないので注意が必要。

/hoge#{"foo"}/#{"ni"}
# => /hogefoo/ #式展開でくっつけたoption値が無視されている。

この問題は%r記法でも同様だった。

optionを動的にしたい場合はRegexp.newメソッドを使う。

Regexp.new("hoge", "i")
# => /hoge/i

Regexp.new("hoge", "o")
# => /hoge/i

……あれ?

どんな値を入れても何故かignore caseがオプションになってしまう。


Regexpのrdocを見て謎が解明。

第二引数が Fixnum であった場合、その値は

Regexp::IGNORECASE

Regexp::MULTILINE

Regexp::EXTENDED

の論理和でなければなりません。

第二引数が Fixnum 以外であれば真偽値の指定として見なされ、真 (nil, false 以外)であれば Regexp::IGNORECASE の指定と同じになります。

第三引数が与えられた時には、$KCODE の値にかかわらず、指定された文字コードでマッチを行います。文字コードは $KCODE への代入と同様に文字列引数の最初の一文字で決定されます。

http://www.ruby-lang.org/ja/man/?cmd=view;name=Regexp

つまり、文字コードの取り扱いは第3引数で、第2引数はそれ以外のオプションになるようだ。今回は文字コードを動的に変えたかったので、最終的には以下のようなコードとなった。


charset = "o"
Regexp.new("hoge", nil, charset)
# => /hoge/o

charset = "u"
Regexp.new("hoge", Regexp::MULTILINE , charset)
# => /hoge/mu


参考

no title

no title

2007-07-07

[][]正規表現オブジェクトの作り方と注意点

Rubyで正規表現オブジェクトを作る方法は以下の三通り。

  1. /pattern/option
  2. %r{pattern}option
  3. Regexp.new('pattern', option)

一番利用頻度が高いのが/pattern/で、この場合patternには式展開を含める事ができる。

/hoge#{"foo"}/
# => /hogefoo/

ただし、optionには式展開を含める事ができない(正確にはできるが、無視される)。これはコンパイルエラーにもならないので注意が必要。

/hoge#{"foo"}/#{"ni"}
# => /hogefoo/ #式展開でくっつけたoption値が無視されている。

%r記法でも同様である。


その為、optionを動的にしたい場合はRegexp.newメソッドを使用する。

…と思っていたのだが、そうでもないらしい。

Regexp.new("hoge", "i")
# => /hoge/i

Regexp.new("hoge", "o")
# => /hoge/i

どんな値を入れても何故かignore caseがオプションになってしまう。


Regexpのrdocを見て謎が解明。

第二引数が Fixnum であった場合、その値は

Regexp::IGNORECASE

Regexp::MULTILINE

Regexp::EXTENDED

の論理和でなければなりません。

第二引数が Fixnum 以外であれば真偽値の指定として見なされ、真 (nil, false 以外)であれば Regexp::IGNORECASE の指定と同じになります。

http://www.ruby-lang.org/ja/man/?cmd=view;name=Regexp

わざわざ論理和とか計算したり長い定数名を書くらいならcaseで分けた方が早いと思う…。

そもそもoptionに式展開を含めたいと考えたのは文字コードを動的に変えたいからだった。

引き続きRegexpのrdocを読んで見ると以下のような記述を発見。

第三引数が与えられた時には、$KCODE の値にかかわらず、指定された文字コードでマッチを行います。文字コードは $KCODE への代入と同様に文字列引数の最初の一文字で決定されます。

http://www.ruby-lang.org/ja/man/?cmd=view;name=Regexp

と言うわけで以下のように使うと今回の目的は達成できる。

charset = "s"
Regexp.new("hoge", nil, charset)
# => /hoge/s

charset = "u"
Regexp.new("hoge", Regexp::MULTILINE , charset)
# => /hoge/mu


参考

no title

no title

2007-05-25

[] RHEL4にTracインストール

yumやapt-getなし。全部手動で入れる。

躓いたところは以下の二点(最終的にはまだあった)。

  1. sqliteのインストールディレクトリを変える(ex:home/hoge/sqlite)とpysqliteのコンパイルが通らない
  2. trac-admin test initenvでエラーが起こる。

前者は/usr/localにインストールし直した。

後者は

Creating and Initializing Project
Failed to create environment. global name 'sqlite' is not defined
Traceback (most recent call last):
  File "/usr/local/lib/python2.5/site-packages/trac/scripts/admin.py", line 613, in do_initenv
    options=options)
  File "/usr/local/lib/python2.5/site-packages/trac/env.py", line 145, in __init__
    self.create(options)
  File "/usr/local/lib/python2.5/site-packages/trac/env.py", line 250, in create
    DatabaseManager(self).init_db()
  File "/usr/local/lib/python2.5/site-packages/trac/db/api.py", line 71, in init_db
    connector.init_db(**args)
  File "/usr/local/lib/python2.5/site-packages/trac/db/sqlite_backend.py", line 121, in init_db
    cnx = sqlite.connect(path, timeout=int(params.get('timeout', 10000)))
NameError: global name 'sqlite' is not defined

こんなエラーが出る。sqlite変数が見つからないようだ。

python-sqliteのバインディングが上手く行っていないのではないかと予想する。

sqlite_backend.pyのソースは

try:
    import pysqlite2.dbapi2 as sqlite
    have_pysqlite = 2
except ImportError:
    try:
        import sqlite3 as sqlite
        have_pysqlite = 2

となっている事から、pyqsliteのインポートに失敗しているのだと思われる。


行き詰り気味になり、pysqliteの動作確認用のソースでもないかな、とググる

ソフト/Bug Tracking/trac/RedHat - discypus

が出てきた。ビンゴ!素晴らすぎる…。


消えたら困るので引用しておきます。

$ cd scripts

テスト(Step 4: Test Your pysqlite Installation より)

$ cat test-pysqlite
#!/usr/bin/env python
from pysqlite2.test import test
test()

$ ./test-pysqlite
Traceback (most recent call last):
 File "./test-pysqlite", line 2, in ?
    from pysqlite2.test import test
  File "/usr/local/lib/python2.3/site-packages/pysqlite2/test/__init__.py", line
 25, in ?
    from pysqlite2.test import dbapi, types, userfunctions, factory, transactions
  File "/usr/local/lib/python2.3/site-packages/pysqlite2/test/dbapi.py", line 26, in ?
    import pysqlite2.dbapi2 as sqlite
  File "/usr/local/lib/python2.3/site-packages/pysqlite2/dbapi2.py", line 32, in ?
    from pysqlite2._sqlite import *
ImportError: libsqlite3.so.0: cannot open shared object file: No such file or directory

失敗した。libsqlite3.so.0の位置を/etc/ld.so.confに登録する。

libsqlite3.so.0の場所を探す。(/usr/local/libだろうけど、ついでにupdatedbも実行しておく)

# updatedb

$  locate libsqlite3.so.0
/usr/local/lib/libsqlite3.so.0.8.6
/usr/local/lib/libsqlite3.so.0                ★
/home/admin/trac/sqlite-bld/.libs/libsqlite3.so.0.8.6
/home/admin/trac/sqlite-bld/.libs/libsqlite3.so.0

/etc/ld.so.confを編集

/usr/kerberos/lib
/usr/X11R6/lib
/usr/lib/qt-3.0.5/lib
/usr/lib/sane
/opt/kakadu
/usr/local/lib    ★この行を追加

ldconfigを実行

# /sbin/ldconfig

再テスト。OK

http://discypus.jp/wiki/?%A5%BD%A5%D5%A5%C8%2FBug%20Tracking%2Ftrac%2FRedHat#n5008889

これでtrac-adminでプロジェクトを作成する事ができたので、tracdでサーバを起動し、アクセスしてみる。

が、何も表示されない。

ターミナルの方で、以下のような例外を確認。

Exception happened during processing of request from ('192.168.1.1', 11194)
Traceback (most recent call last):
  File "/usr/local/lib/python2.5/SocketServer.py", line 464, in process_request_thread
    self.finish_request(request, client_address)
  File "/usr/local/lib/python2.5/SocketServer.py", line 254, in finish_request
    self.RequestHandlerClass(request, client_address, self)
  File "/usr/local/lib/python2.5/SocketServer.py", line 522, in __init__
    self.handle()
  File "/usr/local/lib/python2.5/BaseHTTPServer.py", line 316, in handle
    self.handle_one_request()
  File "/usr/local/lib/python2.5/site-packages/trac/web/wsgi.py", line 174, in handle_one_request
    gateway.run(self.server.application)
  File "/usr/local/lib/python2.5/site-packages/trac/web/wsgi.py", line 87, in run
    response = application(self.environ, self._start_response)
  File "/usr/local/lib/python2.5/site-packages/trac/web/standalone.py", line 88, in __call__
    return self.application(environ, start_response)
  File "/usr/local/lib/python2.5/site-packages/trac/web/main.py", line 363, in dispatch_request
    env_paths)
  File "/usr/local/lib/python2.5/site-packages/trac/web/main.py", line 456, in send_project_index
    req.hdf = HDFWrapper(loadpaths)
  File "/usr/local/lib/python2.5/site-packages/trac/web/clearsilver.py", line 135, in __init__
    raise TracError, "ClearSilver not installed (%s)" % e
TracError: ClearSilver not installed (No module named neo_cgi)

ClearSilverが入っていないとな。

インストールはしたんだが…。

とりあえず再インストールでもしようと思い、./configureで実行結果を確認。

checking for python includes... found /usr/include/python2.3

と、ここで違和感が。

Tracが参照してるのはpython2.5の方で、実際にインストールしたpythonのバージョンは2.5。

どうやらpython2.3が既に入っており、そちらを参照してしまっているようだ。

/usr/local/includeよりも/usr/includeを先に見てしまうのね。

whichだと/usr/localの方を見てるんだけどなぁ…。


インストール - cooldaemonの備忘録

を参考に、オプションを追加し、

./configure --disable-perl --with-python=/usr/local/bin/python

に変更。

checking for python includes... found /usr/local/include/python2.5
Disabling perl module
checking for ruby... found /usr/local/bin/ruby

python2.5を見てくれるようになった。

ついでにrubyもdisableにする事に。

./configure --disable-ruby --disable-perl --with-python=/usr/local/bin/python

checking for python includes... found /usr/local/include/python2.5
Disabling perl module
Disabling ruby module

これでmake installしてみる。

成功を確認。

再度tracdを起動し、アクセス。


今度はトップ画面が見れた。ClearSilverのエラーも起こらない。

プロジェクト一覧と言う簡素な画面からプロジェクト名(TracTest)のリンクをクリック。

見慣れたTracのトップ画面が表示された。

が…

Trac detected an internal error:

またまたエラー。画面下部にスタックトレースがある。

Python Traceback

Traceback (most recent call last):
  File "/usr/local/lib/python2.5/site-packages/trac/web/main.py", line 406, in dispatch_request
    dispatcher.dispatch(req)
  File "/usr/local/lib/python2.5/site-packages/trac/web/main.py", line 191, in dispatch
    chosen_handler = self._pre_process_request(req, chosen_handler)
  File "/usr/local/lib/python2.5/site-packages/trac/web/main.py", line 263, in _pre_process_request
    chosen_handler = f.pre_process_request(req, chosen_handler)
  File "/usr/local/lib/python2.5/site-packages/trac/versioncontrol/api.py", line 73, in pre_process_request
    self.get_repository(req.authname).sync()
  File "/usr/local/lib/python2.5/site-packages/trac/versioncontrol/api.py", line 94, in get_repository
    ((self.repository_type,)*2))
TracError: Unsupported version control system "svn". Check that the Python bindings for "svn" are correctly installed.

python-svnのバインディングができていない模様。

ソフト/Bug Tracking/trac/RedHat - discypus

を参考にpythonを対話的に起動してバインディングを確認。

Python 2.5.1 (r251:54863, Apr 26 2007, 16:32:28)
[GCC 3.4.3 20041212 (Red Hat 3.4.3-9.EL4)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import svn
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named svn
>>>

入ってない…。

http://subversion.tigris.org/project_packages.html

と言うわけでここからrpmパッケージをダウンロードしてインストール

http://the.earth.li/pub/subversion/summersoft.fay.ar.us/pub/subversion/latest/rhel-4/i386/


rpm -i subversion-python-1.4.3-1.i386.rpm

ところがこれもpython2.3の方にバインドされる…。

rpm -ql subversion-python
...
/usr/local/lib/python2.3/site-packages/libsvn/_delta.la
...

これに関しては二次情報がなかったので悪戦苦闘。

rpmのmanを見ながら色々なオプションを試した結果、

rpm -ivh --relocate /usr/lib/python2.3=/usr/local/lib/python2.5  subversion-python-1.4.3-1.i386.rpm

と言う非常に強引な方法でインストール成功。

ほんとにいいのか。もっとスマートな方法があると思うんだけどなぁ…。


で、再度またtracdから確認。

ようやくエラーもなく、見慣れたトップ画面が表示された!


感想

いやー、大変だった。

でもネット上で悪戦苦闘している人がたくさんいるお陰で効率の悪い英語の一次情報をほとんど参考せずにトラブル対応できた。

感謝ですなぁ…。スキルも英語力もない人間からすると本当にありがたい。


さて、これからApacheで動かしたり、まだまだやる事はたくさんある…。Tracしんどいな。




参考

Trac をインストールしてみたよ

インストール - cooldaemonの備忘録

プロジェクト管理ツール Trac を入れてみた | 秋元@サイボウズラボ・プログラマー・ブログ

ソフト/Bug Tracking/trac - discypus