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

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



Le Wed, Apr 10, 2013 at 12:07:19PM +0200, Raphael Hertzog a écrit :
> 
> Here are my comments. There's quite a bit of work left.

Thanks a lot Raphaël and everybody !

I think that I took care of all of your comments.

Here is an updated patch.  Among the changes, it introduces
sub-section to make the information easier to digest.

Cheers,

-- 
Charles
diff --git a/policy.sgml b/policy.sgml
index 1508231..f7948de 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, wich 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>
+	      activations.
 	    </item>
 
 	    <tag><var>old-postinst</var> <tt>abort-upgrade</tt>
@@ -4141,6 +4192,27 @@ 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 "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 +4766,199 @@ 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</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 <tt>interest-noawait</tt> variant does not put the
+		triggering packages in the "Triggers-Awaited" state.
+	      </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 <tt>activate-noawait</tt> variant does not
+		put this package in the "Triggers-Awaited" state.
+	      </item>
+	    </taglist>
+	  </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-mechanims">
+	<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, its state becomes
+	    "Triggers-Awaited" instead of "Installed".  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 "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, <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 "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 it must do whatever
+	    actions are necessary to deal with any trigger activations when they
+	    are called with <tt>configure</tt>.
+	  </p>
+	</sect1>
+      </sect>
     </chapt>
 
 
@@ -4978,7 +5243,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 +8363,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

Reply to: