RoR なでびあんパケジを無理やりでっち上げるの巻

うぶんつには redmine なソースパケジがあるので debian 配下の以下を確認してみました。

今回、debconf とか ucf あたりは完全にスルーさせて頂きます。

debian/postinst

まず変数の設定してます。

fRailsEnv=production
fRailsLog=/var/log/redmine
fRailsVar=/var/lib/redmine
fRailsCache=/var/cache/redmine
fRailsDir=/usr/lib/ruby/vendor_ruby/rails
if [ ! -e "$fRailsDir" ]; then
    # keep rails package compatibility
    fRailsDir="/usr/share/rails-ruby1.8"
fi

で、引数が configure 乃至 reconfigure だった時の処理になります。
まず、var 配下のナニに権限を設定してます。コメントにあるように passenger 限定なあたりがアレです。あと、postinst なのでファイルは配置されている、が前提という認識で良いのですよね。

        # passenger runs as the owner of that file, thanks Micah Anderson.
        chown www-data:root /usr/share/redmine/config/environment.rb
        chown -f www-data:www-data $fRailsLog
        chown -f www-data:www-data $fRailsVar
        chown -f www-data:www-data $fRailsCache
        savedir="`pwd`"
        cd /usr/share/redmine

で、カレントディレクトリを移動して vendor/railties が symlink だったファイルを削除しています。

        if [ -L vendor/railties ]; then
            # rails 2.2 to 2.3 migration
            rm -f vendor/actionmailer
            rm -f vendor/actionpack
            rm -f vendor/activemodel
            rm -f vendor/activerecord
            rm -f vendor/activeresource
            rm -f vendor/activesupport
            rm -f vendor/railties
            rm -f vendor/rails
        fi

あるいは vendor/rails が無い、または存在するけど symlink じゃない場合 (で、良いのかな)、symlink 張ってますね。あるいは test -L が真の場合は必要であれば symlink の張りなおしをしている様子。

        if [ ! -L vendor/rails ]; then
            ln -s "$fRailsDir" vendor/rails
        else
            # rails 2.3 to ruby-rails-2.3 migration
            fMigrateLink=$(readlink vendor/rails)
            if [ "$fMigrateLink" != "$fRailsDir" ]; then
                rm -f vendor/rails
                ln -s "$fRailsDir" vendor/rails
            fi
        fi

あとは以下なナニ達が無ければ mkdir とか。

        if [ ! -e app/views/members ]; then
            mkdir app/views/members
        fi
        if [ ! -e app/sweepers ]; then
            mkdir app/sweepers
        fi
        if [ ! -e lib/plugins ]; then
            mkdir lib/plugins
        fi

あるいは tmp ディレクトリは削除してます。コメントによれば /usr に書いてはいけない、というのはでびあんポリシーに依るのかな。
む、そーゆー意味では余談ですがでびあん系を使用する場合、/usr は共用可能なのか。

        # this directory should never be used: /usr not writable policy
        if [ -e tmp ]; then
            rm -rf tmp
        fi
        cd $savedir
    ;;

ちなみに app/views/members とかなあたりは redmine 独自と思われるので必要なければ削除しても構わないと見ています。vendor/rails とか vendor/railties のあたりは Rails 共通な気がしています。
上記の直後に以下な記述があったので redmine を導入した仮想ホストを起動して確認してみました。

db_get redmine/current-instances || true
gInstances="${RET}"
for lInstance in $gInstances; do
    fRailsEtc=/etc/redmine/$lInstance
    fRailsLog=/var/log/redmine/$lInstance
    fRailsVar=/var/lib/redmine/$lInstance
    fRailsCache=/var/cache/redmine/$lInstance
    # dbconfig needs this folder to ouput database.yml
    mkdir -p $fRailsEtc
    chown -f www-data:www-data $fRailsEtc

ええと、確認結果が以下ッス。

$ ls /etc/redmine
default
$ ls /var/log/redmine
default
$ ls /var/lib/redmine
default
$ ls /var/cache/redmine
default
$

