windows版rsyncとubuntuサーバを使って、開発環境を同期しよう

 私は現在、デスクトップPCとノートパソコンで開発しています。

 こういった時に問題になるのが、開発環境の同期です。同じソフトを何度もインストールしてメンテナンスするのは時間の無駄ですから、できるだけ同期させる必要があります。

 そのために、ここ数年間様々な方法を検討して実際に使ってきました。

方法1:USBメモリ

 PortableApps等を見習って、USBに開発環境一式を入れて使うというアプローチです。ある意味、一番素直ですね。8GB~16GB程度のUSBメモリもそれなりに安価に入手できるようになり、実用性が出ました。

  • メリット
    • “コピー”は存在しないので、同期を考えなくていい。
    • PortableAppsあたりで確立されているノウハウがそのまま使える。
  • デメリット
    • 安いUSBメモリは想像以上に遅い。そして、結構クラッシュする。
    • モバイル環境で、USBメモリが出っ張ってるのはちょっと怖い。USBが物とぶつかった場合、てこの原理でUSBコネクタが破壊されるかもしれない。

 16GBのUSBメモリが2本も壊れてしまったので、この方法は諦めました。今はまた別のUSBメモリ†1を買いましたが、大きなサイズのデータのやり取りに留めています。

方法2:dropbox

 USBメモリを諦めて、同期すると考えた場合、まっさきに思いついた方法です。専用のクライアントをインストールすることで、Windows/Mac OSX/Linuxの各OSで、ファイルを全自動で同期してくれます。

 初期容量が2GBしかありませんが、お金を払うor無駄に頑張ることで、容量を増やすことができます。私は無料で6.1GB手に入れました!(ドヤ

  • メリット
    • 自動でやってくれる
  • デメリット
    • 間違えて消した結果も全自動でミラーリング。ノートPCの不意のクラッシュによってデータが破壊された場合も同様。

 とはいえ自動でシンクロしてくれるのは便利で、現在でも、開発中のソースコードをシンクロさせるのに使っています。gitリポジトリも一緒に同期しているため冗長化されている上に、仮にファイルが紛失しても元のリポジトリから取得してくれば大丈夫なようになっています。

方法3:Bazaarの軽量チェックアウト

 新進気鋭のバージョン管理システムBazaarの、軽量チェックアウト機能を使ってSyncします。

 軽量チェックアウトというのは、SVNと似たような方式で、バージョンの一番新しいものだけが同期されます。ではなぜSVNを使わないとかというと、SVNも最新バージョンだけを同期しますが、最新バージョンのコピーも作成し、結果ファイル数が倍になってしまうのと、全フォルダに.svnというメタ情報を格納したフォルダ(先述の最新バージョンのコピーもここに入ってます)が作成され、これが存外邪魔だからです。

  • メリット
    • バージョン管理システムのリッチな所がすべて使える。
    • 変更点が一目で分かる
  • デメリット
    • クライアント側は最新バージョンだけだが、サーバ側は全バージョンなのでサーバのディスクを逼迫する(注:このsyncサーバはSSDで動いています)
    • 流石に10万ファイルを超えるとbazaarが重い。

 GUIのクライアントが一切使えないのには困ってしまいました…。コマンドラインだけだと正直ちょっとしんどいです。

rsync

 というわけで、rsyncに乗り換えました。これにより、速度の改善とディスクの逼迫を改善したいです。バージョン管理はなくても、たぶんなんとかなります。まだそんなに使っていないので、効果についてはこれから検証!です。

というわけで、実際にrsync環境を作ってみよう。

Ubuntu側のセットアップ

 基本的に公式マニュアルの通りです。玄箱でやっていたあたりからずっとinetdを使って来たのですが、どうやら最近はxinetdが推奨のようですね。

 設定ファイル先頭にこんなのを書き加えるともうちょっとセキュアかも。

use chroot = yes

 一つ引っかかったのは、xinetdだけでなく、システム全体の再起動をしないとうまく接続できない(telnetで叩いてもconnection refusedされる)事くらいでしょうか。どうしてかは分からないのですが、再起動すればうまく動いたのでよしとします。

Windows側のセットアップ

 cygwinをパッケージしたcwRsyncをDLします。インストーラだからインストール…。いえいえ、あり得ないですよね。Universal Extractで解答できます。使い方はこの辺を参考にね

 解答するとbinやdocといったフォルダが含まれるフォルダが出てくるので、そのフォルダを頂戴して”sync”とか適当にリネームして、そのフォルダに色々とsyncのためのスクリプトを書きましょう。

 まず必要なのは、pathを通してくれるようなバッチファイルです。

rem "common.bat"として保存してね。
@echo off
set PATH=%~dp0bin;%PATH%
rem この辺は適当に調整してね。
SET REPOS=ledyba@ledyba.org::windev/
rem cwRsyncはcygwinなので、パスの形式はcygwin形式です。
SET TARGET=/cygdrive/d/software/

 同期のための個々のバッチファイルを書く際は、このファイルをcallすることにしましょう。

 %~dp0に関してはこの辺を参考にしてください。バッチファイルが置かれたフォルダに置き換えられます。結構便利。

ファイルをサーバへバックアップする(push)

call "%~dp0common.bat"
rsync -rzht --progress --stats --chmod=a+rwx --delete %TARGET% %REPOS%
pause

 環境設定のための、先程作成したcommon.batを呼び出して環境を設定した後、rsyncを叩くだけです。

 それぞれのオプションは…

  • “-r”:再帰的にコピー。そうしないと、一番上段だけコピーされて意味が無い。
  • “-z”:圧縮をかける。exeが多いので意味があります。
  • “-h”:それっぽいログを出してくれるようになるので、ちょっとうれしくなります(ぇ
  • “-c”:チェックサムを取り、その結果を用いてコピーするかどうか判断します。
  • “–progress”:転送中の状態を表示します。
  • “–stat”:転送後に結果を表示します。
  • ” –chmod=a+rwx”:ファイル転送時にパーミッションを設定します。
    • これが一番重要です。転送時に、rsyncサーバが、デフォルトでは000でファイル・フォルダを作成してしまい、エラーが起きます。
  • “–delete”:ローカルで削除したファイルを、転送先にも反映させます。

 詳しくはこの辺参照。一番いいのは、それよりもお使いのrsyncの設定を見ることだと思いますが…。

 こんな感じです。特にこったところはありません。

ファイルから更新されたファイルを引き出す(pull)

call "%~dp0common.bat"
rsync -rzhc --progress --stats --delete %REPOS% %TARGET%
pause

 逆の事をしているだけです…。

ファイルが破壊されたかもしれない時用。

 私のノートパソコンは比較的クラッシュしやすい(どうしてだろう…)ので、そのための対策です。

call "%~dp0common.bat"
rsync -rzhc --progress --stats %REPOS% %TARGET%
pause

 –deleteをなくしただけです。こうすると、クライアント側には、クライアント側とサーバ側の和集合が残ります。

 この辺のノウハウはかなり無駄に貯めこんでるので、ちょっとずつ放出していけると良いかもしれませんね。

 みなさんも、リモート環境のノウハウが合ったら、ぜひ教えてくださいね。

 @ryoutenihamuさんに、common.batの存在しているフォルダのパスに空白が含まれている場合を忘れているとご指摘頂きました、ありがとうございます!また、WindowsNT系OSでは、.cmdがバッチファイルの標準拡張子だそうです…(どっちでも動くみたいですけど)。

  • †1: デザインが可愛くてかっこよくて、中々気に入っています。無くしがちなフタ部分もないし。