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で解決しましたので、ご参考までに。