2009年10月19日

smtp2webをMac OS X(10.5)で動かす

GAEではメールを受信するアプリを作るときには、smtp2webを使う必要があるけれども、いちいちサーバにデプロイしないとテストができない。非常に不便なので、何とかmac上でローカルにsmtp2webをサービスとして起動できないかどうか確認する。

1. smtp2webのインストール
smtp2webのソースコードは公開されているので、subversionを使ってチェックアウトする。
チェックアウトフォルダは、とりあえずログインしているユーザーの書類フォルダに展開。

2. smtp2webの起動
そのままだとsmtp2webは動かない。server/smtpserver.tacファイルの修正が必要。具体的には-uにroot、-gにdaemonを指定する。
runserver.shファイルがあるフォルダに移動して、sudoコマンドを使ってrunserver.shを起動する。

3. (以下作成中)  続きを読む
Posted by 中垣健志 at 22:24Comments(32)TrackBack(0)GAE

2009年10月12日

PILをMac OS 10.5 (Leopard)に入れる

Google App Engineでは、画像処理を行うためのサービスが提供されている。
このサービスをローカルでも使うためには、MacにPILをインストールする必要がある。
http://code.google.com/intl/ja/appengine/docs/python/images/overview.html#Development_Server

このPILをMac OS 10.5に入れるに大変だったので、備忘録として記述。

1. PILのインストール
dmgファイルをダウンロードしてインストールしようとすると、途中でインストーラーが「このディクスにはpythonが入っていない」という警告を出して、次に進めなくなる。これは、dmgの代わりにソースをダウンロードして、コマンドラインからインストールするのがよいようだ。

Finder -> アプリケーション -> ユーティリティ -> ターミナル
$cd (ダウンロードしたtar.gzファイルを展開したディレクトリ。"setup.py"ファイルがあるはず)
$sudo python setup.py install

2. JPEGデコーダーのインストール
PILをインストールしても、JPEG画像を操作しようとすると次のエラーが発生する事がある。
IOError: decoder jpeg not available
このときは、JPEGデコーダーを追加でインストールする。

http://www.ijg.org/
jpegsrc.v7.tar.gzファイルをダウンロードして、展開する
Finder -> アプリケーション -> ユーティリティ -> ターミナル
$cd (展開したディレクトリ。install.txtがあるはず)
./configure
make
make test
sudo make install

このあと、1.をもう一度行う。
そのとき1.のディレクトリにあるbuildディレクトリを削除しておく
sudo rm -fr build
  
Posted by 中垣健志 at 21:43Comments(14)TrackBack(0)GAE

2009年10月12日

djangoテンプレートで日本語が文字化けする

utf-8で保存された文字列をsjisで定義されたdjangoのテンプレートで表示すると、日本語が化けます。
このときは、djangoのカスタムフィルターを用意して、utf-8をsjisに変換します。

[customfilters.py (utf-8 -> sjis変換をするフィルターを定義する)]
from google.appengine.ext import webapp

register = webapp.template.create_template_register()

@register.filter
def sjis(value):
return value.encode('sjis')

[main.py (テンプレートを出力するロジックのあるモジュール)]
webapp.template.register_template_library('customfilters')

[template.html]
{{ myValue|sjis }}


参考
http://kaihatsu.mikagamikobo.com/2009/09/google-app-engine-1.html  
Posted by 中垣健志 at 12:19Comments(29)TrackBack(0)GAE

2009年10月08日

reportlabは1.2系では動かない

Google App EngineでPDFを出力するには、reportlabを使うとよいと書かれている。
しかしこのreportlab、ローカルのSDKではバージョンが1.2になると以下のエラーが発生する。

: 'HardenedModulesHook' object has no attribute '_files'

対応方法は、以下のURLから1.9をダウンロードしてアプリケーションに上書きすること。

「Google App Engine プロジェクト ホームページ」
http://code.google.com/p/googleappengine/downloads/list
※検索条件で「All donwloads」を選択する

ちなみに、本番環境ではSDKの環境に関係なくreportlabでPDFを生成できました。
  続きを読む
Posted by 中垣健志 at 21:06Comments(12)TrackBack(0)GAE

2009年10月04日

静的ファイルを公開する

Google App Engineで言語がpythonのときに、静的なファイルを公開する方法。

1. 公開したいファイルを用意する。このときURLとファイル名は異なっていてもよい。
2. app.yamlのhandlersに次のエントリを用意する
- url: 静的ファイルをリクエストするURL
static_files: 用意した静的ファイルのパス
upload: 用意した静的ファイルのパス

例:http://foo.bar.com/hoge.htmlを公開する。

/static/hogeimpl.htmlファイルを用意する
- url: /hoge.html
static_files: static/hogeimpl.html
upload: static/hogeimpl.html

smtp2webがらみで使えるネタです。
この内容は、用途は違いますがGAEの一般的な質問に載っていました。
http://code.google.com/intl/ja/appengine/kb/general.html#erroruris  
Posted by 中垣健志 at 14:24Comments(980)TrackBack(0)GAE

2009年10月04日

macのGAE Launcherでdebugログが出ない

Google App Engineのmac用環境で、ログ出力を実行してもdebugレベルのログが出力されない。

import logging

logging.info("これは出力される")
logging.debug("これは出力されない")

多分、サーバプロセス起動時にモードを変更する引数を渡せばよいのだと思うけど、macなのでそもそもコマンドラインの引数の渡し方がわかっていません。調査中です。  続きを読む
Posted by 中垣健志 at 14:07Comments(36)TrackBack(0)GAE

2009年10月03日

メールを送ろうとしてエラー

Google App Engineでメールを送ろうとしたら次のエラーが発生した

Traceback (most recent call last):
File "/base/python_lib/versions/1/google/appengine/ext/webapp/__init__.py", line 509, in __call__
handler.post(*groups)
File "/base/data/home/apps/golfpaper/1.336764943207147696/main.py", line 83, in post
, body
File "/base/python_lib/versions/1/google/appengine/api/mail.py", line 239, in send_mail
message.send(make_sync_call)
File "/base/python_lib/versions/1/google/appengine/api/mail.py", line 714, in send
raise ERROR_MAP[e.application_error](e.error_detail)
InvalidSenderError: Unauthorized sender

原因を検索中...  続きを読む
Posted by 中垣健志 at 14:25Comments(11)TrackBack(0)GAE

2009年08月26日

「はじめてのiPhoneプログラミング」を試す

「はじめてのiPhoneプログラミング」は、amazonなどでも評価の高い一冊。なるほど、わかりやすい内容になっている。でもOS 2.xをベースとして書かれているのと、省略されている事が多いので、本の通りにやってもうまく行かない事が多い。そんな詰まった事を、ここに書いておきます。

・第7章 タブバーとピッカー
P161
サンプルでは、@interfaceの中の宣言でIBOutletにより*window変数を修飾しているが、Xcodeが吐き出すスケルトンコードでは@propertyでIBOutletを修飾している。これはどちらでもよいみたい。

P161
Viewアイコンをクリックしてサイズインスペクタを開き、ビューの高さを411にすることと書かれているが、実は編集ができない状態になっている。このようなときは、Apple + 1で属性インスペクタを開き"Status bar"の値を確認する。ここがデフォルトでは"None"以外の値が設定されている。これを"None"にすることでビューの高さを変更できるようになる。  
Posted by 中垣健志 at 20:36Comments(18)TrackBack(0)iPhone

2009年07月09日

FLOSS桜山で発表できず、残念

OpenVZに関する勉強の成果をFLOSS桜山で発表しようと思ったのですが、プロジェクターで投影できないというありがちな事象のため発表できませんでした。主催の方にいろいろとりなしていただきましたが、やはり残念だし、もしかして楽しみにしていた方がいれば申し訳ないと思います。
プロジェクターがうまくいかないというのはありがちなことだし、そういう意味ではリスク管理が足りなかったなと反省しています。次回チャンスをいただけるのであれば、万全の態勢で臨みたいと思います。まずは、発表できなかった内容をこのblogで公開していきたいと思います。
  
Posted by 中垣健志 at 00:12Comments(15)TrackBack(0)

2009年06月21日

OpenVZ #2

CentOS 5の上でOpenVZを導入するにあたって、vethを使ってネットワークを構築するときに得たノウハウを公開しておきます。

用語解説
HN:OpenVZが稼働しているホストマシン(ハードウェアノード)
CT:vzctl createで作成した仮想マシン(コンテナ)

HN上に複数のCTを構築する

この作業は、必ずコンソール上から行ってください。SSHなどネットワークを経由しているときには、途中で一時的にネットワークがつながらなくなるため、作業続行不能となります。

#1の記事にそって、もうひとつCTを作成します(IP:10.0.1.102)
そしてHNから各CTに対してpingを打つと、きちんと結果が返ってきます。

[root@hn ~]# ping -c4 10.0.1.101
PING 10.0.1.101 (10.0.1.101) 56(84) bytes of data.
64 bytes from 10.0.1.101: icmp_seq=1 ttl=64 time=0.093 ms
64 bytes from 10.0.1.101: icmp_seq=2 ttl=64 time=0.110 ms
64 bytes from 10.0.1.101: icmp_seq=3 ttl=64 time=0.109 ms
64 bytes from 10.0.1.101: icmp_seq=4 ttl=64 time=0.113 ms

--- 10.0.1.101 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.093/0.106/0.113/0.010 ms
[root@hn ~]# ping -c4 10.0.1.102
PING 10.0.1.102 (10.0.1.102) 56(84) bytes of data.
64 bytes from 10.0.1.102: icmp_seq=1 ttl=64 time=0.122 ms
64 bytes from 10.0.1.102: icmp_seq=2 ttl=64 time=0.116 ms
64 bytes from 10.0.1.102: icmp_seq=3 ttl=64 time=0.110 ms
64 bytes from 10.0.1.102: icmp_seq=4 ttl=64 time=0.115 ms

--- 10.0.1.102 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3002ms
rtt min/avg/max/mdev = 0.110/0.115/0.122/0.013 ms

しかし、CTからCTにはpingが通りません。
[root@ct101 /]# ping -c4 10.0.1.102
PING 10.0.1.102 (10.0.1.102) 56(84) bytes of data.
From 10.0.1.101 icmp_seq=2 Destination Host Unreachable
From 10.0.1.101 icmp_seq=3 Destination Host Unreachable
From 10.0.1.101 icmp_seq=4 Destination Host Unreachable

--- 10.0.1.102 ping statistics ---
4 packets transmitted, 0 received, +3 errors, 100% packet loss, time 2999ms
, pipe 3

これは、HNにあるveth101.0とveth102.0がネットワーク的につながっていないのが原因です。
eth0(CT101) --- veth101.0(HN) --|ここが切れている| -- veth102.0(HN) --- eth0(CT102)

HN側に作成された二つの仮想ネットワークインターフェイス(veth101.0, veth102.0)を接続するためには、HN内に仮想のブリッジを作成します。

[root@hn ~]# yum install bridge-utils
[root@hn ~]# brctl addbr vzbr0
[root@hn ~]# brctl addif vzbr0 eth
[root@hn ~]# brctl addif vzbr0 veth101.0
[root@hn ~]# brctl addif vzbr0 veth102.0
[root@hn ~]# ifconfig eth0 down
[root@hn ~]# ifconfig eth0 0.0.0.0 promisc up
[root@hn ~]# ifconfig vzbr0 192.168.0.101 up
[root@hn ~]# route add -net 10.0.1.0 netmask 255.255.255.0 vzbr0
[root@hn ~]# route
ernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.1.0 * 255.255.255.0 U 0 0 0 vzbr0
192.168.0.0 * 255.255.255.0 U 0 0 0 vzbr0
169.254.0.0 * 255.255.0.0 U 0 0 0 vzbr0
default 192.168.0.230 0.0.0.0 UG 0 0 0 vzbr0

