mongrelを起動するユーザー

個人プロジェクトなら自分のアカウントでmongrelを動かせばいいんだけど、チームでとなるとそれはやらない方がいいので、mongrelを動かすプロジェクトで共通のアカウントを作ります。

$ sudo -m -p "" bar
$ su - bar
$ passwd

で適切なパスワードを設定します。
で、後々capistranoでこのユーザーでログインして、svnからコードをチェックアウトするんですけど、このユーザーでログインするなら svn+sshではなく、fileでリポジトリにアクセスすりゃいいかなと。
なので、とりあえず、capistranoでアクセスする際に必要なSSH用のキーを生成します。

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/bar/.ssh/id_rsa): 
Created directory '/home/bar/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/bar/.ssh/id_rsa.
Your public key has been saved in /home/bar/.ssh/id_rsa.pub.
The key fingerprint is:
78:e3:72:d3:63:4a:8f:10:0d:d9:1d:4e:68:15:3b:dc bar@bar.org
$
$ cat .ssh/id_rsa.pub > ~/.ssh/authorized_keys
$ chmod go-rw .ssh/authorized_keys

で、もうSCPでコピーするのも面倒なので、catで表示した内容をコピペして、ローカルに持ってくる。

$ cat .ssh/id_rsa
$ cat .ssh/id_rsa.pub

で表示させた内容を、ローカルのターミナルで

$ vi ~/.ssh/bar_id_rsa
$ vi ~/.ssh/bar_id_rsa.pub

でそれぞれ貼付ける。
んで、chmodしておきましょう。

$ chmod go-rw ~/.ssh/bar_id_rsa*

で、それを使ってアクセスしてみる。

$ ssh-agent bash
$ ssh-add ~/.ssh/bar_id_rsa
$ ssh bar@xxx.xxx.xxx.xxx

でログインできればオッケー。

あ、svnにアクセスするために、グループに追加しておかないとね。

# usermod -a -G svn bar

で、再度barでログインして、svn infoとかが成功すればオッケーだと思われ。

$ svn info file:///var/svn/baz-repo/trunk

capistranoでの初めてのアクセス

デプロイ用のユーザーもできたので、railsのプロジェクトをcapifyして接続をテストします。

$ cd /path/to/rails/project
$ capify .

で、config/deploy.rb が作られているはずなので、それをこんな感じにします。

# -*- coding: utf-8 -*-
require 'mongrel_cluster/recipes'

set :application, "bar"
set :repository,  "file:///var/svn/baz-repo/trunk"
set :user, "bar"
set :use_sudo, false

set :scm, :subversion
set :deploy_via, :remote_cache
set :deploy_to, '/home/bar/capistrano/bar'

role :app, "ホスト名"
role :web, "ホスト名"
role :db,  "ホスト名", :primary => true

desc "接続テスト用のタスク"
task :hello, :roles => [:app, :web, :db] do
  run "echo HelloWorld! $HOSTNAME"
end

ssh-agentあついは、SSHKeychianとか、pagentとかに bar_id_rsaを追加してあげたら、おもむろに、

$ cap hello

とか実行してみましょう。こんな結果になるはずです。

$ cap hello
  * executing `hello'
  * executing "echo HelloWorld! $HOSTNAME"
    servers: ["ホスト名"]
    [ホスト名] executing command
 ** [out :: ホスト名] HelloWorld! ホスト名
    command finished
$

sqlite3用の設定

今回はSQlite3をつかうアプリなので、以下の記述を config/deploy.rb に追加します。

# config/database.ymlはsvnにコミットしません。
# ですので、サーバー側のshared以下にdatabase.yamlを保持するディレクトリを作成し、
# デプロイ時に config/database.yml はそのdatabase.ymlへのsymlinkとして作成します。
#
# また、本プロジェクトではDBにSQLite3を使います。
# production.sqlite3は shared以下にないといけないので、
# cap deploy:setupで自動的に作られるようにsetup後に呼び出す
# shared/dbを作るタスクを作成し、afterで登録します。
namespace :db do
  desc "setup directories for database"
  task :setup_shared_db_dirs do
    run "mkdir -p #{shared_path}/config #{shared_path}/db"
  end

  desc "Make symlink for shared/config/database.yml" 
  task :symlink do
    run "ln -nfs #{shared_path}/config/database.yml #{release_path}/config/database.yml" 
  end
end
after "deploy:setup", "db:setup_shared_db_dirs"
after "deploy:update_code", "db:symlink"

んで、ローカルでcap deploy:setupを実行

$ cap deploy:setup
  * executing `deploy:setup'
  * executing "mkdir -p /home/bar/capistrano/bar /home/bar/capistrano/bar/releases /home/bar/capistrano/bar/shared /home/bar/capistrano/bar/shared/system /home/bar/capistrano/bar/shared/log /home/bar/capistrano/bar/shared/pids &&  chmod g+w /home/bar/capistrano/bar /home/bar/capistrano/bar/releases /home/bar/capistrano/bar/shared /home/bar/capistrano/bar/shared/system /home/bar/capistrano/bar/shared/log /home/bar/capistrano/bar/shared/pids"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
    triggering after callbacks for `deploy:setup'
  * executing `db:setup_shared_db_dirs'
  * executing "mkdir -p /home/bar/capistrano/bar/shared/config /home/bar/capistrano/bar/shared/db"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished

