Handlers¶
Overview¶
The pulp agent supports an API for remote operations. These operations can be categorized as those that are type-specific and those that are not. In this context, the term type-specific includes a wide variety of Pulp conceptual types. Just as the handling of these types is pluggable within the Pulp server, it is also pluggable within the Pulp agent. The agent delegates the implementation of type-specific operations to the appropriate handler.
The collection of type-specific operations is logically grouped into named capabilities to support a good division of responsibility within handlers. An agent handler provides an implementation of one or more of these predefined capabilities.
Handler capabilities are as follows:
- The bind capability is a collection of agent operations responsible for updating the consumer’s configuration so that it can consumer content from a specific Pulp repository. Handler classes are mapped to the bind capability by distributor type ID.
- The content capability is a collection of agent operations responsible for installing, updating, and uninstalling content on the consumer. Handler classes are mapped to the content capability by content type ID.
- The system capability is a collection of agent operations responsible for operating system level operations. Handler classes are mapped to the system capability using the operating system type as defined to the Python interpreter.
Each handler is defined using a configuration file, called a descriptor. In addition to handler configuration, the descriptor associates capabilities with Python classes that are contributed by the handler. The mapping of capabilities to handler classes is qualified by a type ID that is appropriate to the capability.
When a remote operation request is received by the agent, the implementation is delegated to an appropriate handler based on the type of the object that is the subject of the operation.
For example, the installation of a content unit of type tarball
would be delegated to
the install()
method on an instance of the handler class mapped to the content
capability and type ID of tarball
.
Handler Descriptors¶
The handler descriptor declares and configures an agent handler. It is an INI formatted
text file that is installed into /etc/Pulp/agent/conf.d/
. A descriptor has two required
sections. The [main]
section defines global handler properties, and the [types]
section
is used to map types to handler classes.
The [main]
section has a required enabled
property. The handler is loaded into
the agent if value of enabled is one of: (true|yes|1).
The [types]
section supports three optional properties that correspond to handler capabilities.
The [content]
property is a comma delimited list of Pulp content types that are supported
by the handler. The values listed must correspond to content types defined within the Pulp
platform types
inventory. The bind
property is a comma delimited list of distributor
types supported by the handler. The values listed must correspond to the distributor_type_id
of a distributor plugin currently installed on the Pulp server. Lastly, the system property
is a single value that must correspond to the operating system name as reported in python
by the os.uname()
function.
For each type listed in the content, bind and system properties, there must be a
corresponding section with the same name. This section has a required property named class
that is used to specify a class that provides the capability for the specified type.
In addition to the class
property, these sections support the inclusion of arbitrary
property names and values which are passed to the specified handler class as configuration.
Let’s take a look at a descriptor example:
[main]
enabled=1
[types]
content=rpm,puppet,tar
bind=yum
system=Linux
[rpm]
class=pulp_rpm.agent.handler.PackageHandler
import_key=1
permit_reboot=1
[puppet]
class=pulp_puppet.agent.handler.PuppetHandler
[tar]
class=pulp_tar.agent.handler.TarHandler
preserve_permissions=1
[yum]
class=pulp_rpm.agent.handler.YumBindHandler
ssl_verify=0
[Linux]
class=pulp.agent.handler.LinuxHandler
reboot_delay=10
In this example, the [types]
section lists support for the rpm
, puppet
,
and tar
content types. Notice that there are the corresponding sections named [rpm]
[puppet]
, and [tar]
that map the handler class and specify-type specific
configuration. This pattern is replicated for the bind
, and system
properties.
Handler Classes¶
The functionality contributed by agent handlers is implemented in handler classes. The required API for each class is dictated by the capability to which it’s mapped. For each capability there is a corresponding abstract base class.
The base classes for each capability are as follows:
- Classes that provide the content capability must extend the
ContentHandler
base class and override each method. - Classes that provide the bind capability must extend the
BindHandler
base class and override each method. - Classes that provide the system capability must extend the
SystemHandler
base class and override each method.
Note
Currently, the APIs for the handler base classes are not published. The code can
be found in platform/src/pulp/agent/lib/handler.py
.
By convention, each handler class method signature contains two standard parameters.
The conduit
parameter is an object that provides access to objects within the agent’s
environment, such as the consumer configuration, Pulp server API bindings, the consumer’s ID,
and a progress reporting object. The options
parameter is a dictionary that defines
options used to influence the operation’s implementation.
Note
Currently, the APIs for the conduit are not published. The code can
be found in platform/src/pulp/agent/lib/conduit.py
.
Reports¶
The agent handler framework defines a set of report classes. Each method implementation
must return the appropriate report object. The HandlerReport
has three main attributes.
The succeeded
flag is boolean indicating the overall success of the operation. The
definition of success is entirely at the discretion of the handler writer. The details
attribute is a dictionary containing the detailed result of the operation. Last, the num_changes
attribute indicates the total number of changes made to the consumer as a result of the
operation. It is intended that the handler writer use either the set_succeeded()
or
the set_failed()
methods to update the report. The default value fo the succeeded
attribute is True.
Table mapping types, handler classes, and report classes:
Type | Class | Method | Report |
---|---|---|---|
content | ContentHandler | install() | ContentReport |
update() | ContentReport | ||
uninstall() | ContentReport | ||
profile() | ProfileReport | ||
bind | BindHandler | bind() | BindReport |
unbind() | BindReport | ||
clean() | CleanReport | ||
system | SystemHandler | reboot() | RebootReport |
Note
Currently, the APIs for the reports are not published. The code can
be found in platform/src/pulp/agent/lib/report.py
.
Exception Handling¶
Exceptions raised during handler class method invocation should be caught and either
handled or incorporated into the result report. Uncaught exceptions are caught by the
agent handler framework, logged, and used to construct and return the appropriate handler
report object. In this report object, the succeeded
attribute is set to False, and
the details
attribute is updated to contain the following keys:
- message - The exception message.
- trace - A string representation of the stack trace.
Installation¶
The two components of an agent handler are installed as follows. The Handler Descriptors
are installed in /etc/pulp/agent/conf.d
. The modules containing Handler Classes
can be either installed in the python path or installed in the /usr/lib/pulp/agent/handlers
.
directory. If installed in the python path, the class
property in the descriptor must be
package qualified as needed to be found within the python path.
The Pulp agent must be restarted for handler changes to take effect.
Logging¶
The Pulp agent is implemented using Gofer plugins. Agent handler log messages are written to syslog.