書式
dpkg-maintscript-helper command [parameter...] -- maint-script-parameter...コマンドおよびパラメータ
rm_conffile conffile [prior-version [package]]
mv_conffile old-conffile new-conffile [prior-version [package]]
説明
このプログラムは、メンテナスクリプトとして実行されることで、dpkg が設計上の判断や制約事項によって (未だに) 自身で対応できていない幾つかの作業を実現するために開発された。
こうした作業の多くは、メンテナスクリプト (preinst, postinst, prerm, postrm) 間の連携した動作が求められる。ミスを避けるために、すべてのスクリプトに対して単に同じ形式のスクリプト呼び出しを設定し、プログラム側で環境変数 DPKG_MAINTSCRIPT_NAME と二重ダッシュの後に設定して渡されるメンテナスクリプト固有の引数とに基づいた挙動の調整を自動的に行うようにしている。
conffile 関連の作業
パッケージをアップグレードする時に、dpkg は、新しいバージョンに存在しない conffile (dpkg がユーザの行った修正を保持する必要がある設定ファイル) を自動的には削除しない。これには 2 つの大きな理由がある。1 つは (パッケージ作成時に) conffile の指定を誤って削除してしまった場合でも、ユーザとしては行った変更を破棄されたくないであろうことを勘案し、設定を削除されないようにしておき、次のバージョンでそれを復活させることができるようにするためである。もう 1 つは、dpkg がメンテナンスする conffile を、パッケージのメンテナスクリプト、通常は debconf や ucf といったツールによって、メンテナンスするファイルに移行することを可能とするためである。
これは、パッケージが conffile のリネームや削除を意図していた場合は、明示的に行う必要があり、dpkg-maintscript-helper が既定を遵守した削除の実装と、conffile をメンテナスクリプトにより移動するために用いられることを意味する。
conffile の削除
conffile が完全に削除される場合は、ユーザが変更していない限り、ディスクから削除されるべきである。ローカルに変更が行われていた場合は、その変更は保持されるべきである。パッケージのアップグレードが中止された場合は、不要となるはずだった conffile が消去されることがないようにすべきである。
これらのすべてがメンテナスクリプト preinst, postinst, postrm 内で以下のようなシェルスクリプトによって行われる。
dpkg-maintscript-helper rm_conffile \
conffile prior-version package -- "$@"
conffile は削除する conffile のファイル名である。
prior-version は、アップグレードが削除の契機となる最新のパッケージのバージョンを定義する。ユーザがローカルなバージョンを用いてパッケージをリビルドした際でも conffile を適切に削除するためには、適切な prior-version を定義することが肝要である。例えば、あるパッケージのバージョン 2.0-1 で削除される conffile は、prior-version を 2.0-1~ に設定する必要がある。これにより、ユーザが以前のバージョンである 1.0-1 を 1.0-1local1 としてリビルドした場合であっても、conffile が削除されることになる。
ある conffile が提供されていないまま、既に複数回のバージョンアップが行われてしまっている場合に、メンテナスクリプトを修正して不要となったファイルを削除したいという場合、prior-version は conffile が不要となった最初のパッケージのバージョンではなく、現在のバージョンを指定する必要がある。
package はパッケージ名を示す。空白もしくは省略された場合、環境変数 DPKG_MAINTSCRIPT_PACKAGE の値 (dpkg により設定される) が用いられる。
メンテナスクリプトのパラメータはすべて、"--" 以降の部分をプログラムに引き渡す必要がある。
現在の実装では、preinst は conffile が変更されたかをチェックし、conffile.dpkg-remove (変更されていない場合) もしくは conffile.dpkg-backup (変更されている場合) にリネームする。postinst は後者のファイルを conffile.dpkg-bak にリネームし、ユーザが変更内容を参照できるように保持するが、前者は削除する。パッケージのアップグレードが中止となった場合、postrm は以前の conffile を再インストールする。完全削除の際に、postrm はここまで保持されていた .dpkg-bak ファイルも削除する。
conffile のリネーム
conffile のパスが変更された場合は、ユーザによる変更点もすべて移行する必要がある。これは、preinst スクリプトに簡単な変更を行うことで実現できそうに見えるが、その場合、ユーザが主体的に変更を行っていないにも関わらず、dpkg からユーザに対して、conffile の変更を受け入れるかどうかの確認が発生してしまう。
以下に示すシェルスクリプトを preinst, postinst, postrm のメンテナスクリプトに入れることで、適切なリネーム処理が実行される:
dpkg-maintscript-helper mv_conffile \
old-conffile new-conffile prior-version package -- "$@"
old-conffile と new-conffile は、リネームする conffile の変更前、変更後の名前である。
prior-version は、バージョンアップにより conffile のリネームを行うパッケージの最新のバージョンを指定する (指定すべき適切な値については、rm_conffile での注記を参照のこと) 。prior-version が空白もしくは省略された場合、バージョンアップの度にリネームが試行される (バージョンを指定することで、リネームの試行を一度に留めておく方が安全である)。
package はパッケージ名を示す。空白もしくは省略された場合、環境変数 DPKG_MAINTSCRIPT_PACKAGE の値 (dpkg により設定される) が用いられる。
メンテナスクリプトのパラメータはすべて、"--" 以降の部分をプログラムに引き渡す必要がある。
現在の実装では、preinst は conffile が変更されたかをチェックし、変更されている場合はそのままに、変更されていない場合は old-conffile.dpkg-remove にリネームする。設定の際に、postinst は old-conffile.dpkg-remove を削除し、old-conffile が存在している場合は、それを new-conffile にリネームする。abort-upgrade や abort-install が行われた場合、postrm は、必要に応じて old-conffile.dpkg-remove をリネームして old-conffile に戻す。
パッケージとの連携
dpkg-maintscript-helper の使用が preinst にて指定された場合は、必要なバージョンの dpkg が事前に展開されていることを担保する事前依存関係が必須となる。必要なバージョンは、使用するコマンドによって異なる。例えば、rm_conffile や mv_conffile の場合は 1.15.7.2 以上となる:
Pre-Depends: dpkg (>= 1.15.7.2)
しかし多くの場合、プログラムによって行われる操作はパッケージにとって不可欠なものではない。そのため、事前依存関係を使用する代わりに、必要なコマンドが現在インストールされている dpkg によってサポートされていることが確認できている場合に限ってプログラムを呼び出してもよい:
if dpkg-maintscript-helper supports command; then
dpkg-maintscript-helper command ...
fi