こんな感じになると思います。
ちゃんとディレクトリが作られているのか確認してみましょう。
sshで普通に繋げてもいいのですが、cap shellというのがあるのでちょっとしたコマンドを実行するときは便利です。

$ cap shell
  * executing `shell'
====================================================================
Welcome to the interactive Capistrano shell! This is an experimental
feature, and is liable to change in future releases. Type 'help' for
a summary of how to use the shell.
--------------------------------------------------------------------
cap> pwd
[establishing connection(s) to ホスト名]
 ** [out :: ホスト名] /home/bar
cap> find ~/capistrano
 ** [out :: ホスト名] /home/bar/capistrano
 ** [out :: ホスト名] /home/bar/capistrano/bar
 ** [out :: ホスト名] /home/bar/capistrano/bar/releases
 ** [out :: ホスト名] /home/bar/capistrano/bar/shared
 ** [out :: ホスト名] /home/bar/capistrano/bar/shared/system
 ** [out :: ホスト名] /home/bar/capistrano/bar/shared/log
 ** [out :: ホスト名] /home/bar/capistrano/bar/shared/pids
 ** [out :: ホスト名] /home/bar/capistrano/bar/shared/config
 ** [out :: ホスト名] /home/bar/capistrano/bar/shared/db
cap> quit
exiting

ちゃんとセットアップできたようなので、shared/config/database.ymlを作成しましょう。
こんどはちゃんとSSHでログインして、/home/bar/capistrano/bar/shared/config/database.ymlを以下のように作成します。

common: &common
  adapter: sqlite3
  pool: 5
  timeout: 5000

development:
  database: /home/bar/capistrano/bar/shared/db/development.sqlite3
  <<: *common

test:
  database: /home/bar/capistrano/bar/shared/db/test.sqlite3
  <<: *common

production:
  database: /home/bar/capistrano/bar/shared/db/production.sqlite3
  <<: *common

で、これでいざデプロイしてみましょう。

リモートでsvn infoする設定

$ cap deploy:update
  * executing `deploy:update'
 ** transaction: start
  * executing `deploy:update_code'
    updating the cached checkout on all servers
    executing locally: "svn info file:///var/svn/bar-repo/trunk  -rHEAD"
svn: Unable to open an ra_local session to URL
svn: Unable to open repository 'file:///var/svn/bar-repo/trunk'
*** [deploy:update_code] rolling back
  * executing "rm -rf /home/bar/capistrano/bar/releases/20090411164633; true"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
/opt/local/lib/ruby/gems/1.8/gems/capistrano-2.5.3/lib/capistrano/recipes/deploy/scm/subversion.rb:58:in `query_revision': tried to run `svn info file:///var/svn/bar-repo/trunk  -rHEAD' and got unexpected result "" (RuntimeError)
	from /opt/local/lib/ruby/gems/1.8/gems/capistrano-2.5.3/lib/capistrano/recipes/deploy/scm/base.rb:35:in `send'
	from /opt/local/lib/ruby/gems/1.8/gems/capistrano-2.5.3/lib/capistrano/recipes/deploy/scm/base.rb:35:in `method_missing'
(以下略)

失敗してしまいました。これは、リビジョンを取得するのに実行するsvn infoをローカルのPCで実行したためです。通常はそれでいいと思うのですが、今回はリポジトリも同じサーバーなので、この辺の処理を書き換えてしまいましょう。

