RPM Scriptlet ってなんだ
2006年2月11日22:54
vine
スペックファイルで嵌まらないように自戒をこめて。

ライブラリ *.so を含む RPM パッケージを作る時には、
次のように書くのが定石らしい。
( RPM scriptlet recipes )

%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig

僕は次のように書きました(編集してあります)。

...
%post -p /sbin/ldconfig
%postun -p /sbin/ldconfig

# files section
%files
...

そうしたところアンインストールする時にエラーが出て、
パッケージを削除できなくなりました。なぜ ???

# rpm -e hoge
/sbin/ldconfig: relative path `0' used to build cache
エラー: %postun(hoge.i386) スクリプトの実行に失敗しました。終了ステータス 1

ちょっとした落し穴がありました。


スクリプトを抽出してみると、

$ rpm -qp --scripts hoge.i386.rpm
postinstall program: /sbin/ldconfig
postuninstall scriptlet (using /sbin/ldconfig):

あれ %postprogram なのに %postunscriptlet になってます。
次のセクションが始まる前にコメント行があると scriptlet になってしまう。

動作を確認するため /sbin/ldconfig を簡単なテストプログラム /usr/local/bin/hello に置き換えてみました。

...
%post -p /usr/local/bin/hello
%postun -p /usr/local/bin/hello

# files section
%files
...

下記はテストプログラム hello.cpp のコード。

#include <cstdio>
int main(int argc, char** argv)
{
    printf("hello, scriptlet!\n");
    for (int i = 0; i < argc; i++)
        printf("argv[%d]: %s\n", i, argv[i]);
    return 0;
}

そして rpm のインストール/アンインストールを試してみると、

# rpm -ivh hoge.i386.rpm
hello, scriptlet!
argv[0]: /usr/local/bin/hello
# rpm -e hoge
hello, scriptlet!
argv[0]: /usr/local/bin/hello
argv[1]: /var/tmp/rpm-tmp.29549
argv[2]: 0

%post (program) の方では引数1個しか渡ってないのに、 %postun (scriptlet) の方では引数3個渡ってます。
デフォルトでは /bin/sh に渡すものを -p program に渡してると云うこと。
考えてみればあたりまえのことですね。

この引数を直接 /sbin/ldconfig に渡してみると、
どこかで見たエラーが出ました。(良い子はマネしないこと)

# /sbin/ldconfig /var/tmp/rpm-tmp.29549 0
/sbin/ldconfig: relative path `0' used to build cache

#rpm -e hoge で出たエラーと同じです。

と云うことで %postun -p /sbin/ldconfig にした時は、
その後 (次のセクションが始まるまで)
たとえコメントでも書いちゃいけませんと云うことでした。


コメントはありません