ページ更新: 2008-08-31 (日) (3731日前)

(2005-12-01 作成)

Tracを動かすためだけのスタンドアロンのWebサーバtracdについて。

これを使えば、別途Webサーバソフト(Apacheなど)を用意しなくても良い。

目次

[編集]

情報源 #

TracStandalone (http://discypus.jp/trac/sandbox/wiki/TracStandalone )

Custom Query - The Trac Project

  • tracdに関するチケット。
[編集]

コマンドラインオプション #

tracdに引数を与えなければ、使用法が表示される。

Linuxの場合

$ tracd

Windowsの場合 (Trac 0.11未満?)

C:\> python C:\Python23\Scripts\tracd  (Python 2.3使用)
C:\> python C:\Python24\Scripts\tracd  (Python 2.4使用)

Windowsの場合 (Trac 0.11以上?)

C:\> C:\Python25\Scripts\tracd (Python 2.5.2使用時)

Trac 0.9.6では、次のように使用方法が表示される:

usage: tracd [options] <projenv> [projenv] ...
usage: tracd [options] --env-parent-dir=[path]

Options:

-a --auth [project],[htdigest_file],[realm]
--basic-auth [project],[htpasswd_file],[realm]
-p --port [port]                Port number to use (default: 80)
-b --hostname [hostname]        IP to bind to (default: '')
-d --daemonize  Run tracd in the background as a daemon
-e --env-parent-dir <path>      Parent directory of the project environments

Trac 0.10 では --help オプションを付けると、次のように使用方法が表示される (2006-10-22):

usage: tracd [options] [projenv] ...

options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -a DIGESTAUTH, --auth=DIGESTAUTH
                        [projectdir],[htdigest_file],[realm]
  --basic-auth=BASICAUTH
                        [projectdir],[htpasswd_file],[realm]
  -p PORT, --port=PORT  the port number to bind to
  -b HOSTNAME, --hostname=HOSTNAME
                        the host name or IP address to bind to
  --protocol=PROTOCOL   http|scgi|ajp
  -e PARENTDIR, --env-parent-dir=PARENTDIR
                        parent directory of the project environments
  --base-path=BASE_PATH
                        base path
  -r, --auto-reload     restart automatically when sources are modified
  -s, --single-env      only serve a single project without the project list
  -d, --daemonize       run in the background as a daemon               ★Windowsでは表示されない
  --pidfile=PIDFILE     When daemonizing, file to which to write pid    ★Windowsでは表示されない

Trac 0.11.1 では、 --help オプションを付けると、次のように使用方法が表示される (2008-08-31):

usage: tracd [options] [projenv] ...

options:
  --version             show program's version number and exit
  -h, --help            show this help message and exit
  -a DIGESTAUTH, --auth=DIGESTAUTH
                        [projectdir],[htdigest_file],[realm]
  --basic-auth=BASICAUTH
                        [projectdir],[htpasswd_file],[realm]
  -p PORT, --port=PORT  the port number to bind to
  -b HOSTNAME, --hostname=HOSTNAME
                        the host name or IP address to bind to
  --protocol=PROTOCOL   http|scgi|ajp
  -e PARENTDIR, --env-parent-dir=PARENTDIR
                        parent directory of the project environments
  --base-path=BASE_PATH
                        the initial portion of the request URL's "path"
  -r, --auto-reload     restart automatically when sources are modified
  -s, --single-env      only serve a single project without the project list
  -d, --daemonize       run in the background as a daemon                ★Windowsでは表示されない
  --pidfile=PIDFILE     When daemonizing, file to which to write pid     ★Windowsでは表示されない
  --umask=MASK          When daemonizing, file mode creation mask to use ★Windowsでは表示されない
                        (default 022)
[編集]

Trac 0.9.6のオプション #

projenv
  • プロジェクトのディレクトリを指定する。複数指定することもできる。(つまり、tracd1つで複数のプロジェクトを同時に扱える)
    例:
     $ tracd /home/admin/trac/sampleproject /home/admin/trac/sampleproject2
-a --auth
  • 認証用の情報を設定する。projenvごとに1つ指定できる。
  • 認証方式はDigest認証を使う。Basic認証を使うときは --basic-authを使う。
  • 書式は 「プロジェクト名」、「htdigestファイル」、「レルム」をカンマで区切ってしてする。
    例:
    --auth sandbox,htdigest,SandBox
    -a sandbox,htdigest,SandBox
  • Digest認証データの作成方法は後述する。
--basic-auth
  • 認証用の情報を設定する。projenvごとに1つ指定できる。
  • 認証方式はBasic認証を使う。
-p -port
  • Webサーバのポート番号を指定する。デフォルトは80番。
-b --hostname
  • 受信に使う(bindする)IPアドレスを指定する。デフォルトは無指定(ホストに割り当てられたすべてのIPアドレスを使用する)
    • マルチホームホストで1つのIPだけアクセスさせたいとき、あるいは自分自身だけが使い、他のホストからは使用させたくないときに有用。
-d --daemonize
  • 端末から標準入出力を切り離す。デーモンとして動作させるときに使う。
-e --env-parent-dir
  • 複数のプロジェクトの共通親ディレクトリを指定する?(いわゆる「WikiFarm」を実現するもの)
[編集]

Trac 0.10で追加されたオプション (2006-10-22) #

--version
  • バージョン番号を表示する
-h, --help
  • ヘルプメッセージを表示する
--protocol=PROTOCOL http
scgi|ajp|
  • プロトコルを指定する。(詳細は未調査...)
--base-path=BASE_PATH
-r, --auto-reload
  • *.pyや*.eggが更新されたときに自動的に再起動するらしい。(実装は Lib/site-packages/trac/util/autoreload.py)
-s, --single-env
  • tracdで単一のプロジェクトを扱う。プロジェクトのリストは表示しない。例: URLは http://hostname:port/ になる。
--pidfile=PIDFILE
  • デーモンとして動かすとき、pid (プロセスID)を書き込むファイルを指定する。 (自分もtracdを改造してこういうことしてた #etcInitdTracd ので、本家に用意されたのでうれしい)
[編集]

Trac 0.11で追加されたオプション (2008-08-31) #

--umask=MASK
  • デーモンでの動作時に、ファイルの作成時に使用されるマスク (デフォルトは 022)
[編集]

htdigestファイルの作成 #

[編集]

Apacheに付属するhtdigestコマンドを使う #

Apacheに付属するhtdigestコマンドを使って、htdigestファイルを作成する

htdigestコマンドについては、マニュアルを参照のこと:

実行例1: Cygwin(のApacheのhtdigest)で作成する: Realm="trac", ユーザー名="username", htdigestファイル名="trac.htdigest"

$ htdigest -c trac.htdigest "trac" ussrname
Adding password for username in realm trac.
New password:   ★パスワードを入力。
Re-type new password:  ★もう一度パスワードを入力。

実行例2: Windows用のApache2(のhtdigest)で作成する:Realm="trac", ユーザー名="username", htdigestファイル名="trac.htdigest"

C:\> "C:\Program Files\Apache Group\Apache2\bin\htdigest" -c trac.htdigest "trac" username
Adding password for username in realm trac.
New password: *******
Re-type new password: *******
[編集]

Pythonで書かれたコマンドを使う #

htdigestを作成したいが、Apacheをインストールしたくない場合、 Generating Passwords Without ApacheのPythonスクリプトでhtdigestを作成できる。

ただし、このスクリプトはパスワードをコマンドラインで指定するため、このスクリプトを動作させているときにpsコマンドを実行されれば、パスワードが漏れてしまう。

そこで、Pythonの6.13 getpass -- 可搬性のあるパスワード入力機構使うように修正してみた。まだ動作確認してない。また、パスワードは1回しか尋ねないので、2回尋ねるように修正した方がよいだろう。

from optparse import OptionParser
import md5
import getpass

# build the options
usage = "usage: %prog [options]"
parser = OptionParser(usage=usage)
parser.add_option("-u", "--username",action="store", dest="username", type = "string",
                  help="the username for whom to generate a password")
parser.add_option("-r", "--realm",action="store", dest="realm", type = "string",
                  help="the realm to use")
(options, args) = parser.parse_args()

password = getpass.getpass()

# check options
if (options.username is None) or (options.realm is None):
   parser.error("You must supply both the username and realm")
   
# Generate the string to enter into the htdigest file
kd = lambda x: md5.md5(':'.join(x)).hexdigest()
print ':'.join((options.username, options.realm, kd([options.username, options.realm, password])))

こんな風にして使えると思う(ってまだ試してない)

C:> htdigest.py -u username -r realm >> realm.htdigest
Password:

C:> type realm.htgiest
username:realm:ffadbcefadd7feadfaadfcad78646245
[編集]

tracdをWindowsのサービスで動かす #

tracdをNTサービスに登録する。

サービスに登録するためのツールはいくつか存在するが、今回はMicrosoftの Windows Server 2003 Resource Kit Tools の instsrv を使用した。

リソースキットは C:\Program Files\Windows Resource Kits\Tools\ に入れ、このディレクトリにはパスを通してある。

  • 当初、trac 0.8を使った。trac 0.8.4, 0,9b2, 0,9, 0.9-ja-1, 0.9.1〜0.9.6 も同じ手順でサービス化できた。(2006-07-24)
[編集]

0. tracのログを出力するようにする #

トラブルシューティングのために、trac.iniにログを出力するようにしておく。 (参照: TracIni#logginghttp://discypus.jp/trac/sandbox/wiki/TracIni#logging 以下では「ファイル名=trac.log」「出力先=ファイル」「レベル=警告」の設定を行っている。

(手動ではなくWebAdminPluginを使ったが)

[logging]
log_file = trac.log
log_level = WARNING
log_type = file
[編集]

1. instsrvでサービスを登録する。 #

instsrvのコマンドラインオプション。

C:\> instsrv
Installs and removes system services from NT

INSTSRV <service name> (<exe location> | REMOVE)
  [-a <Account Name>] [-p <Account Password>]

  Install service example:

    INSTSRV MyService C:\MyDir\DiskService.Exe
    -OR-
    INSTSRV MyService C:\mailsrv\mailsrv.exe -a MYDOMAIN\joebob -p foo

  Remove service example:

    INSTSRV MyService REMOVE

サービス名"tracd"でsrvany.exeを登録する。 (2005-12-01 修正)

C:\> instsrv tracd "C:\Program Files\Windows Resource Kits\Tools\srvany.exe"

The service was successfuly added!

Make sure that you go into the Control Panel and use
the Services applet to change the Account Name and
Password that this newly installed service will use

やり直すときは、instsrvのREMOVEオプションでサービスを消す (未確認)

C:\>instsrv tracd REMOVE

あるいはscでサービスを消す。 (2005-10-27 追加)

C:\> sc delete tracd
[SC] DeleteService SUCCESS
[編集]

2. サービスの登録を確認 #

サービスが登録されていることを確認。

起動が「自動」になっているので、動作をちゃんと確認するまでは「手動」にしておく。

[編集]

3. srvany.exeの引数を設定 #

レジストリエディタで設定。1.で次のエントリが作成されている。

 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\tracd

Parameters キー作成

Parameters\Application (文字列値)を作成、値は:

C:\Python23\python.exe

Parameters\AppParameters (文字列値)を作成、値は:

C:\Python23\Scripts\tracd -p 8080 c:\trac\rep0

#ref(): File not found: "tracd-service-01.png" at page "ソフト/Bug Tracking/trac/tracd"

  • tracのディレクトリが複数ある時は、次のようにする。
    C:\Python23\Scripts\tracd -p 8080 c:\trac\rep0 c:\trac\rep1

instsrvでサービス化したときのレジストリ (tracd.reg)

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\tracd\Parameters]
"Application"="C:\\Python23\\python.exe"
"AppParameters"="C:\\Python23\\Scripts\\tracd --port 8000 --auth rep0,c:/trac/rep0.htdigest,rep0 c:\\trac\\rep0"
[編集]

srvany で環境変数を追加 (2006-09-15) #

(2006-06-16 新規作成)

srvanyでは、レジストリエントリ HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\tracd\Parametersに 「AppEnvironment」って名前の「複数行文字列値」(REG_MULTI_SZ) を追加すれば、 環境変数を1行に1つ、「名前=値」形式で定義できるようだ。

tracd-srvany-env-01.png

手元では、LANG(必須ではない)、PYTHON_EGG_CACHEと、以下の環境変数を定義。(足りないとtracdのWebにアクセスできなくなるので、1つずつ削って調べればわかるだろうが‥‥)

LANG=C
PYTHON_EGG_CACHE=C:\WINDOWS\Temp
APR_ICONV_PATH=C:\Program Files\Subversion\iconv
Path=C:\Program Files\Subversion\bin;C:\Python23;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\system32\WBEM
SystemDrive=C:
SystemRoot=C:\WINDOWS
[編集]

4. サービスを起動・終了を試す #

起動

C:\> net start tracd
tracd サービスを開始します.
tracd サービスは正常に開始されました。

終了

C:\> net stop tracd
tracd サービスは正常に停止されました。
[編集]

/etc/init.d/tracdの例 (2006-01-04) #

Debian 3.1 (Sarge) 用にでっち上げた起動スクリプト。未完成。tracdも改造している。

/usr/bin/tracd (pidfile出力を追加: start-stop-daemon --make-pidfileでは対処できなかったため)

--- tracd.org   2006-01-04 13:02:25.000000000 +0900
+++ tracd       2006-01-04 14:02:42.000000000 +0900
@@ -32,6 +32,7 @@
     print '-b --hostname [hostname]\tIP to bind to (default: \'\')'
     print '-d --daemonize\tRun tracd in the background as a daemon'
     print '-e --env-parent-dir <path>\tParent directory of the project environments'
+    print '--pidfile <file>\t\tCreate pid file (with --daemonize)'
     print
     sys.exit(1)

@@ -53,10 +54,11 @@
     auths = {}
     daemonize = 0
     env_parent_dir = None
+    pidfile = ''
     try:
         opts, args = getopt.getopt(sys.argv[1:], "a:p:b:de:",
                                    ["auth=", "port=", "hostname=","daemonize",
-                                    "env-parent-dir=", "basic-auth="])
+                                    "env-parent-dir=", "basic-auth=", "pidfile="])
     except getopt.GetoptError, e:
         print e
         usage()
@@ -74,6 +76,8 @@
             daemonize = 1
         if o in ("-e", "--env-parent-dir"):
             env_parent_dir = a
+        if o == '--pidfile':
+            pidfile = a

     if not env_parent_dir and not args:
         usage()
@@ -93,6 +97,10 @@
                 sys.stderr = open('/dev/null', 'w')
             else:
                 print 'tracd daemon running with pid: %d' % pid
+                if pidfile:
+                    f = open(pidfile, 'w')
+                    f.write('%d\n' % pid)
+                    f.close()
                 sys.exit(0)
         httpd.serve_forever()
     except OSError:

/etc/init.d/tracd (pidfileを/var/run/tracd/tracd.pidに出力)

#! /bin/sh
#
# tracd
#
# Version:	@(#)skeleton  2.85-23  28-Jul-2004  miquels@cistron.nl
#

set -e

PATH=/bin:/usr/bin
DESC="tracd"
NAME=tracd
DAEMON=/usr/bin/$NAME
PIDFILE=/var/run/$NAME/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME

PORT=8000
ENV_PARENT_DIR=/var/trac
AUTH='--auth sandbox,/var/trac/sandbox/htdigest,Sandbox' 
USER=www-data
OPTS="--daemonize --port $PORT --env-parent-dir $ENV_PARENT_DIR --pidfile $PIDFILE $AUTH"
export PYTHON_EGG_CACHE=/var/cache/eggcache


