It is possible supply scripts as part of a package which
dpkg
will run for you when your package is
installed, upgraded or removed.
These scripts should be the files preinst, postinst, prerm and postrm in the control area of the package. They must be proper exectuable files; if they are scripts (which is recommended) they must start with the usual #! convention. They should be readable and executable to anyone, and not world-writeable.
dpkg
looks at the exit status from these
scripts. It is important that they exit with a non-zero
status if there is an error, so that dpkg
can
stop its processing. For shell scripts this means that you
almost always need to use set -e (this is
usually true when writing shell scripts, in fact). It is
also important, of course, that they don't exit with a
non-zero status if everything went well.
It is necessary for the error recovery procedures that the scripts be idempotent: ie, invoking the same script several times in the same situation should do no harm. If the first call failed, or aborted half way through for some reason, the second call should merely do the things that were left undone the first time, if any, and exit with a success status.
When a package is upgraded a combination of the scripts from the old and new packages is called in amongst the other steps of the upgrade procedure. If your scripts are going to be at all complicated you need to be aware of this, and may need to check the arguments to your scripts.
Broadly speaking the preinst
is called before
(a particular version of) a package is installed, and the
postinst
afterwards; the prerm
before (a version of) a package is removed and the
postrm
afterwards.
Programs called from maintainer scripts should not
normally have a path prepended to them. Before installation
is started dpkg
checks to see if the programs
ldconfig
, start-stop-daemon
,
install-info
, and update-rc.d
can
be found via the PATH environment variable. Those
programs, and any other program that one would expect to on
the PATH, should thus be invoked without an
absolute pathname. Maintainer scripts should also not reset
the PATH, though they might choose to modify it by
pre- or appending package-specific directories. These
considerations really apply to all shell scripts.
The procedure on installation/upgrade/overwrite/disappear (ie, when running dpkg --unpack, or the unpack stage of dpkg --install) is as follows. In each case if an error occurs the actions in are general run backwards - this means that the maintainer scripts are run with different arguments in reverse order. These are the `error unwind' calls listed below.
old-prerm upgrade new-version
new-prerm failed-upgrade old-versionError unwind, for both the above cases:
old-postinst abort-upgrade new-version
If a `conflicting' package is being removed at the same time:
deconfigured's-prerm deconfigure \ in-favour package-being-installed version \ removing conflicting-package versionError unwind:
deconfigured's-postinst abort-deconfigure \ in-favour package-being-installed-but-failed version \ removing conflicting-package versionThe deconfigured packages are marked as requiring configuration, so that if --install is used they will be configured again if possible.
conflictor's-prerm remove in-favour package new-versionError unwind:
conflictor's-postinst abort-remove \ in-favour package new-version
new-preinst upgrade old-version
new-preinst install old-version
new-preinst installError unwind versions, respectively:
new-postrm abort-upgrade old-version new-postrm abort-install old-version new-postrm abort-install
dpkg
will follow the symlink if there is
one.
old-postrm upgrade new-version
dpkg
will attempt:
new-postrm failed-upgrade old-versionError unwind, for both cases:
old-preinst abort-upgrade new-version
dpkg
gets this far, it won't back off past this point if an
error occurs. This will leave the package in a fairly
bad state, which will require a successful
reinstallation to clear up, but it's when
dpkg
starts doing things that are
irreversible.
Any packages all of whose files have been overwritten during the installation, and which aren't required for dependencies, are considered to have been removed. For each such package,
dpkg
calls:
disappearer's-postrm disappear \ overwriter overwriter-version
dpkg
). Note that
disappearing packages do not have their prerm
called, because dpkg
doesn't know
in advance that the package is going to
vanish.
When we configure a package (this happens with dpkg --install, or with --configure), we first update the conffiles and then call:
postinst configure most-recently-configured-version
No attempt is made to unwind after errors during configuration.
If there is no most recently configured version
dpkg
will pass a null argument; older versions
of dpkg may pass <unknown> (including the
angle brackets) in this case. Even older ones do not pass a
second argument at all, under any circumstances.
prerm remove
postrm remove
dpkg
status.
postrm purge