リビジョンを取得する処理は、gems/capistrano-2.5.3/lib/capistrano/recipes/deploy.rb の 以下の部分で記述されています。

_cset(:real_revision)     { source.local.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run_locally(cmd) } } }

これをローカルじゃなくてリモートで実行したい訳です。なので、安直に

set(:real_revision)     { source.query_revision(revision) { |cmd| with_env("LC_ALL", "C") { run(cmd) } } }

とするとエラーになります。これは、run_locallyメソッドが返していたsvn infoの結果をrunメソッドは返さないからです。なので、ちょっとややこしいですが以下のようにします。

# バージョンを取得するsvn infoコマンドは通常run_locallyで実行されますが、
# 今回はログインしたサーバーで取得したいので、デフォルトの設定を変更します。
set(:real_revision) do
  source.query_revision(revision) do |cmd| 
    result = nil
    with_env("LC_ALL", "C") { run(cmd){|conn, out, res| result = res} } 
    result
  end
end

これで正しくリビジョンが取得できるようになりました。再度 svn deploy:update してみましょう。

$ cap deploy:update
  * executing `deploy:update'
 ** transaction: start
  * executing `deploy:update_code'
    updating the cached checkout on all servers
  * executing "svn info file:///var/svn/bar-repo/trunk  -rHEAD"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
  * executing "if [ -d /home/bar/capistrano/bar/shared/cached-copy ]; then svn update -q  -r17 /home/bar/capistrano/bar/shared/cached-copy; else svn checkout -q  -r17 file:///var/svn/bar-repo/trunk /home/bar/capistrano/bar/shared/cached-copy; fi"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
    copying the cached version to /home/bar/capistrano/bar/releases/20090411171455
  * executing "cp -RPp /home/bar/capistrano/bar/shared/cached-copy /home/bar/capistrano/bar/releases/20090411171455 && (echo 17 > /home/bar/capistrano/bar/releases/20090411171455/REVISION)"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
  * executing `deploy:finalize_update'
  * executing "chmod -R g+w /home/bar/capistrano/bar/releases/20090411171455"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
  * executing "rm -rf /home/bar/capistrano/bar/releases/20090411171455/log /home/bar/capistrano/bar/releases/20090411171455/public/system /home/bar/capistrano/bar/releases/20090411171455/tmp/pids &&\\\n      mkdir -p /home/bar/capistrano/bar/releases/20090411171455/public &&\\\n      mkdir -p /home/bar/capistrano/bar/releases/20090411171455/tmp &&\\\n      ln -s /home/bar/capistrano/bar/shared/log /home/bar/capistrano/bar/releases/20090411171455/log &&\\\n      ln -s /home/bar/capistrano/bar/shared/system /home/bar/capistrano/bar/releases/20090411171455/public/system &&\\\n      ln -s /home/bar/capistrano/bar/shared/pids /home/bar/capistrano/bar/releases/20090411171455/tmp/pids"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
  * executing "find /home/bar/capistrano/bar/releases/20090411171455/public/images /home/bar/capistrano/bar/releases/20090411171455/public/stylesheets /home/bar/capistrano/bar/releases/20090411171455/public/javascripts -exec touch -t 200904111714.56 {} ';'; true"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
    triggering after callbacks for `deploy:update_code'
  * executing `db:symlink'
  * executing "ln -nfs /home/bar/capistrano/bar/shared/config/database.yml /home/bar/capistrano/bar/releases/20090411171455/config/database.yml"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
  * executing `deploy:symlink'
  * executing "rm -f /home/bar/capistrano/bar/current && ln -s /home/bar/capistrano/bar/releases/20090411171455 /home/bar/capistrano/bar/current"
    servers: ["ホスト名"]
    [ホスト名] executing command
    command finished
 ** transaction: commit

おおーできたっぽい。さっそく確認ー。

$ cap shell
  * executing `shell'
====================================================================
Welcome to the interactive Capistrano shell! This is an experimental
feature, and is liable to change in future releases. Type 'help' for
a summary of how to use the shell.
--------------------------------------------------------------------
cap> ls -la ~/capistrano/bar/releases/
[establishing connection(s) to ホスト名]
 ** [out :: ホスト名] total 12
 ** [out :: ホスト名] drwxrwxr-x  3 bar bar 4096 Apr 12 02:18 .
 ** [out :: ホスト名] drwxrwxr-x  4 bar bar 4096 Apr 12 02:18 ..
 ** [out :: ホスト名] drwxrwxr-x 16 bar bar 4096 Apr 12 02:18 20090411171819

うひょー!ばっちりー!


ではSSHでログインして、確認してみましょう。

$ cd ~/capistrano/bar/current
$ ruby script/console
>> ActiveRecord::Base.connection.tables
MissingSourceFile: no such file to load -- sqlite3
	from /usr/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:31:in `gem_original_require'
(以下略)

あ、sqlite3-rubyを入れてなかった。

sqlite3-rubyのインストール

# gem install sqlite3-ruby
Building native extensions.  This could take a while...
ERROR:  Error installing sqlite3-ruby:
	ERROR: Failed to build gem native extension.

/usr/bin/ruby extconf.rb install sqlite3-ruby
checking for fdatasync() in -lrt... yes
checking for sqlite3.h... yes
checking for sqlite3_open() in -lsqlite3... no

make
make: *** No rule to make target `ruby.h', needed by `sqlite3_api_wrap.o'.  Stop.


Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/sqlite3-ruby-1.2.4/ext/sqlite3_api/gem_make.out
#

これはよくあるパターン。-develが入ってないっぽい。
調べてみると、sqlite-develが入っていないっぽい。

# yum list sqlite3
(中略)
=================================================================== Matched: sqlite3 ====================================================================
sqlite-devel.i386 : Development tools for the sqlite3 embeddable SQL database engine.
sqlite-devel.x86_64 : Development tools for the sqlite3 embeddable SQL database engine.
# 

早速インストール。

# yum install sqlite-devel

で、sqlite3-rubyもインストール

# gem install sqlite3-ruby

ばっちり!
もう一回試してみる。

$ ruby script/console
>> ActiveRecord::Base.connection.tables
=> []
>> exit

おっけー!DBに接続できた!

では、こんどはちゃんとcapistranoマイグレーションしてみましょう。

$ cap deploy:migrate 

成功すれば、マイグレーションの結果が出力されるはずです。

おっけー!では、サーバーを起動してみましょう

$ cap deploy:start
  * executing `deploy:start'
  * executing `mongrel:cluster:start'
  * executing "mongrel_rails cluster::start -C /etc/mongrel_cluster/bar.yml"
    servers: ["ホスト名"]
    [ホスト名] executing command
*** [err :: ホスト名] !!! Configuration file does not exist. Run mongrel_rails cluster::configure.
*** [err :: ホスト名] 
*** [err :: ホスト名] cluster::start reported an error. Use mongrel_rails cluster::start -h to get help.
*** [err :: ホスト名] 
    command finished
failed: "sh -c \"mongrel_rails cluster::start -C /etc/mongrel_cluster/bar.yml\"" on ホスト名

ああ、mongrel_clusterの設定をしてなかったっすね。

mongrel_clusterの設定

mongrel_clusterの設定をやっちゃいましょう。
ローカルのRAILS_ROOTで

$ mongrel_rails cluster::configure -e production -p 8000 -N 3 -c /home/bar/capistrano/bar/current --user bar --group bar

を実行すると、config/mongel_cluster.yml ができるので、コミットしてsvnに反映させます。で、サーバーに反映させます。

$ cap deploy:update

サーバーにSSHでログインして、以下の処理を行います。

$ sudo mkdir /etc/mongrel_cluster
$ sudo ln -s /home/bar/capistrano/bar/current/config/mongrel_cluster.yml /etc/mongrel_cluster/bar.yml

これは後々自動起動用に使うから/etcの下に置いています。詳しくは http://mongrel.rubyforge.org/wiki/MongrelCluster を参照してください。

で改めて、起動

$ cap deploy:start
  * executing `deploy:start'
  * executing `mongrel:cluster:start'
  * executing "mongrel_rails cluster::start -C /etc/mongrel_cluster/bar.yml"
    servers: ["bar.com"]
    [bar.com] executing command
 ** [out :: bar.com] starting port 8000
 ** [out :: bar.com] starting port 8001
 ** [out :: bar.com] starting port 8002
    command finished

まだapacheの設定をしていないので、SSHでログインして、

$ wget http://localhost:8000

でindex.htmlができていれば成功です。

$ ps aux | grep ruby

あと、プロセスが起動していることを確認してください。

明日はapacheの設定をやります。

覚え書き

