Package Hooks

This document will serve as the documentation of the Hook API that will be implemented by any tool wishing to claim that it is a package manager for OpenCSW.

Purpose

The purpose of introducing hooks into the package management tools is to allow for other software to do 'smart' things at various points during package maintenance. These 'smart' things are actions that do not belong in package scripts, as they are not specific to any one package. These things also don't belong directly in the the package management tools as they may not be desirable at every site (or even every machine at a site).

Example Uses

  1. The original impetus for adding Hooks to the OpenCSW package management tools was to allow for the integration of etckeeper. This tool maintains /etc in a version control system. Using Hooks, it is able to take a pre and post commit of /etc, which allows an administrator to see changes made to configuration during package maintenance (and easily undo them if necessary).
  2. A system/site administrator could create hook scripts that disallow use of the package tools except during specific windows of time (eg: only allow package changes in the first week of a new quarter, etc).
  3. Package install, update and removal operations could be recorded to syslog or some other logging facility.

Hook Overview

We define two groups of hooks that are package specific and allow for generic hooks as well. The two groups of package specific hooks are batch and per-package. The batch hooks run before (pre) and after (post) a 'series' of package maintenance actions. We define 'series' as one or more package maintenance actions. The per-package hooks run before (pre) or after (post) an individual package maintenance action.

We define the following as package maintenance actions:

  • Upgrade - A package is installed on the system and will be replaced with another different, but not necessarily newer, version of the same package. This corresponds to `pkgrm SOMEpkg` followed immediately by `pkgadd SOMEpkg`.
  • Install - A package is to be newly installed. This corresponds to `pkgadd SOMEpkg`.
  • Remove - A package exists on the system and will be removed. It is allowable for some configuration files to remain behind after this action. This corresponds to `pkgrm SOMEpkg`.

Generic hooks are not concerned with the package actions directly, but rather with actions in the program implementing the hook api. An example of a generic hook is argproc, in both pre and post versions, that will allows hook scripts to see the arguments passed to the tool both before and after processing.

List Of Available Hooks

  • preargproc
  • postargproc
  • prefetch
  • postfetch
  • prebatchinstall
  • postbatchinstall
  • prebatchupgrade
  • postbatchupgrade
  • prebatchremove
  • postbatchremove
  • preinstall
  • postinstall
  • preupgrade
  • postupgrade
  • preremove
  • postremove

Hook Implementation

For each Hook, as defined previously, there may exist a directory in /etc/opt/csw/pkg-hooks with a name in the format $hook_name.d where $hook_name is the name of the Hook being called. For example, any Hook scripts to be executed when the prebatchupgrade Hook is called must be placed in /etc/opt/csw/pkg-hooks/prebatchupgrade.d/.

Hook providers (packages, tools or administrators) will place files in the appropriate directories, creating the directories first if required.

Package management tools must treat the absence of a specific Hook directory as a no-op and continue in their normal course of operation. Files in a Hook directory that are not executable must be ignored by package management tools, thus allowing administrators to disable certain hooks easily without removing software or otherwise altering their systems.

The complete list of valid Hooks and their corresponding directories is:

  • preargproc: /etc/opt/csw/pkg-hooks/preargproc.d/
  • postargproc: /etc/opt/csw/pkg-hooks/postargproc.d/
  • prefetch: /etc/opt/csw/pkg-hooks/prefetch.d/
  • postfetch: /etc/opt/csw/pkg-hooks/postfetch.d/
  • prebatchinstall: /etc/opt/csw/pkg-hooks/prebatchinstall.d/
  • postbatchinstall: /etc/opt/csw/pkg-hooks/postbatchinstall.d/
  • prebatchupgrade: /etc/opt/csw/pkg-hooks/prebatchupgrade.d/
  • postbatchupgrade: /etc/opt/csw/pkg-hooks/postbatchupgrade.d/
  • prebatchremove: /etc/opt/csw/pkg-hooks/prebatchremove.d/
  • postbatchremove: /etc/opt/csw/pkg-hooks/postbatchremove.d/
  • preinstall: /etc/opt/csw/pkg-hooks/preinstall.d/
  • postinstall: /etc/opt/csw/pkg-hooks/postinstall.d/
  • preupgrade: /etc/opt/csw/pkg-hooks/preupgrade.d/
  • postupgrade: /etc/opt/csw/pkg-hooks/postupgrade.d/
  • preremove: /etc/opt/csw/pkg-hooks/preremove.d/
  • postremove: /etc/opt/csw/pkg-hooks/postremove.d/