# Gracefully exit if the package has been removed.
test -x $DAEMON || exit 0

# Read config file if it is present.
#if [ -r /etc/default/$NAME ]
#then
#	. /etc/default/$NAME
#fi

# Make pidfile directory
if [ ! -d /var/run/$NAME ]
then
	mkdir /var/run/$NAME
	chown $USER:$USER /var/run/$NAME
fi

# Make python egg cache directory
if [ ! -d $PYTHON_EGG_CACHE ]
then
	mkdir $PYTHON_EGG_CACHE
	chown $USER:$USER $PYTHON_EGG_CACHE
fi

#
#	Function that starts the daemon/service.
#
d_start() {
	/sbin/start-stop-daemon --start --quiet --pidfile $PIDFILE --chuid $USER \
		--exec $DAEMON -- $OPTS
}

#
#	Function that stops the daemon/service.
#
d_stop() {
#	/sbin/start-stop-daemon --stop --quiet --pidfile $PIDFILE --user $USER \
	/sbin/start-stop-daemon --stop --pidfile $PIDFILE --user $USER && rm $PIDFILE
}

#
#	Function that sends a SIGHUP to the daemon/service.
#
d_reload() {
	/sbin/start-stop-daemon --stop --quiet --pidfile $PIDFILE --user $USER \
		--name $NAME --signal 1
}

