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

Hooks mechanism



I won't bother with the usual `why are we doing this' questions.  I
think we know what the point of a hooks mechanism is.

I do want to make some observations, though:

* Packages whose hook scripts fail should _not_ be marked as properly
installed.

* Hook scripts will often interact with data supplied by many other
packages (e.g. the menu system).  The package which `owns' a
particular set of this data should be able to validate the data
supplied by a package, so that a package with a bad hook data item
(better name, please?) can be marked as broken.

* Sometimes hook data will be supplied by conffiles.  The admin will
be required to run an `update' program if they edit the conffiles.
If they get the syntax wrong then the update program may fail, and the
package with the hook script will be marked as broken (?)

* Hook scripts should be triggerable from other events - at least, on
status change of a certain named package (or provider thereof) and on
installation/removal/modification of a certain file or directory.

* Hook scripts should not usually be a prerequisite for the event
taking place; instead, all packages' hooks should be run later.
Otherwise the error handling complexity (and possible recursion) will
become even more fearsome.

* One package's hook(s) cannot invoke another's: ie, the hook scripts
are run last, and cannot cause more hooks to need to be run.

I propose to have _one_ hook script for each package triggered by the
hooks mechanism, which will be invoked for all hooks.  This will make
it obvious that it has to be idempotent.  It will be much simpler if
we don't have to record why the script is being run (ie, what
triggered the hook) - then we can have the package have a new Status
value meaning `need to run the hooks for this package'.

Possibly this script ought to be the postinst, but I don't think so,
because a state change to `not-configured' ought to involve running
the prerm and we don't want to do that.

So, how about a new `posthook' script, kept in the control archive,
and new Status values `hook-triggered' and `hook-failed'.
`hook-triggered' means that something on the system thinks the hook
should be run, and `hook-failed' means that the posthook script
returned a non-zero exit status.

If A -depends-> B then dpkg will not run the posthook script from
package A if B is not `installed' (this means that if both A's and B's
hooks are triggered by an event then B's, if any, will be run first).

So, how do we invoke these hooks ?  I propose three main mechanisms:

* Package hooks.  The control file contains:
     Hook-Packages: <dependency syntax>
If any status change happens to any package listed or a provider of
such a package, then the package whose control file this appears in
has its hook triggered.  `Status change' includes such a package being
installed, removed, or upgraded, unless all the versions of the
package(s) involved fail to satisfy the dependency.

* File/directory hooks.  The control archive contains a file
`filehooks' with a list of absolute pathnames.  If dpkg installs,
upgrades or removes a package which contains a file or directory whose
name is listed in this file then the package with the filehook script
has its hook triggered.

* File-in-directory hooks.  The `filehooks' file contains a line of
the form:
<directory-path>\t<checking-program>
In this case, after new or changed file(s) have been installed in the
directory (or one of its subdirectories), the <checking-program> will
be run with the pathnames of the new or changed file(s) _before_ dpkg
leaves the installation/upgrade stage.  If the <checking-program>
fails then dpkg's error message will say which package declared the
check, but then back out of the install or upgrade of the package with
the new or changed (hopefully faulty) file.  This is in addition to
the usual function of the filehooks file.

Good practice would be for all packages which use a particular hook
directory to depend on the same core package containing the checking
script.

We need an escape syntax for the `filehooks' file in case people want
\n's or \t's in their filenames.  C's \ooo will do (but means we have
to escape \ as well).


What does it mean to trigger a package's hook ?  If the package is not
installed and configured (ie, state half-configured or worse), then
nothing happens.  From states `installed' and `hook-failed' the
package gets put back into `hook-triggered'.

dpkg will run hooks after each normal processing run, unless told
otherwise.


Comments ?

Ian.


Reply to: