タグ別アーカイブ: python

FreeBSDでwsgiを使ったtracがどうもおかしい

FreeBSDでwsgiを使ったtracがどうもおかしい。なんだか重い。もともとfcgiを利用してたんだけれどfcgi版のtrac(というかpythonかな)って重い、なのでwsgiにて動かすことにした。

過去にyubirdたんがdebianで、また別件でcentosにてwsgi版のtracを動かしたけどとっても快調だった。

どうやらapache+pythonでの最近のハヤリはwsgiらしい。ということでテキトウにインストールした。

さて、confの変更もすんで動かしてみたんだけれどどうにも重い。topすればpythonの名前でapacheから独立してプロセスが走り続けてたりする。なんかおかしいな、って。ログを見ると気になる記述が。


[Wed Apr 11 13:37:47 2012] [info] mod_wsgi (pid=1189): Attach interpreter ''.
[Wed Apr 11 13:37:52 2012] [info] mod_wsgi (pid=1189): Cleanup interpreter ''.
[Wed Apr 11 13:37:52 2012] [info] mod_wsgi (pid=1189): Terminating Python.
[Wed Apr 11 13:37:52 2012] [error] Exception KeyError: KeyError(34382823872,) in <module 'threading' from '/usr/local/lib/python2.6/threading.pyc'> ignored

最後の行にあるException KeyError: KeyErrorのあたり。なんかスレッド周りの処理でエラーが出てるらしい。

でググってみるとそれらしき記述を発見。

InstallationOnFreeBSD -  modwsgi - Python WSGI adapter module for Apache. - Google Project Hosting

http://code.google.com/p/modwsgi/wiki/InstallationOnFreeBSD

上記のgoogle codeによるとあれしろコレしろ、ってあるけど、結局最後にはwsgi3.3使ったら直ったよってことが。

調べてみるとwsgiのバージョンは2.8を使ってた。


shell> pkg_info -Ix wsgi
ap22-mod_wsgi-2.8_2 Python WSGI adapter module for Apache
shell> psearch wsgi

www/mod_wsgi              Python WSGI adapter module for Apache
www/mod_wsgi3             Python WSGI adapter module for Apache


どうやらバージョンデュアルツリー(っていう名前を今作った!)らしくて2系がstableで3系は実験的なのかな、両方存在してた。2系をアンインスコして3系を入れる。


shell> pkg_deinstall -f www/mod_wsgi
** No matching package found.
shell> portinstall –c www/mod_wsgi3

以上でちゃんといけたっぽい。めでたしめでたす。

でも早くなったかどうかは微妙、残念。

tracのアップデートを行って動かなくなった時の対処法

1. 始めに

tracのアップデートを行ったら動かなくなった。
ミスった。かなりミスった。
このアップデート中に実は編集中のユーザがいて、コメントを記述し終えてpostで内容を送信した時に問題が発覚。
おかげさまで送信すべきコメントの内容が紛失されてしまった。ブラウザからpostを再送したりしてみたけれどその内容は見つからず、ダメでした。ごめんなさい。 続きを読む tracのアップデートを行って動かなくなった時の対処法

FreeBSDでtracを動かそうとしたときに起きたエラーについて

FreeBSDでtracを動かそうとしたときに起きたエラーについて。

ホームディレクトリが存在しないユーザでpythonを実行するとエラーになる件。pythonのことをよくしらないけど、厳密にはpythonのエラーではなくeggのエラー?になるような気がする。

以下エラーメッセージ


shell> sudo -u www python
Python 2.6.6 (r266:84292, Mar 16 2011, 02:49:37)
[GCC 4.2.1 20070719  [FreeBSD]] on freebsd8
Type "help", "copyright", "credits" or "license" for more information.
>>> import MySQLdb
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/MySQLdb/__init__.py", line 19, in <module>
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/_mysql.py", line 7, in <module>
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/_mysql.py", line 4, in __bootstrap__
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/pkg_resources.py", line 882, in resource_filename
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/pkg_resources.py", line 1351, in get_resource_filename
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/pkg_resources.py", line 1373, in _extract_resource
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/pkg_resources.py", line 962, in get_cache_path
File "build/bdist.freebsd-8.2-RELEASE-amd64/egg/pkg_resources.py", line 928, in extraction_error
pkg_resources.ExtractionError: Can't extract file(s) to egg cache

The following error occurred while trying to extract file(s) to the Python egg
cache:

[Errno 17] File exists: '/nonexistent'

The Python egg cache directory is currently set to:

/nonexistent/.python-eggs

Perhaps your account does not have write access to this directory?  You can
change the cache directory by setting the PYTHON_EGG_CACHE environment
variable to point to an accessible directory.

このエラーは、www, svnといったホームディレクトリを持たないユーザがpythonを使ったスクリプトを実行したときに遭遇する。 たとえばtrac-adminをwwwユーザで実行したとき、またsubversionでコミット時のフック、hooks/post-commitのところでもエラーがでてたりする。 今回はpost-commitのあとtrac-svn-hookを呼び出していたので、ログがtrac/log/svn-hooks-testrep.logにエラーが出ていた。コレに書いてあるだけで他にはwarningとか出ないのでなかなか気づかなかった。


shell> tail svn-hooks-testrep.log

Changeset 4 added
Traceback (most recent call last):
File "/usr/local/lib/python2.6/logging/handlers.py", line 796, in emit
self.socket.send(msg)
error: [Errno 40] Message too long
TracError: Unsupported database type "mysql"
FAILED: see the Trac log

同様にwwwユーザでtrac-adminを走らせてもエラーがでる。


> sudo -u www trac-admin /path/to/trac repository resync testrep
Traceback (most recent call last):
File "/usr/local/lib/python2.6/logging/handlers.py", line 796, in emit
self.socket.send(msg)
error: [Errno 40] Message too long
TracError: Unsupported database type "mysql"

で、解決方法は・・・、一筋縄ではいかない。 それぞれのユーザにホームディレクトリを持たせるのが一番手っ取り早い。でもこれらのユーザをnisで管理してたらそこも一斉に書き換わっちゃう。 いらないところは最小限に、ってことで、該当するホストに/nonexistentフォルダを作ってみる。いいのかな、こんなやりかたで・・・。


shell> sudo mkdir /nonexistent
shell> sudo chmod 777 /nonexistent/

ひとまずこれで動いた。 おしまい。

tracの導入に当たっての注意点他

FreeBSD7.3-R, 32bit版にtrac-0.12を入れてみた。

長らく使用してたtrac-0.11はマルチリポジトリに対応して無くて、対応するぞーって言ってた0.12を待ってた。ちょくちょくインストールしたりしてたけど、これまでうまくいかなかった。なんとなく動くようになったぽいのでメモ。

FreeBSD7.3-R i386
apache-2.2.16
py26-sqlite3-2.6.5_1
sqlite3-3.6.23.1_1
trac-0.12

fast cgiモード?で動かす
マルチリポジトリ
全部のリポジトリで共通の認証。リポジトリごとに分けたりもできるぞたぶん。

まずリポジトリのおいてあるサーバとtracを稼働させようとしているサーバが違うのでそこをなんとかする。tracは必ずtracを動かしたローカルにリポジトリがないと駄目らしい。

nfsで見れるようにしようかと思ったけど、うちのnfsってだいたいrw出しちゃうから、一方的に読み取りのみの参照&ネットワークの負荷もかけないってことからrsyncしてみる。良いか悪いかわかんないけど。

crontabに下記を追加。先だって一発コマンドを通しておくとknown_hostsがどうのこうのするはず。ディレクトリが無いとか怒られないためにも。

*/10    *       *       *       *       root    /usr/local/bin/rsync -arv -e "ssh -i /usr/home/hogetan/.ssh/id_dsa" [email protected]:/usr/local/repositories/ /usr/local/repositories/ > /dev/null 2>&1

各種必要なパッケージ?はportinstallで適当に入れる。

%sudo portinstall /usr/ports/www/mod_fcgid

公式を見ながら設定する。

まずはapacheのhttpd.conf

LoadModule fcgid_module libexec/apache22/mod_fcgid.so
<IfModule alias_module>
  ScriptAlias /trac "/usr/local/share/trac/cgi-bin/trac.fcgi"
</IfModule>
<IfModule mod_fcgid.c>
  AddHandler fcgid-script .fcgi
</IfModule>
<LocationMatch "/trac/login">
  AuthType Basic
  AuthName "Trac"
  AuthUserFile /var/trac/.htpasswd
  Require valid-user
</LocationMatch>

scriptaliasを書く位置に注意。あとは.htpasswdが読めないと後で怒られる。.htpassswdの作成とかconfの参考とかは公式
TRAC_ENVはtrac.fcgiに直接書く。なんか理由があったけど忘れた。公式のどこかに書いてあった気がする。

basic認証させるディレクトリの記述に注意。公式通りだと/trac/hogehoge/loginしか受け付けなかったりする。

%sudo ee /usr/local/share/trac.fcgi
import os
os.environ['TRAC_ENV'] = "/var/trac"
os.environ['PYTHON_EGG_CACHE'] = "/tmp"

ここの設定で、TRAC_ENVを書くとそこのディレクトリにあるconf/trac.iniを読もうとするみたい。ここをマルチリポジトリだから~、って、TRAC_ENV_PARENT_DIRを設定すると、そのディレクトリから一つしたのディレクトリをそれぞれの独立したtracのプロジェクトと認識してしまうっぽかった。

(/var/trac/hogeproject/conf/trac.ini, /var/trac/hoge2project/conf/trac.ini, …)と、どんどん参照しちゃうみたい。ここでちょっとはまった。というか以前こんなことやってたけど、それぞれのディレクティブをhttpd.confに書いたりしてた・・・。これを知ってれば、ってかんじ。

次にtracのなんとかディレクトリ?(tracディレクトリとでも呼ぶのかな)、TRAC_ENVで設定されたディレクトリを作成してやる、tracのフォーマットで。

%sudo trac-admin /var/trac initenv

これでできる。nfsだとエラー。ミスったら消して直せば良い。気にくわなければ消して直せば良い。

.htpasswdは個人的な好みで/var/trac直下に。作り方は割愛。このファイルが残っててもinitenvできない。うざい。

次にconf/trac.iniを編集。

Trac 0.12b1が出たね - watawata日記
[repositories]
hoge1.dir=/usr/local/repositories/hoge1
hoge2.dir=/usr/local/repositories/hoge2
hoge3.dir=/usr/local/repositories/hoge3

こんな感じで列挙。元サイトにはtypeとかdescriptionとかあったけど、desc書いたらごちゃごちゃしちゃったし、typeはデフォルトでsvnなので今回はdirのみ定義。下記のコード+適当に選び出すでおk。

%php -r '$h = opendir("/usr/local/repositories"); while($f = readdir($h)){ print basename($f).".dir = /usr/local/repositories/$f\n";}'

そろそろ見て確認してみる。対象サーバのURLにscriptaliasで名付けた/tracとか付ける。


パーミッションとかよく怒ってくるので適当に対処。pythonのエラーは見慣れないので困ったら泣く。結構同じエラーにはまってる人とか少なかったりして泣ける。

tracの管理者権限をそれっぽいユーザに付与。これするとtrac画面の一番右端の方にadminってのが出てきて管理ができるらしい。

%sudo trac-admin /var/trac permission list
%sudo trac-admin /var/trac permission add tracadminisry TRAC_ADMIN

ログインしてTracを使う - へたれプログラマな日々

このあと、adminの画面の一番左下の方にあるrepositriesをクリック。
リポジトリが複数あるかチェック

これだとまだ利用できない。同期?が必要らしい。でも何を同期するんだろう。他にはどんなタイミングで同期すれば良いんだろう。

%sudo trac-admin /var/trac repository resync '*'
%sudo trac-admin /var/trac changeset added '*'

リビジョンが多いと結構時間がかかる。
これが終わったらさっきの管理画面でリビジョンが出てたりする。そんでなんかうまくいけたっぽい。

ここから先はこれから試す。

以上