[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#582109: debian-policy: document triggers where appropriate



Le Wed, Jul 24, 2013 at 03:58:04PM +0200, Julien Cristau a écrit :
> On Wed, Jul 17, 2013 at 09:27:19 +0200, Raphael Hertzog wrote:
> 
> > On Wed, 17 Jul 2013, Charles Plessy wrote:
> > > About the problem of triggers being called with Depends not satisfied, can you
> > > give more explanations or suggest some text for the warning ?  Would it be
> > > enough to add a notice that the triggered postinst script may be called when
> > > the package is "Unpacked", which is a state that does not require that the
> > > packages that are depended on are configured ?
> > 
> > Julien is referring to this bug:
> > http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=671711
> > 
> > It might be fixed for jessie, at least I hope so, but he seems to doubt
> > it.
> 
> It doesn't really matter whether it's fixed for jessie.  Since it's not
> fixed in wheezy, it's relevant for packages in jessie when they're
> upgraded.

Hi Julien,

does the current patch (attached) address your concerns ?  If yes, would
you second it ?

The paragraph on "postinst triggers" is now as follows.

	postinst configure was already run and the dependencies ought to be configured.
	However, dpkg currently suffers of a bug which means that postinst triggered
	can be called while some dependencies are being upgraded (see bug 671711).
	Until this bug is absent from the stable release, you should thus only rely on
	the fact that the dependencies are at least unpacked and were already
	configured once (similar to what Pre-Depends ensures for preinst maintainer
	scripts). postinst triggered processes one or more triggers that this package
	is interested in. In case of failure the package's state becomes
	"Half-Configured" and the task associated to the trigger processing will be
	completed by the postinst configure during the next package's
	configuration[48].

Have a nice day,

-- 
Charles
diff --git a/debian/changelog b/debian/changelog
index fe4a858..20e3f84 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -33,6 +33,11 @@ debian-policy (3.9.5.0) UNRELEASED; urgency=low
     Seconded: Charles Plessy <plessy@debian.org>
     Seconded: Jonathan Nieder <jrnieder@gmail.com>
     Closes: #715804
+  * Policy: Document dpkg states and triggers.
+    Wording: Charles Plessy <plessy@debian.org>
+    Seconded: Raphaël Hertzog <hertzog@debian.org>
+    Seconded:
+    Closes: #582109
   * debconf_spec: Document the 'escape' capability.
     Wording: Jonathan Nieder <jrnieder@gmail.com>
     Seconded: Charles Plessy <plessy@debian.org>
diff --git a/policy.sgml b/policy.sgml
index 953d5d2..b846118 100644
--- a/policy.sgml
+++ b/policy.sgml
@@ -900,9 +900,11 @@ 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>triggers</file> file, which defines the package's interaction with
+	<prgn>dpkg</prgn>'s <qref id="dpkg-triggers">trigger</qref> system.
       </p>
 
       <p>
@@ -3959,6 +3961,51 @@ Checksums-Sha256:
 	</p>
 
 	<p>
+	  Dpkg defines the following states for the packages.
+	  <taglist>
+	    <tag>Not-Installed</tag>
+	    <item>
+	      The package is not installed on the system.
+	    </item>
+
+	    <tag>Config-Files</tag>
+	    <item>
+	      Only the configuration files of the package exist on the system.
+	    </item>
+
+	    <tag>Half-Installed</tag>
+	    <item>
+	      The installation of the package has been started, but not
+	      completed for some reason.
+	    </item>
+
+	    <tag>Unpacked</tag>
+	    <item>
+	      The package is unpacked, but not configured.
+	    </item>
+
+	    <tag>Half-Configured</tag>
+	    <item>
+	      The package is unpacked and its configuration or the processing
+	      of one of its triggers has not yet completed for some reason.
+	    </item>
+
+	    <tag>Triggers-Awaited</tag>
+	    <item>
+	      The package awaits trigger processing by another package.
+	    </item>
+
+	    <tag>Triggers-Pending</tag>
+	    <item>
+	      The package has been triggered.
+	    </item>
+
+	    <tag>Installed</tag>
+	    <item>
+	      The package is unpacked and configured.
+	    </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>
@@ -4106,7 +4153,11 @@ Checksums-Sha256:
 	      are no circular dependencies involved, all package
 	      dependencies will be configured.  For behavior in the case
 	      of circular dependencies, see the discussion
-	      in <ref id="binarydeps">.
+	      in <ref id="binarydeps">.  Even when called with
+	      <tt>configure</tt>, this script must do whatever actions are
+	      necessary to deal with any
+	      <qref id="dpkg-triggers-intermediate-states">triggers</qref>
+	      activation.
 	    </item>
 
 	    <tag><var>old-postinst</var> <tt>abort-upgrade</tt>
@@ -4141,6 +4192,39 @@ 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>
+	      <prgn>postinst configure</prgn> was already run and the
+	      dependencies ought to be configured. However, <prgn>dpkg</prgn>
+	      currently suffers of a bug which means that <prgn>postinst
+              triggered</prgn> can be called while some dependencies are being
+	      upgraded (see bug <url id="http://bugs.debian.org/671711";
+	      name="671711">). Until this bug is absent from the stable
+	      release, you should thus only rely on the fact that the
+	      dependencies are at least unpacked and were already configured once
+	      (similar to what <tt>Pre-Depends</tt> ensures for
+	      <prgn>preinst</prgn> maintainer scripts).
+
+	      <prgn>postinst triggered</prgn> processes 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 "Half-Configured" and the task associated
+	      to the trigger processing will be completed by the
+	      <tt>postinst configure</tt> during the next package's
+	      configuration<footnote>
+		When an interested package has more than one trigger and wants
+		to process them differently, the list of triggers 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>
 
@@ -4694,6 +4778,215 @@ fi
 
 	</p>
       </sect>
+
+      <sect id="dpkg-triggers">
+	<heading>Dpkg triggers</heading>
+
+	<sect1 id="dpkg-triggers-concepts">
+	<heading>Concepts</heading>
+
+	  <p>
+	    Dpkg triggers allow packages to monitor events caused by
+	    the installation, upgrade or removal of other packages. Monitoring
+	    packages are said to be <em>interested</em> in some triggers. On the
+	    other side, triggers must be <em>activated</em> to notify the
+	    interested package, which is then said to have <em>pending</em>
+	    triggers.  The activating package (if any) is said to <em>await</em>
+	    the processing of the trigger.
+	  <p>
+
+	  <p>
+	    The purpose of this feature is to to avoid duplication of processing
+	    logic among packages by implementing it in one package and making
+	    sure that all other packages rely on triggers to execute the wanted
+	    code.
+	  </p>
+
+	  <p>
+	    Each trigger is named, and at any time zero or more packages may be
+	    <em>interested</em> in it.  For a package to declare its interest in
+	    a trigger, it must include one of the <tt>interest</tt> directives
+	    in the <file>triggers</file> file in its control archive.
+	  </p>
+	</sect1>
+
+	<sect1 id="dpkg-triggers-syntax">
+	<heading>Syntax</heading>
+
+	  <p>
+	    The <file>triggers</file> control 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-noawait</tt> <var>trigger-name</var></tag>
+	      <tag><tt>interest</tt> <var>trigger-name</var></tag>
+	      <item>
+		Specifies that the package is interested in the named trigger.
+		The <tt>interest</tt> variant puts the triggering packages in
+		the "Triggers-Awaited" state, and the <tt>interest-noawait</tt>
+		variant does not.
+	      </item>
+
+	      <tag><tt>activate-noawait</tt> <var>trigger-name</var></tag>
+	      <tag><tt>activate</tt> <var>trigger-name</var></tag>
+	      <item>
+		Specifies that changes to this package's state will activate the
+		named trigger.  The <tt>activate</tt> variant puts this package
+		in the "Triggers-Awaited" state, and the
+		<tt>activate-noawait</tt> variant does not.
+	      </item>
+	    </taglist>
+	  </p>
+
+	  <p>
+	    The <tt>*-noawait</tt> directives should be used unless the
+	    packages awaiting triggers can not satisfy <tt>Depends</tt>
+	    relationships until the triggers have been processed.
+	    In that case, the <tt>interest</tt> or <tt>activate</tt> directives
+	    should be used, as they will put the triggering packages in the
+	    "Triggers-Awaited" state, which does not satisfy dependencies.
+	    Note that packages unnecessarily entering this state can cause the
+	    early processing of triggers or even dependency loops.
+	  </p>
+
+	  <p>
+	    There are 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), and by state changes of packages having an
+		<em>activate</em> directive in their <file>triggers</file>
+		control file.
+	      </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><footnote>
+		  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.</footnote>.
+	      </item>
+	    </taglist>
+	  </p>
+
+	  <p>
+	    The name of a file trigger is 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 be 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>
+	</sect1>
+
+	<sect1 id="dpkg-triggers-mechanism">
+	<heading>Mechanism</heading>
+
+	  <p>
+	    Triggers are processed by running the interested 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 (unless
+	    <tt>--no-triggers</tt> has been used); so, normally, in the same dpkg
+	    run as the event which marked the package "Triggers-Pending".
+	  </p>
+
+	  <p>
+	    When a configured package activates a trigger through the
+	    <tt>interest</tt> or <tt>activate</tt> directives, its state becomes
+	    "Triggers-Awaited" instead of "Installed".  For this package,
+	    <prgn>dpkg</prgn> keeps a list of interested packages whose trigger
+	    processing is awaited, which is stored in the
+	    <tt>Triggers-Awaited</tt> field in dpkg's status database.  Every
+	    package in this list either has a nonempty list of pending
+	    triggers, or is in "Half-Configured" or worse.  When a package in
+	    the state "Triggers-Pending" becomes "Installed", "Config-Files" or
+	    "Not-Installed", 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 "Triggers-Pending".  For each package, <prgn>dpkg</prgn>
+	    keeps a list keeps a list of interested packages whose trigger
+	    processing is pending, which is stored in the
+	    <tt>Triggers-Pending</tt> field in dpkg's status database.
+	    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 "Triggers-Pending" that activate a trigger
+	    become "Triggers-Awaited".  If a package has nonempty
+	    <tt>Triggers-Awaited</tt> and <tt>Triggers-Pending</tt> lists, then
+	    its state is "Triggers-Awaited".  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
+	    "Triggers-Awaited" no longer awaits any packages, it becomes 
+	    "Installed" or "Triggers-Pending".  
+	  </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>
+	</sect1>
+
+	<sect1 id="dpkg-triggers-intermediate-states">
+	<heading>The case of packages in intermediate states</heading>
+
+	  <p>
+	    Packages in "Config-Files" or "Not-Installed" do not await triggers.
+	  </p>
+
+	  <p>
+	    Packages in "Half-Configured" or worse never have pending triggers.
+	    A package is only guaranteed to become notified of a trigger
+	    activation if it is continuously interested in the trigger, and never
+	    in "Half-Configured" or worse.  A package whose postinst is being run
+	    can however acquire pending triggers during that run (ie, a package
+	    can trigger itself).
+	  </p>
+
+	  <p>
+	    However, if such a package (between "Half-Installed" and
+	    "Half-Configured" inclusive) declares some trigger interests then the
+	    triggering packages will await their configuration (which implies
+	    completion of any necessary trigger processing) or removal.
+	  </p>
+
+	  <p>
+	    For this reason, the <tt>postinst</tt> scripts must do whatever
+	    actions are necessary to deal with any trigger activation when they
+	    are called with <tt>configure</tt>.
+	  </p>
+	</sect1>
+      </sect>
     </chapt>
 
 
@@ -4978,7 +5271,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 triggered</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
@@ -8097,8 +8391,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
diff --git a/upgrading-checklist.sgml b/upgrading-checklist.sgml
index 5714e84..b0e6a29 100644
--- a/upgrading-checklist.sgml
+++ b/upgrading-checklist.sgml
@@ -55,6 +55,18 @@ Unreleased.
   <item>New section documenting the <tt>Package-Type</tt> field in source
   package control files.
   </item>
+<tag>6.1</tag>
+  <item>The Dpkg states are now documented.  The Policy has been proofread
+  and occurences of "Failed-Config" have been corrected to "Half-Configured".
+  </item>
+<tag>6.5</tag>
+  <item>The <tt>triggered</tt> call for the <var>postinst</var> script is now
+  documented.  <var>postinst</var> <tt>configure</tt> must do whatever actions
+  are necessary to deal with any triggers activation.
+  </item>
+<tag>6.9</tag>
+  <item>New section describing Dpkg triggers in details.
+  </item>
 <tag>11.5.2</tag>
   <item>Stop recommending to serve HTML documents from
   <file>/usr/share/doc/<var>package</var></file>.

Reply to: