= DPKG Script Order =

Debian packages may contain scripts.  These scripts are run at
specific steps in the operation of installing and erasing packages on
the system. These are necessary such as when installing GNU info
documentation that needs to modify a shared info dir file.

The [http://www.debian.org/doc/debian-policy/ch-maintainerscripts.html
Debian Policy Manual] is the official reference to package scripts.
Look over that reference first.  I am going to expand on the ordering
of the scripts here.  Four scripts may be called.

 * prerm
 * postrm
 * preinst
 * postinst

== Install and Remove Examples ==

Installation of version 1:
{{{
dpkg --install trial-1.deb

preinst-1 install
postinst-1 configure ""
}}}

When no previously existing package is installed then the preinst
script is called with the {{{install}}} option.  The postinst script
is called with the {{{configure}}} option and an empty second
argument.  The empty argument would otherwise be the version of the
previously configured package.  Since none previously exist it is
empty.

Upgrade version 1 to version 2:
{{{
dpkg --install trial-2.deb

prerm-1 upgrade 2
preinst-2 upgrade 1
postrm-1 upgrade 2
postinst-2 configure 1
}}}

Upon an upgrade the previously installed package's prerm and postrm
scripts will be called.  These will be called before the incoming
package's preinst and postinst scripts respectively.  An existing
package has been previously installed and so this is an {{{upgrade}}}
instead of an {{{install}}} for the first argument.  The second
argument for the {{{rm}}} scripts is the version of new package and
for the {{{inst}}} scripts is the version of the old package.  If
something special needs to be done to handle the upgrade from one
particular version to another it may be triggered using the value of
that argument.

Upgrade 2 to 3:
{{{
dpkg --install trial-3

prerm-2 upgrade 3
preinst-3 upgrade 2
postrm-2 upgrade 3
postinst-3 configure 2
}}}

Continued upgrades are normal and there are no surprises.

Remove:
{{{
dpkg --remove trial

prerm-3 remove
postrm-3 remove
}}}

A dpkg --remove removes the package but leaves configuration files
configured on the system.  Because the configuration files remain the
package may be installed again without need to reconfigure.  In order
to remove the configuration files too the package can be purged.
Purging means to remove all trace that the package was installed.
Both configuration files and other files are removed.

Purge after a remove:
{{{
dpkg --purge trial

postrm-2 purge
}}}

In the above case the postrm script has already been called with the
{{{remove}}} argument.  Upon purge it is called again with the purge
argument.

Install 1, Purge 1:
{{{
dpkg --install trial-1

preinst-1 install
postinst-1 configure ""

dpkg --purge trial

prerm-1 remove
postrm-1 remove
postrm-1 purge
}}}

In this example the package was purged in one operation.  This calls
the {{{prerm}}} and {{{postrm}}} scripts with the remove option and
then again calls the {{{postrm}}} script with the purge option.  It is
called twice with different options each time.

Install 1, Upgrade 1, Purge 1:
{{{
dpkg --install trial-1

preinst-1 install
postinst-1 configure ""

dpkg --install trial-1

prerm-1 upgrade 1
preinst-1 upgrade 1
postrm-1 upgrade 1
postinst-1 configure

dpkg --purge trial

prerm-1 remove
postrm-1 remove
postrm-1 purge
}}}

The same version of a package can be installed over an existing
package of the same version.  The script order and arguments are as
you would expect.

== Error Examples ==

If a package script returns an error the system will take steps to
ensure robust system operation by running scripts as needed to return
to a good state.  The exact action is specific to each script that
could return an error.  Therefore a number of cases result due to the
combinations.  This will explore a few paths in detail.

The cases here are rarely needed to be used by most typical packages.
They are included for special cases where special processing is
needed.  But for most developers this information should only be an
idle curiosity and not something that is needed to be known in any
detail.  Merely note that it is available if the need for it arises.
Most of the time it is best to ignore this capability.