これでct101とct102から、それぞれ別の子サーバへのpingが通るようになります。  
Posted by 中垣健志 at 00:58Comments(499)TrackBack(0)環境構築

2009年06月17日

OpenVZ #1

CentOS 5の上でOpenVZを導入するにあたって、vethを使ってネットワークを構築するときに得たノウハウを公開しておきます。

用語解説
HN:OpenVZが稼働しているホストマシン(ハードウェアノード)
CT:vzctl createで作成した仮想マシン(コンテナ)

まずは、HN上でvzctl createを実行してCTを作成し、vzctl enterでCTにログインできる状態までたどり着いてください。そこまでの道のりについては
http://wiki.openvz.jp/index.php/%E3%82%AF%E3%82%A4%E3%83%83%E3%82%AF%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB
あたりが参考になります。


HN上に一つのCTを構築する

HNのeth0のアドレスは192.168.0.101/24とします。
CTに新規に作成するeth0のアドレスは10.0.0.101/24で作成します。

[root@hn ~]# vzctl create 101 --ostemplate centos-5-x86
Unable to get full ostemplate name for centos-5-x86
Creating container private area (centos-5-x86)
Performing postcreate actions
Container private area was created

[root@hn ~]# vzctl set 101 --hostname ct101 --save
Set hostname: ct101
Saved parameters for CT 101

[root@hn ~]# vzctl set 101 --netif_add eth0 --save
Saved parameters for CT 101

[root@hn ~]# vzctl start 101
Starting container ...
Container is mounted
Setting CPU units: 1000
Configure meminfo: 65536
Set hostname: ct101
Configure veth devices: veth101.0
Container start in progress...

[root@hn ~]# ifconfig veth101.0
veth101.0 Link encap:Ethernet HWaddr **:**:**:D4:49:6C
inet6 addr: ****::****:****:fed4:496c/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

[root@hn ~]# echo 1 > /proc/sys/net/ipv4/conf/veth101.0/forwarding
[root@hn ~]# echo 1 > /proc/sys/net/ipv4/conf/veth101.0/proxy_arp
[root@hn ~]# echo 1 > /proc/sys/net/ipv4/conf/eth0/forwarding
[root@hn ~]# echo 1 > /proc/sys/net/ipv4/conf/eth0/proxy_arp
※上記四行のコマンドは、HN上でsysctlコマンドの実行状況によっては不要かもしれない

[root@hn ~]# vzctl enter 101
entered into CT 101

