Dear all, pasting a lot from /usr/share/doc/dpkg-dev/triggers.txt.gz and deb-triggers(1), I have drafted a patch to the Policy to document triggers.
Your comments are very welcome. Have a nice week-end, -- Charles
>From 04f094a0bfa98643ccead594be9d880439eae0b8 Mon Sep 17 00:00:00 2001 From: Charles Plessy <ple...@debian.org> Date: Sat, 2 Mar 2013 22:48:04 +0900 Subject: [PATCH] Document dpkg triggers. Closes: #582109. --- policy.sgml | 280 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 273 insertions(+), 7 deletions(-) diff --git a/policy.sgml b/policy.sgml index d81891c..7d9872d 100644 --- a/policy.sgml +++ b/policy.sgml @@ -892,9 +892,12 @@ zope. the package. Other control information files include the <qref id="sharedlibs-symbols"><file>symbols</file> file</qref> or <qref id="sharedlibs-shlibdeps"><file>shlibs</file> file</qref> - used to store shared library dependency information and + used to store shared library dependency information, the <file>conffiles</file> file that lists the package's - configuration files (described in <ref id="config-files">). + configuration files (described in <ref id="config-files">), and the + file <file>triggers</file> that lists the + <qref id="dpkg-triggers">triggers</qref> that the package is interested + in. </p> <p> @@ -3950,6 +3953,56 @@ Checksums-Sha256: </p> <p> + Dpkg defines the folowing states for the packages. + <taglist> + <tag><tt>not-installed</tt></tag> + <item> + The package is not installed or has been purged. + </item> + + <tag><tt>config-files</tt></tag> + <item> + The package has been removed; its configuration files remain. + </item> + + <tag><tt>half-installed</tt></tag> + <item> + Errors happened during installation, upgrade or removal. Solving + them requires the package to be re-installed. + </item> + + <tag><tt>unpacked</tt></tag> + <item> + The files contained in the package have been successfuly unpacked, + but the maintainer scripts have not been executed. Thus, the + files created by the maintainer scripts are not yet available. + </item> + + <tag><tt>half-configured</tt></tag> + <item> + The package has been unpacked, and an error occured during the + execution of one of its maintainer scripts. + </item> + + <tag><tt>triggers-awaited</tt></tag> + <item> + The package has been unpacked and configured, and its + installation activated some <prgn>dpkg</prgn> triggers that have + not yet been executed. + </item> + + <tag><tt>triggers-pending</tt></tag> + <item> + Some triggers handled by this package have been activated and are + not yet executed. + </item> + + <tag><tt>installed</tt></tag> + <item> + The package is installed, no further action is required. + </item> + </taglist> + <p> Broadly speaking the <prgn>preinst</prgn> is called before (a particular version of) a package is unpacked, and the <prgn>postinst</prgn> afterwards; the <prgn>prerm</prgn> @@ -4133,6 +4186,26 @@ Checksums-Sha256: from the package dependencies are not available is often the best approach. </item> + + <tag><var>postinst</var> <tt>triggered</tt> + "<var>trigger-name</var> <var>trigger-name</var> ..."</tag> + <item> + Process one or more <qref id="dpkg-triggers">triggers</qref> that + this package is <em>interested</em> in. In case of failure the + package's state becomes <tt>config-failed</tt>, so that the trigger + processing will not be attempted again until explicitly + requested<footnote> + When an interested package has more than one trigger and wants + to process them differently, the list of triggers can be can be + examined in a shell script like this: + <example> +case " $2 " in +*" trigger-name-a "*) process-trigger-a ;; +esac</example> + Generally each trigger name should be tested for separately, as + the postinst will often be called for several triggers at once. + </footnote>. + </item> </taglist> </p> @@ -4686,6 +4759,198 @@ fi </p> </sect> + + <sect id="dpkg-triggers"> + <heading>Dpkg triggers</heading> + + <p> + A <prgn>dpkg</prgn> trigger is a facility that allows events caused + by the installation, upgrade or removal of one package, and of + <em>interest</em> to another package, to be recorded and + aggregated, and processed later by the interested package. This + feature simplifies various registration and system-update tasks and + reduces duplication of processing. + <p> + + <p> + Each trigger is named, and at any time zero or more packages may be + <em>interested</em> in it. Packages declare their interest by + including a <file>triggers</file> file in their control archive. + This file contains one directive per line. Leading and trailing + whitespace, everything after the first hash character (<tt>#</tt>) + on any line, and empty lines are ignored. The following directives + are supported. + <taglist> + <tag><tt>interest</tt> <var>trigger-name</var></tag> + <tag><tt>interest-noawait</tt> <var>trigger-name</var></tag> + <item> + Specifies that the package is interested in the named trigger. + The <em>noawait</em> variant does not put the triggering packages + in <tt>triggers-awaited</tt> state, and does not add the + interested package to the <tt>Triggers-Awaited</tt> list of the + triggering package. + </item> + + <tag><tt>activate</tt> <var>trigger-name</var></tag> + <tag><tt>activate-noawait</tt> <var>trigger-name</var></tag> + <item> + Specifies that changes to this package's state will activate the + named trigger. The <em>noawait</em> variant does not put the + triggering packages in <tt>triggers-awaited</tt> state, and does + not add the interested package to the <tt>Triggers-Awaited</tt> + list of the triggering package. + </item> + </taglist> + </p> + + <p> + There currently two kinds of triggers. + <taglist> + <tag>Explicit triggers</tag> + <item> + These can be activated by any program by running + <prgn>dpkg-trigger</prgn> (at any time, but ideally from a + maintainer script. + </item> + + <tag>File triggers</tag> + <item> + These are activated automatically by <prgn>dpkg</prgn> when a + matching file or directory is created, upgraded or deleted as + part of a package's unpacking or removal. They may also be + explicitly activated by running <prgn>dpkg-trigger</prgn>. + Trigger activation due to a particular file should not generally + modify that file again. If there are directory symlinks which + result in packages referring to files by different names, then to + be sure of activation all of the paths which might be included in + packages should be listed. The path specified by the interested + package is matched against the path included in the triggering + package, not against the true name of the file as installed. + Only textually identical filenames (or filenames where the + interest is a directory prefix of the installed file) are + guaranteed to match. + </item> + </taglist> + </p> + + <p> + Trigger names are composed of US-ASCII characters excluding + control characters and space (i.e., characters in the range 33-126, + inclusive). The names of file triggers is an absolute path to + a file or a directory. The names of Explicit triggers have the same + syntax as package names, but should not by identical to a package + name<footnote> + When choosing an explicit trigger name it is usually good to + include a relevant package name or some other useful identifier + to help make the trigger name unique. On the other hand, + explicit triggers should generally not be renamed just because + the interested or triggering packages' names change. + </footnote>. + </p> + + <p> + When a configured package activates a trigger, its state becomes + <tt>triggers-awaited</tt> instead of <tt>installed</tt>. For this + package, <prgn>dpkg</prgn> keeps a list, <tt>Triggers-Awaited</tt> + of interested packages whose trigger processing is awaited. Every + package in this list either has a nonempty list of pending triggers, + or is in <tt>config-failed</tt> or worse. When a package in the + state <tt>triggers-pending</tt> becomes <tt>installed</tt>, + <tt>config-files</tt> or <tt>not-installed</tt>, its entry is + removed from the <tt>Triggers-Awaited</tt> lists of other packages. + </p> + + <p> + When a trigger is activated, the state of every interested package + becomes <tt>triggers-pending</tt>. For each package, + <prgn>dpkg</prgn> keeps a list, <tt>Triggers-Pending</tt>, of + triggers whose processing is pending. Repeated activation of the + same trigger has no additional effect. In general a trigger will + not be processed immediately when it is activated; processing is + deferred until it is convenient. + </p> + + <p> + Packages in the state <tt>triggers-pending</tt> that activate a + trigger become <tt>triggers-awaited</tt>. If a package has nonempty + <tt>Triggers-Awaited</tt> and <tt>Triggers-Pending</tt> lists, then + its state is <tt>triggers-awaited</tt>. Nevertheless efforts will + still be made to process its triggers so as to empty the + <tt>Triggers-Pending</tt> list. When a package in the state + <tt>triggers-awaited</tt> no longer awaits any packages, it become + <tt>installed</tt> or <tt>triggers-pending</tt>. + </p> + + <p> + Packages should be written so that they do not break just because + their pending triggers have not yet been run. It is allowed for the + functionality relating to the unprocessed trigger to fail (ie, the + package which is awaiting the trigger processing may be broken), but + the remainder of the interested package must work normally. + </p> + + <p> + Packages in <tt>config-files</tt> or <tt>not-installed</tt> do not + await triggers. + </p> + + <p> + Triggers are processed by running the intersted packages' + <tt>postinst</tt> script with the <tt>triggered</tt> parameter (see + <ref id="mscriptsinstact">). This will be attempted for each + relevant package at the end of each <prgn>dpkg</prgn> run; so, + normally, in the same dpkg run as the event which made the package go + to <prgn>triggers-pending</prgn>. + </p> + + <p> + Packages in <tt>config-failed</tt> or worse are never considered to + have lists of pending triggers. A package whose postinst is being + run can however acquire pending triggers during that run (ie, a + package can trigger itself). + </p> + + <p> + This means that if a triggering package <var>T</var> awaits trigger + processing by an interested package <var>I</var>, and <var>I</var> + goes to <tt>config-failed</tt> or worse (eg, during unpack for + upgrade), then when <var>I</var> is reconfigured (goes to + <tt>installed</tt>) or removed, <var>T</var> will no longer await + processing by <var>I</var>, so that <var>T</var> may automatically go + from <tt>triggers-awaited</tt> to <tt>installed</tt>. + </p> + + <p> + Or to put it another way, triggered actions are considered irrelevant + if the interested package <var>I</var> is not configured. When + <var>I</var>'s postinst is called with <tt>configure</tt>, it must do + whatever actions are necessary to deal with any trigger activations + which might have occurred while it was not configured, just as if the + package was being configured for the first time. + </p> + + <p> + A package is only guaranteed to become notified of a trigger + activation if it is continuously interested in the trigger, and never + in <tt>config-failed</tt> or worse, during the period from when the + trigger is activated until dpkg runs the package postinst (either due + to <tt>--configure --pending</tt>, or at the end of the relevant run, + as described above). Subsequent to activation and before + notification, the interested package will not be considered in state + <tt>installed</tt>, so long as the package remains interested, and + the triggering package will not be considered <tt>installed</tt>. + </p> + + <p> + If the package is not in state <tt>installed</tt>, + <tt>triggers-pending</tt> or <tt>triggers-awaited</tt> then pending + triggers are not accumulated. However, if such a package (between + <tt>half-installed</tt> and <tt>config-failed</tt> inclusive) + declares some trigger interests then the triggering packages will + await their configuration (which implies completion of any necessary + trigger processing) or removal. + </p> + </sect> </chapt> @@ -4708,8 +4973,8 @@ fi dependencies on other packages, the package names listed may also include lists of alternative package names, separated by vertical bar (pipe) symbols <tt>|</tt>. In such a case, - if any one of the alternative packages is installed, that - part of the dependency is considered to be satisfied. + if any one of the alternative packages is installed or has pending + triggers, that part of the dependency is considered to be satisfied. </p> <p> @@ -4970,7 +5235,8 @@ Build-Depends: foo [linux-any], bar [any-i386], baz [!linux-any] <prgn>postinst</prgn> or <prgn>prerm</prgn> scripts require the depended-on package to be unpacked or configured in order to run. In the case of <tt>postinst - configure</tt>, the depended-on packages will be unpacked + configure</tt> and <tt>postinst triggers</tt>, + the depended-on packages will be unpacked and configured first. (If both packages are involved in a dependency loop, this might not work as expected; see the explanation a few paragraphs back.) In the case @@ -8089,8 +8355,8 @@ Reloading <var>description</var> configuration...done. <p> The <package>mime-support</package> package provides the <prgn>update-mime</prgn> program, which integrates these - registrations in the <file>/etc/mailcap</file> file, using dpkg - triggers<footnote> + registrations in the <file>/etc/mailcap</file> file, using + <qref id="dpkg-triggers">dpkg triggers</qref><footnote> Creating, modifying or removing a file in <file>/usr/lib/mime/packages/</file> using maintainer scripts will not activate the trigger. In that case, it can be done by calling -- 1.8.2.rc0