Standardized Hooks: Basic Usage
For cPanel & WHM 11.32
Note: The Standardized Hooks documentation is currently under revision. You should check back shortly for improvements to this information.
Introduction
We can break simple hooks in the Standardized Hooks system into 2 basic parts. They are the
describe method and the
hook code. This is true for both hooks written as Perl modules and those written as scripts.
- The describe method — A method within a hook module, or a flag for a script hook, that tells the hook system when the hook should run. This also includes any other information that the system will require for the hook. This method registers the hook with cPanel & WHM.
- The hook code — The code to execute when a particular event occurs.
The describe method
The
describe method is a method within a hook module, or a flag for a script hook, that tells the hook system when the hook should run. This also includes any other information that the system will require for the hook. This method registers the hook with cPanel & WHM.
The describe data structure
This following information is
required:
| Parameter |
Description |
| namespace |
The namespace of the function to call. This value determines which hash should be placed in /var/cpanel/hooks.yaml. Some examples include PkgAcct, Whostmgr, and Stats. |
| function |
The function on which the hook will act (e.g. Accounts::Create or RestorePkg). |
| stage |
The stage of the hook. This value is generally pre or post, indicating whether the hook should be called before or after the specified action. |
The following parameters are
optional:
| Parameter |
Description |
| escalateprivs |
A boolean value that indicates whether the hook will run with root privileges. |
| check |
A string value that points to another piece of code, which determines whether or not the hook should run. For more information, view our Advanced Hook Usage documentation. |
| rollback |
A string value that points to another piece of code, which executes whenever a hook fails. For more information, view our Advanced Hook Usage documentation. |
| weight |
The priority for running the hook. Lower numbers indicate that the hook should execute earlier. This value defaults to 1000, and can be set to any integer 0 or greater. For more information, view our Advanced Hook Usage documentation. |
Using scripts
When using a script as a hook, the
describe method must be invoked by passing a
--describe parameter to the script.
When the script receives the parameter, the hook system expects the hook to output a JSON data structure. This data structure must describe the areas that the script should hook into. For example:
<?php
$describe = array(
array(
'namespace' => 'Whostmgr',
'function' => 'Accounts::Create',
'stage' => 'pre',
'hook' => '/var/cpanel/MyApp/createaccthook.php',
),
array(
'namespace' => 'Whostmgr',
'function' => 'Accounts::Remove',
'stage' => 'post',
'hook' => '/var/cpanel/MyApp/deleteaccthook.php',
),
);
if ( in_array('--describe', $argv) ) {
print json_encode($describe);
exit();
}
Note: The
hook value does not have to be the path to the script used to describe the hook. The value defined in
hook simply needs to be an executable script.
Using Perl modules
A Perl module hook must contain a subroutine called
describe. This subroutine must be loaded by the hooks management code in
/usr/local/cpanel/bin/manage_hooks.
For example:
package Boo;
sub describe {
my $hooks = [
{
'namespace' => 'Passwd',
'function' => 'ChangePasswd',
'stage' => 'pre',
'hook' => 'Boo::passwd_length',
},
{
'namespace' => 'Stats',
'function' => 'RunUser',
'hook' => 'Boo::copy_logfiles',
'stage' => 'post',
},
];
return $hooks;
}
1;
/usr/local/cpanel/bin/manage_hooks
The hooks management interface is
/usr/local/cpanel/bin/manage_hooks. This CLI application allows you to add hooks, remove hooks, and list available hooks on your system.
This application invokes the
describe method within the hook, and adds the hook to the hooks database, based on the information returned by the
describe method.
Please view
/usr/local/cpanel/bin/manage_hooks fullhelp for more information.
In the examples below:
| Parameter |
Description |
$type |
The type of hook to add or remove. This value can be either module or script. |
$path |
The path to the hook to add or remove. |
Adding a hook
/usr/local/cpanel/bin/manage_hooks add $type $path
Removing a hook
/usr/local/cpanel/bin/manage_hooks del $type $path
Listing hooks
/usr/local/cpanel/bin/manage_hooks list
Examples
Adding a script:
/usr/local/cpanel/bin/manage_hooks add script /var/cpanel/MyApp/foo_describe.php
Removing a Perl module:
/usr/local/cpanel/bin/manage_hooks del module PackageName
The hook code
The hook code is executed whenever a particular event occurs. This is where most of your development will take place.
The hook you create is passed 2 pieces of data whenever it is executed: a
context and an
arbitrary data set.
- The context defines the hook insertion point that is executing the hook code. Ultimately, the context describes the event that will trigger the hook. The context is then compared against the hooks database to ensure that it should run.
-
Note: Context, as it applies here, is the same as defined in the abstract.
- The data set should simply contain any data relevant to the hook.
If your hook is a Perl module, the hook subroutine will receive "context" and "dataset" as two variables in
@_. If you hook is a script, this data will be pass via STDIN in the form of a JSON data structure; the data structure will be a hash containing keys for
context and
data that provide the "context" and "dataset" values, respectively.
The hook data structure
This following information is
required:
| Parameter |
Description |
| namespace |
The namespace of the function to call. This value determines which hash should be pulled from /var/cpanel/hooks.yaml. Some examples include PkgAcct, Whostmgr, and Stats. |
| function |
The function on which the hook will act (e.g. Accounts::Create or RestorePkg). |
| stage |
The stage of the hook. This value is generally pre or post, indicating whether the hook should be called before or after the specified action. |
The following parameters are
optional:
| Parameter |
Description |
| escalateprivs |
A boolean value that indicates whether the call will be allowed to run with root privileges. |
| blocking |
A boolean value specifying how the overlying code will behave if the hook fails. This parameter has important implications when dealing with hooks that can roll back (undo) their actions. |
Important: These values are passed as an array of hashes to the hook. The first element in the array is the context, the second is the data. Please review our
hook insertion points reference for more information.
Perl module example
sub MyAwesomeHook {
my ( $context, $data ) = @_;
}
Perl script example
use JSON::Syck ();
my $raw_data;
while (<STDIN>) {
$raw_data .= $_;
}
my $hookdata = JSON::Syck::Load($raw_data);
my $context = $hookdata->['context'];
my $data = $hookdata->['data'];
PHP script example
<?php
$stdin_fh = fopen('php://stdin', 'r');
while ($line = fgets( $stdin_fh )) {
$raw_data .= $line;
}
fclose($stdin_fh);
$hookdata = json_decode($raw_data, true);
$context = $hookdata['context'];
$data = $hookdata['data'];
Return values
Hooks are expected to return at least one piece of data.
| Parameter |
Type |
Required |
Description |
| result |
boolean |
Yes |
This value should indicate whether the hook ran successfully. If the context is defined as blocking and this value returns 0, all hooks will stop processing, and rollback routines will be executed wherever necessary. For more information, please read our Advanced Hook Usage documentation. |
| reason |
string |
No |
This value should contain a message of success or a reason for failure, depending on the value of result. |
Perl module hooks are expected to return the data in 2 scalar variables:
return 1, $reason;
Script hooks are expected to print a single line to
STDOUT:
For Perl scripts
print "$result $reason";
For PHP
echo "$result $reason";
Data printed to
STDERR is stored in
/usr/local/cpanel/logs/error_log.
More on module hooks
The Standardized Hooks system introduces a new path within the cPanel ecosystem —
/var/cpanel/perl5/lib. This path is where third-party Perl code, and your hook module, should reside.
This is the last path stored in
@INC, so that code contained here will not overwrite any code that already exists in cPanel & WHM.
Note: A module hook can run within 1 of 2 environments: the system Perl or the internal Perl. The version of Perl that is run is the main difference between these 2 installations. The system Perl will run the current version of
/usr/bin/perl while the internal Perl will run as version 5.6.2. The Perl used by different hooks can be determined by the hook's namespace.
The following namespaces run with the internal Perl 5.6.2:
All other namespaces should run as the system Perl.
Suggested reading
- Advanced Usage — If you comprehend the material in this document, we strongly recommend reviewing the Advanced Usage document.
- Abstract — If you experienced any difficulties with the material in this document, you should review the Standardized Hooks system's Abstract.