百度首页 | 百度空间
 
查看文章
 
openQRM 3.1 Plugins 介绍
2008-04-25 09:22
PDF | Print |

这篇文章可以让你知道插件是什么东西,里面都包括什么,

看的时候和前面一篇文章一起看,效果很好(透露一下,前面的代码有问题,自己找一下吧)。

Table of contents:

What is a plugin?

OpenQRM is designed and implemented using a pluggable architecture which allows users/developers to add (enhance/change) features and components to the openQRM without changing code in the main engine. Each plugin is self contained and can add/modify the functionality of the openQRM engine or of the connected nodes.

Plug-in Architecture

The openQRM engine uses an plugin architecture based on "extension points" - the engine publishes different types of extension points. Each plugin can implement "extensions" which connect to those extension points. E.g. a plugin that wants to add a capability to the openQRM server might have an extension connecting to the ServerService extension point to initialize the service, and an extension connecting to the MenuItem extension point to add its configuration page to the main menu.
The extension point mechanism is based on the Java Plugin Framework (http://jpf.sourceforge.net).

Another important concept is "execution" - different extension points accept "execution" definitions as parameters - these are the actions to take for the relevant extension point. Different execution types are supported - binaries (including scripts), Java classes, URLs and even PHP files.

Building, Installing and Uninstalling Plugins

To build a plugin from source, you need the openQRM sources as well - parts of the build usually use definitions and functions from the base engine.

Unpack the plugin into <openQRM-source-dir>/src/plugins/<plugin-name>.
Then change into that directory and run make && make install.
The binary plugin will be placed into <openQRM-source-dir>/out/qrm/plugins/<plugin-name>
This directory should then be moved to <openQRM-base-dir>/qrm/plugins/<plugin-name> (or the binary plug-in package can be unpacked into it).

Prepare the plugin for running and tell openQRM about it by calling:

<openQRM-base-dir>/qrm/sbin/qrm-plugin <plugin-name> register
<openQRM-base-dir>/qrm/sbin/qrm-plugin <plugin-name> install

The next time you restart the openQRM server engine, the plugin will be available - currently all installations and uninstallations of plugins require a openQRM server restart. Note that nodes continue to function normally while the server is restarted.

To uninstall the plugin, call <openQRM-base-dir>/qrm/sbin/qrm-plugin <plugin-name> uninstall
The plugin will be uninstalled from the engine the next time the openQRM server engine is restarted.

Note that uninstalling a plugin does not remove its files from <openQRM-base-dir>/qrm/plugins/<plugin-name>, allowing you to reinstall the plugin should you wish to do so.

Plugin Initialization

Each plugin has a functions file in <openQRM-base-dir>/qrm/plugins/<plugin-name>/include/<plugin-name>-functions

In this file, the following functions are implemented:

  • <plugin-name>_install - called when the plugin is installed into the openQRM engine. Here the plugin can do things like initialize its database tables (if any) or modify some part of th engine configuration.
  • <plugin-name>_uninstall - called when the plugin is uninstalled from the engine - for example, to restore original configurations.
  • <plugin-name>_run_once - called the first time the openQRM server is started after the plug-in installation. While an installation of a plug-in may fail, leaving the plug-in disabled, this operation may not fail. It is used for follow-on initialization and set-up. For example - calling a CLI command to modify the database.
  • <plugin-name>_start - called every time the server starts, to start up the plugin. This can be used to run startup and initialization actions. For example - the tftpd plugin uses this function to start the tftpd server.
  • <plugin-name>_stop - called when the openQRM server shuts down. This can be used to shut down services that the plugin started along-side the engine core.

Extension Definition

Plugins that connect to one or more extension points need to define their provided extensions. To do that, the plugin uses the file <openQRM-base-dir>/qrm/plugins/<plugin-name>/etc/qrm-<plugin-name>-plugin.xml

This file defines the identifier and requirements of the plugin - what other plugins it is dependant on as well as the extensions provided by the plugin.

An example of that file, from the sshlogin plugin, which provides an addition "action" item to the resource menu:

<?xml version="1.0" ?>
<!DOCTYPE plugin PUBLIC "-//JPF//Java Plug-in Manifest 0.2" "http://jpf.sourceforge.net/plugin_0_2.dtd">
<plugin id="com.qlusters.qrm.plugins.sshlogin-plugin" version="0.0.1" >
    <requires>
        <import plugin-id="com.qlusters.qrm.plugins.core"/>
    </requires>

<extension plugin-id="com.qlusters.qrm.plugins.core" point-id="MenuItem" id="sshlogin">
    <parameter id="key" value="resource_actions"/>
    <parameter id="title" value="ssh-login" />
    <parameter id="description" value="sshlogin"/>
    <parameter id="hierarchy" value="Actions"/>
    <parameter id="url" value="../unsecure/sshlogin/sshlogin.jsp?host_ip=${resource.ipString}"/>
</extension>
</plugin>

This example defines the "sshlogin" plugin with identifier com.qlusters.qrm.plugins.sshlogin-plugin, that requieres only the core engine.

The plugin provides an extension to the MenuItem extension point of the core engine. The identifier of this extension is sshlogin. The extension has parameters that mean it modifies the resource_actions menu, adding an item with title ssh-login to under Actions. That item then leads to the given url, with the IP address of the node as a parameter.

See the next sections for the available extension points, executions and parameter passing.

Executions

In many cases, we want an extension to invoke an action - for example running a script or calling a function in the Java code. The way to do this is through "executions" - A defined execution can invoke a given action and succeed or fail according to the defined expected result. When possible, the execution is invoked in the right context - e.g. the execution of a Java class will be in the context of the engine core calling it.

The following parameters are expected for an execution:

  • Type - the specific type of the execution. Currently supported types are:
    • exec - binary executable (could be a script)
    • java - Java class
    • php - PHP file - it will have access to the engine context through the "Scripting for the Java Platform" specification (JSR-223).
    • http - URL
  • resource - what to invoke - can be a file for the "exec" or "php" types, resource locator for "java" and a URL for the "http" type.
  • config - provides instructions on how to invoke the execution. For example, synchronous=false;variable-passing=env
  • expected-result - how to know if the action succeeded or failed. Can take values like return_value=0 for an "exec" type or result_type=html;title=success for an "http" type.
  • params - the parameters to pass to the execution invocation. For example, ip_addr=${resource.ipString}

See the next section on how to provide parameters for execution.

Parameters

The openQRM architecture uses OGNL (http://www.ognl.org/about.html) for defining and passing parameters. OGNL is an expression language for accessing the properties of Java objects.

For example, given a Resource object called "myNode" with a property called "externalId", the following expression provides the value of this property: ${myNode.externalId}

Extension Points

There are several extension points defined by the openQRM engine. In addition, each plugin can define its own extension points, to be used by other plugins.

The following extension points are defined in the core openQRM engine. You can see the full list, with parameters in <openQRM-base-dir>/qrm/java/plugins/plugin.xml.

Server Service

This extension point is for initializing an execution at the time of server startup or shutdown.
The following parameter are required:

  • priority - when to start this service compared to other services. The lowest priority gets started first
  • start-execution - the execution to call on server startup
  • stop-execution - the execution to call on server shutdown
MenuItem

This extension point is for adding an item to any of the menus in the system. The extension should provide the following parameters:

  • key - The key of the menu. A list of acceptable values appears in the appendix.
  • hierarchy - The item identifier of the parent item under which to add the new item. Leave empty (or don't specify) to add a top-level item. For most menu items, their identifier is simply their title (including any special formatting characters.)
  • title - The title for the new item.
  • description - This description appears in a tool-tip when the hovering with the mouse over the menu item. Optional.
  • icon - An icon to display with the menu item. Optional.
  • url - The link to which pressing on this item leads.
  • composite - A boolean value specifying whether the given URL should be processed as a JSP page. Optional.
  • item-id - Specify the identifier of this item explicitly. Optional.
EventListener

This extension point allows you to trigger an action when the openQRM server detects an event. The events are hierarchical - for example, the Resource.State.Operation.Error.Timeout.Heartbeat is a sub-event of Resource.State.Operation.Error
System events are listed in the following file: <openQRM-base-dir>/java/webapp/WEB-INF/classes/events.properties
In addition, see the appendix for a compilation of useful events, and for defining new events.
EventListeners can also be set up for events triggers by plugins.

The following parameters should be given for an EventListener extension:

  • eventKey - The key of the event
  • execution - The execution to trigger for that event
Tab

This extension points allows you to add another tab on pages that have them. For example, you can add another tab next to the Status and Configuration tabson the Resource screen.


Required parameters:

  • entityType - The entity to which the tab will be added. Possible values: VirtualEnvironment, Resource
  • title - The title of the new tab
  • url - The link to which clicking on the tab leads
PageIntegration

This extension points allows you to add information on any page in the system. By placing a "hook" in a page, plugins can add their information and fields to the displayed page. Required parameters for the extension:

  • key - The unique key of the hook.
  • url - Where to bring the data to display - this is fetched and displayed inside the page.
  • charEncoding - Specifies the encoding of the added content. Optional.

For example, adding the following tag to the node status JSP page:

<qrm:page-integration key="resource_config_monitor"/>

Will let any other plugin to add content to the node status by defining an extension like the following:

<extension plugin-id="com.qlusters.qrm.plugins.core" point-id="PageIntegration" id="sampleId">
<parameter id="extKey" value="resource_config_monitor"/>
<parameter id="url" value="http://localhost/monitor?resource=${resource.ipAddres}"/>
</extension>

BootService

Unlike the other extension points which effect the openQRM server, this extension point effects the booted entities. The BootService extension points lets plugins add customized packages and daemons to the nodes running under openQRM.

When defining a BootService, the following parameters must be specified:

  • name - The identifying name for this Boot Service
  • runlevel - At what init run-levels should this boot service run. Can be 1-6 or "initrd". Usually the plugin will specify "initrd" for services needed to configure or access the filesystem-image, 3 and 5 for starting daemons on the node, or 1 and 6 for triggering actions on node shut-down.
  • package - The package that contains the files needed on the node for that service. For example:
    http://$QRM_SERVER_IP_ADDRESS/unsecure/my-plugin/my-plugin.tgz
  • init - The commandline to call for triggering the service on the node after unpacking the package. E.g. plugins/my-plugin/bin/start.sh. Optional.

After a plugin defines a BootService extension, it can associate different entities with this BootService. The entities that can be associated are:

  • resource - A physical node, or a partition on a hosting node
  • ve - All nodes running the given Virtual Environment
  • image - All nodes running the given filesystem-image
  • kernel - All nodes booted with the given kernel

The syntax for the associate command:

<openQRM-base-dir>/bin/qrm-cli boot associate <parameters>

Where <parameters> are:

  • -k,--key <string> Key of boot service
  • -t,--type <resource|kernel|ve|image>   Type of entity
  • one of:
    • [-n,--name <name>]   Name of entity (resource | ve | image | kernel)
    • [-i,--id <number>]   ID of entity
    • [--ip <x.x.x.x>]   IP of resource
    • [--vem <ve_id:vem>]   VEM of resource (ve_id can be id/name)

If an init script is defined for the boot service, it will be called using the from the initialization sequence of the node using the chkconfig+RC standards. This means that the init script should contain a chkconfig comment line, and expect to receive 'start' or 'stop' parameters for starting or stopping the boot service.
For example:

#!/bin/bash
# chkconfig: 12345 80 99
# description: openQRM plugin init script
case "$1" in
'start')
start_something
;;
'stop')
stop_something
;;
esac

Other Extension Points

In addition to these extension points, there are other extension points, which are more advanced in nature and are for extending specific aspects of the openQRM engine:

  • ExecutionDelegate - Defining the different execution types
  • NodeControl - Performing control operations for different types of resources
  • PartitionBridge - Implementing different partitioning technologies
  • MigrationBridge - Implementing different application migration technologies
  • MacAddressProvider - Maintain and provide MAC addresses for virtual partitions
  • PlacementController - Decide how to assign resource to Virtual Environments
  • Hibernate - Part of the database layer

Plugin Files

Each plugin is self contained under a single directory - this allows easier management of the installed plug-ins.

he following files in the openQRM engine core are relevant for plugins. The location is given relative to the openQRM base directory

  • etc/qrm.xml - lists the plugins that are installed during the openQRM installation (running the qrm-install script)
  • java/plugins/plugin.xml - contains the different extension points and the paramters that each extension must provide
  • java/webapp/WEB-INF/classes/events.properties - the heirarchical list of events in the system and their properties

The plugins themselves are located under <openQRM-base-dir>/qrm/plugins. Each plugin is in a seperate directory, named according to the plugin. Each such directory typically contains the following subdirectories:

  • etc/ - for configuration files
  • include/ - for function files used by plugin
  • bin/ - for binaries used by the plugin
  • web/ - for web pages
  • doc/ - for documentation
  • build/ - for building the plugin from source. Not there when using a binary plug-in

Appendices

MenuItem keys

The following are useful predefined keys for menu integration:

  • navigation – the left sidebar menu
  • resource_actions – actions for each resource (node or partition)
  • ve_actions – actions for each VE
  • storage_server_actions – actions for each storage server
  • header_buttons – buttons at the top of the page (near the “help” and “user” buttons)
  • fs_image_actions – actions for each filesystem image
  • kernel_actions – actions for each kernel image
Useful Parameter Fields

TBD

List of useful fields, according to context, for example ${resource.ipString} for node actions

Events

Events are defined in the file <openQRM-base-dir>/java/webapp/WEB-INF/classes/events.properties
Each line in that file contains a definition for an event parameter. Most events have three parameters -
EventName$level – the level of the event. Can be “Attention”, “Event” or “Alert”.
EventName$message – the message to show the user. Event or context parameters can be specified as per the “Parameters” section.
EventName$recommendation – the recommendation to the user as to how to resolve the event.

The event definitions are heirarchical – if a property is undefined for 'Event.Sample.Test', the property of 'Event.Sample' is used. This lets the user easily specify sub-events. To add an event, simply add the event with any of its properties to this file. At the least, define a message for the new event. For example:
My.New.Event$message=the new event I defined.

To trigger events, you can call “qrm-cli event add” - it accepts the following parameters:

-k,--event_key <key> Event Key
[-t,--attr <key=value>] Event attributes. Can be specified multiple times
one of:
[--internal_cr_id <id>] Internal id of a resource
[--resource_ip <x.x.x.x>] IP of the resource
[--resource_mac <xx:xx:xx:xx:xx:xx>] MAC of the resource [--resource_id <external id>] Resource external id
[--vem <ve_id:vem>] VEM of resource (ve_id can be id/name)
[-v,--ve_name <name>] Virtual environment name
[--internal_ve_id <id>] Internal id of a virtual environment
[-g,--global] the event is global

list of some of the more useful events that you can set up listeners for -

  • QRM.Pool.State.Red – when there are not enough resources available for high availability
  • VirtualEnvironment.State.Failure.Begin – when a VE fails
  • VirtualEnvironment.State.Failure.End – when a VE recovers from failure
  • VirtualEnvironment.State.Composite.Growing – when a VE scales out
  • VirtualEnvironment.State.Composite.Shrinking – when a VE scales down
  • VirtualEnvironment.State.Composite.Error – when a VE has resources with errors
  • VirtualEnvironment.State.Lifecycle.Starting – when a VE is just starting
  • VirtualEnvironment.State.Provisioning.NotEnoughResources – when a VE does not have enough resources
  • VirtualEnvironment.Action.Grow.Policy.MaxProvisioning – when the provisioning policy means a VE should scale out, but it has already reached the maximum number of allowed resources.
  • Resource.State.Operation.Error – when a resource (node or partition) is in error state
  • Resource.State.Role.Assigned – when a resource is being assigned to a VE
  • Resource.State.Role.Deassigning – when a resource is release from a VE
Sample Plugin

The Sample plugin demonstrates basic functionality of many of the available extension points. The actual operations performed by the plugin are not very useful, but its code can be easily adapated for many different plugins.

The plugin should be installed under <openQRM-base-dir>/plugins/sample.
The plugin utilizes the following integration points:

  • Install function – called from include/sample-functions this function creates links from the openQRM base directory to the different components used by the plugin – such as the JSP web pages and the packages supplied by the plugin.
  • Uninstall function – called from include/sample-functions this function removes the links and configurations created by the install function.
  • Startup function – called from include/sample-functions this function outputs a system log line stating that the plugin has started. Usually the system log can be viewed in /var/log/messages.
  • Shutdown function – called from include/sample-functions this function outputs a system log line stating that the plugin has stopped. Usually the system log can be viewed in /var/log/messages.
  • Server service – defined in a Java file, this service outpus a line to the openQRM log (logs/qrm.log) announcing the Sample plugin Server-Service is starting or stopping.
  • Menu item – this simple item is added to the left sidebar menu and displays a very simple page.
  • VE Tab Integration – this tab is added to every VE (next to the status, configuration and policy tabs) and demonstrates how the plugin's JSP page can access data from that VE.
  • Node boot service – which can be associated with any entity (a VE or a resource). When associated, the relevant entity outputs a line to that node's system log, and sends an event to the openQRM server. That event is a new custom event declared from the installation function.
  • Event listener – which traps the event sent by the node boot service and calls an execution. That execution points to a script which reports the event and the node which generated it to the system log (usually in /var/log/messages).
Page-Integration Sample

TBD

Giving a detailed example of adding more data to a page with a plugin that connects to the PageIntegration extension-point.


类别:Openqrm | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码:
 

     

©2008 Baidu