Hook Script Naming Conventions

To avoid naming collisions the following naming convention should be used for Hook files:

##-NAME[-freeform]

Where ## is a two digit number used for execution ordering and NAME is either the SVR4 package name (not the catalog name) such as CSWfoo or a non-conflicting value (eg: site or domain as a good example). The -freeform part is optional and may be used in the case where a single package wants to deliver multiple hook actions that are not part of the same logical operation or to clarify the purpose of the hook.

Example hook file names include:

  • 99-CSWetckeeper-precommit
  • 01-CSWetckeeper-postcommit
  • 01-CSWsomepkg
  • 50-mydomain-mailwhendone

While this naming is by convention only, all CSW packages must adhere to it.

When hooks are run, the files in the hook directory will be run serially, sorted by their filenames using a standard ascii comparison (eg: unix sort or perl sort { $a cmp $b }). This means that a given a set of hook scripts named 'unnumbered', '20-CSWpkg', '2-foo', 'test', '10-CSWfoo-function', '10-CSWbar', and '1-CSWbaz', the execution order would be:

  • 1-CSWbaz
  • 10-CSWbar
  • 10-CSWfoo-function
  • 2-foo
  • 20-CSWpkg
  • test
  • ununumbered

Calling Hooks

Here, we will define specifically when each hook is and is not to be called.

  1. A package management tool must call preargproc before any command line option processing is done.
  2. A package management tool must call postargproc after command line option processing is done.
  3. The postargproc hook must be called before any fetch, install, upgrade or remove hooks.
  4. A package management tool must not call more than a single type of batch Hook in a single invocation. That is to say that the batchupgrade, batchinstall and batchremove Hooks are mutually exclusive.
  5. A package management tool must not call more than one of install, upgrade or remove for a single package during its invocation.
  6. The proper per-package Hook must be called regardless of the type of batch operation taking place.
  7. The package management tool may abort execution at any point. It should not run further Hooks if it deems the result of a package operation to be a fatal error. For example, the postbatchinstall Hook should not be called if not all required pkgadd calls were successful.
  8. The prefetch Hook is to be called prior to the download (or local fetch) of the package file from a mirror.
  9. The postfetch Hook is to be called only after a successful download (or local fetch) of the package file from a mirror.
  10. A tool is not required to call the pre and post fetch hooks in any designated relation to install or upgrade hooks. A tool may download all packages and then process them for install or upgrade, or a tool may download each package as it is required during install or upgrade processing. It is only important that the actual download of the package files is bracketted with the pre and post fetch hooks as described above.
  11. The preupgrade Hook is to be called immediately prior to the pkgrm/pkgadd calls that perform the version change of the affected package.
  12. The preupgrade Hook must not be called following any call to prebatchremove.
  13. The postupgrade Hook is to be called immediately following the successful pkgrm/pkgadd calls that perform the version change of the affected package.
  14. The postupgrade Hook may only be called for a package if a previous call to the preupgrade Hook was made for the same package.
  15. The preinstall Hook is to be called immediately prior to a pkgadd call that is not part of a package upgrade.
  16. The preinstall Hook must not be called following any call to prebatchremove.
  17. The postinstall Hook must be called immediately following a pkgadd call that is not part of a package upgrade.
  18. The postinstall Hook may only be called for a package if a previous call to the preinstall Hook was made for the same package.
  19. The preremove Hook is to be called immediately prior to a pkgrm call that is not part of a package upgrade.
  20. The preremove Hook may be called following a call to either prebatchinstall or prebatchupgrade to allow packages to satisfy Incompatible dependencies.
  21. The postremove Hook must be called immediately following a call to pkgrm that is not part of a package upgrade.
  22. The postremove Hook may only be called for a package if a previous call to the preremove Hook was made for the same package.
  23. The prebatchupgrade Hook must be called prior to one or more packages being upgraded (having their versions increased or decreased). This pre-depends on at least one of the affected packages having been previously installed.
  24. The prebatchupgrade Hook must be called prior to any per-package Hooks.
  25. The postbatchupgrade Hook must be called following a successful series of package maintenance actions if a prior call to the prebatchupgrade Hook was made.
  26. The postbatchupgrade Hook must be called after all per-package Hooks have been run.
  27. The prebatchinstall Hook must be called in any situation where new packages are added to the system, but no existing package experiences a version change
  28. The prebatchinstall Hook must be called prior to any per-package Hooks.
  29. The postbatchinstall Hook must be called following a successful series of package maintenance actions if a prior call to the prebatchinstall Hook was made.
  30. The postbatchinstall Hook must be called after all per-package Hooks have been run.
  31. The prebatchremove Hook must be called in any situation where packages will be removed using pkgrm but no new packages will be installed and no existing packages will be upgraded.
  32. The prebatchremove Hook must be called prior to any per-package Hooks.
  33. After a call to prebatchremove, the only acceptable per-package Hook calls are preremove and postremove.
  34. The postbatchremove Hook must be called following a successful series of package maintenance actions if a prior call to the prebatchremove Hook was made.
  35. The postbatchremove Hook must be called after all per-package Hooks.

NOTE: As a specially highlighted point, it should be noted that the batch hooks should be called even if only a single package is to be modified.

Communication Between Hooks and Package Tools

Hooks that work on packages (per or batch) should expect to receive a list of packages that are being acted on. For batch hooks, this means that one or more packages may be defined as arguments. The per-package hooks should only receive information for a single package. These hooks expect arguments of the form $srv4name-$version, where $svr4name would look like CSWfoo and $version will be defined differently for install/upgrade and remove as follows:

If either prebatchupgrade or prebatchinstall is called, all Hooks should expect the $version part of the argument to be the version of the package that will exist on the system after the package management tool has run to completion. If the prebatchremove Hook is run, the $version portion of the arguments will be the version of the package being removed.

The pre and post fetch hooks will expect two arguments, even though they are run per-package. The first is the full URL of the file being retrieved, even when local, and the second argument is the $svr4name-$version format of the package being retrieved.

The pre and post argproc hooks are less strict in what they will expect from the invoking package management tool. since these arguments will be tool specific. The tools should pass all command line arguments to the preargproc hook. The postargproc hook will receive arguments that remain after processing by the program, which would typically be only a list of packages to act on. It is recommended that this list be normalized to $svr4name (eg: CSWfoo) to avoid a mix of package name with svr4 name being used.

In return, each hook will communicate back to the package manager by way of exit code. We will define the following exit codes as having special significance:

  • 0: As per usual this indicates success. The Hook ran successfully and the package management tool should execute the next script in sequence or move to the next package maintenance action.
  • 1: The Hook is indicating that the package manager should not proceed. No further package maintenance actions should be performed, no futher scripts for the present Hook executed and no futher Hooks should be called.
  • 2: The Hook is indicating that it would prefer no further actions are taken, but the package tool may proceed based on user preferences or lacking a configuration item for the user, its own discretion.

In the future, more exit codes may be added to enhance communication abilities.

Typically, a hook should execute quietly. In the event that output is generated on either stdout or stderr, it is up to the package management tool what happens to it. Options for handling may include passing it out to the user or logging it. This may be controlled by options to the package management tool.

Hook State

Some Hooks may work collaboratively to collate information. An example of this might include the prebatchupgrade Hook recording a list of all packages on the system prior to a set of package maintenance actions and the subsequent postbatchupgrade Hook capturing the same list and storing the differences in a log.

To facilitate this type of state maintenance, the directory /var/opt/csw/pkg-hooks may be used by Hook scripts as a place to store files. This directory should exist (or be created) on all systems where CSW package maintenance tools are run.

Hook Invocation

The following examples are meant to illustrate which hooks are called and when. $packagelist represents the entire list of affected packages passed to the Hook being called. These examples are not exhaustive, but should help to illustrate the Hook calling sequence. These example scenarios describe package actions as seen from the perspective of the tools, not the user that requested the action. A user may as for package CSWfoo to be installed. If CSWfoo is on the system, but a newer version is available from the catalog, the tool will treat the action as an upgrade (and run the upgrade hook) instead of an install (the install hook will not be run).

Unless otherwise stated, the content of this page is licensed under Creative Commons Attribution-ShareAlike 3.0 License