Home / Alt manpages / deb-triggers(5)

  • deb-triggers(5)
  • File format
  • linux

Declare Debian Package Triggers with deb-triggers

Your cache package needs to refresh whenever another package changes, and you do not want every upgrade to stall waiting for it. This guide gets you a valid DEBIAN/triggers file and a clear rule for choosing between interest-noawait and its waiting variants.

Allow about fifteen minutes. The examples match dpkg 1.22.6, provided here by package version dpkg-dev 1.22.6ubuntu6.6.

  • You need: a shell, dpkg-deb from the installed dpkg suite, and a writable temporary directory.
  • It will not touch: your system. The guide builds and inspects an archive only. It does not install it, activate a trigger on the host, or change package state, so the commands normally need no elevated privileges.

1. Decide which package owns the event

A trigger is a named hand-off between packages. Two roles, one shared name:

  • Interest. The package that receives and processes the event declares an interest.
  • Activation. The package whose state change causes the event declares an activation.
  • The name. For an explicit trigger, both packages must agree on the exact name.

Pick a name that describes the interface and is unlikely to collide with another package. The trigger name is not a shell command and should not contain whitespace. In this example, a package that maintains a cache will process example-cache-refresh when another package changes:

$ TRIGGER_NAME='example-cache-refresh'
$ printf '%s\n' "$TRIGGER_NAME"
example-cache-refresh

Checkpoint

Write down the interested package, the activating package, and the trigger name before editing either package. A spelling mismatch creates two unrelated interfaces.

2. Add the interested package's declaration

In a source package, put the declaration in debian/triggers. When one source builds several binary packages, use debian/BINARY-PACKAGE.triggers to target one binary package. During package construction, the file becomes DEBIAN/triggers in that binary package's control archive.

For a cache refresh that is useful but not required before the activating package can be configured, use the no-wait form:

interest-noawait example-cache-refresh

File rules:

  • Whitespace at the start or end of a line is ignored.
  • Comments start at the first #, and blank lines are ignored.
  • One directive per line. Unknown directives are errors and prevent installation.

Choosing the interest form:

  • interest permits the activation to put the triggering package into triggers-awaited.
  • interest-await is the explicit spelling of that waiting behaviour.
  • interest-noawait prevents that wait even when the activating side asks for one.

Tip

Choose no-wait only when delaying the trigger processing cannot make the activating package unusable or leave a required invariant broken.

Checkpoint

Inspect the file as plain text. There should be one supported directive and the exact trigger name:

$ sed -n 'l' debian/triggers
interest-noawait example-cache-refresh$

3. Add activation to the changing package

In the package whose installation or removal represents the event, add the matching activation directive. The activation is associated with package state changes, not with an arbitrary file write during normal operation:

activate-noawait example-cache-refresh

dpkg activates this trigger when the package is unpacked, configured, removed, purged or deconfigured. If the package disappears while another package is being unpacked, dpkg activates it when that disappearance is noticed near the end of the unpack. Trigger processing itself does not cause another activation.

The activation forms mirror the interest forms:

  • activate allows the requested waiting mode.
  • activate-await requests waiting.
  • activate-noawait never puts the triggering package into triggers-awaited.

The interested package still has the final say: interest-noawait forces no-wait for activations it receives.

Warning

Do not assume that activate-await always creates a wait. It only does so when the interested package uses interest or interest-await. This pairing is the most common source of misleading package-state checks.

4. Build a harmless archive and inspect it

You can test the file without installing anything. A minimal binary package needs a control file and the triggers file under a temporary package tree:

$ workdir=$(mktemp -d)
$ mkdir -p "$workdir/pkg/DEBIAN"
$ printf '%s\n' \
  'Package: example-cache' \
  'Version: 1.0' \
  'Architecture: all' \
  'Description: Trigger declaration test package' \
  > "$workdir/pkg/DEBIAN/control"
$ printf '%s\n' 'interest-noawait example-cache-refresh' > "$workdir/pkg/DEBIAN/triggers"
$ dpkg-deb --build "$workdir/pkg" "$workdir/example-cache.deb"
dpkg-deb: building package 'example-cache' in '.../example-cache.deb'.
$ dpkg-deb --control "$workdir/example-cache.deb" "$workdir/control"
$ sed -n 'l' "$workdir/control/triggers"
interest-noawait example-cache-refresh$

The temporary directory is not package state. Review the extracted control data, then remove it when you are finished:

$ rm -rf "$workdir"

Warning

That final command is destructive for the temporary directory only. If you need the archive for later review, copy it somewhere deliberate before removing the directory. Never substitute a broad path for $workdir.

5. Handle the trigger in the maintainer script

When an interested package has a pending trigger, dpkg runs its postinst with the action triggered and a space-separated list of trigger names as the second argument. Several activations can arrive together, so a shell maintainer script should handle each name independently:

case "$1" in
  triggered)
    case " $2 " in
      *" example-cache-refresh "*) refresh-cache ;;
    esac
    ;;
esac
  • Make it repeatable. dpkg may aggregate repeated activation, and the package may need to recover work that happened while it was not configured.
  • Treat the list as a hint. It is an optimisation, not permission to skip necessary initial setup.
  • Keep it to package events. Do not use a trigger just because a daemon should react to every runtime event. Debian package triggers cover installation and state changes. Runtime notification needs a separate mechanism.

6. Diagnose waiting and pending states

After a real package operation, inspect package status with dpkg rather than assuming that a successful unpack means every trigger has completed:

$ dpkg-query -W -f='${Package} ${Status}\n' example-cache
example-cache install ok installed

During processing, an interested package can be triggers-pending; a triggering package can be triggers-awaited. Pending trigger work is normally attempted at the end of the relevant dpkg run. If the triggered maintainer script fails, the package can become config-failed, and dpkg will not silently retry it forever.

Recovery

If a package stays in one of these states, first read the maintainer-script error and package status. Do not run a blind reinstall or delete dpkg's database files. Re-run the normal package configuration procedure only after correcting the script or dependency problem, and keep a copy of the diagnostic output.

7. Check compatibility before publishing

Older dpkg versions reject these directives, so check the oldest supported distribution before shipping them:

  • The -noawait variants have been supported since dpkg 1.16.1.
  • The -await aliases have been supported since dpkg 1.17.21.
$ dpkg-query -W -f='${Package} ${Version}\n' dpkg
dpkg 1.22.6ubuntu6.6

For a package family with older targets, either require a sufficiently new dpkg or use the older directive vocabulary supported by those targets. Record that decision in packaging documentation. An unknown trigger directive is an installation failure, not a harmless compatibility downgrade.

Done means

  • Same name on both sides. The interested and activating packages use the same whitespace-free trigger name.
  • Right file. Each directive is in the correct source-package or binary-package triggers file.
  • No-wait is deliberate. You chose it only where deferred processing is safe.
  • The archive builds. It contains the expected DEBIAN/triggers data.
  • The script copes. The postinst triggered path handles names separately and can be run repeatedly.
  • You can recover. You checked the minimum supported dpkg version and kept a recovery path for script failures.