なんていうんでしょう、えーと。こんにちは。
mogwai超カッコいい。それより。
ソースの世代管理にバージョン管理システムを導入しました。
当初は普通にリモートサーバ(以降の呼称は開発サーバ)にリポジトリサーバ(以降の呼称はSVNサーバ)をインストールしようと思ったのですが、昔買った玄箱がほとんど働いていないので、この際そっちにいれることにしました。
うちでは開発サーバは本番サーバを兼ねているので(本当は開発兼本番サーバと言うべきかもしれないけど)外部公開していますが、玄箱は公開していません。閉じたネットワーク内でファイルサーバとして使っていましたが、今後もそのかたちは変えたくありません。
ところが、今回の開発は僕以外に外部の共同開発者も開発に参加しているため、外側からもSVNサーバにアクセスできるようにしなければなりません。
相関図にするとこうなります。
図の右下の「管理者」が僕です。リレーションが薄くひいてあるのは外部非公開の意味で、外からは「管理者」のPCと「SVNサーバ」はアクセスできないようになっています。
外部の開発者がいなければ「管理者」が直接プライベートネットワーク内の「SVNサーバ」にアクセスすれば事足りるのですが、このままだと「外部開発者A」と「外部開発者B」が「SVNサーバ」にアクセスできません。
じゃあ「SVNサーバ」を公開しよう、というのはなしです。「SVNサーバ」を玄箱に置かずにやっぱり「開発」サーバに置こう、というのの100場合くらいない話です。
なので、「SVNサーバ」は引き続き外部非公開のまま、公開済の「開発サーバ」を踏み台にして、「SVNサーバ」を使用できるように構築します。
経路にするとこうなります。
では以下その手順です。
■前提条件
管理者のアカウント名は「inner」とする。すでに作成済
外部開発者のアカウント名は「outer」とする。未作成
開発サーバのホスト名は「devel」
SVNサーバのホスト名は「svn」
■SVNサーバの構築
・概要
SVNサーバにはSubversionをインストール
Subversionは開発サーバのTrac「redmine」からHTTPアクセスできるようにするため、apacheもインストール
Subversion操作ユーザのアカウント名は「repos」
SVNプロジェクトは「project」
・手順
apache操作ユーザの作成
inner@svn:~$ sudo /usr/sbin/groupadd -g 500 www inner@svn:~$ sudo /usr/sbin/useradd -g www -s /sbin/nologin apache inner@svn:~$ sudo /usr/bin/passwd -d apache
apacheのインストール
inner@svn:~$ sudo apt-get install apache2 inner@svn:~$ sudo vi /etc/apache2/apache2.conf # ↓追加 ServerName svn:80 inner@svn:~$ sudo vi /etc/apache2/envvars # ↓変更 export APACHE_RUN_USER=apache export APACHE_RUN_GROUP=www inner@svn:~$ sudo /etc/init.d/apache2 restart # apache操作ユーザで起動していることを確認 inner@svn:~$ ps aux | grep apache | grep -v grep # HTTPステータスコード200が返ることを確認 inner@svn:~$ wget http://localhost -O -
SSHの鍵認証と許可ユーザの設定
inner@svn:~$ sudo vi /etc/ssh/sshd_config # ↓変更 PermitRootLogin no PermitEmptyPasswords no PasswordAuthentication no # ↓追加 AllowUsers inner repos inner@svn:~$ sudo /etc/init.d/ssh reload
Subversionのインストール(SVN用のapacheモジュールもインストール)
inner@svn:~$ sudo apt-get install subversion inner@svn:~$ sudo apt-get install subversion-devel inner@svn:~$ sudo apt-get install subversion-tools inner@svn:~$ sudo apt-get install subversion-mod_dav_svn inner@svn:~$ sudo apt-get install libapache2-svn # dav_svnがapacheモジュール配下に置かれているか確認 inner@svn:~$ ll /usr/lib/apache2/modules | grep dav inner@svn:~$ find /etc/apache2/ -name dav_svn.conf # 置かれていなかったのでシンボリックリンクで回避 inner@svn:~$ sudo ln -s /usr/lib/apache2/modules /etc/apache2/modules inner@svn:~$ sudo vi /etc/apache2/mods-enabled/dav_svn.conf # ↓追加 <Location /repos> DAV svn SVNPath /usr/local/repos/ </Location> inner@svn:~$ sudo /etc/init.d/apache2 reload
Subversion操作ユーザの作成
inner@svn:~$ sudo /usr/sbin/useradd -g www -d /home/repos -m repos inner@svn:~$ sudo /usr/bin/passwd -d repos
リポジトリの作成
inner@svn:~$ sudo -u apache mkdir /usr/local/repos inner@svn:~$ sudo chmod 0775 /usr/local/repos inner@svn:~$ sudo -u repos svnadmin create /usr/local/repos inner@svn:~$ ll /usr/local/repos
Subversion操作ユーザによる動作確認
inner@svn:~$ svn mkdir file:///usr/local/repos/project -m "create project" inner@svn:~$ svn mkdir file:///usr/local/repos/project/trunk -m "create trunk" inner@svn:~$ svn mkdir file:///usr/local/repos/project/tags -m "create tags" inner@svn:~$ svn mkdir file:///usr/local/repos/project/branches -m "create branches" inner@svn:~$ svn list file:///usr/local/repos/project/branches inner@svn:~$ svn list http://svn/repos/project/trunk
■外部開発者のアカウント用意
・概要
鍵はSSH-2 RSA形式。管理者PCのPuTTYで事前に作って、秘密鍵だけ開発サーバにアップしておく
操作は開発サーバ「devel」でおこなう (途中からSVNサーバに乗り換えます)
・手順
外部開発者用のユーザ作成
# 外部開発者×nはすべてグループ「mate」に属する。パスワードは適当に。いずれも省略。
[inner@devel~]$ sudo /usr/sbin/useradd -g mate -d /home/outer -m outer [inner@devel~]$ sudo /usr/bin/passwd outer [inner@devel~]$ sudo mkdir /home/outer/.ssh [inner@devel~]$ sudo mv ~/id_rsa.pub /home/outer/.ssh/authorized_keys [inner@devel~]$ sudo chown -R outer:mate /home/outer/.ssh [inner@devel~]$ sudo chmod 0700 /home/outer/.ssh [inner@devel~]$ sudo chmod 0600 /home/outer/.ssh/authorized_keys
管理者PCからouterユーザで、PuTTYの鍵認証でログインできることを確認しておく(略)
開発サーバからSVNサーバに、SSH鍵認証でログインできるようにする
[inner@devel~]$ sudo scp -p /home/outer/.ssh/authorized_keys svn:~/ [inner@devel~]$ ssh -A svn inner@svn:~$ sudo mkdir /home/repos/.ssh # 管理者の公開鍵をSubversion操作ユーザに渡しておく inner@svn:~$ sudo cp -p ~/.ssh/authorized_keys /home/repos/.ssh/authorized_keys # 外部開発者の公開鍵をSubversion操作ユーザに渡しておく inner@svn:~$ sudo mv ~/authorized_keys /home/repos/.ssh/authorized_keys2 inner@svn:~$ sudo chown -R repos:www /home/repos/.ssh inner@svn:~$ sudo chmod 0700 /home/repos/.ssh inner@svn:~$ sudo chmod 0600 /home/repos/.ssh/authorized_keys* inner@svn:~$ sudo -u repos mkdir /home/repos/workspace
ログインできることの確認(SVN操作の確認も)
inner@svn:~$ exit [inner@devel~]$ ssh -A repos@svn repos@svn:~$ exit [inner@devel~]$ sudo -u outer ssh -A repos@svn repos@svn:~$ cd workspace repos@svn:~/workspace$ svn co file:///usr/local/repos/project/trunk . repos@svn:~/workspace$ vi test.txt repos@svn:~/workspace$ svn add test.txt repos@svn:~/workspace$ svn commit -m "test" repos@svn:~/workspace$ exit
本当は、外部開発者はjailkitでホームDIR配下に閉じ込めて、使用できるコマンドもsshとsvnとその他適当なコマンドに制限させたかったのですが、ログイン後のsshがどうしても利用できるようにできず、断念しました。
詳細は省きますが、今後の課題として残りました。
■開発サーバにSVNクライアントをインストール
・概要
SVNクライアントにはSubversionを利用
開発サーバのTrac「redmine」がSVNサーバのリポジトリにHTTP経由でアクセスするための設定
なお、HTTP経由となっていますが、開発サーバがHTTPでアクセスするのはサーバサイドなので、開発サーバからSVNサーバの80番ポートがプライベートネットワーク内で見えていれば、SVNサーバは引き続き外部非公開で問題ありません(特にTracアプリケーションを使わなければ必要ないと思います)。
・手順
SVNクライアントをインストール
[inner@devel~]$ cd /usr/local/src [inner@devel~/src]$ wget http://subversion.tigris.org/downloads/subversion-1.6.13.tar.gz [inner@devel~/src]$ tar zxvf subversion-1.6.13.tar.gz [inner@devel~/src]$ wget http://subversion.tigris.org/downloads/subversion-deps-1.6.13.tar.gz [inner@devel~/src]$ tar zxvf subversion-deps-1.6.13.tar.gz [inner@devel~/src]$ cd subversion-1.6.13 # SVNクライアントのみインストールします [inner@devel~/subversion-1.6.13]$ ./configure --without-berkeley-db --without-apxs \ [inner@devel~/subversion-1.6.13]$ --without-swig --without-serf --with-ssl [inner@devel~/subversion-1.6.13]$ make [inner@devel~/subversion-1.6.13]$ sudo make install [inner@devel~/subversion-1.6.13]$ cd ~/ [inner@devel~]$ svn list http://svn/repos/project
■クライアントPCにSVNクライアントをインストール
・概要
SVNクライアントにはTortoiseSVNを利用
クライアントPCはWindowsVISTA
・手順
TortoiseSVNのインストール
http://www.gside.org/Gentoo/subversion/subversion_client.html
上記の手順を元に以下をインストールしました
http://sourceforge.net/projects/tortoisesvn/files/Application/1.6.11/TortoiseSVN-1.6.11.20210-win32-svn-1.6.13.msi/download
http://sourceforge.net/projects/tortoisesvn/files/Language%20Packs/1.6.11/LanguagePack_1.6.11.20210-win32-ja.msi/download
■クライアントPCから開発サーバ経由でSVNサーバにアクセス
・概要
PuTTY(ごった煮版)はインストール済
トンネルに利用するポートは20022とする
手順では開発者アカウント「outer」を設定(管理者「inner」は省略)
・手順
まず、開発サーバのSSHログイン設定をおこないます。
putty.exeをダブルクリック、「PuTTY設定」を以下のように設定
セッション
ホスト名:devel ポート:22 接続タイプ:SSH セッション一覧:任意の名前(例:devel)
接続=>データ
自動ログインのユーザ名:outer
SSH=>認証
Pagentを使って認証する:チェックをいれる "keybord-interactive"認証を試みる:チェックをいれる エージェントフォワーディングを認める:チェックをいれる
SSH=>トンネル
源ポート:20022 送り先:svn ローカル:チェックをいれる 「追加」ボタンを押して、フォワードするポート一覧に「L20022 svn:22」と追加
セッションの項目に戻って「保存」ボタンを押します。
「開く」ボタンを押してログイン(パスワード認証ダイアログが出たら、鍵生成時のパスフレーズを入力)。
ログインできたら、開いたターミナルはそのままにしておきます。
次にSVNのSSHログイン設定をおこないます。
上記のトンネル経由でログインできるようにします。
putty.exeをダブルクリック、「PuTTY設定」を以下のように設定
セッション
ホスト名:localhost ポート:20022 接続タイプ:SSH セッション一覧:任意の名前(例:svn)
接続=>データ
自動ログインのユーザ名:repos
SSH=>認証
Pagentを使って認証する:チェックをいれる
セッションの項目に戻って「保存」ボタンを押します。
「開く」ボタンを押してログイン(パスワード認証ダイアログが出たら、鍵生成時のパスフレーズを入力)。
ログインできたら成功です。
TortoiseSVNの設定
適当な「作業フォルダ」の下で右クリックしてコンテキストメニューを開き、TortoiseSVN→「ここにリポジトリを作成」を選択します。
再び右クリックからTortoiseSVN→「設定」で、「一般」欄の「編集」ボタンを押下。設定ファイルがテキストで開くので、
[tunnels]
testssh(SVNトンネル用の適当なスキーマ名) = “<PuTTYのインストール先フォルダのパス>/plink.exe” -agent -load svn(PuTTYのセッション名) -i “<秘密鍵を保存したフォルダのパス>/id_rsa.ppk”
として保存。
例) testssh = “E:/tools/PuTTY/plinkw.exe” -agent -load svn -i “E:/tools/PuTTY/outer/id_rsa.ppk”
再び右クリックからTortoiseSVN→「SVNチェックアウト」で、
リポジトリのURL:svn+testssh:///usr/local/repos/project/trunk
チェックアウトDIR:<作業フォルダのパス>\project
として「OK」押下。これでチェックアウト完了です。
失敗する場合は設定ファイルを
[tunnels]
donassh(SVNトンネル用の適当なスキーマ名) = “<PuTTYのインストール先フォルダのパス>/plinkw.exe” -v -agent -load svn(PuTTYのセッション名) -i “<id_rsa.ppkを保存したフォルダのパス>/id_rsa.ppk”
として、再び「SVNチェックアウト」をおこないます。plinkw.exeはplink.exeのGUI版で、-v(verbose)をつけることでデバグコンソールから内容を確認できます。
これですべての設定が完了です。
外部開発者にアカウント名とパスワード、秘密鍵とパスフレーズを渡して、PuTTYとTortoiseSVNの設定をしてもらえば今回の用件を満たした開発がおこなえます。
■補足
ちなみにTrac「redmine」を使うと上で書きましたが、ついでにredmine側の設定で、SVN連携に必要な部分も書いておきます。
・開発サーバのredmineURL
設定=>リポジトリ
バージョン管理システム:Subversion
URL:http://svn/repos/project
として保存。プロジェクトの「リポジトリ」をクリックすると「リポジトリに、エントリ/リビジョンが存在しません」となる場合は開発サーバのSVNコマンドのパスがredmineに見えてないことが多いようなので、以下を修正
[inner@devel redmine]$ which svn /usr/local/bin/svn [inner@devel redmine]$ vi scm/adapters/subversion_adapter.rb #SVN_BIN = "svn" SVN_BIN = "/usr/local/bin/svn"
ついでにruby ver1.9.1でredmine ver1.0.3を動かす場合は以下を修正
[inner@devel redmine]$ vi vendor/rails/actionpack/lib/action_controller/request.rb #value.each { |k, v|h[k] = normalize_parameters(v) } value.each { |k, v| v.force_encoding("UTF-8") if v.class==String h[k] = normalize_parameters(v) }