2011/06/19

CKEditorの塩っぱいプレビュー機能を改善する(2)

前回はダイアログ化に成功したので、トドメのカスタムプレビュー表示を実装した。
とりあえず、導入後のイメージ
サンプル一覧ページに編集内容を挿入した。
おおよそ、期待する動作を実現できたと思われる。

以下、導入方法の説明。
まずは、こちらから最新ソースを取得する。
導入手順は、前回を参照。
前回からの追加は、
function CKEDITOR_PREVIEW_URL(){
 //プレビューに利用するページのURL
  return '/_samples/';
 }
 
 /**
  * プレビュー表示のイベントハンドラー
  * @param {String} frameId プレビュー表示用IFRAME要素のID
  * @param {String} content エディタ編集中の内容
  */
 function CKEDITOR_PREVIEW(frameId,content){
   $('#'+frameId).contents().find('h1').after('
'+content+'
') .end() .find('a').click( function(e){ e.preventDefault(); } ); }
などとCKEditorと同じスコープ内に記述する。
プレビュー画面上での画面遷移を抑止したい場合は、上記のようにpreventDefaultを入れた方がいい。
子供だましかな...

クロスドメインページをプレビューに利用したい場合は、
function CKEDITOR_PREVIEW_URL(){
  return '';
 }

 function CKEDITOR_PREVIEW(frameId,content){
   $.getJSON('http://www.hoge.com/?callback=?',
              function(json){
                      $('#'+frameId).contents().find('html').html(json.data)
                          .find('#foo').html('
'+content+'
'); } ); }
のような実装にする(クロスドメインでの動作自体は未確認)。
この場合、必要であればspinnerなどを入れた方がいい。
ちなみに、CKEDITOR_PREVIEW_URL、及びCKEDITOR_PREVIEWの何れか未定義の場合は、
フォールバックとしてエディタ編集中の内容のみがダイアログ表示される。

tumblerdが異常にメモリーを溜め込む

Xubuntu環境下で、tumblerdプロセスが異常に4GB以上もメモリーを溜め込む症状に陥った。
実行環境のメモリーは6GBのため、スワップしまくりで使い物にならない。
まさか、8GBオーバーが前提じゃあるまいな...

ググってみると過去にメモリーリークバグがあったみたいだけれど、該当しそうなバグレポートが直ぐに見当たらなかった。
Synapticで検索してみると、どうやらサムネイル処理関連のD-busサービスと判明。
確かに、発症した状況では大量に画像や動画が配置されているディレクトリをThunarで巡回していた。
Thunarのサムネイル処理は、tumblerに統合されている(されている途中?)らしい。

仕方ないので、一度tumblerdプロセスを終了してみた...が、しぶとく復活&発症してくれたorz
これでは根本的に解決しない。
どうも一過性のバグではないらしい。
Synapticを再び眺めてみると、tumbler-plugins-extraなるものがインストールされていることを見付けた。
extra...怪しいネーミングだ。
試しに、
apt-get remove tumbler-plugins-extra
などと実行して削除してみると発症しなくなった!
既存アプリケーションへの影響度が分からないけれど、workaround(回避策)としては正解だったか?
ちなみに、当然ながら動画サムネイルは利用できなくなった。

2011/06/18

Puppet、Chefより先にKokkiを試す(1)

Oneiricにdotdeeが入るらしいから、OpenVZ上のDebian(6.0)に突っ込もうとした...が、upstartとか依存関係で諦めた。
本家では、黒魔術とか突っ込まれてる(w
それにしても、作者的にはPuppetChefなんてスカイネットかとネタにされている。
けれど時流としては、カオスな運用 → PuppetChef

PuppetChefを試そうにも、Rubyなだけに食べず嫌いだった。
それぞれイイヨ!とかいっている人達は、まさかこの運用改善って目的だけにRubyいれてるのかな...
そこは規模なんだろうか?
先日、たまたまChefのPythonポートといわれるKokkiを見付けたので、試してみる。
やっぱりPythonはどこでも走る(走ってる)から気楽だなぁ。

まずは、ソースを取得する。
本来は本家ドキュメントにある通り、
easy_install kokki
としてインストールするべきだけど、いきなり突っ込むなんて恐ろしくて出来ない(w

本家のcookbookへのリンク切れ気になったので、
ドキュメント(sphinx)をmakeしたけど一切記載がない。
というか、githubのIssuesにあがってたけど、放置プレー状態orz
これは...ソース嫁ということか。
ということで、ソースを少し眺めると...
apach2のレシピにRubyのコードっぽいものがコメントアウトされていた(w
cookbook( v 0.4 )には、
apache2
aspersa
avatartare
aws
boto
busket
cassandra
cloudera
cloudkick
exim4
flume
gearmand
java
jenkins
librato
limits
mdadm
membase
memcached
minecraft
mongodb
monit
munin
mysql
nagios3
nginx
pip
postgresql84
postgresql9
powerdns
rabbitmq
redis
serverdensity
ssh
sudo
supervisor
users
zookeeper
が配置されている。
monitやredisなんて珍味やjenkinsやnginxまであるのは面白い。
とはいえ、postfixやlighttpdなかったりする。
どういう基準なんだろうか?
新しいシステムインフラを取り込んでいく姿勢は歓迎するけど、
メジャーなものが満たされていないと常用は難しいかな。
個人的には、
  • bind
  • php
  • Postfix
  • qmail
  • vsftpd
  • proftpd
  • OpenVZ
辺りが外せない。
実際、Chefのcookbokサイトでは他にも色々ある。
使えそうなら、何かしらポートしようかな。

2011/06/17

WPScan試してみた

昨日、色々なメディアで取り上げられてたWPScan( Wordpress Security Scanner )を試してみた。
実行環境はDebain( 6.0 )なので、
apt-get install rubygems libcurl4-gnutls-dev
gem install –user-install typhoeus
gem install –user-install xml-simple
などとして下準備をする。
次にソースを
svn checkout http://wpscan.googlecode.com/svn/trunk/ wpscan-read-only 
で取得する。
実行環境では、502エラーが出たので何度かリトライした。
実行オプションは、READMEなどから分かる。

お楽しみの実行結果は...
root@dev:~/trunk# ruby wpscan.rb --url localhost --username wp_admin                                                                                       
____________________________________________________
 __          _______   _____                  
 \ \        / /  __ \ / ____|                 
  \ \  /\  / /| |__) | (___   ___  __ _ _ __  
   \ \/  \/ / |  ___/ \___ \ / __|/ _` | '_ \ 
    \  /\  /  | |     ____) | (__| (_| | | | |
     \/  \/   |_|    |_____/ \___|\__,_|_| |_| v.ALPHA

  WordPress Security Scanner by ethicalhack3r.co.uk
_____________________________________________________

# Copyright (C) 2011 Ryan Dewhurst
# This program comes with ABSOLUTELY NO WARRANTY.
# This is free software, and you are welcome to redistribute it
# under certain conditions. See GNU GPLv3.

| URL http://localhost/
| Started on Fri Jun 17 09:42:32 2011

[+] WordPress version 3.1.3 identified from meta generator.
[+] The WordPress http://localhost/readme.html file seems to exist.

[+] Finished.
となった。

どうやら、
  • data/wp_vulns.xmlに定義されたパターンのスキャン
  • 独自実装( readme.html のみ? )のスキャン
  • 辞書を使ったブルートフォース
をやってくれるらしい。

Wordpress向けMetasploitみたいな感じ。
現状は、既知のセキュリティーホールなどがメインになりそうだから、
ゼロデイアタックとかコミッターの体力勝負になりそう。
むしろ、その類に悪用されないと願いたい...

2011/06/13

CKEditorの塩っぱいプレビュー機能を改善する(1)

CKEditorには標準でプレビュー機能が搭載されているけれど、
別ウィンドウで開くし、プレビューといいつつエディタ単体の編集内容しか表現できない...etc
これでは、かなり利用シーンが限られている。
CMSでプレビューする時って、普通はエディタ編集内容+装飾やページ全体で出力する。
これを可能な限り、CKEditorで再現したいなぁという話。

とりあえず、でっち上げでダイアログ表示に対応したプレビュープラグインを作成した。
導入前、
旧来のプレビューは別ウィンドウでプレビュー表示される

導入後、
プラグイン導入後は、同ウィンドウ内のダイアログとしてプレビュー表示される。
別ウィンドウを開かない分、画面応答が早くなっている。
といった感じに変わる。

以下、インストール方法。

1. プラグインソースを配置する
まずは、こちらからソースをダウンロードして、
適宜解凍したものをソースディレクトリ(  /_source )に設置する。

2. ビルド設定を変更する
ckeditor.pack中、
'_source/plugins/preview/plugin.js'

を探して、

//'_source/plugins/preview/plugin.js'
 '_source/plugins/previewdialog/plugin.js'
などと書き換える。

後は、ビルドするだけ。
本来ならコピペで済ますのがプラグインとしての流儀だけど、
これ入れたら旧来のプレビュー機能は状況的に使われないし、
CSSとかシンドイので(ぉ

尚、このプラグインは、PoCレベルなので悪しからず。

[追記]
一応、期待する実装は完了した。
追加機能の説明は、こちらを参照

2011/06/12

CKEditorを自分色に染める(4)

今回は、
  1. エディタ領域のサイズ指定
  2. ダイアログのリサイズ時のサイズ指定
を扱う。

1. エディタ領域のサイズ指定
まず、初期表示状態のサイズ指定は、
 config.width  = 640;
 config.height = 480;
などとする。

次に、リサイズ時のサイズ指定は、
 config.resize_maxWidth  = 1024;
 config.resize_maxHeight = 768;
 config.resize_minWidth  = 640;
 config.resize_minHeight = 480;
などとする。

デザイン的に色々リサイズされると崩れて困る場合は、
config.resize_enabled  = false;      //そもそもリサイズさせない
 config.resize_dir      = 'vertical'; //リサイズは縦方向のみに限定する
などとする。

2. ダイアログのリサイズ時のサイズ指定
ダイアログのサイズなどの定義は、プラグイン自体かダイアログ定義イベントハンドラで指定することになる。
ダイアログ定義イベントハンドラで指定する場合は、
CKEDITOR.on( 'dialogDefinition', function( ev )
  {
    //定義中のダイアログ種類名を取得する
    var dialogName = ev.data.name;

    //ダイアログ定義を取得する
    var dialogDefinition = ev.data.definition;

    //全ダイアログ共通してリサイズを無効にする
    dialogDefinition.resizable = CKEDITOR.DIALOG_RESIZE_NONE;

    //ダイアログ個別に指定する
    if ( dialogName == 'image' )
     {
        //縦横方向のリサイズを許可する
        dialogDefinition.resizable = CKEDITOR.DIALOG_RESIZE_BOTH;

        //ダイアログ初期表示サイズ
        dialogDefinition.width  = 640;
        dialogDefinition.height = 480;

        //ダイアログ最小表示サイズ
        dialogDefinition.minWidth  = 320;
        dialogDefinition.minHeight = 240;

        // ( これ以降は独自実装 )
        //ダイアログ最大表示サイズ
        //CKEditor v3.6では最大表示サイズが指定出来ないので、独自プロパティを設定する
        dialogDefinition.maxWidth  = 800;
        dialogDefinition.maxHeight = 500;

        //定義中のダイアログのリサイズイベントハンドラを定義
        dialogDefinition.dialog.on('resize',function(e){
          //リサイズ後のダイアログサイズ
          var resizedWidth  = e.data.width;
          var resizedHeight = e.data.height;

          //リサイズされたダイアログ
          var senderDialog           = e.sender;
          var senderDialogDefinition = e.sender.definition;

          //ダイアログ最大表示サイズ
          var maxWidth  = senderDialogDefinition.maxWidth;
          var maxHeight = senderDialogDefinition.maxHeight;

          //最大表示サイズを超過している場合は、適宜補正する
          var revisedWidth  = maxWidth < resizedWidth   ? maxWidth  : resizedWidth;
          var revisedHeight = maxHeight < resizedHeight ? maxHeight : resizedHeight;
          
          if( revisedWidth  < resizedWidth ||
              revisedHeight < resizedHeight )
            {
              //リサイズをやり直し
              senderDialog.resize( revisedWidth, revisedHeight );
            }
        });  
     }
 });
などと記述する。
ダイアログ自体のカスタマイズは、これを参考に進められる。

CKEditorを自分色に染める(3)

前回のckeditor_basic.jsネタのところで、但し書きを入れた話。
事の発端は、別件でJQueryでCKEditorをgetScriptしたことだった。
現象としては、pluginが読み込めなかった。
その時は、前回紹介したこちらではなく、本家ドキュメントから回避方法に辿り着いた。

ちなみに発生シナリオとしては、
  1. ckeditor.js又は_basic.js何れかのエディタ本体を読み込む
  2. 相対パス指定?されているリソースを読み込む
  3. JSなどのエラー発生
といった具合らしい。

回避方法は、CKEDITOR_BASEPATHか、CKEDITOR_GETURLの2つ。
CKEDITOR_BASEPATHには、エディタの基準URLパスを指定する。
CKEDITOR_GETURLは、エディタで読み込むリソースのURLを取得する関数。
別件では、CKEDITOR_GETURLのみで回避した。
この関数は、ckeditor*.jsより前処理でグローバル定義しておかなければならない。

実際の実装は、
var CKEDITOR_BASE_URL = '/assets/js/ck/';
function CKEDITOR_GETURL( resource )
{
  return resource.indexOf(CKEDITOR_BASE_URL) != 0 ? CKEDITOR_BASE_URL+resource : resource;
}
などとした。
これで、CKEditor自身が迷子になっても正しいリソースURLを指し示せる。
それにしても、CKEditorのNewbie Developer向けドキュメント整備具合はTinyMCEに遠く及ばないことを痛感した。
API Docなんて飾りです。偉い人にはわからんのですよ。

CKEditorを自分色に染める(2)

カスタムビルドをやったら、今度は読み込み最適化。
これまたヘビー(w
とはいえ、

  1. CSSもminifyする
  2. ckeditor_basic.jsを利用する

の2点のみをやる。
詳しい情報は、本家にある通り。
本家では微妙な表現だけど、読み込み最適化の話をするならgzip転送は前提なんだなぁ...
mod_deflate対応してないホスティングサービスではこの辺シンドイなぁ。
みんなphpとかの変換スクリプト挟んでいるのだろうか?

CSSをminifyするには、minifierを事前に準備しておく。
yuicompressorを利用する。他に好みのものがあれば、そちらをどうぞ。
yuicompressorでは、
java -jar yuicompressor.jar -o  出力ファイル 入力ファイル
とするだけで、CSSとJSの2種類がminifyできる。

それでは、読み込みを最適化させる。

1. 関連するCSSをminifyする
まずは、_ckeditor自体のスタイルとなる、
 /contents.css
をminifyする。

次に、利用するスキンのスタイルとなる、
/skins/%利用するスキン%/
 dialog.css
 editor.css
 templates.css
をminifyする。
2. ckeditor_basic.jsを利用する
基本的には、「ckeditor.js」として読み込んでいるscript記述を「ckeditor_basic.js」に書き換えるだけでいい。
但し、ckeditor.jsの配置場所がbasic.jsと違ったり、
JQueryでいうgetScriptみたいなXHR経由でckeditorを読み込むとハマる。
回避法方法の具体的な実装ついては、別記する。
お楽しみのBefore & After。
基準となるオリジナルでは、
ckedirot.jsがonloadまでに読み込まれている

そして最適化後は、
ckeditor_basic.jsが追加されている。
ckeditor.js自体や関連するファイルは、onload以後に読み込まれているのが分かる。
結果として、onloadまでの時間が大幅に短縮されている。
となる。
たった少しの手間で絶大な効果があったと言える。

CKEditorを自分色に染める(1)

CKEditor+KCFinderネタが好評らしいので、いくつかCKEditorネタを扱うことにした。
まずは、カスタムビルド。
いきなりヘビーなネタ(w
minifyされてるJSが同梱されてるけど、やっぱりビルドしたい輩もいる訳で。
ちなみにビルドすると、
  1. デフォルトスキンに好きなものを指定できる
  2. デフォルト言語に日本語を指定できる
  3. 要らないプラグインを外せる
  4. 1~3を実施することで、CKEditor表示完了までの時間を短縮できる
といったメリットがある。

カスタマイズするには、まずは本家からソースを取得する。
といっても、既にCKEditorをダウンロードしている場合は、minifyされたJSと同梱されているので取得不要。
次に、専用minifierを取得する。
JAR版は、こちら。EXE版は、こちら

カスタマイズの流れとしては、
  1. ckeditor.packを編集
  2. 必要であれば、関連リソースを編集
  3. Let's Build!
になる。

それでは、カスタムビルドに取り掛かる。

1. デフォルトスキンに好きなものを指定する
まずはckeditor.pack中で、
 '_source/skin/kama/skin.js'
を探して、「kama」→「office2003」など好きなものに書き換える。

次に、_source/core/config.js中で、
 skin : 'kama'
を探して、「kama」→ckeditor.packで指定したものに書き換える。

2. デフォルト言語に日本語を指定する
まずは、_source/core/config.js中で、
 defaultLanguage : 'en'
を探して、「en」→「ja」に書き換える。

もし、日本語でしか運用しないのなら、ckeditor.js自体に言語ファイルを組み込んでしまった方が都合がいい。
言語ファイルを組み込むにはckeditor.pack中で、
 '_source/lang/en.js'
を探して「en.js」→「ja.js」に書き換える。
デフォルトでは、この行はコメントアウトされているので適宜コメントを外す。

3. 要らないプラグインを外す
まずはckeditor.pack中で、
 '_source/plugins/print/plugin.js'
などのプラグインファイルを探して、コメントアウトする。

次に、_source/core/config.js中で、
 plugins : 
を探して、ckeditor.packでコメントアウトしたものを同様にコメントアウトする。
そして、
 removePlugins : ''
を探して、ckeditor.packでコメントアウトしたものを列記する。
こんな感じで編集する。
ちなみにサイト内で完結するコンテンツのエディタとして利用する場合は、
  • basicstyles (Boldなどを利用したい場合は、外すと利用出来なくなる!)
  • bidi
  • flash
  • format
  • forms
  • iframe
  • newpage
  • print
  • scayt
  • stylescombo
  • specialchar
などが不要なプラグインと思われる。

さて、お楽しみのビルドタイム!
JAR版でのビルドは、
java -jar ckpackager.jar ckeditor.pack
と実行する。

基準となるオリジナルビルドは、
Packaging file ckeditor_basic.js


    Checking compressed code...

    Number of files processed: 5
    Original size............: 41471 bytes
    Output file size.........: 6940 bytes (17% of original)

Packaging file ckeditor.js


    Checking compressed code...

    Number of files processed: 117
    Original size............: 1189255 bytes
    Output file size.........: 356683 bytes (30% of original)
初期状態は、言語ファイルやスタイル定義など色々読み込んでいる。


そしてカスタムビルドは、
Packaging file ckeditor_basic.js


    Checking compressed code...

    Number of files processed: 5
    Original size............: 41471 bytes
    Output file size.........: 6940 bytes (17% of original)

Packaging file ckeditor.js


    Checking compressed code...

    Number of files processed: 107
    Original size............: 1130877 bytes
    Output file size.........: 340796 bytes (30% of original)
CKEditor自体が9KBくらい軽量化されていて、
言語ファイルなどの読み込みが減っているのが分かる
結果として、onloadまでの時間が短縮されている。
となった。
実は、言語ファイルを組み込むだけでは、オリジナルビルドより肥大化するけれど、
プラグイン外しが効いている結果だったりする。
用途次第では、もっとプラグインを外せたり、そもそもconfig.jsを読み込む必要すらなくなる。

TinyMCEに比べて軽いと聞いて使っているのに、初期ロードがいまいちと感じる方はお試しあれ。

2011/06/11

そろそろモダンな開発環境へシフトしよう(5)

さて、Photoshop。
そもそもテキストデータを扱わないソフトだけに、一般的にはCVS(バージョン管理)の普及が遅れている分野みたい。
実際、CVSを探すと高価な大規模組織向けのCVS+α的な代物しか見つからない。
TortoiseDiff+TortoiseSVNで頑張るのは、やれば分かるけれど現実的ではない。
そこで、Timelineを試してみたい。

Timelineは、PhotoshopプラグインとSubversion連携プログラムの2つから構成されている。
本家サイトにあるTimeline Liteはこの無料版(制約あり)。
動作検証していたら、面白いことが分かったので合わせて載せておく。

まずは、正規系インストール手順を行う。
本家からTimeline_Setup.exeをダウンロードしてインストールする。
インストールを終えてPSを起動すると、
Timelineのウィンドウが表示される
Timelineのウィンドウから、SVNリポジトリブラウザが起動できる



























SVNリポジトリへのアクセス設定を入力する。
プロトコルの指定は、DreamWeaverに及ばずHTTP/S限定らしい。
SVN以外には、PixelNovelのオンラインストレージや他サービスも利用できる。
DreamWeaverで色々やってたSVNリポジトリに繋いでみた。
phpファイルが確認できる。
チェックアウトすると、左ペインの「Working Copy」に溜まっていく。























チェックアウトしたファイルを編集して、通常通り上書き保存すると
コミット誘導ダイアログが開始される。
まずは、ファイルロックをするかの確認ダイアログ。
変更有り→これからも変更するよね→一応ロックする?みたいな発想らしい。






















ロックをキャンセルすると、いきなりコミットを案内される。
ここで「Commit」をクリックすると、実際にコミットされる。























コミット時には、当然ながらコメントを入力出来る。





















更に変更を重ねていくと、Timelineウィンドウにサムネイルが並んでいく
























ざっとこんな流れで利用する。
Subversionをテキストファイル主体で利用する人間からすると、
チェンジセットは?ブランチ切り替えは?diffは?mergeは?
といった当たり前に機能がないことに気付かされる。

チェンジセットは、必ず1ファイルでしかコミットしないから意味をなしてない。
ブランチは、チェックアウトで切り替えるしかない。
TortoiseDiffしたくても、外部diff呼び出し機能がない。
mergeしたくても、そもそも画像のmergeってどうやるんだ??

不満は色々あるけど、プラグインで違和感を低減させたことで実用化出来る範囲に
ギリギリ達してはいる。
一番問題なのは、このプラグインに$100出せるかどうか。
様々な事情で$100出せない方は、Timeline Liteをどうぞ。

Timeline Liteは、SVNではなくPixelNovelのオンラインストレージ専用に制限されたもの。
...と謳われている...一般人向けには。
Timeline LiteをインストールしたPS。
ウィンドウデザインなど細かな差異がある。


































実は、PixelNovelのオンラインストレージでなくてSVNでも利用できる。
利用方法は、2つある。

1. オンラインストレージの動作を偽装する
Wiresharkで眺めてて気付いたけれど、どうやらオンラインストレージなるものは
単純に「SVN over HTTP」らしい。
そんな訳で、hostsやDNSをでっち上げればどのmod_dav_svn環境でも利用できる可能性が高い。
但し、以下の構成にすべし。
/resources/reppath/reppath 
を配置する。
中身は、
http://pixcelnovel.com/svn/
などとアカウントディレクトリ(SVNリポジトリ)の配置ディレクトリパスを記述する。
このファイルは、URL1行のみ記述して改行文字(\n)などで終わってはいけない。

次に、アカウントディレクトリを作成する。
mod_dav_svnの設定に準じて、
/svn/%アカウント%
などとディレクトリを作成し、リポジトリを作成する。

パスワードの設定は、Basic認証で通過可能なのを確認した。
他プロトコルは未検証。

後は、Timeline Liteの画面に従って入力を進める。
Timeline Project Asistant を起動すると、
簡易プロジェクト管理機能ダイアログを表示される。
リポジトリの設定などは全てこのダイアログで行う。


































2. プラグイン周りの動作を偽装する
Timelineはプラグイン側でアクティベーション管理をしている。
この為、Timeline Liteをプラグインとして機能させ、
SVN操作はTimelineのものを使うと...ktkr
詳しい手順は、「1」以上にヤバそうなので割愛する。

Timeline Liteプラグイン+Timelineで構築した様子。
見た目に違いはないものの...
































いずれにしても、バージョン依存、環境依存であるため、
一般人にはオススメ出来ない方法。
Adobe関連でhostsを書き換えるような好事家は、是非とも試してみては?

2011/06/10

そろそろモダンな開発環境へシフトしよう(4)

前投稿から大分経ったため、対象環境のアプリ群もバージョンアップを重ねてしまった。
けれど、これが幸いして、DreamWeaver(以下、DW)がようやくSubversionに正式対応した。
そんな訳で、以下の構成でAdobe+αでBazaar+SVNを試す。

[バックエンドエンジニア]
1. Eclipse → bzr → bzr-svn → svn
2. bzr-explorer  → bzr → bzr-svn → svn

[フロントエンドエンジニア]
1. Eclipse → bzr → bzr-svn → svn          
2. bzr-explorer  → bzr → bzr-svn → svn
3. TortoiseSVN → svn 
4. DW → svn
※1~3は、作業レベルにより変動

[デザイナー]
1. DW → svn
2. TortoiseSVN → svn 
3. Photoshop / Illustrator → Timeline → svn
※1~2は、作業レベルにより変動

[その他]
1. TortoiseSVN → svn

長くなるので、とりあえずはDWとEclipse( QBzrEclipse on Xubuntu )との連携。
SVNリポジトリは、svnserve(*nix)とmod_dav_svn経由で利用する。
svnserveやmod_dav_svn自体の構築は、本筋から外れるので省略する。

まずは、Eclipse。
subversive的なポジションのらしいBzrEclipseを使いたかったけれど、
実行環境では必ずbzrがクラッシュしたのでQBzrEclipseを採用した。
状況を鑑みて、変更する予定ということで暫定採用。

EclipseへのQBzrEclipseインストール手順は、他のプラグイン導入と同じ。
本家サイトに記載されている

http://development.bitwig.com/qbzr-eclipse

をリポジトリに追加設定する。
リポジトリからQBzrEclipseを選択してインストールする
インストールが終わると、上部メニューやコンテキストメニューに
Bazaar関連メニューが追加される

空のSVNリポジトリをチェックアウトしてみる
テストファイルを追加する
新規追加の為、リポジトリへ追加処理を行う
準備が整ったので、コミットしてみる

DWでSVNリポジトリの利用設定をする。
今回は新規なので「新規サイト」。
既存サイトの場合は、「サイト管理」から行う
SVNリポジトリの利用設定情報を入力する。
小規模の場合は、プロトコルにsvnを選んでもいい。
SVNリポジトリの設定が終わると、
バージョンコントロール関連メニューが利用出来るようになる。
早速、Eclipseでコミットした内容を取得してみる

ローカルファイルを編集すると、リポジトリとの比較が行える。
今回は、WinMergeを利用した。
編集内容をコミットする
Eclipseに戻って、最新データを引っ張ってくる(Pull)
変更内容が取得できた!
今度は、コンフリクト(衝突)を発生させてみる。
まずは、Eclipseで編集してコミットする
次に、DWで編集してコミットすると...
コミット出来なかった。
リポジトリ内データよりローカルデータの方が古いとの警告。
コンフリクトとは分かりにくいメッセージだ...
最新バージョンを取得すると、リポジトリ最新、ローカル最新、
それぞれを結合したものが作成された。
手動マージをして、解決済みとしてマークする。
その後、コミットする。これで、コンフリクト解消

ざっとこんな流れかと。
DWに一切マージなどの基本機能がないのは痛いと感じた。
その辺は、WinMergeとか外部ツール任せということだろうか?
Eclipseは、GUI統合がされていないお陰で、Subversiveとかに比べると
使い勝手が悪いのは否めない。
正直、ここまで使い勝手が悪いとBazaarを捨てたくなる。

さて、次はPhotoshopでのSVN運用をまとめる。

2011/06/05

lessfs を試す

Linux Jornalのコラムに惹かれてlessfsを試してみたくなった。
ちなみに、lessfsは「Deduplication」(ファイル重複除外?)を目的としたfuse。
他にも暗号化機能、レプリケーション機能(MasterSlave)や圧縮ストレージ機能もあって、
圧縮フォーマットにはLZO、QuickLZ、BZipその他色々あるらしい。

Deduplication自体は、一部で熱いらしいBtrfsZFSにも搭載されている。
2つとも色々と問題があって、あまり簡単には導入出来ない。
そこでlessfsの登場。
fuseなだけに他のfuse系同様のボトルネックはあるものの、
アーカイブ用途ならパフォーマンス問題は少ないと思われる。

おまけでLinux Jornalでは、Opendedup も触れられていた。
こっちは、Javaかつシステムリソースの要求スペックが高いので論外。

lessfsで必要になるのが、
 tokyocabinet
 mhash
 fuse
の2つ。
メタ情報とかの管理にtokyocabinetを使っているらしいけど、
同様のDBMSとしてHamsterDBやBDBと色々いけるみたい。詳細不明。

早速、まずはCentOSで構築を始める...が5.6な環境のepelと標準リポジトリのパッケージでは、
tokyocabinetとfuseのバージョン古すぎて対応出来ない。
一番致命的なのはfuse。
色々と依存性が高いモジュールなだけに、CentOSは諦めた。
門前払いされた感じ。
お家騒動もあるし、CentOSにはウンザリしてきた。
野良ビルドするくらいなら、Debianに切り替える。

Debian(squeeze)で構築を始める。
ベアメタルな環境のため、
 apt-get install gcc zlib1g-dev libbz2-dev libmhash-dev pkg-config
で地盤作りから始める。

最初は、tokyocabinet(執筆時の最新版1.4.47)を構築する。
wget http://fallabs.com/tokyocabinet/tokyocabinet-1.4.47.tar.gz
tar xf tokyocabinet-1.4.47.tar.gz && cd tokyocabinet-1.4.47 
./configure && make && make install

次に、lessfs(執筆時の最新版1.4.7)
まずは、sourceforgeから取得。
tar xf lessfs-1.4.7.tar.gz && cd lessfs-1.4.7
./configure && make && make install

無事導入が終われば、まずは一段落。
同梱のlessfs.cfgを利用して一気に設定ファイル配置から初期化まで進める
cp etc/lessfs.cfg /etc/
mkdir -p /data/{dta,mta}
mklessfs -c /etc/lessfs.cfg

これでようやく準備が整ったので、
lessfs /etc/lessfs.cfg /mnt
でマウントしてみる。

ちなみに構築した環境下では、
root@dev:~# df
Filesystem           1K-blocks   Used      Available Use%  Mounted on
/dev/simfs            2097152 635080 1462072  31%   /
tmpfs                   393216         0          393216      0%   /lib/init/rw
tmpfs                   393216         0          393216     0%    /dev/shm
fuse                     2097152 635080 1462072  31%   /mnt
となっている。

実際に期待する働きをしてくれるのか実験する。
検証シナリオ:
  1. 100MBの0埋めデータtest.datを作る      ( 通常は、100MB 消費する )
  2. test.datをtest2.datにコピー                 ( 通常は、更に100MB 消費する ) 
  3. テストデータ削除
  4. 最新カーネルlinux-3.0-rc1.tar.bz2取得 ( 通常は、73MB 消費する )
  5. linux-3.0-rc1.tar.bz2をlinux-3.0-rc1_2.tar.bz2 にコピー  ( 通常は、更に73MB 消費する )
実験結果:
root@dev:~# dd if=/dev/zero of=/mnt/test.dat bs=1M count=100
100+0 records in
100+0 records out
104857600 bytes (105 MB) copied, 1.05934 s, 99.0 MB/s
root@dev:~# df
Filesystem           1K-blocks   Used      Available Use%  Mounted on
/dev/simfs            2097152    635108   1462044  31%  /
tmpfs                   393216                0   393216      0%  /lib/init/rw
tmpfs                   393216                0   393216      0%  /dev/shm
fuse                     2097152    635108   1462044  31%  /mnt
root@dev:~# cp /mnt/test.dat /mnt/test2.dat
root@wp:~# df   
Filesystem           1K-blocks   Used       Available Use%  Mounted on
/dev/simfs            2097152    635108   1462044  31%   /
tmpfs                   393216                0   393216      0%   /lib/init/rw
tmpfs                   393216                0   393216      0%   /dev/shm
fuse                     2097152    635108   1462044  31%   /mnt
....色々と実施したので消費量が変動orz root@dev:~# df Filesystem           1K-blocks   Used       Available Use% Mounted on /dev/simfs            2097152    635168   1461984  31%   / tmpfs                   393216                0   393216      0%   /lib/init/rw tmpfs                   393216                0   393216      0%   /dev/shm fuse                     2097152    635168   1461984  31%   /mnt root@dev:~# wget http://www.kernel.org/pub/linux/kernel/v3.0/testing/linux-3.0-rc1.tar.bz2 -O linux-3.0-rc1.tar.bz2
root@dev:~# df
Filesystem 1K-blocks Used Available Use% Mounted on /dev/simfs 2097152 711200 1385952 34% / tmpfs 393216 0 393216 0% /lib/init/rw tmpfs 393216 0 393216 0% /dev/shm fuse 2097152 711200 1385952 34% /mnt
root@dev:~# cp /mnt/linux-3.0-rc1.tar.bz2 /mnt/linux-3.0-rc1_2.tar.bz2
root@dev:~# df
Filesystem 1K-blocks Used Available Use% Mounted on /dev/simfs 2097152 711200 1385952 34% / tmpfs 393216 0 393216 0% /lib/init/rw tmpfs 393216 0 393216 0% /dev/shm fuse 2097152 711200 1385952 34% /mnt

おぉ! 圧縮されてるし、重複除去も効いている!! 100MBが100KB未満!!!
あまりに消費量の変動のなさにオペミスかと思って何度も検証シナリオを実施してしまった。

一応、リアルなデータとしてカーネルで変動を見たものの、
圧縮済みアーカイブデータは再び圧縮されることで余分に消費しているように伺える。
格納データが、プログラムソースとかExcelやwordなら圧縮が有効に働きそう。
但し、コピーに対するオペレーションが若干遅い印象を受けた。
この動作は、実際の運用でありそうなsamba経由でのファイル操作でも同様なことを確認済み。
NFSは未検証。
FAQに、nfsにはunfs3を使うように記載がある。
FAQには、他にもVMware環境下のワークアラウンドが載っている。
一応、導入前にREADMEと併せてFAQは参照しておいた方がいい。

それにしてもdfを何度か繰り替えしていると、
 消費量増加 ー> 圧縮実施? ー> 消費量減少 ー> 消費量増加(圧縮前増加分)
と遷移が確認出来た。
ディスクフルギリギリまで詰め込んで運用していると、不味いシナリオが発生しそう...

ちなみに、分かる人には分かるけど、実行環境はOpenVZ。
そんな訳で、Bonnieなどによるレポートは現実的な値が出ない可能性が高いので止める。

[感想]
人柱erは、是非ともお試しを。
但し、真面目に運用するには、バックアップは別途実施すべき。
他のファイルシステムでRAID0組んでれば安全!といった妄想が成立しないのと一緒。

2011/06/03

Ubuntuのfusesmbはマルチスレッド非対応

CentOSでは問題なかったSMBネットワーク内に対して、
Ubuntuでfusesmb接続すると必ず、
Transport error: [Errno 107] 通信端点が接続されていません
というようなエラーを吐いてfuse毎逝ってしまう。

仕方なくGigoloに切り替えて以降、これといった問題は起きていなかった。
しかし、Bazaar(SMB上)に接続しようとすると必ず失敗したため、
リベンジしてみた。

調べてみると、
[all variants] fuse and "Transport endpoint is not connected"
というUbuntu本家フォーラムに同様の書き込みがあった。
どうやらfusesmbは、マルチスレッド非対応らしい...CentOSは古すぎてOKだったのか?


とりあえず、
 fusesmb -s ~/mnt
等と実行して問題ないことを確認して一件落着。