Dropboxをサーバ版Ubuntuでも見える様にSubversion使うよ

Dropbox はご存知無料で,Win でも Mac でも Linux でも使える同期ソフトです. フォルダ丸ごと Dropbox のサーバにレポジトリが管理されるみたいで, リビジョンまで記録されます.しかも,見た目はただのフォルダだから使いやすい. 裏で Daemon が動いてて勝手に同期してくれるみたいです.これにいろんな設定ファイル とかを突っ込んでシンボリックリンクさせれば,マジで簡単に環境を再現できそうで wktk しています.

しかーーーーし!現在の Linux 版では X がないとインストールできません>< Ubuntu Server 版はそんな生温いものは入っていない硬派なデストリなので どうにも困りました.どうも,Daemon は X 無くても動くっぽいので何とかならないかと がんばってみましたが,よくわからなくて挫折.

そこで僕は考えました.

「自分でレポジトリ作ってしまって.add/remove と commit と update を 1 分毎に cron で行えば,Dropbox っぽくなるんじゃねwwww ついでに Mac で動いてる Dropbox のディレクトリを同期すれば擬似的に Dropbox じゃんwwwww」

ハイ,あほですね.rsync というバックアップツールがあって,最初はこれで 同期しようかと思ったのですが,rsync はレポジトリなしの 1 対 1 の単純コピーです. 従って同期という用途ではちょっと使いにくいです.特にファイルを消したり するとわけわかんなくなります.てか,rsync で一度作りましたよ! でもマジ同期は無理>< rsync はバックアップツールとしては超優秀ですが 同期にはつらいです.

さぁというわけで,自宅の Ubuntu Server に Subversion でレポジトリを立てて, MacBook の Dropbox フォルダと自宅 Ubuntu Server の Dropbox フォルダ,さらに MacBook の VirtualBox 上の Ubuntu Server の Dropbox フォルダを同期させて しまいましょう!もちろん,GUI のあるマシンが増えたら,即 Dropbox を 入れればこれに混ざることができますし,更に期待するのは Dropbox が X 無しにも対応することですが,その時にもすぐ移行できますね!

というわけで,ほぼ初めて Subversion を触るのでした.

まずは SSH を公開鍵で入れる様にする

最終的に svn を ssh で行い,それを cron でまわすので毎回パスワードが 必要な状況では動きません.そこで,レポジトリを置くサーバへの SSH を 公開鍵方式にします.

公開鍵暗号って何?とか言う人はググレカスで無視して,さくっとやりましょう. とりあえず現状でクライアント(僕の場合 MacBook と VirtualBox の Ubuntu)からは パスワードで SSH をしているとします.

クライアントのターミナルで公開鍵と秘密鍵のペアを生成し,とりあえず SCP で サーバに送ってしまいます.鍵は~/.ssh に出来上がりますが生成の途中で パスフレーズを設定します.これを入力しないと鍵が機能しないので結局 パスワードとあんまり変わらない様に見えますが,あとでパスフレーズいらない 方法をやるのでとりあえずパスフレーズ設定しておきます.

$ ssh-keygen -t rsa
$ scp ~/.ssh/id_rsa.pub user@server:

SCP の時に聞かれるのは SSH のパスワードです.正しく入力できれば サーバのホームディレクトリに公開鍵が送れているはずです. (この辺は別に SCP で無くても FTP でも Samba でも何でもいいです. SCP の時は最後のコロンを忘れない様に w)

そうしたら,このクライアントの公開鍵をサーバに登録します.登録は サーバの~/.ssh/authorized_keys というファイルに鍵の中身をコピーするだけ. よくわからん人は下のコマンドで.

$ cat ~/id_rsa.pub >> ~/.ssh/authorized_keys
$ rm ~/id_rsa.pub

これをクライアントの数だけ繰り返します.登録できたら,改めて SSH してみて 下さい.すると,SSH のパスワードではなく,鍵のパスフレーズを聞かれます. まぁ見た目は似た様なもんですけどね w

続いて keychain を使ってパスフレーズ入力無しで SSH できる様にする

さて,先ほども書いた様にこのままでは結パスフレーズの手入力が 必要です.そこで keychain というプログラムを使ってこれを解消しましょう. 秘密鍵を持っていれば一応認証ということができるはずですからね.

とりあえず,クライアントに keychain を入れます.Ubuntu なら apt,Mac は GUI のキーチェーンはありますが,UNIX 用に MacPorts から入れます.(よく 分かんない人はバイナリ探すかググレカス)

Ubuntu
$ sudo apt-get install keychain
Mac
$ sudo port install keychain

こいつは何をやるかを少し説明.実はクライアントの Shell で ssh-agent という プロセスを立ち上げておいて秘密鍵を登録すると,その Shell が開いている間は秘密鍵の パスフレーズを管理してくれます,なので,実は keychain 無しでも同じ Shell の 中であれば最初の 1 回だけパスフレーズを入力すればよくて,2 回目以降は パスフレーズ無しで入れちゃいます.