ふむ。redmine/current-instances には default というナニが格納されているのか。
また、その直後 (?) に以下な条件分岐と初期設定がありまして

    if [ $lInstall -eq 1 ]; then
        fYml=$fRailsEtc/database.yml.new

そのファイルがあったらば、という前提で以下な記述もあります。

    if [ -e $fYml ]; then
        hasdb=$(grep -m 1 -o -E 'adapter: (mysql|pgsql|sqlite3|postgresql)' $fYml) || true
        if [ -n "$hasdb" ]; then
            hasdb=$(echo -n ${hasdb#*:})
            withdb=1
            case "$hasdb" in
                mysql|postgresql|pgsql)
                    sed -i -r -e 's/pgsql/postgresql/g' $fYml
                ;;
                sqlite3)
                    sed -i -r -e 's/^[^#]+((host|port|username|password): [^:]*)$/# \1/g' $fYml
                ;;
            esac
        fi
        ucf --debconf-ok $fYml /etc/redmine/$lInstance/database.yml
        rm -f $fYml
    fi

なんか置き換えのナニが微妙な気がするんですが、ここは自分でヤれ、なのかなぁ。sqlite3 な場合は記述の通りになっているのは確認できてます。でもこれ、何が元になっているのかがちょっと分からない。
と、思ったらソースパケジの debian/conf の中に database.yml.template というファイルを発見。中身が以下。

$ cat debian/conf/database.yml.template 
production:
  adapter: _DBC_DBTYPE_
  database: _DBC_DBNAME_
  host: _DBC_DBSERVER_
  port: _DBC_DBPORT_
  username: _DBC_DBUSER_
  password: _DBC_DBPASS_
  encoding: utf8
$

を、これって /usr/share/redmine/template に投入されておりますな。とは言え、どこで fYml な $fRailsEtc/database.yml.new が生成されているかが分からない。
深追いは止めておいて直後の処理を見てみます。以下が継続かな。

    case "$1" in
        configure|reconfigure)
            # create directories

作ってますね。

            # create directories
            mkdir -p $fRailsLog
            mkdir -p $fRailsVar
            mkdir -p $fRailsVar/files
            mkdir -p $fRailsCache
            mkdir -p $fRailsCache/plugin_assets
            chmod 750 $fRailsLog
            chmod 750 $fRailsVar
            chmod 755 $fRailsCache
            chmod 755 $fRailsCache/plugin_assets
            chown -f www-data:www-data $fRailsLog
            chown -f www-data:www-data $fRailsVar
            chown -f www-data:www-data $fRailsVar/files
            chown -f www-data:www-data $fRailsCache
            chown -f www-data:www-data $fRailsCache/plugin_assets

先頭あたりで chown とかしてるんですが、-f が付いてるので新規導入時はスルーなのか。そういった意味では最初に引用したあたりは tmp の扱い以外は既に導入されていたケイスを想定しているのかな。
次が以下なあたり。

            savedir="`pwd`"
            cd /usr/share/redmine
            # copy schema.db to its instance directory
            if [ -f db/schema.db ]; then
                cp db/schema.db $fRailsCache/schema.db
            fi

ソースパケジには db/schema.db は無いんですよね。Rails 共通な記述としてあったら /etc 方面に持っていこうね、って意味だと思ってて良いのかな。
次な部分もあまり良く分かっていないあたりなんですが session.yml に関する記述。

            # add secret key, set permissions, manage file with ucf
            if [ ! -f "${fRailsEtc}/session.yml" ]; then
                rake -s generate_session_store YML_SESSION_FILENAME="session.yml.new" RAILS_ENV=$fRailsEnv X_DEBIAN_SITEID="${lInstance}" || true
                chown -f root:www-data ${fRailsEtc}/session.yml.new
                chmod 640 ${fRailsEtc}/session.yml.new
                ucf --debconf-ok ${fRailsEtc}/session.yml.new ${fRailsEtc}/session.yml
                rm ${fRailsEtc}/session.yml.new
                # move old session_store.rb
                echo "A new secret session key has been generated in ${fRailsEtc}/session.yml"
            else
                fHasOldSessionName=$(fgrep -c session_key "${fRailsEtc}/session.yml" || true)
                if [ $fHasOldSessionName -gt 0 ]; then
                    # in-place, because ucf might be configured to keep the old version without asking
                    sed -i -r -e 's/session_key/key/g' ${fRailsEtc}/session.yml             
                fi
            fi

