RSS

日々のメモ書き

Debian Developerが綴るメモ

live-helper

Debian Live build scripts

Live CDを作成するツール。とりあえず動けばいいやは非常に簡単。

% lh_config
# lh_build
# kvm -cdrom binary.iso

とここまでで起動する。簡単だった。

wkhtmltopdf

Command line utility to convert html to pdf using WebKit

WebKitを使ってウェブページのスナップショットをPDFで作成してくれる。これは便利だ。

modelformset_factoryのこと

modelformset_factoryを作ってフォームの一括処理をしようとしたらどうも挙動がおかしい。

ModelFormSetを作って新規のフォームを初期データ付きで作成しようとした。しかし新規にデータを挿入しているつもりなのに既存のデータが上書きされる。なぜだなぜだと考えていたがそもそもそういう挙動だった。

TheModelFormSet = modelformset_factory(TheModel)
print TheModelFormSet(inital=init_data)

だいたいこのような記述になるがほっておくとフォームの雛形をTheModel.objects.all() 相当から作ることになる。そこから初期値が、特にidが作成されてしまう。idがフォームのパラメータに含まれるということはinsertではなくてupdateの挙動になる。まいった。

完全にデータの入ってないフォームを作成しようと思ったらできる。例えばhttp://code.djangoproject.com/ticket/9538にあるようにすればできる。ただ、これにinitialを引数で与えるとエラーになる。initialはquerysetで作成したModelのインスタンスに対して適用しようとするので、当然数が合わずにエラー。initialのパラメータに {'id':None}を渡してやれば id が空のフォームはできるが必要のないquerysetを内部で実行することになる。それも気持が悪い。

自分でTheModelFormを作成してから TheModelFormSet を作成すればもちろん問題ないがめんどくさい。はてさて、簡単な方法がないものか。

darcs-buildpackageを使ってみる

意外に簡単。

debian/とupstreamをまとめてdarcsで管理するツール。

準備。~/.darcs-buildpackgeを設定。リポジトリをどこに展開するか設定する。

repobase     = /home/takaki/dbp
upstreamrepo = %(repobase)s/%(package)s.upstream
debianrepo   = %(repobase)s/%(package)s

まず最初のリポジトリを作成する。

$ dbp-importdsc tokyocabinet-haskell_0.0.2-1~1.dsc 
VCSCMD: darcs
LOGTEXT Imported tokyocabinet-haskell-0.0.2
into Darcs repository



Finished recording patch 'Imported tokyocabinet-haskell-0.0.2'
Finished tagging patch 'TAG UPSTREAM_tokyocabinet-haskell_0.0.2'
Finished pulling and applying.
dpkg-source: warning: extracting unsigned source package (/home/takaki/deb/htc/tokyocabinet-haskell_0.0.2-1~1.dsc)
dpkg-source: extracting tokyocabinet-haskell in tokyocabinet-haskell-0.0.2
dpkg-source: info: unpacking tokyocabinet-haskell_0.0.2.orig.tar.gz
dpkg-source: info: applying tokyocabinet-haskell_0.0.2-1~1.diff.gz
VCSCMD: darcs
LOGTEXT Imported tokyocabinet-haskell-0.0.2
into Darcs repository



Finished recording patch 'Imported tokyocabinet-haskell-0.0.2'
Finished tagging patch 'TAG DEBIAN_tokyocabinet-haskell_0.0.2-1~1'
$

これで ~/dbpにtokyocabinet-haskellとtokyocabinet-haskell.upstreamという二つのリポジトリが作成される。debをbuildする作業はtokyocabinet-haskellのほうで行う。_darcsディレクトリが存在するのでそのままdebuildをやっても駄目である。darcs-buildpackageを利用する。

buildの風景は省略。

さて、新しいupstreamができたとき、uupdateを今までは使ったが変わりにdbp-importorigを使う。

$ dbp-importorig ~/Desktop/tokyocabinet-haskell-0.0.4.tar.gz  tokyocabinet-haskell 0.0.4
 VCSCMD:  darcs
LOGTEXT Imported tokyocabinet-haskell-0.0.4
into Darcs repository



Finished recording patch 'Imported tokyocabinet-haskell-0.0.4'
Finished tagging patch 'TAG UPSTREAM_tokyocabinet-haskell_0.0.4'
$

という具合になる。

debの作業用リポジトリで darcs pull を実行すると upstreamの変更がmergeされる。

~/dbp/tokyocabinet-haskell$ darcs pull
Pulling from "/misc/home/takaki/dbp/tokyocabinet-haskell.upstream"...
Thu Apr 30 16:59:35 JST 2009 takaki@asis.media-as.org
* Imported tokyocabinet-haskell-0.0.4
into Darcs repository


