Software Development Kit

cPanel & WHM's API [+] cPanel & WHM's API [-]


Modules and Plugins [+] Modules and Plugins [-]


cPanel & WHM Hooks [+] cPanel & WHM Hooks [-]


cPAddons (Site Software) [+] cPAddons (Site Software) [-]


System Administration [+] System Administration [-]


Developer Software [+] Developer Software [-]


Back to All Documentation

Standardized Hooks Management Interface

Summary

Hook action code must be associated with a hookable event so that it is executed in response to the appropriate cPanel & WHM event. You can establish these associates using the Standardized Hooks management CLI utility.

The CLI utility takes Standardized Hooks descriptors and a reference to the hook action code. Using this information, a registry entry is added to the Standardized Hooks database.

You can use this utility to add, delete, or list Standardized Hooks on the local server.

Synopsis

manage_hooks UTILITYACTION [HOOKACTIONTYPE HOOKACTIONREFERENCE] [options]

Arguments

UTILITYACTION

The action the utility should perform against the hook database. Valid actions include add, delete, list, and fullhelp.

update_db is also a valid action of older hook databases prior to cPanel & WHM 11.32.1. Using this action should not be necessary as pre-existing database entries will be altered properly during the next cPanel & WHM update.

HOOKACTIONTYPE

Valid input values include script and module and correspond to the format of the hook action code in question. This argument is only valid and required when using the add or delete UTILITYACTION.

HOOKACTIONREFERENCE

A string that provides the location of the custom hook action code. If the hook action code is a script, this value should contain an absolute path and filename of the script. If the hook action code is a Perl module, the value will be the same as the package within the Perl module. This argument is only valid and required when using the add or delete UTILITYACTION.

Options

Most of the following options are descriptors and attributes that define when and how the hook action code should be executed. However, some options are used directly by the CLI utility and alter the way the arguments and descriptors are processed.

Like many Linux/GNU CLI utilities, when an option is passed and a value is not provided, an implicit true value is assigned. While this style of usage functions in a deterministic way, it’s usually best to be explicit, providing an appropriate value to each option.

--category

The category with which the hook action code will be associated.

--event

The category’s event, with which the hook action code will be associated.

--rollback

Additional hook action code that should be executed when another Standardized Hook associated with the same hookable event fails. This option is only applicable to events that have the blocking attribute.

--escalateprivs

A boolean value indicating whether privilege escalation (to root) should occur before executing the hook action code. This option is only applicable for hookable events that have the escalateprivs attribute and for hook action code implemented as a script.

--weight

An integer value for ordering the hook action code when multiple Standardized Hoooks are associated with the same hookable event. Lower values are executed before higher values. By default, the first Standardized Hook associated with a given event will be assigned a weight of 100. Subsequent default values will be 100 points higher than the highest next registered hook. For example, 3 Standardized Hooks added without a defined weight would be assigned values of 100, 200, and 300, respectively. If a Standardized Hook was added later, that defined a specific weight of 455, subsequent auto-assignment weights would be 555, 655, etc.

--check

Additional hook action code that should be executed before the execution of the primary hook action code. If the check hook action code returns a fail status, the primary hook action code will not be performed.

--manual

A boolean value indicating that all descriptors and attributes should be sourced from option flags. If not provided, the CLI utility will attempt to source descriptors and attributes from within the hook action code reference via an implementation of the describe pattern. If a describe pattern is not found, the CLI utility will use any descriptors and attributes provided as options. Furthermore, if not provided, and a describe pattern is not implemented, the CLI utility will attempt to recover and act as if a value of --manual 1 were passed, sourcing any options flags, and producing a warning.The describe pattern descriptors and attributes cannot be mixed with ones pass as option flags. All items must come from one source or the other.

--action

A string value representing a specific sub-action. This option is provided for use in combination with the --manual 1 option and value. If the hook action type is script, the value will be appended to the hook action reference, i.e., a CLI argument used when invoking the hook action code. If the hook action type is module, the value is treated as a function contained within the Perl package that was declared in the hook action reference. The action option is provided to emulate the explicit nature available within a describe pattern implementation. In most cases, developers will be better served by employing a describe pattern instead of using this option to remove potentially ambiguous use.

--output

This option is only available with the list utility action. Passing a string value of JSON here will produce a JSON serialization for programmatic digest instead of the default, human-readable output.

--help

Print basic usage documentation for the CLI utility to STDOUT. This option is assumed if an invalid utility action is provided. More verbose help documentation is available by executing the CLI utility with the fullhelp utility action argument.

