[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ next ]
Debian ポリシーマニュアル
Chapter 6 - パッケージ管理スクリプトとインストールの手順
6.1 パッケージ管理スクリプトへの手引き
パッケージをインストール、アップグレード、削除する際に、パッケージ管理システムが走らせるスクリプトをパッケージの一部として供給することが可能です。
これらのスクリプトは
preinst、postinst、prerm と
postrm という制御情報ファイルです。
これらは適正な実行可能ファイルでなくてはなりません。 もし、これらがスクリプト
(スクリプトであることを推奨します) ならば、 通常行われているように
#! で始めなくてはなりません。
これらのスクリプトは、誰でも読むことと実行が可能でなければならず、
誰でも書き込み可能なパーミッションであってはいけません。
パッケージ管理システムはこれらのスクリプトからの終了ステータスを見ます。 パッケージ管理システムが手続きを止められるように、 エラーがあった場合にはスクリプトが 0 でないステータスで終了するようにしておくことが重要です。 シェルスクリプトでは ほとんど常に set -e を使う必要があるということを意味します (実際には、 通常シェルスクリプトを書く場合は一般に、このようにします)。 もちろん、全てがうまくいった場合に、0 ステータスで終了しないことも重要です。
さらに、postinst 中で debconf
を用いてユーザとの対話を行うパッケージでは、制御情報ファイル内に
config スクリプトをインストールすべきです。 詳細は、メンテナスクリプト中のプロンプト使用について,
Section 3.9.1 を参照ください。
パッケージがアップグレードされる時には、アップグレード手続きの間に古いパッケージと新しいパッケージのスクリプトが、組み合わせて呼び出されます。 もし、あなたのスクリプトがとても複雑になっていく場合には、このことに注意し、スクリプトの引数のチェックが必要になるでしょう。
大まかに言えば、preinst は (ある特定のバージョンの)
パッケージがインストールされる前に、postinst
はインストールされた後に呼び出されます。prerm は
(あるバージョンの) パッケージが 削除される前に、 postrm
は削除された後に呼び出されます。
管理スクリプトから呼ばれるプログラムは、通常そのスクリプトにおいてプログラムの前にパスをつけて呼び出すべきではありません。
インストールが始まる前に、パッケージ管理システムは
ldconfig、start-stop-daemon、
install-info や update-rc.d
などのプログラムが指定された PATH
環境変数から発見できるかどうかをチェックします。
ですから、これらのプログラムや、PATH
にあることを期待してもいいようなプログラムについては、絶対パス名をつけずに呼び出すべきです。
管理スクリプトは PATH をリセットすべきではありませんが、
PATH
の前か後に、パッケージに対して特別なディレクトリを付け加えるという方法を採るのはかまいません。
このような考慮は、実際には、全てのシェルスクリプトに対して当てはまるものです。
6.2 メンテナスクリプトの再入結果の同一性
メンテナスクリプトが再入結果の同一性をもつようにすることはとても重要です。
エラー回復手続きをできるようにするため、スクリプトは同じ状況にあるときに、それを何度か起動しても無害でなければなりません。 もし、一回目の呼び出しが失敗した、または何らかの理由によって途中で中止した場合、 二回目の呼び出しでは一回目で実行し残したものを単に実行し、 もし何もかもうまくいったなら成功ステータスで終了するようにすべき [43] です。
6.3 メンテナスクリプトからのターミナルの制御
メンテナスクリプトは制御端末がある状態で実行されているとは限らず、 ユーザとの対話ができることは保証されていません。 制御端末が提供されていない場合、非対話型で処理することができるようにしなければなりません。 Debian Configuration Management Specification に準拠したプログラムを使ってプロンプトを出しているメンテナスクリプト (メンテナスクリプト中のプロンプト使用について, Section 3.9.1 参照) は、非対話型の動作になった場合の扱いを、そのプログラムが行うと仮定して構いません。
優先順位の高い、妥当な標準回答の無いような対話を行いたい場合、 制御端末がない際に異常終了することは許されています。 但し、可能な限りそのようなことが起きないようにすべきです。 これは、自動インストールや、無人インストールの妨げになるからです。 大抵の場合は、このような挙動はユーザにそのパッケージのバグと見做されるでしょう。
6.4 終了ステータス
各スクリプトは成功の場合には終了ステータスを 0 に、失敗の場合には 0 でない値にして帰ってください。これは、 パッケージ管理システムがこれらスクリプトの終了ステータスを監視しており、このデータに基づいて次に取るべき処理を決めているためです。
6.5 メンテナスクリプトの呼ばれ方のまとめ
-
new-preinst install
-
new-preinst install old-version
-
new-preinst upgrade old-version
-
old-preinst abort-upgrade new-version
-
postinst configure most-recently-configured-version
-
old-postinst abort-upgrade new-version
-
衝突しているパッケージの postinst abort-remove in-favour package new-version
-
postinst abort-remove
-
設定破棄されるパッケージの postinst abort-deconfigure in-favour failed-install-package version [removing conflicting-package version]
-
prerm remove
-
old-prerm upgrade new-version
-
new-prerm failed-upgrade old-version
-
衝突しているパッケージの prerm remove in-favour package new-version
-
設定破棄されるパッケージの prerm deconfigure in-favour package-being-installed version [removing conflicting-package version]
-
postrm remove
-
postrm purge
-
old-postrm upgrade new-version
-
new-postrm failed-upgrade old-version
-
new-postrm abort-install
-
new-postrm abort-install old-version
-
new-postrm abort-upgrade old-version
-
削除されるパッケージの postrm disappear overwriter overwriter-version
6.6 インストール時とアップグレート時のパッケージの展開段階の詳細
インストール/アップグレード/上書き/消去 (すなわち、 dpkg --unpack が走っているとき、または dpkg --install の展開段階のとき) の手続きは下記の通りになります。どのような場合においても、 もしエラーが起これば (下記の場合を除けば) そこでの動作は、一般に逆方向へ走る処理です。 これは、管理スクリプトが異なる引数で逆順に走らされるということです。 このような呼び出しは以降の説明では「エラー回復」呼び出しとして記しています。
-
-
対象となるパッケージの、あるバージョンが既に インストールされている場合は次の呼び出しをします。
old-prerm upgrade new-version
-
もし、これがエラーとなったら (つまり、 ゼロでない終了ステータスであったら)、
dpkgはかわりに次の呼び出しをします。new-prerm failed-upgrade old-versionこれが動作するなら、アップグレード作業を続けます。 うまくいかないなら、エラー回復は次の通りです。
old-postinst abort-upgrade new-versionこれが正常動作するなら、"old-version" がインストールされています。正常動作しないなら、 "old-version" は "Half-Configured" 状態になっています。
-
-
「衝突する (conflicting)」パッケージが同時に削除される場合、 またはいずれかのパッケージが壊れている (Breaks のため) 場合には
-
もし、--auto-deconfigure が指定されている場合、 Breaks で設定破棄されるパッケージ各々に対し以下を呼び出します。
設定破棄されるパッケージの prerm deconfigure \ in-favour package-being-installed versionこのときのエラー回復は
設定破棄されるパッケージの postinst abort-deconfigure \ in-favour package-being-installed-but-failed versionです。もし、--install が使われたばあいに再設定可能としておくため、設定破棄 (deconfigured) されたパッケージには設定を要求するマークが付けられます。
-
もし、その削除されようとしている衝突するパッケージに依存するパッケージがあり、 --auto-deconfigure が指定されているならば、 該当の各パッケージについて、次の呼び出しを行ないます。
設定破棄されるパッケージの prerm deconfigure \ in-favour package-being-installed version \ removing conflicting-package versionこのときのエラー回復は
設定破棄されるパッケージの postinst abort-deconfigure \ in-favour package-being-installed-but-failed version \ removing conflicting-package versionです。もし、--install が使われたばあいに再設定可能としておくため、 設定破棄 (deconfigured) されたパッケージには設定を要求するマークが付けられます。
-
衝突しているパッケージを削除するための準備として、各パッケージに対して次の呼び出しが行われます。
衝突しているパッケージの prerm remove \ in-favour package new-versionこのときのエラー回復は
衝突しているパッケージの postinst abort-remove \ in-favour package new-versionです。
-
-
-
パッケージがアップグレードされる場合には、次の呼び出しが行われます。
new-preinst upgrade old-versionこれらが失敗した場合、
new-postrm abort-upgrade old-versionを呼びます。
-
これが正常終了する場合、次に
old-postinst abort-upgrade new-versionを呼びます。更にこれが正常終了する場合、旧バージョンは "Installed" 状態になっており、正常終了しない場合は "Unpacked" 状態のままになっています。
-
これが失敗した場合、旧バージョンは "Half-Installed" 状態で残っています。
-
-
そうではない場合、もしそのパッケージの以前のバージョンからの設定ファイルがあった (すなわち「設定ファイルのみ」の状態にあった) ならば、次の呼び出しが行われます。
new-preinst install old-versionこのときのエラー回復は
new-postrm abort-install old-versionです。これが正常終了しない場合、パッケージは "Half-Installed" 状態で残っており、この修正には再インストールが必要になります。 正常終了した場合には、パッケージは "Config-Files" 状態になっています。
-
そうでもない (つまり、そのパッケージが完全削除されていた) 場合、次の呼び出しが行われます。
new-preinst installこのときのエラー回復は
new-postrm abort-installです。これが正常終了しない場合、パッケージは "Half-Installed" 状態で残っており、この修正には再インストールが必要になります。 正常終了した場合には、パッケージは未インストール 状態になっています。
-
-
新しいパッケージのファイルが展開され、システムに既にあるファイル、例えば同じパッケージの古いバージョンからのファイルや、 他のパッケージからのファイルに上書きされます 古いファイルのバックアップが一時的に保持され、もし何か問題が起こればパッケージ管理システムがエラー回復の一部としてそれらを元に戻そうとします。
あるパッケージが、現在システムにある別のパッケージの ファイルと同名のファイルを含んでいる場合、Replaces (ファイルの上書きとパッケージの置換 - Replaces, Section 7.6 参照) が指定されていない場合にはエラーになります。
パッケージにとってもっと深刻なエラーとなるのは、他のパッケージからのディレクトリがある場所に そのパッケージが普通のファイルやほかのディレクトリでないような内容物を含んでいた場合です (ここでも、Replaces が使われていない場合においてです)。もし望むなら、 --force-overwrite-dir を使ってこのエラーを無効にすることができますが、これは勧められません。
お互いのファイルに上書きするパッケージは、決定論的に決まるのではあるけれども、システム管理者には理解しがたい振る舞いをします。 この状態では、簡単にプログラムを「見失う」事態が起こり得ます。 例えば、他のパッケージからのファイルに上書きするようなパッケージをインストールして、それから、そのパッケージを削除することでこのような 「見失い」 [44] が起こります。
ディレクトリは、決してディレクトリへのシンボリックリンクに置き換わってしまうことはありませんし、その逆もありません。 そのかわりに、現在ある状態 (シンボリックリンクであるのか否か) はそのままにされて、シンボリックリンクの場合
dpkgはそのリンクをたどります。
-
-
もし、パッケージがアップグレードされている最中なら、次の呼び出しを行ないます。
old-postrm upgrade new-version
-
--> もしこれに失敗したら、
dpkgは次の呼び出しを試みます。new-postrm failed-upgrade old-versionこれが正常終了する場合、インストールを続行します。 うまくいかない場合には、エラー回復は
old-preinst abort-upgrade new-versionです。これが失敗した場合、パッケージは "Half-Installed" 状態で残っています。これが正常終了した場合、dpkg は次に、
new-postrm abort-upgrade old-versionを実行します。これが失敗した場合、パッケージは "Half-Installed" 状態で残っています。 これが正常終了した場合、dpkg は次に、
old-postinst abort-upgrade new-versionを実行します。これが失敗した場合、旧バージョンは "Unpacked" 状態になっています。
ここが戻れなくなるポイントです。
dpkgがさらに先に進むと、エラーがあった場合にもこのポイントより前には戻りません。 この場合、パッケージが非常に悪い状態で残り、 これをきれいにするためには、再インストールを成功させる必要があります。 ですが、ここはdpkgが戻ることのできない作業を始める時です。 -
-
古いバージョンのパッケージにはあって、新しいものには無いファイルは削除されます。
-
ファイルリストが、古いものから新しいものに置きかえられます。
-
新しいメンテナスクリプトで、古いものを置きかえます。
-
あるパッケージに属するファイルが、インストールの間に全て上書きされ、依存の要求も無いような場合、そのパッケージは削除されたと見なします。 そのようなパッケージそれぞれに対して、
-
dpkgは次の呼び出しを行ないます。disappearer's-postrm disappear \ overwriter overwriter-version
-
パッケージ管理スクリプトが削除されます。
-
パッケージ状態のデータベースには、正常な状態、つまりインストールされていないものとして記録されます (そのパッケージが持っていた設定ファイルがあれば、それは
dpkgによって削除されるのではなく、無視されます)。dpkgは前もって、そのパッケージが削除されそうなのかどうかを知らないので、 削除されるパッケージの `prerm' は 呼び出されないということに注意してください。
-
-
展開しようとしているパッケージの中にあって、他のパッケージのファイルリストにも記されている全てのファイルは、これらのリストから削除されます (これにより、もし「衝突する」パッケージがあれば、その衝突するパッケージのファイルリストが修正されます)。
-
今までのインストール作業の中で作成されていたバックアップファイルを消去します。
-
新しいパッケージの状態は、今では正常になっていますので、「展開 (unpacked)」として記録されます。
ここが次の戻れなくなるポイントです。 もし衝突するパッケージの削除に失敗したばあいでも、これから後のインストール作業を戻すようなことはしません。 衝突したパッケージは半分削除された亡霊状態で残ってしまいます。
-
もし衝突するパッケージがあれば、次項に記載の削除作業へ移り、実行します。 削除作業は衝突するパッケージのファイルを削除することから始まります (インストールされたパッケージの中にもあるファイルは、すでに衝突するパッケージのファイルリストから削除されているので、 この際に削除されてしまうことはありません)。
6.7 設定の詳細
パッケージを設定する (この状況は dpkg --install や dpkg --configure で起きます) とき、まず conffile を更新し、それから次の呼び出しが行われます。
postinst configure most-recently-configured-version
設定中にエラーが起こった後、回復は行われません。設定に失敗した場合、パッケージは "Failed Config" 状態になっており、エラーメッセージが作成されます。
もし最近設定されたバージョン (上の呼び出しの
most-recently-configured-version) が存在しなければ、
dpkg は引数として何も渡しません。 [45]。
6.8 削除と設定の完全削除の詳細
-
prerm removeもし、prerm が競合 (conflict) のために置きかえに失敗する場合、
conflictor's-postinst abort-remove \ in-favour package new-versionまたは、
postinst abort-removeを実行します。
これが正常終了しない場合、パッケージは "Half-Configured" 状態か、"Installed" 状態のままのいずれかになります。
-
パッケージのファイルを (conffile 群を除いて) 削除します。
-
postrm remove失敗した場合にエラーを巻き戻す方法はありません。パッケージは "Half-Installed" 状態となっています。
-
postrm以外のメンテナスクリプトを全て削除します。もしパッケージを完全削除しているのでなければ、ここで止まります。 パッケージに
postrmも conffile もないのであれば、削除 (remove) と完全削除 (purge) にはdpkgの状態以外に違いが無いので、自動的に完全削除されることに注意してください。
-
conffile と全てのバックアップファイル (~ ファイル、 #*# ファイル、% ファイル、 .dpkg-{old,new,tmp} など) が削除されます。
-
postrm purgeこれが失敗した場合、パッケージは "Config-Files" 状態のままになっています。
-
パッケージのファイルリストが削除されます。
[ previous ] [ Contents ] [ 1 ] [ 2 ] [ 3 ] [ 4 ] [ 5 ] [ 6 ] [ 7 ] [ 8 ] [ 9 ] [ 10 ] [ 11 ] [ 12 ] [ A ] [ B ] [ C ] [ D ] [ E ] [ F ] [ G ] [ next ]
Debian ポリシーマニュアル
バージョン 3.9.1.0, 2011-07-05The Debian Policy Mailing List