Shall I pull this patch? (1/2) [ynWvplxdaqjk], or ? for help: y
Thu Apr 30 16:59:36 JST 2009 takaki@asis.media-as.org
tagged UPSTREAM_tokyocabinet-haskell_0.0.4
Shall I pull this patch? (2/2) [ynWvplxdaqjk], or ? for help: y
Finished pulling and applying.
~/dbp/tokyocabinet-haskell$

さて、このままでは deb としての変更は認識されていないので dch -v 0.0.4-1として新しいdebian/changelogのエントリーを追加する。dbp-buildpackageを実行したりしてパッケージのbuildのテストをしたりする。作業したあとにdarcs recordを適宜実行する。debのリビジョンとして区切りだなと思ったら darcs record と dbm-markdebを実行してtagを打つ。その繰り返しで進めていく。思ったより簡単だった。

メモ

間違えてdbp-markdebをやってしまったときにはdarcsのtagを削除するやりかたで普通にできる。

~/dbp/tokyocabinet-haskell$ darcs unrecord -t 'DEBIAN_tokyocabinet-haskell_0.0.4-1~2'
Thu Apr 30 17:11:37 JST 2009  takaki@asis.media-as.org
  tagged DEBIAN_tokyocabinet-haskell_0.0.4-1~2
Shall I unrecord this patch? (1/1)  [ynWvplxdaqjk], or ? for help: y
Finished unrecording.
~/dbp/tokyocabinet-haskell$
# いろいろ作業
~/dbp/tokyocabinet-haskell$ dbp-markdeb 
Finished tagging patch 'TAG DEBIAN_tokyocabinet-haskell_0.0.4-1~2'
~/dbp/tokyocabinet-haskell$


FusionForgeって?

Developer Newsを読んでいたらaliothがgforgeからFusionForgeに変更したという記述が。

gforgeのfree版という位置付けのようだ。GForge, L.L.C.がfrom scratchでgforge-5.0を作って今までのようなフリーソフトウェアとは違う取り扱いになったので、4.xからGPL forkを作って名称変更しました…ということか。

NVIDIAのドライバー

やっと173.14.18のドライバーが入った。

ということでxorg-7.4に家のPCが上がる。

チャレンジリーグ 春の長良川クリテ

今年最初のレース頑張ってきました。

突然寒くなったものだ。長島の駅から出て走っていたら半袖ジャージでは寒かった。風も強くて押し返される感じで。

スポーツIに出て5周目で死亡。ホームストレートに入ってついてけなかった。まだ厳しいです…。


な、なんだってー

OracleがSunを買収!!!!!

えーと、MySQLってどうなるんだ?

業界的にはいろいろあるんだろうけど、あのSunがあのSunが、という感じ。自分がSunOS4でUNIXの世界に飛び込み…長い時間を過ごし。寂しい話だ。

OCFS2の実験

OCFS2を実験してみた。

NFSの代わりに使ったりするということだったので、サーバとクライアントという図式でサーバが調整を行うのだと思っていたら違っていた。各サーバーが共有のブロックデバイスを持ち、各サーバーが互い協調して書き込みをする仕組みだった。つまりFCやiSCSIで共有ディスクを接続して運用するということになる。

今回の実験ではLinuxのiscsitargetを使った。iscsitargetでiSCSIディスクを提供するサーバーを1台用意して2台のクライアントからiSCSIでブロックデバイスを共有。そしてOCFS2でマウントする構成を取った。kernelは 2.6.26-2-{686,amd64}で実験。

iSCSIの設定

ざっと書く。iSCSIなりFCなりで共有ディスクがすでにあるなら飛ばす。

iscsitargetをインストールしてLVMのボリュームをiSCSIで公開する。LVMで/dev/vgmain/iscsi0というボリュームを作成して/etc/ietd.confに
Target iqn.2009-04.com.example:storage.iscsi0
Lun 0 Path=/dev/vgmain/iscsi0,Type=blockio

としてiSCSIのディスクを公開する。

クライアント側ではopen-iscsiをインストールする。iscsi_discoverを使ってiscsiのディスクをブロックデバイスとして登録できるところまでやる。例えば /dev/sdaなりに登録されたとする。

OCFS2の設定

次にOCFS2の設定を行なう。
クライアント側でocfs2-toolsをインストール。debconfでブート時に起動されるように設定する。
/etc/ocfs2/cluster.confを設定する。
node:
name = client0
cluster = ocfs2
number = 0
ip_address = 192.168.1.100
ip_port = 7777

node:
name = client1
cluster = ocfs2
number = 1
ip_address = 192.168.1.101
ip_port = 7777