Example

This example illustrates the lists UTILITYACTION, which outputs a list of existing registered hooks. In this example, there are three registered hooks:

[usr/local/cpanel/bin] $ ./manage_hooks list
Cpanel:
   Api2::StatsBar::stat:
      stage: pre
      weight: 1000
                id: rA73DrbGgM8QXvypjRkvsuLL
      exectype: module
      hook: MyApp::TestStatsBar
Whostmgr:
   Accounts::Create:
      stage: post
      escalateprivs: 0
      weight: 1000
                      id: OtAWTxns6w1wuIGTCmdnydcX
      exectype: script
      hook: /var/cpanel/myapp/testhook_post.php
      --
      stage: pre
      escalateprivs: 0
      weight: 1000
                      id: au9Pf6EdpOKNtWjrQKW_1IZC
      exectype: script
      hook: /var/cpanel/myapp/testhook_pre.php

In the example above:

  1. A Perl module subroutine, MyApp::TestStatsBar, located in /var/cpanel/perl5/lib/MyApp.pm, will execute the cPanel API 2 StatsBar::Stat function.
  2. A PHP script at /var/cpanel/myapp/testhook_post.php will be executed after cPanel accounts are created. This script will run regardless of which method was used to create the account, i.e., the WHM interface, the /usr/local/cpanel/scripts/wwwacct script, the remote API createacct, etc.
  3. A PHP script at /var/cpanel/myapp/testhook_pre.php will be executed before cPanel accounts are created. This script will run regardless of which method was used to create the account, i.e., the WHM interface, the =/usr/local/cpanel/scripts/wwwacct script, the remote API createacct, etc.

Describe patterns

The Standardized Hooks System provides a robust way to embed details of hookable actions within custom hook action code. If the author utilizes this pattern, he or she is absolved from having to specify all of the details required by the CLI utility when registering the hookable action.

While the Standardized Hooks System does not require a describe pattern, we strongly recommend using this method as it is far simpler than specifying each option to the manage_hooks utility.

Be aware that current implementation does not allow for individual hook selection in any automated sense. That is, the CLI utility invokes the describe pattern as a single action and digests the return as authoritative and absolute.

Using a describe pattern in a Perl module

Perl modules utilize a subroutine inside the module named describe(). The describe() subroutine must return a Perl array reference. This array reference must contain one or more hash references. Each hash reference is related to 1 hookable action and is used for a single entry for the Standardized Hooks database.

The hash reference must, at minimum, contain the category, event, stage, exectype, and hook descriptors. You can find examples of this in the appropriate section below.

Using a describe pattern in a script

Authors of scripts must include argument evaluation in the hook action code in order to use describe patterns. The CLI utility will call the script with one CLI script argument, --describe. The return output, via STDOUT, of the script should be a JSON encoded string. When decoded, the JSON structure should be an array that contains one or more hashes, or associative arrays. Each hash reference is related to one hookable action and is used for a single entry for the Standardized Hooks database.

For scripts that implement the describe pattern, the hook descriptor should be exactly how the script should be invoked to perform the hookable action.

  • If the script is monolithic, and performs internal logic based on the context, simply provide the script's absolute path and filename.
  • If the script can parse input arguments via a shell argument array ($argv or @argv, etc) then it should specify the absolute path and filename, followed by the proper argument required to switch to the proper code block.

You can find examples of this in the appropriate section below.

Examples

Management via CLI options

Managing a Perl module

The following section illustrates how to manually add and delete Standardized Hooks implemented in a Perl module. The examples assume that the /var/cpanel/perl5/lib/MyApp/ directory contains WHM.pm. This module contains the remove() subroutine that will be called prior to an account being removed from the system.

Adding a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks add module MyApp::WHM --manual --category Whostmgr --event 'Accounts::Remove' --stage pre --action remove

Removing a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks delete module MyApp::WHM --manual --category Whostmgr --event 'Accounts::Remove' --stage pre --action remove

Managing a script

The following section illustrates how to manually add and delete a Standardized Hook implemented in a script. The examples assume that the /var/cpanel/myapp/ directory contains whm.php. Inside this script, there is logic that can interpret command line arguments, to which a --do_remove switch is honored. /var/cpanel/myapp/whm.php --do_remove will be called prior to an account being removed from the system.

Adding a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks add script /var/cpanel/myapp/whm.php --manual --category Whostmgr --event 'Accounts::Remove' --stage pre --action='--do_remove'