sessyon.yml.new を rake generate_session_store で作って権限設定して ucf で /etc 方面にぶち込んでいる様子。else な分岐はとりあえずスルー。以下もちょっとよく分からないですね。

            if [ -f config/initializers/session_store.rb ]; then
                mv config/initializers/session_store.rb config/initializers/session_store.rb.dpkg-old
                echo "The old secret session key can be found in
/usr/share/redmine/config/initializers/session_store.rb.dpkg-old"
            fi

手元の redmine なソースパケジには config/initializes 配下には session_store.rb は無いんですよね。セッション関連ってのは理解できてるんですが、生成される契機が不明。乱暴ですがこのあたりもスルー。
以降が核心なのかどうか。rake な処理の記述がみっつあります。

  • rake db:migrate
  • rake redmine:load_default_data
  • rake db:migrate_plugins

以下。

            if [ $withdb -eq 1 ]; then
                db_get redmine/instances/${lInstance}/default-language && DEFAULT_LANGUAGE="$RET"
                    
                # handle rake install
                echo "Populating database for redmine instance \"${lInstance}\".
This may take a while."
                fCode=0
                rake -s db:migrate RAILS_ENV=$fRailsEnv X_DEBIAN_SITEID="${lInstance}" VERBOSE=$RAKE_VERBOSE || fCode=$?
                if [ $fCode -eq 0 ]; then
                    echo "Done."
                    if [ $lInstall -eq 1 ]; then
                        rake -s redmine:load_default_data RAILS_ENV=$fRailsEnv X_DEBIAN_SITEID="${lInstance}" REDMINE_LANG=$DEFAULT_LANGUAGE || true
                        # because rake task is executed as root here, and this file is used later by web server, make sure owner is www-data
                        touch ${fRailsLog}/production.log
                        chown -f www-data:www-data ${fRailsLog}/production.log
                    fi
                    # handle plugins migration
                    rake -s db:migrate_plugins RAILS_ENV=$fRailsEnv X_DEBIAN_SITEID="${lInstance}" VERBOSE=$RAKE_VERBOSE || true
                else
                    echo "Error when running rake db:migrate, check database configuration."
                    exit -1
                fi
            else
                echo "Redmine instance \"${lInstance}\" database must be configured manually."
            fi
            cd $savedir || true

詳細略です。とは言え、なんとなくざっくりベースな構造は見えました。が、debconf が絡んでくるとまだちょっと微妙なカンジです。

debian/prerm

debconf 以外の部分だと vendor/rails を削除しているのみ、です。

debian/postrm

remove な引数の場合は debconf で云々しているのみ。purge の場合は設定ファイルの類とか全部削除になるのでそれなりに手厚いケアが必要な模様です。
とは言え purge な処理で実際にファイルを云々しているのは以下な記述。

        # package-generated or runtime files are removed
        rm -f /usr/share/redmine/db/schema.db
        # removing /var/run files is not needed : it is mounted tmpfs in wheezy - anyway it does not hurt
        rm -rf /var/run/redmine
        rm -rf /var/log/redmine
        rm -rf /usr/share/redmine/tmp
        rm -rf /var/lib/redmine/*/sessions
        rm -rf /var/cache/redmine
        rm -rf /etc/redmine
        # user files are not
        rmdir /var/lib/redmine/*/files || true
        rmdir /var/lib/redmine/* || true

逆に言えば remove および purge 以外の例えば upgrade な処理だと何もしていないんですね。

とりあえずの課題

という意味では debconf と ucf 云々を確認したいと思ってます。