cluster:
name = ocfs2
node_count = 4

このファイルは各クライアントで同じ内容を持つ必要がある。
mkfs.ocfs2を実行してiSCSIのデバイスにOCFS2のファイルシステムを作成する。

# mkfs.ocfs2 /dev/vgmain/ocfs 
mkfs.ocfs2 1.4.1
Cluster stack: classic o2cb
Filesystem label=
Block size=4096 (bits=12)
Cluster size=4096 (bits=12)
Volume size=1073741824 (262144 clusters) (262144 blocks)
9 cluster groups (tail covers 4096 clusters, rest cover 32256 clusters)
Journal size=67108864
Initial number of node slots: 4
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Writing backup superblock: 0 block(s)
Formatting Journals: done
Formatting slot map: done
Writing lost+found: done
mkfs.ocfs2 successful
#
/etc/fstabに次のように設定。書かないと /etc/init.d/ocfs2 が起動しない。
/dev/sda /mnt/ocfs ocfs2 _netdev 0

そのあとに o2cbとocfs2を再起動する。

# /etc/init.d/o2cb restart
Stopping O2CB cluster ocfs2: OK
Unloading module "ocfs2": OK
Unmounting ocfs2_dlmfs filesystem: OK
Unloading module "ocfs2_dlmfs": OK
Unloading module "ocfs2_stack_o2cb": OK
Unmounting configfs filesystem: OK
Unloading module "configfs": OK
Loading filesystem "configfs": OK
Mounting configfs filesystem at /sys/kernel/config: OK
Loading stack plugin "o2cb": OK
Loading filesystem "ocfs2_dlmfs": OK
Mounting ocfs2_dlmfs filesystem at /dlm: OK
Setting cluster stack "o2cb": OK
Starting O2CB cluster ocfs2: OK
# /etc/init.d/ocfs2 restart
Stopping Oracle Cluster File System (OCFS2) OK
Starting Oracle Cluster File System (OCFS2) OK
#

というところで終了。かなり簡単。

pgpool-IIをPITRでリカバリ

前回はrsyncでリカバリーをおこなったが今回はPITRを使う。

やってしまえば簡単な話なんだが、それまでにいろいろ試行錯誤。結果的にPITRのことがわかるようになった。流れは次のとおり。

  • WALのアーカイブログを取るように設定
  • pg_functionの設定(省略)
  • pgpool.confの設定とリカバリーのスクリプトの作成

まずそれぞれのクラスターがWALのアーカイブをするように設定する。cl0,cl1/postgresql.confの設定を行う。

archive_mode = on 
archive_command = 'cp -f %p archive_log/%f'

と設定する。archive_command を

test ! -f archive_log/%f && /bin/cp %p archive_log/%f'

という説明もあるのだが、これやるとエラーになってしまう。

次にpgpool関係の設定。recovery_1st_stage.shを以下のとおり。色々デバッグメッセージが出るので注意。

#!/bin/bash -vx
CLUSTER=$(basename $(cd $(dirname $0);pwd ))

if [ $CLUSTER = cl0 ]; then
PORT=5433
else
PORT=5434
fi

MASTER_BASEDIR=$1
RECOVERY_HOST=$2
RECOVERY_BASEDIR=$3

psql -h localhost -p $PORT -c "select pg_start_backup('pgpool-recovery')" postgr
es

echo "restore_command = 'cp -v $RECOVERY_BASEDIR/archive_log/%f %p'" > $MASTER_BASEDIR/recovery.conf

rsync -av $MASTER_BASEDIR/ $RECOVERY_BASEDIR/
rm -f $RECOVERY_BASEDIR/postmaster.pid

rm -f $MASTER_BASEDIR/recovery.conf

psql -h localhost -p $PORT -c 'select pg_stop_backup()' postgres

次にrecovery_2nd_stage.shを設定する。

#! /bin/bash -vx
CLUSTER=$(basename $(cd $(dirname $0);pwd ))

if [ $CLUSTER = cl0 ]; then
PORT=5433
else
PORT=5434
fi

MASTER_BASEDIR=$1
RECOVERY_HOST=$2
RECOVERY_BASEDIR=$3

psql -h localhost -p $PORT -U postgres -c 'select pg_switch_xlog()' postgres

rsync -av $MASTER_BASEDIR/archive_log/ $RECOVERY_BASEDIR/archive_lo

それぞれのファイルを$PGDATAの中に配置。

pgpool.confは次のように設定。

recovery_1st_stage_command = 'recovery_1st_stage.sh'
recovery_2nd_stage_command = 'recovery_2nd_stage.sh'

これで同じようにpcp_recovery_nodeを動かせばいい。いろいろと雑だが一応動く。

< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 >