Removing a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks delete script /var/cpanel/myapp/whm.php --manual --category Whostmgr --event 'Accounts::Remove' --stage pre --action='--do_remove'

More about the --action option

As observed in the above examples, when using the --action descriptor option with scripts, you should pay particular attention to how the value is presented. If not properly expressed, manage_hooks can misinterpret that value as a description option switch. This only occurs for values that lead with one or more hyphens. Some valid expressions are:

--action='--for_hook_script'
--action="--for_hook_script --more_hook_switch"
--action '"--for_hook_script'"
--action ""-one_hyphen_switch” “-more_switches""

The choice of double or single quotes is irrelevant. If the ‘--action’ descriptor is immediately followed by an equal sign, simply quote the entire value once. If it is immediately followed by a space, quote each script switch and encapsulate the entire value in another type of quote

Management via describe patterns

The preferred method for defining hookable actions is to use a describe pattern. Managing the hook with the CLI utility becomes easier, as all of the descriptor options are embedded in the Perl module or script.

Managing a Perl module

In order to use the describe pattern, the Perl module must contain a describe() subroutine. It must return an array reference which contains one or more hash references.

The following example illustrates two hooks. Both utilize the MyApp::WHM.pm (in /var/cpanel/perl5/lib/). The first will execute MyApp::WHM::add() after an account is created by cPanel & WHM, and the second will execute MyApp::WHM::remove() prior to account deletion:

# file - /var/cpanel/perl5/lib/MyApp/WHM.pm
package MyApp::WHM;

sub describe {
    my $my_add = {
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Create',
        'stage'    => 'post',
        'hook'     => 'MyApp::WHM::add',
        'exectype' => 'module',
    };

    my $my_remove = {
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Remove',
        'stage'    => 'post',
        'hook'     => 'MyApp::WHM::remove',
        'exectype' => 'module',
    };

    return [$my_add, $my_remove];
}

sub add {
# ....
}

sub remove {
# ....
}
1;

Adding a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks add module MyApp::WHM

Removing a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks delete module MyApp::WHM

Managing a script

The same methodologies apply to a describe pattern implemented in a script as do when implementing them in a Perl module. The primary difference is that the describe data will not be returned, but printed to STDOUT as a JSON encoded string.

The following example is of a PHP script, implementing the same hookable events as in the Perl module example above.

#!/usr/bin/php -q
<?php
// file - /var/cpanel/myapp/whm.php

// Any switches passed to this script
$switches = (count($argv) > 1) ? $argv : array();

if (in_array('--describe', $switches)) {
    echo json_encode( describe() );
    exit;
} elseif (in_array('--add', $switches)) {
    list($status, $msg) = add();
    echo "$status $msg";
    exit;
} elseif (in_array('--remove', $switches)) {
    list($status, $msg) = remove();
    echo "$status $msg";
    exit;
} else {
    echo '0 myapp/whm.php needs a valid switch';
    exit(1);
}

function describe() {
    $my_add = array(
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Create',
        'stage'    => 'post',
        'hook'     => '/var/cpanel/myapp/whm.php --add',
        'exectype' => 'script',
    );
    $my_remove = array(
        'category' => 'Whostmgr',
        'event'    => 'Accounts::Remove',
        'stage'    => 'post',
        'hook'     => '/var/cpanel/myapp/whm.php --remove',
        'exectype' => 'script',
    );
    return array($my_add, $my_remove);
}

function add() {
    //....
}

function remove() {
    //....
}
?>

Adding a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks add script /var/cpanel/myapp/whm.php

Removing a Standardized Hook

[usr/local/cpanel/bin] $ ./manage_hooks delete script /var/cpanel/myapp/whm.php

Standardized Hooks database

The Standardized Hooks Database is located at /var/cpanel/hooks.yaml. It is a YAML datastore. The datastore is the authoritative reference for hooks that should be executed at various hookable events.

This file should not be edited by hand, as accidental errors are easily introduced. Hooks should be managed using a defined utility, such as the CLI utility /usr/local/cpanel/bin/manage_hooks. Additionally, the Standardized Hooks System maintains a cached copy of this database, /var/cpanel/hooks.cache.

If manual changes are made the YAML datastore, the cache file should be deleted. The cache file will be regenerated automatically the next time the Standardized Hooks System is queried internally or by a management utility.

Topic revision: r4 - 03 May 2012 - 14:45:18 - Main.JenniferDoubrava
SoftwareDevelopmentKit.StdHooksManagement moved from Sandbox.StdHooksManagement on 12 Mar 2012 - 20:46 by Main.JustinSchaefer - put it back