case "$1" in
  start)
	echo -n "Starting $DESC: $NAME"
	d_start
	echo "."
	;;
  stop)
	echo -n "Stopping $DESC: $NAME"
	d_stop
	echo "."
	;;
  #reload)
	#
	#	If the daemon can reload its configuration without
	#	restarting (for example, when it is sent a SIGHUP),
	#	then implement that here.
	#
	#	If the daemon responds to changes in its config file
	#	directly anyway, make this an "exit 0".
	#
	# echo -n "Reloading $DESC configuration..."
	# d_reload
	# echo "done."
  #;;
  restart|force-reload)
	#
	#	If the "reload" option is implemented, move the "force-reload"
	#	option to the "reload" entry above. If not, "force-reload" is
	#	just the same as "restart".
	#
	echo -n "Restarting $DESC: $NAME"
	d_stop
	sleep 1
	d_start
	echo "."
	;;
  *)
	# echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
	echo "Usage: $SCRIPTNAME {start|stop|restart|force-reload}" >&2
	exit 1
	;;
esac

exit 0
[編集]

メモ #

[編集]

tracdの日付のロケールをCに切り替える (2005-11-11) #

RedHat 8.0にて。

マイルストーンやチケットの日付が文字化けした。

tracdの日付表示が、使用中のロケールに対応していないようだ。

tracdを使っているので、起動するときに次のようにしてCロケールを使うようにした。

LANG=C tracd ...(以下引数は省略)...

LC_TIME=Cだけでもしれないけど、まあいいや。