# rake gems:install 

でconfig/environment.rbに記述してあるgemが入るはずなんですが、
同時もうまく行きませんでした。# gem sources -a http://gems.github.com もしてあるのに。
仕方ないので、手動で以下のgemをインストールしました。

# gem install mislav-will_paginate kakutani-yaml_waml rspec rspec-rails mongrel mongrel_cluster sqlite3-ruby 

パスワード認証から公開鍵認証へ

いつもいきなり設定を変えてしまったーとか思うんで、ちゃんと記録しておきます。

sshdを再起動しても接続がキープできることを確認

切れることはないと思うんだけど、sshdの設定を間違えて誰もログインできない状態になることをまず避けるために、sshでログインした状態で

$ sudo /etc/init.d/sshd restart
Stopping sshd:                                             [  OK  ]
Starting sshd:                                             [  OK  ]
$

で接続が切れないことを確認する。ここで切れたら、一か八かの設定しかできなくなっちゃう。確認しておけばひと安心。

RSAの鍵を生成

アクセスするための鍵がある場合はいいんだけど、サーバー毎に分けておきたい場合もあります。その時は作っておきましょう。

$ ssh-keygen -t rsa
Generating public/private rsa key pair.
Enter file in which to save the key (/home/foo/.ssh/id_rsa): /home/foo/.ssh/foo_bar_id_rsa
Created directory '/home/foo/.ssh'.
Enter passphrase (empty for no passphrase): 
Enter same passphrase again: 
Your identification has been saved in /home/foo/.ssh/foo_bar_id_rsa.
Your public key has been saved in /home/foo/.ssh/foo_bar_id_rsa.pub.
The key fingerprint is:
24:2b:11:37:f7:6d:92:58:40:ce:7f:8e:56:9b:fa:2d foo@bar.org
$ 
$ ls -la ~/.ssh

で、~/.sshに鍵が作られているのを確認。で、authrolized_keysに追加

$ cat .ssh/foo_bar_id_rsa.pub > ~/.ssh/authorized_keys

~/.ssh/authorized_keys が他のユーザーも読めちゃうをちゃんと動いてくれないので、chmodしておきます。

$ chmod go-rw ~/.ssh/authorized_keys


で、実際ににログインするクライアントのPCに鍵をscpでコピー。これはサーバー側ではなくて、クライアントの別のターミナルで実行します。

$ scp foo@xxx.xxx.xxx.xxx:~/.ssh/foo_bar_id_rsa* ~/.ssh/
$ ls -la ~/.ssh

でコピーできていることを確認。

sshdの設定

/etc/init.d/ssh/sshd_config を以下のように設定して、パスワード認証をやめて、RSAの認証を有効にします。ルートでのログインもできないようにして、PAMを使わないようにします。

PermitRootLogin no
(中略)
RSAAuthentication yes
PubkeyAuthentication yes
AuthorizedKeysFile      .ssh/authorized_keys
(中略)
PasswordAuthentication no
(中略)
ChallengeResponseAuthentication no
(中略)
UsePAM no

保存したら

$ sudo /etc/init.d/sshd restart

再起動したら、クライアントの別のターミナルで、接続してみます。

$ ssh -i ~/.ssh/foo_bar_id_rsa foo@xxx.xxx.xxx.xxx

ちゃんと設定できていれば、これでいけるはず。
もしダメだったら、

$ sudo tail -f /var/log/secure

とかして、ログを見てみてください。~/.ssh/authorized_keysをchmodしてないと

Apr 11 15:59:19 bar sshd[15908]: Authentication refused: bad ownership or modes for file /home/foo/.ssh/authorized_keys

とか出ました。

svn+sshの設定

公開鍵認証も設定したので、開発するにはやっぱりSubversionがほしいので、svn+sshでアクセスできるように設定します。
まずはインストールと確認

$ sudo yum install subversion
$ svn --version

次は、http://wiki.mmj.jp/index.php?Service%2FSubversion#c2d14f3c を参考に設定していきます。
まずsvnユーザーを作成

# mkdir /var/svn
# groupadd svn
# useradd -g svn -d /var/svn svn
useradd: warning: the home directory already exists.
Not copying any file from skel directory into it.
# chown svn:svn /var/svn
# ls -la /var/svn/
total 8
drwxr-xr-x  2 svn  svn  4096 Apr 11 16:59 .
drwxr-xr-x 22 root root 4096 Apr 11 16:59 ..

次にsvnリポジトリにアクセスするユーザーをグループに追加してコミットできるようにします。

usermod -a -G svn foo

リポジトリを作成します。

# su svn
$ svnadmin create /var/svn/baz-repo
$ ls -la /var/svn/
total 12
drwxr-xr-x  3 svn  svn  4096 Apr 11 17:02 .
drwxr-xr-x 22 root root 4096 Apr 11 16:59 ..
drwxr-xr-x  7 svn  svn  4096 Apr 11 17:02 baz-repo
$

umaskを確認します。002なら要らないらしいのですが、0022と出ました。

$ umask
0022

dbディレクトリのパーミッションを確認

$ cd /var/svn/baz-repo
$  ls -la db/
total 36
drwxr-sr-x 5 svn svn 4096 Apr 11 17:02 .
drwxr-xr-x 7 svn svn 4096 Apr 11 17:02 ..
-rw-r--r-- 1 svn svn    6 Apr 11 17:02 current
-r--r--r-- 1 svn svn    2 Apr 11 17:02 format
-rw-r--r-- 1 svn svn    5 Apr 11 17:02 fs-type
drwxr-sr-x 2 svn svn 4096 Apr 11 17:02 revprops
drwxr-sr-x 2 svn svn 4096 Apr 11 17:02 revs
drwxr-sr-x 2 svn svn 4096 Apr 11 17:02 transactions
-rw-r--r-- 1 svn svn   37 Apr 11 17:02 uuid
-rw-r--r-- 1 svn svn    0 Apr 11 17:02 write-lock

ディレクトリにはSGIDは有効になっているのは確認できたけど、グループの書き込み権限がないので、権限を与える。

$ find db/ -perm +200 -exec chmod g+w {} \;
$ ls -la db/
total 36
drwxrwsr-x 5 svn svn 4096 Apr 11 17:02 .
drwxr-xr-x 7 svn svn 4096 Apr 11 17:02 ..
-rw-rw-r-- 1 svn svn    6 Apr 11 17:02 current
-r--r--r-- 1 svn svn    2 Apr 11 17:02 format
-rw-rw-r-- 1 svn svn    5 Apr 11 17:02 fs-type
drwxrwsr-x 2 svn svn 4096 Apr 11 17:02 revprops
drwxrwsr-x 2 svn svn 4096 Apr 11 17:02 revs
drwxrwsr-x 2 svn svn 4096 Apr 11 17:02 transactions
-rw-rw-r-- 1 svn svn   37 Apr 11 17:02 uuid
-rw-rw-r-- 1 svn svn    0 Apr 11 17:02 write-lock

で、このままだと、svn+sshでのアクセス時に起動されるsvnserveが作成するファイルがグループに書き込み権限のないものになってしまうので、umask 002で動くように、スクリプトを書き換えます。

# cd /usr/bin
# mv svnserve svnserve-org

で、/usr/bin/svnserveは以下のように作成します。

#!/bin/sh
umask 002
/usr/bin/svnserve-org "$@"

で、この新しいスクリプトも実行可能にしておきます。

# chmod 755 svnserve

これでサーバー側の設定はオッケーなはず!


ここからクライアントで確認します。
秘密鍵ssh-agentに使ってもらうために以下のようにした上で

$ ssh-agent bash
$ ssh-add ~/.ssh/foo_bar_id_rsa

リポジトリのURLについて、svn infoしてみます。

$ svn info foo@xxx.xxx.xxx.xxx/var/svn/baz-repo/

これで、リポジトリの情報が表示されたら成功です。

あとは普通にチェックアウトして、何かコミットしてみるといいでしょう。

一応、コミット後、svnリポジトリにグループの書き込み権限がないファイルが作られていないことを確認しましょう。

$ ls -la /var/svn/baz-repo/db/revs/
total 16
drwxrwsr-x 2 svn   svn 4096 Apr 11 17:45 .
drwxrwsr-x 5 svn   svn 4096 Apr 11 17:45 ..
-rw-rw-r-- 1 svn   svn  115 Apr 11 17:02 0
-rw-rw-r-- 1 foo   svn  273 Apr 11 17:45 1
$

Macなら

SSHKeychainの環境設定の[SSH キー]に作成した秘密鍵を登録しておくと便利です。もしかしたら[エージェント]-[一つのキーを追加]から作成した秘密鍵を登録する必要があるかもしれません。
すると、コマンドラインからssh-agent, ssh-addを行う必要がなくなります。