しかし,ssh-agent は Shell 毎に別々だったり,ログアウトすると無くなったり色々 不便です.そこで,その ssh-agent を管理してくれるのが keychain というツールです. Shell の起動時に keychain を立ち上げると,ssh-agent が動いているかを チェックしてくれて,動いてなければ ssh-agent を起動してくれます. しかも,秘密鍵のパスフレーズとか環境変数とかも管理してくれるので, 一度でもパスフレーズを入力しておけば,以降はログアウトしようが何しようが パスフレーズなしの SSH が可能になります!

というわけで,とりあえず Shell の設定ファイルに keychain の設定を書いておきます. Shell の設定ファイルというのは,大抵は bash でしょうから~/.bashrc とかです. 僕は現在は Ubuntu は bash のままですが,Mac は MacPorts で入れた zsh にしていますので ~/.zshrc になります.(いずれはすべて zsh にするのだ><!)いずれにせよ 設定ファイルのお好きなところに以下を追加.

keychain ~/.ssh/id_rsa
source ~/.keychain/$HOST-sh #Macの場合
source ~/.keychain/$HOSTNAME-sh #Ubuntuの場合

ホストの名前はその設定ファイルの中を見たり,$ echo $HOST とかやってみて 入ってるかどうか確認して下さい.これで Shell を起動しなおせば, なんか keychain の起動を確認できると思います.\$ ps -e | grep ssh-agent とかしてみればちゃんと起動してることが分かると思います.

この状態で,先ほど公開鍵を登録したサーバに SSH してみれば多分パスフレーズ無しで いけるかな.もしかしたら 1 度聞かれるかも知れませんが,2 回目以降は パスフレーズ無しになるはず.Shell をログアウトしてもその状態が継続していることを 確認しておきましょう.

ちなみに keychain とか ssh-agent についてはココが完璧.Thx!

さて,次は Subversion だよ><

