こちら では JDK・JRE インストーラの仕組みを説明しましたが、この形式で一度インストーラをつくってみます。
インフラの仕事をしていてこれまで RPM インストーラ等を作っていたりはしていたのですが、どうも以下のように自分の思ったようにいかない部分があります。
-
/etc 等の設定ファイル系が上書きされない
-
勝手に strip されてしまう為、デバッグできなくなる
-
はいいのか悪いのか微妙ですが、既に前バージョンの RPM がインストールされており設定ファイルとされているものをユーザが更新していたとします。
この場合、RPM はユーザに更新があったものとしてこのファイルを更新せず別のファイル名(.rpmnew)で新バージョンの RPM 内設定ファイルを保存して更新することはありません。これは結構障害として上がってきたります。
また、2. については http://daily-note.blog.so-net.ne.jp/2008-08-17-1 の辺りを参考にすれば strip は行われなくなりそうですが、デバッグできなくなることは致命的でした。
この辺りを考えて「自分で完全に制御できるインストーラをつくってみよう」と考えました。今回はその方法を説明します。
インストーラをつくってみる
だいたいのインストーラの処理は こちら の JDK・JRE に合わせてもっと簡単な内容のインストーラをつくってみます。
最初にインストールする階層をつくる
最初はインストールするものを格納するディレクトリ階層を作り、ファイルをそれぞれ置きます。今回はテストなので以下のような方法でダミーデータを作ってみました。
$ mkdir -p aaa bbb/eee/fff ccc/ddd
$ echo `date` > aaa/date.txt
$ top -b -n 1 > bbb/eee/top.txt
$ df -h > ccc/ddd/df_h.txt
インストーラ(bash)をつくる
次に作成した階層をインストールするようなプログラムを作ります。今回は以下のようなプログラムを作りました(ファイル名は installer.sh)。
#! /bin/bash
echo "準備はいいですか?(N/y)"
read ANS
if [ "${ANS}" = "y" ]
then
# このプログラム内の "this is exit" が最後に出現する箇所
# の行番号を取得する
TARGET_LINE=`grep -n –text "this is exit" $0 | tail -1 | cut -d: -f1`
# "this is exit" の次の行を解凍ターゲットとする
let COUNT=${TARGET_LINE}+1
# バイナリ部分だけを temporary.zip に出力する
tail -n +${COUNT} $0 > temporary.zip
echo "unziping …"
unzip temporary.zip && rm -f temporary.zip
echo "exit …"
# 解凍した階層構造をインストールする
cp -pfvr aaa work
cp -pfvr bbb work
cp -pfvr ccc work
# 最後に解凍した階層を削除する
rm -rf aaa bbb ccc
fi
exit 0 # this is exit
この後、バイナリデータをプログラムに埋め込んだりプログラム自体の説明もしたいのですが次回へまわします。