puppet-mode.el のパッチ

Posted by Gosuke Miyashita Wed, 29 Aug 2007 15:30:00 GMT

Puppet で同じタイプのリソースを大量に記述する時には、

package { sudo:
  ensure => latest
}

package { ntp:
  ensure => latest
}

package { ssh:
  ensure => latest
}

なんて書くのはだるいので、

package {
  sudo:
    ensure => latest;
  ntp:
    ensure => latest;
  ssh:
    ensure => latest;
}

と書きたいのですが、Emacs + puppet-mode.el では、後者みたいな書き方だと、インデントが意図した通りにならなくて、イラっときてパッチ書いた。

=== puppet-mode.el
==================================================================
--- puppet-mode.el      (revision 1800)
+++ puppet-mode.el      (local)
@@ -106,7 +106,9 @@
                  (progn
                     (setq cur-indent (- (current-indentation) 2))
                    (setq not-indented nil))
-               (setq cur-indent (- (current-indentation) 2))))
+               (setq cur-indent (- (current-indentation) 2)))
+              (if (looking-at "^.*;")
+                  (setq cur-indent (- cur-indent 2))))
            (if (< cur-indent 0)     ; We can't indent past the left margin
                (setq cur-indent 0)))
        (save-excursion
@@ -125,6 +127,18 @@
                    (setq cur-indent (+ (current-indentation) 2))
                    (setq not-indented nil))
                (if (bobp)
+                   (setq not-indented nil)))
+             (if (looking-at "^.*:\s*$")
+                 (progn
+                   (setq cur-indent (+ (current-indentation) 2))
+                   (setq not-indented nil))
+               (if (bobp)
+                   (setq not-indented nil)))
+             (if (looking-at "^.*;")
+                 (progn
+                    (setq cur-indent (- (current-indentation) 2))
+                   (setq not-indented nil))
+               (if (bobp)
                    (setq not-indented nil)))))))
       (if cur-indent
          (indent-line-to cur-indent) 

他にもインデントまわりの動作で微妙なところはあるけど、ちょっとはましになった。インデントまわりの処理で参考になる emacs-lisp って何かないかな?

Trac の SearchHyperEstraierPlugin を Trac 0.10.x で動かすパッチ

Posted by Gosuke Miyashita Wed, 08 Aug 2007 18:03:00 GMT

SearchHyperEstraierPlugin が、Trac 0.10.x というか、うちの環境で動かないので、パッチ書いた。初 Python プログラミング。(というほどのものじゃないけど。)


=== searchhyperestraier/searchhyperestraier.py
==================================================================
--- searchhyperestraier/searchhyperestraier.py    (revision 892)
+++ searchhyperestraier/searchhyperestraier.py    (local)
@@ -2,8 +2,9 @@
 # SearchRepositoryWithNamazu plugin

 from trac.core import *
-from trac.Search import ISearchSource, query_to_sql, shorten_result
+from trac.Search import ISearchSource, shorten_result
 from trac.util import NaivePopen
+from trac.util.text import to_unicode
 from StringIO import StringIO
 import urllib
 import time
@@ -44,9 +45,9 @@
         browse_trac = self.env.config.get('searchhyperestraier', 'browse_trac','enabled')

-        cmdline = "%s %s %s %s" % (estcmd_path,estcmd_arg,index_path,unicode(query,'utf-8').encode(estcmd_encode))
+        cmdline = "%s %s %s %s" % (estcmd_path,estcmd_arg,index_path,' '.join(query))
         self.log.debug('SearchHyperEstraier:%s' % cmdline)
-        np = NaivePopen(cmdline)
+        np = NaivePopen( cmdline.encode(estcmd_encode) )
         #self.log.debug('Result:%s' % unicode(np.out,'utf-8').encode('mbcs'))
         #self.log.debug('Result:%s' % np.out)
         if np.errorlevel or np.err:
@@ -74,7 +75,7 @@
             attrelem_array = element.getElementsByTagName("attribute")
             for attrelem in attrelem_array:
                 attr_name = attrelem.getAttribute("name")
-                attr_value = unicode(attrelem.getAttribute("value")).encode('utf-8')
+                attr_value = to_unicode(attrelem.getAttribute("value"))
                 #URLとタイトルを生成
                 if attr_name == "_lreal":
                     attr_value=attr_value[len(replace_left):].replace("\\","/")

エラーが出るたびに、適当にいじってたら動いた、という感じ。なので、こんなんでいいのかはよく分からない。

Pushmi つかってます & 技術者募集中 at 福岡 3

Posted by Gosuke Miyashita Thu, 02 Aug 2007 16:52:00 GMT

弊社 は東京と福岡にオフィスがあり、それぞれの拠点に Subversion + Trac 環境を構築し、OpenVPN により VPN 接続してお互いの開発状況を公開しています。サービス絡みの開発は基本的に、東京は東京、福岡は福岡で完結しているので、この方式で問題はないのですが、サーバ管理関連のスクリプトなんかは、東京と福岡で共通するものが多いため、別々の SVN リポジトリで管理されてると不便なんですよね。かといって、どちらかの拠点だけしかリポジトリがないと、VPN の障害発生時に、リポジトリのない拠点からはまったくアクセスができない、という困ったことになってしまいます。

そこで、SVN リポジトリレプリケーションツール Pushmi を導入してみました。詳細は YAPC::Asia での 作者 Cl Kao によるスピーチ動画 を見て頂くとして、ここでは行った設定についてメモを残しておきます。ほとんど perldoc Pushmi の内容と同じですが。

まず当然 Pushmi のインストールが必要です。これの手順は省略。また、より良いアトミックロック実現のために memcached を利用している、ということなのでインストールしておきます。これも手順は省略。

memcached を起動します。

$ sudo /usr/bin/memcached -p 8123 -dP /var/run/memcached.pid -u nobody

/etc/pushmi.conf を設定します。弊社の環境では memcached のポートのみ指定してます。

authproxy_port: 8123

ミラーリポジトリを作成します。

$ pushmi mirror /var/db/my-local-mirror http://master.repository/svn
Mirror initialized.

ミラーリポジトリとマスターリポジトリを同期します。

$ pushmi sync /var/db/my-local-mirror
Retrieving log information from 1 to 62

ミラーリポジトリは、svnadmin create で作成するのと同様なディレクトリ、ファイル構造になってますが、Pushmi 用の pre-commit スクリプトと post-commit スクリプトが置かれている、というところが異なります。

pre-commit では以下の様なコマンドが実行され、ミラーリポジトリにコミットされた内容を、マスターリポジトリにコミットしに行きます。

/usr/bin/pushmi runhook $1 --txnname $2

post-commit では以下の様なコマンドが実行され、ミラーとマスターの整合性を確認しています。

/usr/bin/pushmi verify $1 --revision $2

Apache + WebDAV で SVN リポジトリにアクセスするために、以下の様な設定を Apache で行います。

<Location /svn/server>
  PerlSetVar SVNPath /var/db/my-local-mirror
  PerlSetVar Pushmi /usr/bin/pushmi
  PerlSetVar PushmiConfig /etc/pushmi.conf
  <LimitExcept GET PROPFIND OPTIONS REPORT>
    AuthName "mirrored private area" 
    AuthType Basic
    Require valid-user
    AuthLDAPURL ldap://localhost:389/ou=people,o=paperboy?uid?sub?(objectclass=*)
    PerlAuthenHandler Pushmi::Apache::AuthCommit
  </LimitExcept>
</Location>

設定見て分かると思いますが、mod_perl を利用していて、Apche2 + mod_perl の環境が必要です。Apache は 2.0 系でも 2.2 系でも大丈夫なようです。弊社では 2.0 系を利用しています。

特にポイントとなるのは、

PerlAuthenHandler Pushmi::Apache::AuthCommit

の部分で、認証で渡されたユーザ名、パスワードをこのモジュールで memcached にキャッシュしておき、マスタリポジトリへのコミット時の認証に利用します。Apache 2.2 系の場合には、以下の様に設定します。

AuthBasicProvider Pushmi::Apache::RelayProvider

この状態では、ミラーへのコミットは即マスターに反映されますが、マスターへのコミットはミラーに反映されませんので、以下の様な cron 設定を行い、5分おきにマスターとミラーを同期するようにします。

*/5 * * * * /usr/bin/pushmi sync --nowait /var/db/my-local-mirror

今のところこれで問題なく動いています。

話変わりまして、弊社福岡支社では、プログラマサーバエンジニア を募集しています。Pushmi を実戦で使ってみたい!という方はぜひ。メガネ女子プログラマもいますよ。(東京本社にもいます。人妻ですが。)