Trac のインストール

Trac を使ってみようかな、と思いました。
Trac のインストールとセットアップのメモです。一緒に Subversion もセットアップしました。


Debian なので apt-get 等で必要なパッケージをインストールします。

sudo apt-get install trac trac-ja-resource libapache2-mod-python subversion libapache2-svn

Subversion のリポジトリ作成

Apache がアクセスできるようにオーナを www-data に変更します。

cd /var/lib
sudo mkdir svn
sudo chown -R www-data:www-data svn
cd svn
sudo -u www-data svnadmin create test-repo1

dav_svn.conf の設定

sudo vi /etc/apache2/mods-available/dav_svn.conf

# dav_svn.conf - Example Subversion/Apache configuration
# For details and further options see the Apache user manual and
# the Subversion book.
# NOTE: for a setup with multiple vhosts, you will want to do this
# configuration in /etc/apache2/sites-available/*, not here.

# <Location URL> ... </Location>
# URL controls how the repository appears to the outside world.
# In this example clients access the repository as http://hostname/svn/
# Note, a literal /svn should NOT exist in your document root.
<Location /svn>

# Uncomment this to enable the repository
DAV svn

# Set this to the path to your repository
#SVNPath /var/lib/svn
# Alternatively, use SVNParentPath if you have multiple repositories under
# under a single directory (/var/lib/svn/repo1, /var/lib/svn/repo2, ...).
# You need either SVNPath and SVNParentPath, but not both.
SVNParentPath /var/lib/svn

# Access control is done at 3 levels: (1) Apache authentication, via
# any of several methods. A "Basic Auth" section is commented out
# below. (2) Apache <Limit> and <LimitExcept>, also commented out
# below. (3) mod_authz_svn is a svn-specific authorization module
# which offers fine-grained read/write access control for paths
# within a repository. (The first two layers are coarse-grained; you
# can only enable/disable access to an entire repository.) Note that
# mod_authz_svn is noticeably slower than the other two layers, so if
# you don't need the fine-grained control, don't configure it.

# Basic Authentication is repository-wide. It is not secure unless
# you are using https. See the 'htpasswd' command to create and
# manage the password file - and the documentation for the
# 'auth_basic' and 'authn_file' modules, which you will need for this
# (enable them with 'a2enmod').
AuthType Basic
AuthName "Subversion Repository"
AuthUserFile /etc/apache2/dav_svn.passwd

# To enable authorization via mod_authz_svn
AuthzSVNAccessFile /etc/apache2/dav_svn.authz

# The following three lines allow anonymous read, but make
# committers authenticate themselves. It requires the 'authz_user'
# module (enable it with 'a2enmod').
Require valid-user


dav_svn.passwd の作成

Subversion と Trac の両方で使用するユーザとパスワードのファイルを作成します。
sudo htpasswd -bc /etc/apache2/dav_svn.passwd user1 password
sudo htpasswd -b /etc/apache2/dav_svn.passwd user2 password

dav_svn.authz の作成

このファイルにより Subversion のディレクトリ単位でのアクセス制御が可能になります。
sudo vi /etc/apache2/dav_svn.authz

group1 = user1,user2

* =

@group1 = rw

Trac のプロジェクト作成と設定

sudo mkdir /var/lib/trac
sudo chown www-data:www-data -R trac
sudo -u www-data trac-admin /var/lib/trac/test-proj1 initenv
Templates directory に日本語リソースのパスを指定します。

/var/lib% sudo -u www-data trac-admin /var/lib/trac/test-proj1 initenv
Creating a new Trac environment at /var/lib/trac/test-proj1

Trac will first ask a few questions about your environment
in order to initalize 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 Project1

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]> /var/lib/svn/test-repo1

Please enter location of Trac page templates.
Default is the location of the site-wide templates installed with Trac.

Templates directory [/usr/share/trac/templates]> /usr/share/trac-ja-resource/templates

Creating and Initializing Project
Installing default wiki pages
/usr/share/trac/wiki-default/TracInterfaceCustomization => TracInterfaceCustomization
/usr/share/trac/wiki-default/TracAccessibility => TracAccessibility
Indexing repository
Project environment for 'Test Project1' created.

You may now configure the environment by editing the file:


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 /var/lib/trac/test-proj1