Install 1 with an error during preinst:
{{{
dpkg --install trial-1.deb

preinst-1 install  # error
postrm-1 abort-install

Status: install ok not-installed
}}}

Install 1 with an error during postinst:
{{{
dpkg --install trial-1.deb

preinst-1 install
postinst-1 configure ""  # error

Status: install ok half-configured
}}}

A status of {{{half-configured}}} will cause the {{{postinst}}}
scripts to be called in the following cases.

{{{
dpkg --configure -a
apt-get install -f
}}}

{{{
dpkg --install trial-1.deb

preinst-1 install  # error
postrm-1 abort-install # another error

Status: install reinstreq half-installed
}}}

If an additional error occurs during a {{{postinst abort-install}}}
then processing stops and the status is left as {{{install reinstreq
half-installed}}}.  This requires a reinstallation of the package
before any other operation is allowed.  Before removing the package it
must be reinstalled first.

Remove 1 with an error during prerm:
{{{
dpkg --remove trial

prerm-1 remove # error
postinst-1 abort-remove

Status: deinstall ok installed
}}}

Remove 1 with an error during prerm plus an error during the abort-remove:
{{{
dpkg --remove trial

prerm-1 remove # error
postinst-1 abort-remove # error

Status: deinstall ok half-configured
}}}

Purge 1 with an error during prerm plus an error during the abort-remove:
{{{
dpkg --purge trial

prerm-1 remove # error
postinst-1 abort-remove # error

Status: purge ok half-configured
}}}

Remove 1 with an error during postrm:
{{{
dpkg --remove trial

prerm-1 remove
postrm-1 remove # error

Status: deinstall ok config-files
}}}

Purge 1 with an error during postrm:
{{{
dpkg --purge trial

prerm-1 purge
postrm-1 remove
postrm-1 purge # error

Status: purge ok config-files
}}}

== Raw Data ==

A section of semi-raw data.
{{{
Install version 1:
  preinst-v1 install
  postinst-v1 configure

Upgrade version 1 to 2:
  prerm-v1 upgrade 2
  preinst-v2 upgrade 1
  postrm-v1 upgrade 2
  postinst-v2 configure 1

Upgrade version 2 to 3:
  prerm-v2 upgrade 3
  preinst-v3 upgrade 2
  postrm-v2 upgrade 3
  postinst-v3 configure 2

Remove version 3:
  prerm-v3 remove
  postrm-v3 remove

Purge version 3:
  postrm-v3 purge

Interruption during preinst-v4 script:
  postrm-v4 abort-upgrade 3
  postinst-v3 abort-upgrade 4

Upgrade version 3 to 4, interruption during postinst-v4 script:
  exits with errors
  Status: install ok half-configured
  dpkg -l reports Failed-config

Upgrade version 4 to 5, interruption during preinst-v5 script:
  prerm-v4 upgrade 5
  postinst-v4 abort-upgrade 5
  prerm-v4 upgrade 5
  preinst-v5 upgrade 4
  postrm-v5 abort-upgrade 4
  postinst-v4 abort-upgrade 5

Reinstalling after interrupt:
  prerm-v4 upgrade 4
  preinst-v4 upgrade 4
  postrm-v4 upgrade 4
  postinst-v4 configure 3

Downgrade version 5 to 3:
  prerm-v5 upgrade 3
  preinst-v3 upgrade 5
  postrm-v5 upgrade 3
  postinst-v3 configure 5

Upgrade v5 to v7, upgrade fails in preinst script.
  prerm-v5 upgrade 7
  preinst-v7 upgrade 5
  postrm-v7 abort-upgrade 5
  postinst-v5 abort-upgrade 7

Install v7, fails in preinst script.
  preinst-v7 install 5
  postrm-v7 abort-install 5

Purge, Install v7, fails in preinst script.
  preinst-v7 install
  postrm-v7 abort-install
}}}