Windowsなら

PuTTYに付属するpagentにキーを登録しておいて、TortoiseSVNとかでpagentを使用するように設定すればクリアしてくれるはずです。結構前にやってたんですけど、忘れましたw。ググってください。

ローカルのgitリポジトリをsvnへ

簡単だけどメモ。

$ git svn clone foo@xxx.xxx.xxx.xxx/var/svn/baz-repo/trunk baz-trunk
$ cd baz-trunk
$ git svn rebase
$ git pull /path/to/source/dir/.git

これで一見問題なさそうに思えるんだけど

git svn rebase 

するとコンフリクトがあるよって怒られる。だけど、そのファイルの中身を見るとコンフリクトしてない。なので、

git status
git add (unmergedになっているファイル名)
git rebase --continue

をひたすら繰り返す。中にはunmergedに何も出てない場合もあるけど、その場合は、git rebase --continueすると進みました。


で、そのうちコンフリクトが無くなって、git svn rebaseが終了します。
でも一応心配なので、もう一度 git svn rebaseしてからdcommitします。

$ git svn rebase
Current branch master is up to date.
$ git svn dcommit

これでいい感じに終わると思ってたんですが・・・下手こいてインストールしたやるがあるっぽくてdcommitが失敗します。
なので、元々のgitリポジトリの問題のある箇所のコミットをrevert、add、commitして、もう一回最初からやり直しました。

http://www8.atwiki.jp/git_jp/pub/Documentation.ja/user-manual.html#rewriting-one-commit
を見ると、昔のコミットを編集し直すこともできるっぽいのですが、どうもうまくいきませんでした・・・

残念ながらスナップショットをそのままコミット・・・うーん、いけてない。

attachment_fu

簡単に画像を扱えるプラグインプラグイン自身のインストールは超簡単。

$ script/plugin install http://svn.techno-weenie.net/projects/plugins/attachment_fu/


でサムネイルを作るにはprocessorを使えるようにする必要があるんだけど、インストール時の出力に

    :processor        # Sets the image processor to use for resizing of the attached image.
                      # Options include ImageScience, Rmagick, and MiniMagick.  Default is whatever is installed.

とある通り ImageScience、Rmagick、MiniMagickが選べるけど、RMagickには何度か泣かされているので、ImageScienceを使うことにします。