Then point your browser to http://localhost:8000/test-proj1.
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



Wiki の日本語リソースの設定を行います。
sudo -u www-data trac-admin /var/lib/trac/test-proj1 wiki load /usr/share/trac-ja-resource/wiki-default

Apache の設定を行います。
sudo vi /etc/apache2/sites-available/trac

<Location /projects>
SetHandler mod_python
PythonHandler trac.web.modpython_frontend
PythonOption TracUriRoot /projects
PythonOption TracEnvParentDir "/var/lib/trac"

<LocationMatch /projects/[^/]+/login>
AuthType Basic
AuthName "Trac"
AuthUserFile /etc/apache2/dav_svn.passwd
Require valid-user

sudo a2ensite trac
sudo /etc/init.d/apache2 reload

Trac の権限設定

ログイン前は anonymous 権限です。
ログインすると authenticated グループに所属します。
authenticated は anonymous からパーミッションを継承します。
ここでは anonymous から作成・編集の権限を削除し、authenticated に全権限を付与します。

anonymous によるチケットの作成編集、wiki の作成編集を禁止します。
sudo -u www-data trac-admin /var/lib/trac/test-proj1 permission remove anonymous TICKET_CREATE TICKET_MODIFY WIKI_CREATE WIKI_MODIFY

sudo -u www-data trac-admin /var/lib/trac/test-proj1 permission add authenticated TRAC_ADMIN


チケットの種類、プライオリティ、コンポーネント、バージョン をカスタマイズします。

sudo -u www-data trac-admin /var/lib/trac/test-proj1 ticket_type remove enhancement
sudo -u www-data trac-admin /var/lib/trac/test-proj1 ticket_type change defect defect:不具合
sudo -u www-data trac-admin /var/lib/trac/test-proj1 ticket_type change task task:タスク

sudo -u www-data trac-admin /var/lib/trac/test-proj1 priority change blocker blocker:最優先
sudo -u www-data trac-admin /var/lib/trac/test-proj1 priority change critical critical:高
sudo -u www-data trac-admin /var/lib/trac/test-proj1 priority change major major:中
sudo -u www-data trac-admin /var/lib/trac/test-proj1 priority change minor minor:低
sudo -u www-data trac-admin /var/lib/trac/test-proj1 priority change trivial trivial:微

sudo -u www-data trac-admin /var/lib/trac/test-proj1 component remove component1
sudo -u www-data trac-admin /var/lib/trac/test-proj1 component remove component2
sudo -u www-data trac-admin /var/lib/trac/test-proj1 component add 基本設計 somebody
sudo -u www-data trac-admin /var/lib/trac/test-proj1 component add プロトタイプ somebody

sudo -u www-data trac-admin /var/lib/trac/test-proj1 version remove 2.0

sudo -u www-data trac-admin /var/lib/trac/test-proj1


チケット登録画面のプルダウン項目のデフォルト値の設定と、担当者(Asign to)をプルダウンに変更する設定を行います。
trac.ini の [ticket] セクションでカスタマイズします。
sudo -u www-data vi /var/lib/trac/test-proj1/conf/trac.ini

default_component = 基本設計
default_milestone = 基本設計書
default_priority = major:中
default_type = task:タスク
default_version = 1.0
restrict_owner = true

trac.ticket.report.* = disabled

あと、メール送信の設定も trac.ini の中で行うことになりますが、今回はここまで。







[Common Lisp] Common Lisp で DI コンテナ

仕事で Java の DI コンテナ(Seasar と Spring)を調べています。
DI って悪くない、と思いました。
ということで、ちょっと Common Lisp でも DI をやってみようかと思います。
Java の DI では定義ファイルは XML ですが、Common Lisp ならやはり S 式です。
S 式なら Seasar の定義ファイルの components, component タグ相当をマクロにしてしまえば、S2ContainerFactory.create("app.dicon") は (load "app") とロードするだけでおしまいになります。
簡単な DI コンテナの機能なら、DI コンテナを実装するというより、定義ファイル用のマクロを実装するだけになります。
また 定義ファイル = ソースコード となるのでコンパイルしておくこともできます。
自動バインディング等はなし、コンポーネントの取得は name による取得のみです。