今までの部分は,Subversion を手動でやるなら必要ないのですが,cron で自動的に 行いたいので仕方ありません.まぁパスフレーズなしで SSH できるのは気持ちいい ものです.鍵とか PC とか紛失したらどうなるかは知りませんが>< それはともかく,本題の Subversion の方へ取りかかりましょう. 「ところで Subversion って何?」とか言う人はとりあえずググレ(ry

・・・Subversion はレポジトリという大元のソースにあたるものを 1 つ作っておき, ファイルを編集したりしたらそれをレポジトリに逐次登録して,次の時は まずレポジトリから DL してから使うという感じのバージョン管理ツールです. まぁ本来は多人数でのソフトウェア開発とかにバリバリつかうわけですが, 今回は Dropbox のサーバ代わりという哀れな,しかし酷な使い方をします.

まずはサーバ(僕の場合は自宅の Ubuntu)にレポジトリを作成します.

$ mkdir ~/svn/dropbox
$ svnadmin create ~/svn/dropbox

ハイ,おしまい.むっちゃ簡単.今はとりあえず Dropbox の方も空ということに しておきます.そうしたら,この空っぽのレポジトリから Dropbox と同期させる フォルダを作ってしまいます.まずはサーバから.これは別に SSH とか要らないので簡単.

$ svn checkout file:///home/user/svn/dropbox ~/Dropbox

これで晴れて Dropbox フォルダができました.ちなみに中は空っぽかと思いきや, バージョン管理のための.svn という隠しフォルダができていることが確認できます.

続いて,クライアントにも Dropbox フォルダを作りましょう.Mac にはすでに Dropbox を インストールしてアカウントを登録した状態だとします.標準なら~/Dropbox が 同期フォルダになっているので,ここにそのままレポジトリを展開しちゃいます.

$ svn checkout svn+ssh://user@server.address/home/user/svn/dropbox ~/Dropbox

ここで,レポジトリへのアクセスに SSH を利用しています.サーバのアドレスは 自宅サーバに設定しているドメイン名にしておくと,外出先からでも同期できるので いい感じだと思います.(なぜか Mac は LAN の中からでもドメイン名でアクセスできる) SSH は先ほどの設定でパスフレーズいらずにしてあるので,さくっと展開完了. 同じことを VirtualBox 上の Ubuntu からもやっておきました.

とりあえずこの状態で Subversion の基本操作をやっておきましょう.

ファイルを登録する

新しいファイルを作った場合,登録してあげないとバージョン管理に入りません. サーバ,クライアントいずれでも良いので,ファイルを追加してみます.

$ cd ~/Dropbox
$ echo aaaa > test.txt
$ svn add *

更新を確認する

直前のバージョンと現在にどういう違いがあるのかを一覧できます.

$ cd ~/Dropbox
$ svn status

更新をコミットする

ファイルを追加する,またはファイルを削除・編集するといった変更を加えたら, それをサーバ上のレポジトリにコミットしなければなりません.コミットすることで レポジトリのバージョンが 1 つ進みます.

$ cd ~/Dropbox
$ svn commit -m "message"

もしクライアントでやっている場合はこの時に裏では SSH されているのですが, keychain のお陰で何も意識する必要ありません.

レポジトリから更新する

現在の Dropbox よりレポジトリが新しい時にはそれを DL したりして反映しないと いけません.

$ cd ~/Dropbox
$ svn update

以上をさくっと Shell Script にまとめます

そして,ここで本番,cron でまわすためのスクリプトを書いてしまいましょう. 手順としてはこんな感じ.

  • ~/Dropbox に入る
  • svn status を元に,削除されたファイルを svn rm
  • svn status を元に,新しいファイルを svn add
  • svn status の結果を一時的にファイルに書き出し
  • svn commit で,先ほどのファイルをメッセージとして付けておく
  • svn update で最新にしておく

というわけで,ソースは以下.ただしこれは MacBook のやつ.Ubuntu の時は Shell のパスを変え,$HOSTを$HOSTNAME,xargs の引数に–no-run-if-empty を加えるようにします.

sync.sh

#!/opt/local/bin/zsh
keychain ~/.ssh/id_rsa
source ~/.keychain/$HOST-sh

svn_dir=~/Dropbox
msg=~/sync_svn.log

cd $svn_dir
svn st | grep "^\!"|cut -d ' ' -f 7|xargs svn rm
svn st | grep "^\?"|cut -d ' ' -f 7|xargs svn add
svn st > $msg
svn commit -F $msg --force-log
rm -f $msg
svn update

こいつを試しに実行してみます.その前に実行権限を付与し忘れないように. もし~/Dropbox が最新のものなら,バージョンが,変更点があれば コミットまでされて新しいバージョンが得られます.

$ chmod +x ~/sync.sh
$ ~/sync.sh

簡単ですね.これも keychain のおかげです.ちなみに Shell Script に もう一度 keychain を書いているのは,あとでこいつを cron で実行しますが, cron の Shell は起動が変なのでこちらで立ち上げてしまいます.Shell Scropt++

ちなみに,以下のページを参考にしています.Thx!

いよいよ,疑似 Dropbox スタートだ!

最後に先ほどの Script を cron で実行します.Plagger の時と同じ様に crontab に追加しましょう.

$ crontab -e

PATH=...
# m h  dom mon dow   command
*/1 * * * * /home/user/sync.sh > /dev/null 2>&1

これだけ!PATH の部分はターミナルの Shell で env した時の PATH を貼付けておきましょう. Mac も Ubuntu も PATH が違う程度でほとんど同じ.らくちんだ w

保存すると,1 分毎に~/Dropbox の中身がレポジトリと同期されます.もしも どこかの~/Dropbox で変更があると,1 分以内にそれが自宅サーバのレポジトリに 反映され,1 分以内にすべての~/Dropbox の中身が最新版に置き換わります!

もちろん,衝突とかなんも考えてないので,2 分以内に 2 つ以上の~/Dropbox を いじらないようにした方が良いかと思いますが,まぁ適当にやってください. 一応レポジトリにリビジョンが残るので,あとで復活させるとかもできるはず! これが rsync との違いだね!

また,MacBook の~/Dropbox は本家 Dropbox と同期されているので, これで X の無いマシンと Dropbox が擬似的に同期していることがわかると 思います.ただし,.svn フォルダが Dropbox に上がってしまうのが ちょっとうざいですが,今のところ Dropbox に除外の設定とかがないので 仕方ないです.もしくは,バージョン管理を git で行えばいいのかも知れないけど, もうそこまでの気力はありません><

ちなみに全般的に参考にしたのは以下のページ.SVN 簡単じゃん w!

あとがき

というわけで,サーバ版に Dropbox が入らないという憤怒から始まった長旅が やっと終わりました w これはあくまで下敷きで,本当にやりたいのは .zshrc とか.emacs とかを全マシンで自動同期することだったはずなのですが, 今回はこれでお腹一杯なので,もうちょっと先になりそう><

  • jbking 09-01-07 (水) 17:00

    どっか別ホストの X サーバに画面飛ばしちゃえばいいんでないですか?
    私の方はフォーラムで公開している DropBox デーモンだけをダウンロードして、セットアップウィザードは画面飛ばして、で使えてます。

  • riywo 09-01-07 (水) 17:20

    ありゃー,やっぱり使えてますか><

    試したんですが,どうもうまくいかなくて,というか
    知識が足りなくて.今度がんばってみます!

  • jjk 10-03-11 (木) 12:16

    大変参考になりました。
    cron でコミットがうまくいかず、ここを読んで解決しました。

    xargs ですが、このままだと手元の Ubuntu では空白入りのファイル名で
    正しく動作しませんでした。
    xargs -0 で解決しましたので、ご参考までに。