で、ImageScienceのサイト( http://seattlerb.rubyforge.org/ImageScience.html )を見ると、

Requirements:
  FreeImage
  RubyInline

FreeImageとRubyInlineを入れろと書いてあります。


MacでFreeImageを入れるのは超簡単。

    sudo port selfupdate
    sudo port install freeimage

しかし仕事で使うこと考えるとWindowsでは入らないのかな?
あ、http://freeimage.sourceforge.net/requirements.html を見るとVisual .NET 2003 or 2005があれば良いらしいっす・・・
どうせLinuxにデプロイするんだからみんなMacかUbutu使えばいいのに。

次のRubyInlineはgemで。

sudo gem install RubyInline


で、最後に image_science をインストール

sudo gem install -y image_science

これでインストールするものは全部っす。

あとは画像を扱うためのモデルを生成して、いろいろごにょごにょやればオッケー。詳しく書くの疲れた。

$ ruby script/generate model FooImage foo_id:integer content_type:string filename:string thumbnail:string size:integer width:integer height:integer

CentOSにFreeImageを

http://seattlerb.rubyforge.org/ImageScience.html に書いてあるやり方の通りやってみる
まずcvsを使うので、cvsyumでインストール。

$ sudo yum install cvs

で、

$ cvs -z3 -d:pserver:anonymous@freeimage.cvs.sourceforge.net:/cvsroot/freeimage login
$ cvs -z3 -d:pserver:anonymous@freeimage.cvs.sourceforge.net:/cvsroot/freeimage co -D 2007-01-01 -P FreeImage
$ cd FreeImage
$ make
(中略)
/usr/bin/ld: ./Source/FreeImage/BitmapAccess.o: relocation R_X86_64_32S against `a local symbol' can not be used when making a shared object; recompile with -fPIC
./Source/FreeImage/BitmapAccess.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
make[1]: *** [libfreeimage-3.9.2.so] Error 1
make[1]: Leaving directory `/home/foo/FreeImage'
make: *** [default] Error 2

なんでー?全然意味分かんないっす。
あ、でもよく見たらこんなの書いてあった。

For 64-bit Systems:

Use 2007-02-11 instead of the date above on the cvs co. Especially if you see:

/usr/bin/ld: ./Source/FreeImage/BitmapAccess.o: relocation R_X86_64_32S against
`a local symbol' can not be used when making a shared object;
recompile with -fPIC
or:

Source/Metadata/Exif.cpp:498: error: cast from 'BYTE*' to 'DWORD' loses precision
make[1]: *** [Source/Metadata/Exif.o] Error 1

で改めてcheckoutしてみる。

$ cd ..
$ rm -rf FreeImage
$ cvs -z3 -d:pserver:anonymous@freeimage.cvs.sourceforge.net:/cvsroot/freeimage co -D 2007-02-11 -P FreeImage
$ cd FreeImage/
$ make
(中略)
cp *.a Dist
cp *.so Dist
cp Source/FreeImage.h Dist
make[1]: Leaving directory `/home/foo/FreeImage'
$

おお、うまくいったっぽい。

では次。

$ PATH=$PATH:/usr/sbin sudo make install
make -f Makefile.gnu install 
make[1]: Entering directory `/home/foo/FreeImage'
install -m 644 -o root -g root Source/FreeImage.h /usr/include
install -m 644 -o root -g root libfreeimage.a /usr/lib
install -m 755 -o root -g root libfreeimage-3.9.2.so /usr/lib
ln -sf libfreeimage-3.9.2.so /usr/lib/libfreeimage.so.3
ln -sf libfreeimage.so.3 /usr/lib/libfreeimage.so	
ldconfig
make[1]: ldconfig: Command not found
make[1]: *** [install] Error 127
make[1]: Leaving directory `/home/foo/FreeImage'
make: *** [install] Error 2

失敗しやがった。訳分からん。checkinstallも当然無理。
ちなみにldconfig は /sbin にあって、PATHに追加してやってみても同じ結果。
あ、sudoじゃなくてrootで実行したらどうでしょう?

$ su
# PATH=$PATH:/usr/sbin:/sbin:/sbin  make install
make -f Makefile.gnu install 
make[1]: Entering directory `/home/foo/FreeImage'
install -m 644 -o root -g root Source/FreeImage.h /usr/include
install -m 644 -o root -g root libfreeimage.a /usr/lib
install -m 755 -o root -g root libfreeimage-3.9.2.so /usr/lib
ln -sf libfreeimage-3.9.2.so /usr/lib/libfreeimage.so.3
ln -sf libfreeimage.so.3 /usr/lib/libfreeimage.so	
ldconfig
make[1]: Leaving directory `/home/foo/FreeImage'
#

うお、いけたよ!

もう一回、checkinstallでやってみよう

# checkinstall
(中略)
**********************************************************************

 Done. The new package has been saved to

 /usr/src/redhat/RPMS/x86_64/FreeImage-20090411-1.x86_64.rpm
 You can install it in your system anytime using: 

      rpm -i FreeImage-20090411-1.x86_64.rpm
**********************************************************************

rpmができた。

# rpm -iv /usr/src/redhat/RPMS/x86_64/FreeImage-20090411-1.x86_64.rpm
Preparing packages for installation...
FreeImage-20090411-1
#

完了っぽいっす。

あとは、RubyInlineとImageScienceをgemで入れればオッケーなはず。

$ sudo gem install RubyInline
Successfully installed ZenTest-4.0.0
Successfully installed RubyInline-3.8.1
2 gems installed
Installing ri documentation for ZenTest-4.0.0...
Installing ri documentation for RubyInline-3.8.1...
Installing RDoc documentation for ZenTest-4.0.0...
Installing RDoc documentation for RubyInline-3.8.1...
$
$ sudo gem install image_science
Successfully installed rubyforge-1.0.3
Successfully installed hoe-1.12.1
Successfully installed image_science-1.1.3
3 gems installed
Installing ri documentation for rubyforge-1.0.3...
Installing ri documentation for hoe-1.12.1...
Installing ri documentation for image_science-1.1.3...
Installing RDoc documentation for rubyforge-1.0.3...
Installing RDoc documentation for hoe-1.12.1...
Installing RDoc documentation for image_science-1.1.3...
$

これで成功のはずー!