DI コンテナの実装、というよりもむしろ定義ファイルのマクロの実装: di.lisp

(defpackage :di
(:use :cl)
(:export :components

(in-package :di)

(defvar *components* (make-hash-table)

(defmacro components (&body body)
`(dolist (f (list ,@body))
(when f (funcall f))))

(defmacro component (&key class (name class) initargs slots
(instance :singleton))
"make-instance でインスタンスを作成して *components* に登録する。
slot への値設定は他のオブジェクトの参照を含んでいても大丈夫なように lambda でくるんで返し、

(let ((self (gensym)))
(if (eq instance :singleton)
`(let ((,self (setf (gethash ',name *components*)
(make-instance ',class ,@initargs))))
#'(lambda ()
,@(loop for (name value) on slots by #'cddr
collect `(setf (slot-value ,self ',name) ,value))
`(progn (setf (gethash ',name *components*)
#'(lambda ()
(let ((,self (make-instance ',class ,@initargs)))
,@(loop for (name value) on slots by #'cddr
collect `(setf (slot-value ,self ',name)

(defmacro ref (name)
`(let ((object-or-function (gethash ,name *components*)))
(typecase object-or-function
(function (funcall object-or-function))
(t object-or-function))))

(defun get-component (name)
"name での取得のみサポート"
(ref name))

サンプル定義ファイル: app.lisp
(in-package :di-test)

(component :name :f1 :class foo)
(component :name :f2 :class foo :initargs (:foo-slot1 "Hello" :foo-slot2 2))
(component :name :b1 :class bar :initargs (:bar-slot1 "ばあ" :bar-slot2 8))
(component :name :f3 :class foo :initargs (:foo-slot1 (ref :b1)))
(component :name :f4 :class foo
:slots (foo-slot1 "まみむめも"
foo-slot2 (ref :b2)))
(component :name :b2 :class bar
:slots (bar-slot1 "ばあ2" bar-slot2 2))
(component :name :f5 :class foo :instance :prototype
:slots (foo-slot1 :prototype foo-slot2 :singleton))

テストコード: di-test.lisp
(defpackage :di-test
(:use :cl :di))

(in-package :di-test)

(eval-when (:compile-toplevel :load-toplevel :execute)
(require :ptester))

(defclass foo ()
((foo-slot1 :accessor foo-slot1 :initarg :foo-slot1)
(foo-slot2 :accessor foo-slot2 :initarg :foo-slot2)))

(defclass bar ()
((bar-slot1 :accessor bar-slot1 :initarg :bar-slot1)
(bar-slot2 :accessor bar-slot2 :initarg :bar-slot2)))

;; components, component はマクロになっているのでロードしてしまう。
(load "app")

(ptester:with-tests ()
;; 単純なオブジェクト生成。
(let ((f1 (get-component :f1)))
(ptester:test nil (null f1)))
;; コンストラクタインジェクション。
(let ((f2 (get-component :f2)))
(ptester:test "Hello" (foo-slot1 f2) :test #'string=)
(ptester:test 2 (foo-slot2 f2)))
;; 他のオブジェクトを引数にしたコンストラクタインジェクション。
(let ((f3 (get-component :f3)))
(ptester:test "ばあ" (bar-slot1 (foo-slot1 f3)) :test #'string=))
;; プロパティインジェクションではなくスロットインジェクション。
(let ((f4 (get-component :f4)))
(ptester:test "まみむめも" (foo-slot1 f4) :test #'string=)
(ptester:test "ばあ2" (bar-slot1 (foo-slot2 f4)) :test #'string=))
;; instance のテスト
(let ((f1 (get-component :f1))
(f2 (get-component :f1))
(f3 (get-component :f5))
(f4 (get-component :f5)))
(ptester:test t (eq f1 f2))
(ptester:test nil (eq f3 f4))
(ptester:test :prototype (foo-slot1 f3))
(ptester:test :singleton (foo-slot2 f4)))

Common Lisp のマクロって素敵じゃありませんか?


Debian に VMware Player を インストールする

Debian に VMware Player を インストールしたときのメモです。

sudo apt-get install vmware-package
Download VMware-player-2.0.1-55017.x86_64.tar.gz
make-vmpkg VMware-player-2.0.1-55017.x86_64.tar.gz
cd vmware-player
sudo dpkg -i *.deb
sudo m-a build --force vmware-kernel
sudo m-a install --force vmware-kernel
sudo dpkg -i *.deb

でも Browser Appliance を起動したら OS ごとかたまってしまいました。


[Common Lisp] condition のクラス階層

Common Lisp のコンディションシステムでは全てのコンディションは condition クラスを継承します。
サブクラスは sb-mop:class-direct-subclasses で取得できます。
今回は common-lisp パッケージのクラスだけに限定します。
表示は cl-dot を使用して condition のクラス階層のグラフを作成してみます。
cl-dot は dot コマンドを使用するため Graphviz をインストールしておく必要があります。
以下のコードで condition クラスを頂点としたクラス階層が表示されます。
表示には evince を使用しています。また後の方は日本語とテストなので気にしないでください。

(require :cl-dot)

(defmethod cl-dot:object-node ((object class))
(make-instance 'cl-dot:node
:attributes (list :label (class-name object)
:shape :box
:fontname "Arial")))

(defmethod cl-dot:object-points-to ((object class))
(loop for each in (sb-mop:class-direct-subclasses object)
if (eq (find-package :common-lisp)
(symbol-package (class-name each)))
collect each))

(defun my-dot-graph (graph outfile &optional (format (pathname-type outfile)))
"cl-dot:dot-graph を出力ファイルの拡張子に合せたフォーマットを使うようにしたもの。
データをファイル経由で dot に渡すようにして日本語が出力できるようにした。"

(let ((dot-file (make-pathname :defaults outfile :type "dot")))
(with-open-file (out dot-file
:direction :output
:if-exists :supersede
:external-format :utf-8)
(cl-dot:print-graph graph out))
(sb-ext:run-program cl-dot:*dot-path*
(list (format nil "-T~a" format) "-o" outfile)
:input dot-file
:output *standard-output*)))

(let ((file "/tmp/condition.png"))
(my-dot-graph (cl-dot:generate-graph (find-class 'condition)) file)
(asdf:run-shell-command (format nil "evince ~a" file)))

;;;; 日本語のテスト
(defclass ばの () ())

(defclass びの (ばの) ())

(defclass がの (ばの) ())

(defclass なの (びの がの) ())

(defmethod cl-dot:object-points-to ((object class))
(sb-mop:class-direct-subclasses object))

(let ((file "/tmp/jp.pdf"))
(my-dot-graph (cl-dot:generate-graph (find-class 'ばの)) file)
(asdf:run-shell-command (format nil "evince ~a" file)))

それにしても、cl-dot の API は Common Lisp らしいです。おもしろい。


[Common Lisp] 『Common Lisp における例外処理 --- Condition System の活用 ---』

Allegro CL Family 情報に『Common Lisp における例外処理 --- Condition System の活用 ---』が公開されているのを見つけました。
そのうちきちんと Common Lisp の例外処理を勉強しないとな、と前々から思っていました。


Dell Inspiron 1720 に Debian をインストールする

注文していた Dell Inspiron 1720 が先日届きました。
プレインストールしてある Vista を起動して一通りの動作確認をしました。
Vista はなかなか重そうな感じでした。

ハードウェアの動作に問題はなさそうだったので、早速 Debian をインストールします。
debian-40r1-amd64-netinst.iso をダウンロードして CD に焼きました。
その CD からブートして普通にインストールします。
インストール完了の時点ではまだ X が動きませんでした。

Debian は unstable で使っていましたので、今回も unstable にします。
/etc/apt/sources.list を編集して unstable にします。
unstable で一式アップグレードすると X が起動するようになりました。
1600 x 1200 で表示されます。

どうやら alsa 1.0.14 では認識できないようです。
ftp://ftp.suse.com/pub/projects/alsa/snapshot/driver/ から一番新しかった alsa-driver-hg20071002.tar.bz2 をダウンロードしました。
sudo ./configure --with-cards=hda-intel
sudo make
sudo make install

次はワイヤレスLANと液晶の上についてる Webcam が動くようしないと。

ワイヤレスLAN は次のパッケージを入れたら動くようになりました。
でも Fonera の調子が悪くて使えません。

Webcam は linux-uvc-source を入れて
sudo make install