This document describes the Paludis hooks interface. A hook is a piece of code that is executed when a particular well defined action occurs.
There are currently four categories of hooks:
ebuild
in the hook name, and
have full access to the ebuild environment (including the ability to call
die
), but are only used for ebuild-based activities.
See Ebuild Phase Hooks.einfo
, ewarn
etc.
See Ebuild Message Hooks.There are currently five categories of hook execution code:
.bash
hooks. These are simple .bash
files that
are executed with a particular environment. See Bash Hooks
for details..hook
hooks. These are also bash
files, but rather
than containing the relevant code in global scope, they make use of functions
to perform hook actions. They also support specifying execution order dependencies
upon other hooks. See Hook Hooks for details..py
hooks. These are much like .hook hooks, but written in Python and
with additional power given by Python bindings and access to the current Environment.
See Python Hooks for details..so
hooks. These are written in C++ and compiled into shared
libraries, and run inside the Paludis process. See .so Hooks
for details.Repository
classes.Not all hook execution code methods are available for all hook categories. The following table indicates availability:
.bash |
.hook |
.py |
.so |
Repository | |
---|---|---|---|---|---|
General | yes | yes | yes | yes | yes |
Ebuild Phase | yes | ||||
Ebuild Message | yes | ||||
Merger | yes | yes | yes | yes | yes |
Where there is a choice, .hook
hooks should be favoured over .bash
hooks.
The following general normal hooks are available:
install_pre
install_fail
install_post
install_all_pre
install_all_post
install_pretend_pre
install_pretend_post
install_pretend_display_item_pre
install_pretend_display_item_post
install_task_execute_pre
install_task_execute_post
uninstall_pre
uninstall_fail
uninstall_post
uninstall_all_pre
uninstall_all_post
clean_pre
clean_post
clean_fail
clean_all_pre
clean_all_post
sync_pre
sync_fail
sync_post
sync_all_pre
sync_all_post
fetch_pre
fetch_post
fetch_all_pre
fetch_all_post
In general, certain special environment variables will be set:
HOOK
will contain the name of the hook.all
hooks, TARGETS
will contain the targets
for the operation.all
hooks, TARGET
will contain the current
target.PALUDIS_CMDLINE
variables described below are also available.
install_pretend_display_item
hooks, the KIND
variable will also be of
interest.install_task_execute_pre
and install_task_execute_post
hooks,
PRETEND
, FETCH_ONLY
and SUCCESS
may be useful.The following ebuild phase hooks are available:
ebuild_metadata_pre
ebuild_metadata_fail
ebuild_metadata_post
ebuild_init_pre
ebuild_init_fail
ebuild_init_post
ebuild_fetch_pre
ebuild_fetch_fail
ebuild_fetch_post
ebuild_tidyup_pre
ebuild_tidyup_fail
ebuild_tidyup_post
ebuild_strip_pre
ebuild_strip_fail
ebuild_strip_post
ebuild_unpack_pre
ebuild_unpack_fail
ebuild_unpack_post
ebuild_compile_pre
ebuild_compile_fail
ebuild_compile_post
ebuild_install_pre
ebuild_install_fail
ebuild_install_post
ebuild_test_pre
ebuild_test_fail
ebuild_test_post
ebuild_setup_pre
ebuild_setup_fail
ebuild_setup_post
ebuild_config_pre
ebuild_config_fail
ebuild_config_post
ebuild_nofetch_pre
ebuild_nofetch_fail
ebuild_nofetch_post
ebuild_preinst_pre
ebuild_preinst_fail
ebuild_preinst_post
ebuild_postinst_pre
ebuild_postinst_fail
ebuild_postinst_post
ebuild_prerm_pre
ebuild_prerm_fail
ebuild_prerm_post
ebuild_postrm_pre
ebuild_postrm_fail
ebuild_postrm_post
As well as the full ebuild environment, the HOOK
environment
variable will contain the name of the hook being called. The
PALUDIS_CMDLINE
variables described below are also available.
Ebuild hooks will not necessarily be called if an ebuild does not define the function in question.
The following ebuild message hooks are available:
einfo
ewarn
eerror
elog
The HOOK
environment variable will contain the name of the hook
being called, and the MESSAGE
environment variable will contain
the message being passed to the function. The PALUDIS_CMDLINE
variables described below are also available.
The merger runs in two stages, for safety. First it checks that it can probably install safely, then it does the actual install. Note that calculating the md5, timestamp etc for VDB CONTENTS is done after the install_post hooks are called.
In each of the following subcategories, the hooks that do not name a specific type of object are called before or after the entire process; those that do are called once for each relevant item.
The following merger check hooks are available:
merger_check_pre
merger_check_post
merger_check_file_pre
merger_check_file_post
merger_check_sym_pre
merger_check_sym_post
merger_check_dir_pre
merger_check_dir_post
The INSTALL_SOURCE
and INSTALL_DESTINATION
environment variables contain the target source and destination. The
ROOT
variable contains the filesystem root. The IMAGE
variable contains the image root.
The following merger hooks are available:
merger_install_pre
merger_install_post
merger_install_file_pre
merger_install_file_post
merger_install_sym_pre
merger_install_sym_post
merger_install_dir_pre
merger_install_dir_post
merger_unlink_file_pre
merger_unlink_file_post
merger_unlink_dir_pre
merger_unlink_dir_post
merger_unlink_sym_pre
merger_unlink_sym_post
merger_unlink_misc_pre
merger_unlink_misc_post
Again, ROOT
and IMAGE
are available. For
install hooks, INSTALL_SOURCE
, INSTALL_DESTINATION
are
set, and for uninstall hooks, UNLINK_TARGET
.
The unmerger hooks are used for uninstalling a package, but not when existing things have to be removed for an install (the merger does that). The following unmerger hooks are available:
unmerger_unlink_pre
unmerger_unlink_post
unmerger_unlink_file_pre
unmerger_unlink_file_post
unmerger_unlink_dir_pre
unmerger_unlink_dir_post
unmerger_unlink_sym_pre
unmerger_unlink_sym_post
unmerger_unlink_misc_pre
unmerger_unlink_misc_post
The UNLINK_TARGET
environment variable specifies the file about
to be unlinked, and ROOT
is the filesystem root.
User defined hooks should be files named *.bash
, *.hook
,
*.py
or *.so
. .bash
and .hook
scripts should be executable (chmod a+x
). They can live in three locations
(or be symlinked there, to allow a single script to be shared between hooks):
confdir/hooks/hookname/
, where
confdir
is the directory in which use.conf
et al. reside.DATADIR/paludis/hooks/hookname/
. On most
systems, DATADIR
is /usr/share
.LIBDIR/paludis/hooks/hookname/
. On most
systems, LIBDIR
is /usr/lib
or /usr/lib64
.For .hook
and .so
hooks, rather than using hookname
, the
auto
directory may be used. In this case, Paludis will ask the hook for which hook names it should be
run.
A .bash
hook is merely executed when the associated action is
triggered. There is no guarantee as to execution order.
A .hook
hook is more powerful. It must not run anything in
global scope, but instead defines all its actions in functions. It must, at
minimum, define a function called hook_run_$HOOK
for each hook
that it can handle. It may also define functions called hook_depend_$HOOK
,
which should output names of any other hooks upon which it depends, and
hook_after_$HOOK
, which is similar but indicates an ordering
rather than hard dependency (the named hooks not existing is not an error).
For example:
#!/usr/bin/env bash hook_run_install_all_post() { # ensure that einfo etc are available export PATH="$(${PALUDIS_EBUILD_DIR}/utils/canonicalise ${PALUDIS_EBUILD_DIR}/utils/ ):${PATH}" source ${PALUDIS_EBUILD_DIR}/echo_functions.bash echo einfo "Checking for monkeys..." if [[ -d "${ROOT}/var/lib/monkeys" ]] ; then for m in "${ROOT}"/var/lib/monkeys/* ; do ewarn "Found monkey $(basename "${m}" )" done else einfo "No monkeys found" fi } hook_depend_install_all_post() { # we need to run after the Paludis standard eselect_env_update hook echo eselect_env_update } hook_after_install_all_post() { # if checking for rabbits or squirrels, do those first echo check_for_rabbits check_for_squirrels }
If the hook is located in an auto
directory, the hook_auto_names
function must also be
provided. This function should output the hook names under which the hook should be run. For example:
hook_auto_names() { echo install_all_pre install_all_post }
Note that the hook_depend_
, hook_after_
and hook_auto_names
functions are
cached, and are generally only called once per session, so the output should not vary based upon outside parameters.
A .py
hook is much like .hook
hook, but written
in Python and with full access to the current Paludis environment through
Python bindings. For each hook it can handle it must, at minimum, define
a function named hook_run_$HOOK
which accepts exactly two positional
arguments: the current Environment used by Paludis, and the additional Hook environment variables
represented by a Python dictionary. It may also define the hook_depend_$HOOK
and hook_after_$HOOK
functions which must take exactly one argument,
the Hook environment, and return a list of strings.
For example:
def hook_run_install_all_post(env, hook_env): from paludis import * print "* Checking for monkeys..." if list(env[Selection.SomeArbitraryVersion(Generator.Package("nice/monkey"))]): print "Found a monkey!" else: print "No monkeys found" def hook_depend_install_all_post(hook_env): # we need to run after the Paludis standard eselect_env_update hook return ["eselect_env_update"] def hook_after_install_all_post(hook_env): # if checking for rabbits or squirrels, do those first return ["check_for_rabbits", "check_for_squirrels"]
A .so
hook is written in C++ and has full access to the Paludis public API.
The hook takes the form of a shared library with a filename ending in .so.N
,
where N is the first component of the Paludis version number multiplied by 100,
plus the second component of the version number (for example, 26 for Paludis 0.26.x,
or 102 for Paludis 1.2.y). The library must export a function with prototype
paludis::HookResult paludis_hook_run_3(const paludis::Environment *,
const paludis::Hook &, const std::shared_ptr<paludis::OutputManager> &)
that performs the action, and optionally one with prototype
void paludis_hook_add_dependencies(const paludis::Environment *, const paludis::Hook &,
paludis::DirectedGraph<std::string, int> &)
if it needs to define ordering dependencies with other hooks. If the hook is to be placed in an auto
directory, it must also define const std::tr1::shared_ptr<const Sequence<std::string> >
paludis_hook_auto_phases(const paludis::Environment *)
. All functions are
declared in the header <paludis/hook.hh>
, including any necessary
extern
or visibility declarations.
The parameters and return values have the following meanings:
const paludis::Environment *
Environment
, as used by all Paludis clients.const paludis::Hook &
paludis_hook_add_dependencies
,
the only useful member is name()
.const std::shared_ptr<paludis::OutputManager> &
paludis::DirectedGraph<std::string, int> &
paludis_hook_add_dependencies
function should add any
edges required to indicate its desired execution order relative to the other hooks,
as follows: g.add_edge("after", "before", 0);
(the 0 is not significant,
but required by the DirectedGraph
API).paludis::HookResult
HookResult
constructor takes two arguments: an int
,
which should be zero if the hook is successful, or positive if not, and a std::string
containing any information that should be passed back to the hook's caller (only
used if the Hook
's output_dest
member is hod_grab
).Paludis places some of its own hooks in
LIBEXECDIR/hooks/hookname
. These directories are
not for end user use.
PALUDIS_CMDLINE
VariablesSometimes hooks need access to the commandline used to invoke
paludis
. However, manual parsing of the commandline by hooks will
lead to bugs when people forget to emulate certain behaviour (say, short
options, aliases or --
support). To work around this issue,
Paludis provides environment variables prefixed PALUDIS_CMDLINE_
that specify the parsed command line:
PALUDIS_CMDLINE_PARAMS
variable contains the parameters (that is,
the parts that aren't -x
or --blah
or values for these).--param-name
, PALUDIS_CMDLINE_param_name
(note
the case and the underscores) is set. If --param-name
takes an argument,
this argument is used for the environment variable's value.-x
) and aliases, the appropriate long option's
variable is set instead.