wiki:docs/making-rpm/symlink

Vine Linux ドキュメント / RPM パッケージの作成方法 / シンボリック・リンク等を %post とかで張らない

シンボリック・リンク等を %post とかで張らない

間違えてもそれ(%post ではったリンクなど)を %preun や %postun で削除してはいけない

シンボリック・リンクを含む全てのファイルを %install まででインストールして、 %files に加えるべきである。

これは特に重要です。よく、%post で、シンボリック・リンクをはって、 %preun でそのリンクを削除するような SPEC ファイルがあります。 これを行うと、アップデート時に問題が生じることがあります。以前、 libc のパッケージでこういう記述が入ってるものがあって、深刻な問題が生じたこともありました。

その理由は、rpm -U <new-rpm> としたときに、

rpm -e <old-rpm>
rpm -i <new-rpm>

ではなく、

rpm -i <new-rpm>
rpm -e <old-rpm>

とはたらくためです。

つまり、%post で、シンボリック・リンクをはって、 %preun でそれを削除するような rpm のバージョンアップをしようと、 rpm -U (アップデート)を実行すると

  1. 新しいパッケージのインストールが行なわれ、 %post でシンボリック・リンクがつくられる。
  2. 古いパッケージのアンインストールが行なわれる。 このとき、%preun でさっき新しいパッケージが作ったシンボリック・ リンクが削除される。

この仕様は、libc とかのアップグレードの途中で libc とかがなくなってトラブルが生じるのを避けようとしたためのものと思われます。

実はこの問題は解決法があります。 %pre, %post, %preun, %postun のスクリプト実行時には、スクリプトに対して以下の引数が与えられます。

  • rpm -iでインストールを行うとき %pre, %postに対して $1=1
  • rpm -Uでアップデートを行うとき
    • 新しいrpmのインストール時に、 %pre, %postに対して $1=2
    • 古いrpmをアンインストール時に、 %preun, %postunに対して $1=1
  • rpm -eでアンインストールを行うとき %preun, %postun に対して $1=0

すなわち、はじめてインストールするときには、引数として 1 がわたされ、 rpm -e でアンインストールするときには 0 がわたされるわけです。 これを利用すると、

%post
if [ $1 = 1]; then
        echo ``First installation!''
fi
%preun
if [ $1 = 0]; then
        echo ``Good bye!''
fi

とかできるわけです。(それでも %post などでシンボリック・リンクをはったりすると、出どころ不明のファイルが増えることになります。その他トラブルをさけるため、できるだけファイルは %files に加えるようにし、 %post などに書くスクリプトはできるだけ少なくしましょう)