[root@ct101 ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr **:**:**:26:E2:55
BROADCAST MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:0 (0.0 b)

[root@ct101 ~]# ifconfig eth0 0
[root@ct101 ~]# ifconfig eth0 netmask 255.0.0.0
[root@ct101 ~]# ifconfig eth0
eth0 Link encap:Ethernet HWaddr **:**:**:26:E2:55
inet addr:10.0.0.101 Bcast:10.255.255.255 Mask:255.0.0.0
inet6 addr: ****::****:****:fe26:e255/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:6 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:0
RX bytes:0 (0.0 b) TX bytes:384 (384.0 b)

ここまでの作業でCTにネットワークインターフェイスを作成することが出来ました。
しかし、CTからHNにpingを打っても返事が返ってきません。

[ve101]# ping 192.168.0.101
connect: Network is unreachable

これは、CTとHNの双方に適切なルーティングの設定をしていないのが原因です。
つまり、CT上には10.0.1.0/24ネットワークに対するルーティングの定義しかないので出ることができず、HN上には192.168.0.0/24ネットワークに対するルーティングの定義しかないので帰ってくることができないのです。だからCTとHNの双方にお互いのネットワークへのルーティングを定義します。

[root@ct101 ~]# ip route add default dev eth0
[root@ct101 ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.0 * 255.0.0.0 U 0 0 0 eth0
default * 0.0.0.0 U 0 0 0 eth0

[root@ct101 ~]# exit
[root@hn ~]# ip route add 10.0.0.101 dev veth101.0
[root@hn ~]# route
Kernel IP routing table
Destination Gateway Genmask Flags Metric Ref Use Iface
10.0.0.101 * 255.255.255.255 UH 0 0 0 veth101.0
192.168.0.0 * 255.255.255.0 U 0 0 0 eth0
169.254.0.0 * 255.255.0.0 U 0 0 0 eth0
default 192.168.0.230 0.0.0.0 UG 0 0 0 eth0

これでpingが通るようになりました。

[root@hn ~]# ping 10.0.0.101 -c 4
PING 10.0.0.101 (10.0.0.101) 56(84) bytes of data.
64 bytes from 10.0.0.101: icmp_seq=1 ttl=64 time=0.095 ms
64 bytes from 10.0.0.101: icmp_seq=2 ttl=64 time=0.112 ms
64 bytes from 10.0.0.101: icmp_seq=3 ttl=64 time=0.112 ms
64 bytes from 10.0.0.101: icmp_seq=4 ttl=64 time=0.116 ms

--- 10.0.0.101 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 3001ms
rtt min/avg/max/mdev = 0.095/0.108/0.116/0.015 ms
  
Posted by 中垣健志 at 23:19Comments(38)TrackBack(0)環境構築

2009年06月06日

mission imposibble

さくらの専用サーバで、OpenVZを使って仮想化環境を作る話は、結局完成しませんでした。

・第1の失敗
OpenVZでカーネルを差し替えるときに、差し替え用のカーネルがCPUの種類やメモリの使用量などによって何種類かに分かれます。
cat /proc/cpu
で確認したところマルチコアCPUだったので、まずはマルチCPU用のカーネルに差し替えて再起動を行ったところ、再起動せず。どうやらカーネルパニックになってしまった様子。

→ サポートに再起動依頼。5,250円支払いました。

・第2の失敗
おそらくは一番安全なシングルCPU用のカーネルを使えばいいだろうと思うも、再び有料の再起動をしたくはないので手を考えることにしました。方法としては、カーネルを差し替えて再起動するときにパニックになったら次のカーネルを使うよう、fallback設定をgrubに対して行います。こんな感じです。

default=0
fallback 1
timeout=5
splashimage=(hd0,0)/grub/splash.xpm.gz
hiddenmenu
title CentOS_OpenVZ (2.6.xx-xxstub.x.xx.el5) ←xxのところは、もう設定が残っていない
root (hd0,0)
kernel /vmlinuz-2.6.18-xx.xstub.xx.el5 ro root=/dev/sda2
initrd /initrd-2.6.18-128.1.10.el5.img
title CentOS (2.6.18-128.1.10.el5)
root (hd0,0)
kernel /vmlinuz-2.6.18-128.1.10.el5 ro root=/dev/sda2
initrd /initrd-2.6.18-128.1.10.el5.img

しかし再起動すると、再び反応なし。想定通りなので再起動してもらうと、やはり反応なし。おかしいなと思ってサポートに再び電話。その結果、カーネルは正常に起動しているが、ネットワークインターフェイスがダウンしているということ。

→といわれてもどうしようもないので、再び再起動依頼。5,250円


その後、Xenを一度動かしてその上でOpenVZを動かそうとも考えましたが、Xenもカーネル差し替えが必要だということがわかり、あきらめモードです。
まあ、仮想化ができなくてもそれなりにやりたいことはできるので、次の一手に進みたいと思います。

次はOpenVPNです。
  
Posted by 中垣健志 at 08:11Comments(19)TrackBack(0)環境構築

2009年06月01日

最初の設定

さくらの専用サーバ上に、OpenVZを使って仮想環境を作り、Webアプリケーションなどの公開を行えるようにする。各仮想環境にはOpenVPNを使って入れるようにする。

★グローバルIPを持ったGWの設定

■ホスト名の修正
デフォルトのホスト名はlocaldomain.localhostとなっていた。これを修正する。修正ファイルは次の通り。
/etc/hosts
/etc/sysconfig/network

■セキュリティホールの可能性をふさぐ
chkconfig --list | grep 3:onでOS起動時に合わせて起動するサービスの確認
→sendmailが動いていた。

chkconfig sendmail offでサービスを起動しないようにする。
/etc/init.d/sendmail stopでサービスを停止する。

その他のサービスは、動いていてもよいようだ。

これで基本的な設定は完了とする。
  
Posted by 中垣健志 at 22:45Comments(80)TrackBack(0)環境構築

2009年05月30日

concrete5

こんな要件を満たすために、CMSツールを探してました。
・CMSサイトそのものは、自分が構築する
・しかしCMSサイトの記事を投稿するのは別の人(つまり管理者じゃない人)
・別の人は、あまりITには詳しくない若者(もっといえば、現役の高校生)
・記事の公開には、別途責任者(=顧問の先生)の許可が必要

検討したのは次のCMS
・SOY CMS
・Movable Type
・Wordpress
・concrete5

SOY CMSは、自分で運営するには構成がシンプル(特にテンプレートがほぼHTMLなところ)が気に入っているのですが、実際にメンテナンスする人にもそれなりの知識が必要そうなのでNG。
Movable Typeは、個人が情報を発信する以外のときはお金がかかりそうなのでNG。
Wordpressは、「CMSで使うこともできますよ」と謳うわりにはそれ用のテンプレートがなく、ずいぶんと構築に手間がかかりそうなのでNG。

というわけでconcrete5がなかなかよさそうなので、採用となりました。良い点としては
・WYSISWYGな編集画面があること→素人にはとっつきやすい。
・CMSの約束事が少ないこと→イコール共通化に関する機能が少ないということですが、そこが却ってよい。
・記事の公開に承認プロセスが踏めること→必須機能なので。

しかし感じたのは、どのツールも導入がかなり考えられているということ。導入がとっつきにくいものは、やはりデファクトスタンダードや大きなシェアを占めるのは難しいということなのでしょう。どのツールも大体5~10個の質問に答えるだけで、最初のサイトが構築できます。これは見習うべきところでしょう。

ちなみに作ったページは、これになる予定です。
http://www.ostmeerphilharmoniker.com/tokai/
  
Posted by 中垣健志 at 23:02Comments(17)TrackBack(0)

2009年05月24日

さくらの専用サーバー

若手を集めて「技術部」を作ろうと思う。いわゆる部活動だ。
その本気度を示すために、まずは自腹で専用サーバーを契約してみた。
OpenVZやXenなどで仮想化などをやってみたい。
オリジナルサービスとか作って公開して、友達に自慢してみたい。

そんなこんなが月々7,800円なら安いもんだ。  
Posted by 中垣健志 at 18:10Comments(12)TrackBack(0)

2009年05月08日

centos5.3でmysqld起動時にyumが実行できない

mysqldが起動中にyumを実行すると、次のエラーが出てきます。

[root@lunch /]# yum update
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
Traceback (most recent call last):
File "/usr/bin/yum", line 29, in ?
yummain.user_main(sys.argv[1:], exit_code=True)
File "/usr/share/yum-cli/yummain.py", line 229, in user_main
errcode = main(args)
File "/usr/share/yum-cli/yummain.py", line 104, in main
result, resultmsgs = base.doCommands()
File "/usr/share/yum-cli/cli.py", line 339, in doCommands
self._getTs(needTsRemove)
File "/usr/lib/python2.4/site-packages/yum/depsolve.py", line 101, in _getTs
self._getTsInfo(remove_only)
File "/usr/lib/python2.4/site-packages/yum/depsolve.py", line 112, in _getTsInfo
pkgSack = self.pkgSack
File "/usr/lib/python2.4/site-packages/yum/__init__.py", line 591, in
pkgSack = property(fget=lambda self: self._getSacks(),
File "/usr/lib/python2.4/site-packages/yum/__init__.py", line 434, in _getSacks
self.repos.populateSack(which=repos)
File "/usr/lib/python2.4/site-packages/yum/repos.py", line 223, in populateSack
self.doSetup()
File "/usr/lib/python2.4/site-packages/yum/repos.py", line 71, in doSetup
self.ayum.plugins.run('postreposetup')
File "/usr/lib/python2.4/site-packages/yum/plugins.py", line 176, in run
func(conduitcls(self, self.base, conf, **kwargs))
File "/usr/lib/yum-plugins/fastestmirror.py", line 181, in postreposetup_hook
all_urls = FastestMirror(all_urls).get_mirrorlist()
File "/usr/lib/yum-plugins/fastestmirror.py", line 333, in get_mirrorlist
self._poll_mirrors()
File "/usr/lib/yum-plugins/fastestmirror.py", line 376, in _poll_mirrors
pollThread.start()
File "/usr/lib/python2.4/threading.py", line 416, in start
_start_new_thread(self.__bootstrap, ())
thread.error: can't start new thread

現在、調べているところです。  
Posted by 中垣健志 at 15:58Comments(40)TrackBack(0)

2009年05月06日

作成情報と更新情報

近頃はすべてのテーブルに、作成日・作成者・更新日・更新者の4フィールドを持たせる設計が多いです。この列を持たせる理由としては、おもにデータの作成された状態をトレースするためですが、改めてこの列の存在価値を考えたいと思います。

メリットとしては、論理的に間違ったデータが入った時にその登録経路のヒントとなることです。更新時間や更新者(あるいは更新モジュール)が分かれば、プログラムのどの場所に間違いがあるのか簡単に判明することがあります。
しかしデメリットも考えると多々あります。
まずこの情報は、最初と最後しか記録していません。そのため時間の経ってしまったデータについては、間でどのような書き換えが行われたかが不明です。
次に、データを書き出すプログラムが更新者や更新日を正しく書き出しているという前提も必要です。更新者や更新日情報を更新せずにデータだけ更新していたら、かえって問題の発見を遅らせてしまいます。
さらには、OracleでいうSQL-Plusのようなクライアントツールで直接SQL文を発行したときの情報も取得できません。

それらも踏まえると、次のような作戦もありなのではないでしょうか?
・トリガーを使って、履歴用のテーブルに更新者と更新日を記録する。
 →テーブル名、操作(CRUD)、更新日、更新者、更新モジュールID、主キーを列とする履歴テーブルにとにかく記録していく。履歴は追えるが内容までは追えない。パフォーマンスに難あり?
・記録しない
 中途半端な情報ならば、いっそ記録しないという手もあります。Oracleなどであれば、その気になればアーカイブログやREDOログなどから更新履歴を取得することも可能です。

何のために情報を残すのかを改めて考え直せば、どのレベルまで履歴を取っておくべきか答えは見えてくるはず。  
Posted by 中垣健志 at 17:38Comments(13)TrackBack(0)

2009年05月05日

トレーサビリティ

ここ数年間の間、システム開発をするには「トレーサビリティ」が重要だという思いが強くなっている。
たとえばコードを書いたときには、それが設計書のどの部分に対応しているのか?
たとえばテスト設計を書いたときには、それが設計書のどの部分に対応しているのか?
これがきちんと説明できないときには、そのコードやテスト設計を書いた人はたぶんわかっていないまま書いている。
そういう非連続性を見つけ出すためには、レビューが重要。というかレビューの重要な観点の一つがトレーサビリティ。  
Posted by 中垣健志 at 21:45Comments(16)TrackBack(0)