Sun N1 Service Provisioning System 5.2 Plug-in Development Guide

Chapter 2 Creating a Plug-In

This chapter explains how to use the plug-in framework to create a provisioning solution for a specific application or platform. The chapter includes the following information:

Installing the Plug-In Development Environment

Most of the pieces that you need to create a plug-in solution are part of the standard Sun N1 Service Provisioning System software. However, you must install a few additional software ingredients to provide you with a complete development solution. These key pieces are contained in the /plugins/lib/sps-compSDK.jar and the /plugins/lib/plugin-core.jar files on the Sun N1 Service Provisioning System 5.2 DVD.

sps-compSDK.jar File

The sps-compSDK.jar contains the N1 SPS public Java API


Note –

Install the sps-compSDK.jar file on your development system, not on your N1 SPS Master Server. Once you place the sps-compSDK.jar file where you want, be sure to modify the classpath for your Java tools to find the file.


The sps-compSDK.jar file contains the following Java classes for creating plug-ins. For detailed explanations of the classes and interfaces in these packages, see Sun N1 Service Provisioning System 5.2 JavaDoc.

com.sun.n1.sps.client

Includes classes and interfaces to execute CLI commands and query information from the Master Server

com.sun.n1.sps.model

Includes classes and interfaces to identify the version number, visibility, and ID of N1 SPS objects

com.sun.n1.sps.model.category

Includes three interfaces to group related objects, such as components and plans, in categories

com.sun.n1.sps.model.component

Includes interfaces and classes for defining component information

com.sun.n1.sps.model.difference

Includes interfaces and classes for defining provisioning comparisons

com.sun.n1.sps.model.executor

Includes interfaces and classes for running plans and native OS commands

com.sun.n1.sps.model.folder

Includes interfaces for defining N1 SPS folders

com.sun.n1.sps.model.host

Includes interfaces and classes for defining host criteria, including host sets, host IDs, host searches, applications running on specific hosts, and upgrade activities for specific hosts.

com.sun.n1.sps.model.install

Includes interfaces for gathering information about components that are installed on target hosts

com.sun.n1.sps.model.plan

Includes interfaces and classes for running N1 SPS plans

Package com.sun.n1.sps.model.plugin

Includes interfaces for defining plug-ins and enabling other users to browse these plug-in in the browser interface

com.sun.n1.sps.model.resource

Includes an interface for defining a resource

com.sun.n1.sps.model.rule

Includes interfaces and classes that you can use to define criteria and rules for specific actions

com.sun.n1.sps.model.user

Includes interfaces and classes that you can use to set user and group permissions, IDs, and variables

com.sun.n1.sps.model.util

Includes interfaces, classes, and exceptions that you can use to perform basic network connectivity validation, through ping and traceroute

com.sun.n1.util.collections

Includes interfaces for defining lists and sets

com.sun.n1.util.enum

Includes interfaces, classes, and exceptions for enumerations and enumerations types

com.sun.n1.util.vars

Includes one interface that you can use to identify the source of variable settings

plugin-core.jar File

The plugin-core.jar contains three packages that provide file system-based component browse and export classes:

com.sun.n1.sps.pluginimpl.system

Includes several constants that identify supported platforms

com.sun.n1.sps.pluginimpl.system.browse

Includes five classes that you can use to support file system-based browsing functionality:

  • FileDisplay – A display appropriate for file system files

  • FilesystemBrowser – A hierarchy browser for files ystems

  • FilesystemBrowserFactory – Factory to return types sufficient for browsing a file system as a hierarchy

  • FilesystemExtensionFilter – A FilesystemFilter that filters based on the file extension suffix

  • FilesystemFilter – Base class for all file system filters

com.sun.n1.sps.pluginimpl.system.export

Provides one class FilesystemExporter that you can use to export a simple filesystem object

Creating a Plug-In: Process Overview

Developing a plug-in solution can be simple or complex, depending on the needs of your environment and the application or platform to which the solution applies. A plug-in solution can involve any of the following segments of the Sun N1 Service Provisioning System environment:

The general process that you follow includes the following steps:

  1. Develop a general model for the platform or application.

    For more information, see Developing a Model.

  2. Create plans and components to implement the model.

    For more information, see Creating Components and Plans

  3. Define specific host types, host sets, and host searches to easily constrain the plug-in.

    For more information, see Limiting Hosts for a Plug-In.

  4. Define an interface for the application within Sun N1 Service Provisioning System.

    For more information, see Defining a User Interface to the Plug-In.

  5. Package the plans, components, resources, and interface definition into a Java Archive (JAR) file.

    For more information, see Packaging the Solution.

  6. Test the plug-in.

    For more information, see Testing the Solution.

Plug-In Directory Structure

As you develop your solution using the plug-in framework, you need to pay attention to where files are placed. Having an accurate record of the files is essential when you package your solution into a JAR file. The following list illustrates a recommended directory structure for plug-ins:


META-INF
components
plans
resources           
gui                  
plugin-descriptor.xml  
readme.txt
META-INF directory

Contains the manifest of pieces of the plug-in. This directory is created when you package your plug-in in a JAR file.

components directory

Contains a series of subdirectories that contain component and component type XML definition files. Subdirectories follow the structure of the plug-in name. For example, if the plug-in name is com.sun.solaris, the components subdirectories would be com, then sun then solaris. For example, the actual component XML files would live inside the components/com/sun/solaris directory.


Note –

You might want to wrap the components, plans, and resources directories into a larger directory structure for a given plug-in version. For example, to differentiate between versions 1.0 and 1.1 of a given plug-in, you might use directory structures such as 1.0/components/com/sun/solaris/Project.xml and 1.1/components/com/sun/solaris/Project.xml


plans directory

Contains a series of subdirectories that contain execution plan XML definition files. Subdirectories follow the structure of the plug-in name. For example, if the plug-in name is com.sun.solaris, the plans subdirectories would be com, then sun then solaris. For example, the actual execution plan XML files would live inside the plans/com/sun/solaris directory.

resources directory

Contains a series of subdirectories that contain resource files. Subdirectories follow the structure of the plug-in name. For example, if the plug-in name is com.sun.solaris, the resource subdirectories would be com, then sun then solaris. For example, the actual resource files would live inside the resources/com/sun/solaris directory.

gui directory

Contains the user interface descriptor file (pluginUI.xml) and files for any icons that need to be displayed in the user interface. See Chapter 7, Plug-In User Interface Schema, in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide for more information about the elements in the user interface descriptor file.

plugin-descriptor.xml file

XML file that describes the plug-in. See Chapter 6, Plug-In Descriptor Schema, in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guidefor more information about the elements in the plug-in descriptor file.

readme.txt file

Text file that contains any instructions on configuring the system for the plug-in.

Developing a Model

Before you build your plug-in solution, you need to do some planning and modeling work. The following questions indicate some common areas to consider:

The following illustrates one possible modelling flow, based on the flow for deploying JavaTM 2 Platform, Enterprise Edition (J2EE) :

  1. Deploy infrastructure.

    • Execute installer binaries to install infrastructure

    • Install targetable components

  2. Capture all application objects as components, such as the following objects:

    • Java Archive (JAR) files, Enterprise Archive (EAR) files, Web Archive (WAR) files, Enterprise Java Beans (EJB) files

    • JDBC connection and data sources

  3. Create an “environment” component that contains environment settings, such as the following:

    • Java Virtual Machine (JVM) settings

    • Session management settings

  4. Configure application and environment components

  5. Deploy components into targetable components

Designing Your Plug-In for Extensibility

Sun N1 Service Provisioning System software enables you to extend plug-ins, allowing you to efficiently add functionality to an existing plug-in and add this new plug-in to your Sun N1 Service Provisioning System environment. You might want to extend an existing plug-in under the following circumstances.

When you extend a plug-in, you extend the XML or Java classes that are used by the existing plug-in. However, the plug-in that you want to extend must be extendable. Follow these guidelines while you develop a plug-in to make your plug-in extendable.

For more information about how to extend a plug-in, see Chapter 3, Extending an Application-Specific Plug-In.

Creating Components and Plans

To be able to effectively reproduce a given solution across an enterprise, you need to define components, resources, and plans that identify common parts of the solution. In addition, you need to define a process for deploying them. For more information about plans, components, and how to manage them, see Sun N1 Service Provisioning System 5.2 Plan and Component Developer’s Guide.

Building Components

A key piece in developing your solution is creating components. In the Sun N1 Service Provisioning System environment, components are deployable objects. Some examples of the objects you might have in components include the following:

The N1 SPS software enables you to capture versions of components. When you modify the components in your plug-in and check these components in to your N1 SPS environment, the components are assigned a new version number. When you use the plug-in to provision your application, you can select the component version that is appropriate for your particular deployment.

For information about creating components by using the Sun N1 Service Provisioning System browser interface, see How to Create a Component in Sun N1 Service Provisioning System 5.2 Plan and Component Developer’s Guide.

Simple and Composite Components

Simple components contain a single physical resource, such as a file, directory, archive file, or application. Simple components do not reference other components.

Composite components only reference other simple or composite components. Composite components do not directly contain any physical resources.


Example 2–1 XML for a Simple Component

The following XML example shows a simple component that extends the system component type system#CR Simple Base to contain a JAR file. For more information about the specific elements and attributes used to define a component, see Chapter 3, Component Schema, in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.

<?xml version="1.0" encoding="UTF-8"?>
<component xmlns='http://www.sun.com/schema/SPS' name='plugin-core.jar' 
    version='5.2' description='Jar file implementation of core plugin services' 
    xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' author='system' 
    softwareVendor='Sun Microsystems' path='/system' 
    xsi:schemaLocation='http://www.sun.com/schema/SPScomponent.xsd'>
  <extends>
    <type name='system#CR Simple Base'>
    </type>
  </extends>
  <resourceRef>
    <resource name='/system/plugin-core.jar' version='1.1'>
    </resource>
  </resourceRef>
</component>

Variables

When you create a component or plan, you can define variables to use when that component is deployed or the plan is executed. Many component types include common variables, such as installPath, which defines where to install the component. The value of the installPath variable is determined for a given host when the component is installed on that host.

Some common variables that you might see include the following:

A variable can refer to another variable, such as the variable of a container component. For example, the value of the installPath variable for a simple component could be the value of the installPath variable for its parent container component.

When defined, each variable must have a name and a default value attribute. The default value can be obtained from several places:

For detailed information about using these attributes, see Types of Variables Available for Substitution in Sun N1 Service Provisioning System 5.2 Plan and Component Developer’s Guide.

You can define a variable through the browser interface or directly in the XML file. Within the XML file, variables are defined using the <var> element and contained within a <varList> element.


Example 2–2 Variable Definitions in XML

The following XML fragment shows several variable definitions.

<varList>
    <var name='installPath' 
         default=':[target:sys.raDataDir]:[/]systemcomps'>
    </var>
    <var name='pluginClasspath' 
         default=':[installPath]:[/]plugin-core.jar'>
    </var>
    <var name='fileBrowser' 
          default='com.sun.n1.sps.pluginimpl.system.browse.FilesystemBrowserFactory'>
    </var>
    <var name='directoryBrowser' 
          default='com.sun.n1.sps.pluginimpl.system.browse.FilesystemBrowserFactory'>
    </var>
    <var name='symlinkBrowser' 
          default='com.sun.n1.sps.pluginimpl.system.browse.FilesystemBrowserFactory'>
    </var>
</varList>

Configuration Templates

A configuration template is a special type of file component. The configuration template enables you to do token substitution in a file that you are deploying. An example of this usage would be deploying the DNS /etc/resolv.conf file. The goal for deployment might be to have the file use a variable substitution and use a host type attribute to define the closest DNS server. The configuration template might look like the following example:

search :[search_path]
nameserver :[primary_dns]
nameserver :[secondary_dns]

In this case, the configuration template would automatically create component variables called search_path, primary_dns, secondary_dns. Then you could use variable substitutions in plans or component controls to provide appropriate values.

For more information about how to define configuration templates, see Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.

Defining Component Types

Many basic component types are included with the Sun N1 Service Provisioning System product. Some of these basic component types include such items as files and directories. You can also define specific component types for use with a specific application or platform. For example, perhaps your application has some specific file types that would always exist for this application. You could then define a new component type for your application that is based on the system#CR Simple Base component type but extends that component type for your specific application.

The component type definition is stored in an XML file like any other component XML file. When you define your plug-in, you provide a path to the file for the backing component in the <component> element in the descriptor file. You use the <componentType> child element of the <component> element to provide additional information, such as its name, description, and so on. For more information, see Example 2–15.

Component types are not versioned. If a plug-in attempts to create a component type that matches the name of an existing component type, the plug-in name is prepended to the name of the new component type to avoid naming conflicts.

For information about how to create a component type, see <componentType> Element in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.

Creating Plans

A plan is a sequence of instructions that is used to manage one or more components on the specified hosts. For example, a plan might install three components and initiate the startup control of another component. To create most plans, you have to edit the XML. The one exception to this rule is an auto-generated plan. The Sun N1 Service Provisioning System software can automatically generate a plan consisting of direct run procedures. For example, you could auto-generate a plan that consists of installing a single component. You could then run this plan directly or save it for use as a template for authoring more complex plans.

The N1 SPS software enables you to capture versions of plans. When you modify the plans in your plug-in and check these plans in to your N1 SPS environment, the plans are assigned a new version number. When you use the plug-in to provision your application, you can select the plan version that is appropriate for your particular deployment.

Simple and Composite Plans

Simple plans contain a series of deployment instructions, or steps. Simple plans are executed on a single host or host set. Simple plans can call common procedures, such as install or uninstall, and can also use conditional programming constructs.

Composite plans contain calls to simple plans. Composite plans can apply some procedures to one host, while applying other procedures to a different host or host set.


Example 2–3 XML for a Simple Plan

A simple plan might look like the following example. This plan provides an install block and an uninstall block. For more information about the specific elements and attributes used to define a plan, see Chapter 4, Plan Schema, in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.

<?xml version="1.0" encoding="UTF-8"?>
<!-- generated by N1 SPS -->
<executionPlan xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' 
    name='plugin-core.jar-1096573592002' version='5.12' 
    xsi:schemaLocation='http://www.sun.com/schema/SPSplan.xsd' 
    xmlns='http://www.sun.com/schema/SPS' path='/system/autogen'>
    <simpleSteps>
        <install blockName='default'>
            <component name='plugin-core.jar' path='/system' version='1.1'>
            </component>
        </install>
        <uninstall blockName='default'>
            <installedComponent name='plugin-core.jar' versionOp='=' 
                 version='1.1' path='/system'>
            </installedComponent>
        </uninstall>
    </simpleSteps>
</executionPlan>


Example 2–4 XML for a Composite Plan

A composite plan might look like the following example. This example calls three sub-plans.

<executionPlan 
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  name="apache-tomcat-uninstall" version="5.2"
  xsi:schemaLocation="http://www.sun.com/schema/SPSplan.xsd"
  xmlns="http://www.sun.com/schema/SPS">
    <compositeSteps>
        <execSubplan planName="mod-jk-uninstall" />
        <execSubplan planName="apache-uninstall" />
        <execSubplan planName="tomcat-uninstall" />
    </compositeSteps>
</executionPlan>


Example 2–5 XML for a More Sophisticated Plan

The following example shows a more complicated plan that determines what to execute based on some conditions.

<?xml version="1.0" encoding="UTF-8"?>
<!-- generated by CR -->
<executionPlan xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    name="BAM_backout_new_version_NODE-A" version="5.2" 
    xsi:schemaLocation="http://www.sun.com/schema/SPSplan.xsd" 
    xmlns="http://www.sun.com/schema/SPS" path="/plans/uat">
   <paramList>
      <param name="backout_type" prompt="Enter type of backout (all,ear,prop)"></param>
   </paramList>
   <varList>
      <var name="admin_server" default="wusx119"></var>
      <var name="node" default="wust3022"></var>
      <var name="wl_server_name" default="bamC"></var>
      <var name="apphome" default="/opt/uat/ceodomain"></var>
      <var name="prop_args" default="-s wust3022"></var>
      <var name="application_name" default="bam"></var>
      <var name="staging_base" default="/usr/local"></var>
      <var name="user" default="weblogic"></var>
   </varList>
   <simpleSteps limitToHostSet="uat-bam">
      <if>
         <condition>
            <or>
               <equals value2="all" value1=":[backout_type]"></equals>
               <equals value2="prop" value1=":[backout_type]"></equals>
               <equals value2="ear" value1=":[backout_type]"></equals>
            </or>
         </condition>
      <then>
         <call blockName="backout_application">
            <argList application_name=":[application_name]" 
                 staging_base=":[staging_base]" 
                 backout_type=":[backout_type]" 
                 user=":[user]">
            </argList>
            <installedComponent name="deploy_tools" 
                  path="/components/function_library">
             </installedComponent>
         </call>
         <call blockName="wl_stop">
            <argList wl_server_name=":[wl_server_name]" 
                  node=":[node]" apphome=":[apphome]" user=":[user]">
            </argList>
            <installedComponent name="deploy_tools" 
                  path="/components/function_library">
            </installedComponent>
         </call>
         <if>
            <condition>
              <equals value2="all" value1=":[backout_type]"></equals>
            </condition>
         <then>
               <call blockName="clusterdeploy">
                  <argList application_name=":[application_name]" 
                        staging_base=":[staging_base]" node=":[node]" user=":[user]">
                  </argList>
                  <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                  </installedComponent>
               </call>
               <call blockName="deploy_prop">
                  <argList application_name=":[application_name]" 
                        prop_args=":[prop_args]" staging_base=":[staging_base]" 
                        user=":[user]">
                  </argList>
                  <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                     </installedComponent>
                  </call>
                  <call blockName="wl_startjsp">
                     <argList application_name=":[application_name]" 
                        wl_server_name=":[wl_server_name]" 
                        node=":[node]" apphome=":[apphome]" user=":[user]">
                     </argList>
                     <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                     </installedComponent>
                  </call>
               </then>
            </if>
            <if>
               <condition>
                  <equals value2="ear" value1=":[backout_type]"></equals>
               </condition>
               <then>
                  <call blockName="clusterdeploy">
                     <argList application_name=":[application_name]" 
                        staging_base=":[staging_base]" node=":[node]" user=":[user]">
                     </argList>
                     <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                     </installedComponent>
                  </call>
                  <call blockName="wl_startjsp">
                     <argList application_name=":[application_name]" 
                        wl_server_name=":[wl_server_name]" 
                        node=":[node]" apphome=":[apphome]" user=":[user]">
                     </argList>
                     <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                     </installedComponent>
                  </call>
               </then>
            </if>
            <if>
               <condition>
                  <equals value2="prop" value1=":[backout_type]"></equals>
               </condition>
               <then>
                  <call blockName="deploy_prop">
                     <argList application_name=":[application_name]" 
                        prop_args=":[prop_args]" 
                        staging_base=":[staging_base]" user=":[user]">
                     </argList>
                     <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                     </installedComponent>
                  </call>
                  <call blockName="wl_start">
                     <argList application_name=":[application_name]" 
                        wl_server_name=":[wl_server_name]" 
                        node=":[node]" 
                        apphome=":[apphome]" 
                        user=":[user]">
                     </argList>
                     <installedComponent name="deploy_tools" 
                        path="/components/function_library">
                     </installedComponent>
                  </call>
               </then>
            </if>
         </then>
         <else>
            <raise message="Please enter a valid deployment type (all/ear/prop)"></raise>
         </else>
      </if>
   </simpleSteps>
</executionPlan>

ProcedureHow to Generate a Plan

Steps
  1. Go to the Components page.

  2. Select the component for which you want to generate the plan.

  3. View the component's details.

  4. If needed, scroll down the page until you see Component Procedures.

  5. Select the procedures that you want to use in the plan.

  6. Click Generate Plan with Checked Procedures.

    The Plans editing page appears. From this page, you can modify the XML to include more complex steps, like those shown in Example 2–5.

Using Native Commands in Plans and Components (<execNative> Step)

The <execNative> XML step enables you to run native commands from within your plans and components. For example, if you need to verify that a process has started, you might use <execNative> to call the UNIX ps command. For more information about the <execNative> schema, attributes, and child elements, see <execNative> Step in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.

Before <execNative> executes the specified command, the Sun N1 Service Provisioning System software verifies that the command exists and that the specified user has permission to run the command. If either of these checks fail, <execNative> exits with an error.


Example 2–6 Using <execNative> to Invoke a Simple Command

The following <execNative> example performs the equivalent of the UNIX ps -ef command.

<execNative>
    <exec cmd="ps">
        <arg value="-ef" />
    </exec>
</execNative>


Example 2–7 Using <execNative> to Start an Application

The following <execNative> example starts a web server instance.

<execNative
  dir="/opt/ns/https-admserv"                Set working directory
  userToRunAs="webadmin"                     Equates to "su -webadmin"
  timeout="5">
    <inputText>
        start.sh                             Input parameters to command
    </inputText>
    <exec cmd="sh />                         Command to run
    <successCriteria status="0" />           execNative succeeds only if exit code is "0"
</execNative>

Calling Java-based Objects in Plans and Components (<execJava>)

The <execJava> mechanism enables agent-side, in-process execution of client-provided Java code within a plan or component definition. <execJava> is similar to <execNative>, but is specifically intended to enable execution of Java code.

The <execJava> feature is provided as an XML step and as a Java-based API. For information about the XML schema, attributes, and child elements, see <execJava> Step in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide. For more information about the execJava API, including examples, see execJava API.

The <execJava> XML step has one required and two optional attributes:

The <execJava> mechanism can pass arguments to the Java Executor using the <argList> child element.


Example 2–8 Using <execJava> in Component XML

<varList>
   <var name="installPath" default="/opt/util"/>
</varList>
<resourceList defaultInstallPath=":[installPath]">
   <resource resourceName="util/propPrint.jar" installName="propPrint.jar"/>
</resourceList>
   ...
<controlList>
   <control name="showProp"/>
   <paramList>
       <param name="propName">
   </paramList>
   <execJava
       className="com.raplix.util.PropertyPrinterFactory"
       classPath="$[installPath]/propPrint.jar">
       <argList>
           <arg name="propertyName" value=":[propName]"/>
       </argList>
       <successCriteria outputMatches="<undefined>" inverse="true"/>
   </execJava>


Example 2–9 Using <execJava> in Plan XML

<executionPlan xmlns="http://www.sun.com/schema/SPS" 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
   xsi:schemaLocation="http://www.sun.com/schema/SPSplan.xsd" 
   name="execJavaExample" version="5.2">
   <paramList>
       <param name="name"></param>
       <param name="value"></param>
   </paramList>
   <varList>
       <var name="classpath" 
           default=":[target:sys.raDataDir]:[/]systemcomps:[/]plugin-com.sun.sample.jar"/>
   </varList>
   <simpleSteps>
       <execJava className="com.sun.n1.sps.pluginimpl.sample.executor.SampleExecutorFactory"
           classPath=":[classpath]">
           <argList nameParam=":[name]" valueParam=":[value]" />
       </execJava>
   </simpleSteps>
</executionPlan>

Conditional Elements

Within a plan or a component, you can use the <if> element to conditionally perform a block of steps. Similar to traditional programming if-then-else constructs, the statement within the <if> element is evaluated. If that statement is true, then the steps of the <then> element are performed. Otherwise, the steps of the <else> element are performed. If no <else> element exists, then no action is taken.


Example 2–10 XML for <if> Element

The following example uses the <if> element to allow users to decide at deployment time whether to take a snapshot of the system to capture the installed state of the component on the target host.

<if>
    <condition>
        <istrue value=:[createSnapshot]"></istrue>
    </condition>
    <then>
        <createSnapshot blockName="default"></createSnapshot>
    </then>
</if>

Error Handling

The XML schemas provides a set of elements for handling possible errors . The parent of this set of elements is the <try> element. You might use these elements for situations similar to the following examples:

The <try> element includes a block of steps that are executed in order until either all complete successfully or a step fails. If a step fails and a <catch> element exists, then the steps in the <catch> element are executed in order until they succeed or a step fails. If a <finally> element is defined, the steps in the <finally> element are executed in order until all steps complete or a step fails regardless of whether the <try> and <catch> elements succeeded. Typically, the <finally> element is used to perform clean-up functions or release resources.

The <raise> element is used to indicate a failure condition without having to create a step to do so. The <raise> step always fails. Although the <raise> element can be used by itself, it is often contained within a <catch> element block.


Example 2–11 XML for <try> Element

The following XML example uses the <try> element to determine whether a fresh install or an upgrade install should be performed.

<installSteps blockName="default">
    <try>
        <block>
            <checkDependency>
                <installedComponent name="foo" version="1.0" />
            </checkDependency>
        </block>
        <catch>
          <raise message="Required component foo is not installed on this system"/> 
        </catch>
    </try>
</installSteps>

Limiting Hosts for a Plug-In

The Sun N1 Service Provisioning System enables you to limit plug-in behavior to hosts that match certain criteria. There are three mechanisms that you can use to limit your hosts:

You define all three host limiters in the plug-in descriptor file, as shown in the following examples.


Example 2–12 Host Type Definition in plugin-descriptor.xml File

The following example defines two host types for use with Solaris containers: one for a global zone and one for a local zone. The plug-in name is appended to the actual hostType name. When a user creates a host of type com.sun.solaris#global_zone, four attributes are provided, each attribute of which has a default value. The com.sun.solaris#local_zone host type, on the other hand, has no user-defined attributes associated with it.

<hostType name="global_zone" 
    description="a physical host from which partitioned local zones can be created"> 
  <varList>
    <var name="local_zone_base_path" default="/export/zones"/>
    <var name="local_zone_connection_type" default="RAW"/>
    <var name="local_zone_port" default="1131"/>
    <var name="local_zone_advanced_params" default=" "/>
  </varList>
    </hostType>
    <hostType name="local_zone" 
      description="a physical host that is created out of the larger global_zone"/>


Example 2–13 Host Set Definition in plugin-descriptor.xml File

The following example defines a host set that contains global zones. The actual contents of the host set are provided when the referenced host search is performed.

<hostSet name="global_zones"
     description="Solaris global zones">
<hostSearchRef name="global_zones"/>


Example 2–14 Host Search Definition in plugin-descriptor.xml File

The following example defines a host search to find all global zones. The search returns a result for any host that matches the following criteria:

<hostSearch name="global_zones" description="Solaris global zones">
  <criteriaList>
    <criteria name="sys.OS" pattern="SunOS"/>
    <criteria name="sys.OSVersion" pattern="5.10"/>
    <criteria name="sys.hostType" pattern="com.sun.solaris#global_zone"/>
  </criteriaList>
  <appTypeCriteria ra="true"/>
  <physicalCriteria physical="true"/>
</hostSearch>

Enabling Users to Browse and Export Files

The Sun N1 Service Provisioning System provides capabilities for you to enable users to include specific resources in their components. The browsing feature consists of two primary functions:

For example, you could enable a user to traverse a file system, select a file, and check in the file through a component.

Browsing and exporting functionality are provided through the com.sun.n1.sps.plugin.browse and com.sun.n1.sps.plugin.export packages, as described in Component APIs.

Browsing and Exporting: Process Overview

From an external view, the browsing and exporting process is similar to the following sequence:

  1. The user selects a component type to create a component. If the backing component of the selected type has exporterClassName defined, the browse and export user interface is launched.

  2. The provisioning software obtains all the browser information in the BrowserInfo class. To obtain this information, the software calls the getAvailableBrowsers method of the ComponentExporter interface.

  3. The provisioning software obtains the information about the BrowserFactory from BrowserInfo and instantiates it. From there, the provisioning software gets the Browser object.

  4. From the Browser object, the software finds the root node by calling the getNode() method of Browser.

  5. When the user selects a node and continues with the check-in process, the provisioning software calls into the constructComponent method of the ComponentExporter class which finally exports and checks-in the resource.

From the plug-in development perspective, a more detailed view of this process is similar to the following sequence:

  1. The backing component of a component type defines a component variable named exporterClassName. The value of exporterClassName is the class that implements com.sun.n1.sps.plugin.export.ComponentExporter.

  2. The ComponentExporter class method getAvailableBrowsers returns an array of BrowserInfo objects. These BrowserInfo objects have the following information about the browser:

    • Name of the system service

    • Variable name in the above system service. This variable will have the BrowserFactory class as its value

    • Variable name in the above system service. This variable will have the class path for the browser as its value.

    • The actual class path, if system service is not used for class path.

  3. The BrowserFactory class has a method to get the browser which implements the Browser interface.

  4. The Browser method getNode(...) finds the nodes of a tree. When used with a null argument, getNode(...) should give the root node.

  5. The ComponentExporter class has another method to construct the component. This method is used once the actual browsing is done. The constructComponent method is passed a ComponentMonitor which is used to finally export and check-in the selected resource into the master server as part of the component.

Browse Function

BrowserNode is the class which implements the entire hierarchy tree functionality. This functionality is segmented into four key areas:

For more information about the classes and methods that you use to implement a browser for your plug-in, see Browsing Function.

Export Function

ComponentExporter is the class which enables a user to export a file to the master server, once he has browsed to it. For more information about the classes and methods that you use to implement the export feature for your plug-in, see Exporting Function.

Defining the Plug-In

To make the solution available for others to use, you wrap the plans, components, and component type definitions into a plug-in. To define the plug–in, you create an XML file that uses the <plugin> element and its children. For information about the <plugin> element, see Chapter 6, Plug-In Descriptor Schema, in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.


Example 2–15 Sample Plug-In Descriptor File

The following sample descriptor file is for the Solaris Zones plug-in.

<?xml version="1.0" encoding="UTF-8"?>
<plugin name="com.sun.solaris"
   description="Solaris plugin"   version="1.0"
   vendor="Sun Microsystems Inc"
   xmlns="http://www.sun.com/schema/SPS"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.sun.com/schema/SPSplugin.xsd"
   schemaVersion="5.1">
   <gui jarPath="gui/pluginUI.xml"/>
   <memberList>
       <folder name="/com/sun/solaris" description="Solaris plugin folder"/>
       <hostType name="global_zone"
            description="a physical host from which partitioned local zones can be created">
          <varList>
            <var name="local_zone_base_path" default="/export/zones"/>
            <var name="local_zone_connection_type" default="RAW"/>
            <var name="local_zone_port" default="1131"/>
            <var name="local_zone_advanced_params" default=" "/>
         </varList>       </hostType>
       <hostType name="local_zone" 
            description="a physical host that is created out of the larger global_zone"/> 
       <hostSearch name="global_zones" description="Solaris global zones">
         <criteriaList>
            <criteria name="sys.OS" pattern="SunOS"/>
            <criteria name="sys.OSVersion" pattern="5.10"/>
            <criteria name="sys.hostType" pattern="com.sun.solaris#global_zone"/>
         </criteriaList>
         <appTypeCriteria ra="true"/>
         <physicalCriteria physical="true"/>
       </hostSearch>
       <hostSet name="global_zones" description="Solaris global zones">
         <hostSearchRef name="global_zones"/>
       </hostSet>
       <component jarPath="fiji/components/com/sun/solaris/zone_util.tar.xml">
         <resource jarPath="fiji/resources/com/sun/solaris/zone_util.tar"
             name="/com/sun/solaris/zone_util.tar"/>
       </component>
       <component jarPath="fiji/components/com/sun/solaris/N1GridContainer.xml" 
         majorVersion="true">
       </component>
       <component jarPath="fiji/components/com/sun/solaris/ZoneSS.xml">
         <systemService name="zoneSS"
           description="the Solaris zone system service"/>
       </component>   </memberList>
</plugin>

Defining a User Interface to the Plug-In

One of the key activities in creating a solution that you can provide to others or distribute across your environment is defining an interface to your solution within the Sun N1 Service Provisioning System browser interface. To define the interface, you create an XML file that uses the <pluginUI> element and its children. For information about the <pluginUI> element, see Chapter 7, Plug-In User Interface Schema, in Sun N1 Service Provisioning System 5.2 XML Schema Reference Guide.


Example 2–16 Sample Plug-In Interface File

The following sample plug-in interface file pluginUI.xml is for the Solaris Zones plug-in.

<?xml version="1.0" encoding="UTF-8"?>
<pluginUI menuItem="Solaris"   xmlns="http://www.sun.com/schema/SPS"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.sun.com/schema/SPS pluginUI.xsd"
   schemaVersion="5.2">
   <icon jarPath="gui/solaris.gif"/>
   <customPage name="Solaris"> 
    <section title="Solaris specific tasks"
       description="create and manage Solaris specific components...">
       <entry title="Solaris Zones" description="create and manage zones">
         <action text="list" toolTip="list of installed zones">
           <compWhereInstalled path="/com/sun/solaris" name="N1GridContainer"/>
         </action>
         <action text="create and manage" toolTip="create and manage zones">
           <compDetails path="/com/sun/solaris" name="N1GridContainer" />
         </action>
       </entry>
     </section>
   </customPage>
</pluginUI>

Packaging the Solution

To enable others to use your solution or to make it available for easy distribution within your own environment, you package your solution in a Java Archive (JAR) file. The contents and instructions for interpreting the contents of the JAR file are contained in an optionally signed plugin-descriptor.xml file located in the top level directory of the JAR. The syntax of the plug-in descriptor is specified using XML Schema as per the May 2, 2001 W3C Recommendation (http://www.w3.org/TR/2001/xmlschema-0-20010502/). The schema can be used in conjunction with a validating parser to determine the syntactical validity of a plug-in. For information about the plug-in descriptor file, see Defining the Plug-In.

To create the JAR file, you use the JAR utility. The JAR utility uses similar options to the standard UNIX tar utility.

To create a JAR file, use the following command from the root directory that contains all the plug-in files: jar cf jarfile inputfiles

where:


Example 2–17 Creating a JAR File That Contains Subdirectories

If you have subdirectories, you can combine them into a single JAR file, as shown in the following example command:


% jar cvf myplugin.jar *
added manifest
ignoring entry META-INF/
ignoring entry META-INF/MANIFEST.MF
adding: components/(in = 0) (out= 0)(stored 0%)
adding: components/com/(in = 0) (out= 0)(stored 0%)
adding: components/com/sun/(in = 0) (out= 0)(stored 0%)
adding: components/com/sun/myplugin/(in = 0) (out= 0)(stored 0%)
adding: components/com/sun/myplugin/mycomponent.xml(in = 6224) (out= 1182)(deflated 81%)
adding: components/com/sun/myplugin/myothercomponent.xml(in = 1291) (out= 507)(deflated 60%)
adding: components/com/sun/myplugin/mycomponenttype.xml(in = 940) (out= 470)(deflated 50%)
adding: resources/(in = 0) (out= 0)(stored 0%)
adding: resources/com/(in = 0) (out= 0)(stored 0%)
adding: resources/com/sun/(in = 0) (out= 0)(stored 0%)
adding: resources/com/sun/solaris/(in = 0) (out= 0)(stored 0%)
adding: resources/com/sun/solaris/zone_util.tar(in = 20480) (out= 4232)(deflated 79%)
adding: gui/(in = 0) (out= 0)(stored 0%)
adding: gui/pluginUI.xml(in = 861) (out= 407)(deflated 52%)
adding: gui/solaris.gif(in = 1622) (out= 1627)(deflated 0%)
adding: plugin-descriptor.xml(in = 1990) (out= 707)(deflated 64%)
% 

To verify the files in the JAR file, use the following command:


% jar tf mypluin.jar
META-INF/MANIFEST.MF
fiji/
fiji/components/
fiji/components/com/
fiji/components/com/sun/
fiji/components/com/sun/solaris/
fiji/components/com/sun/solaris/N1GridContainer.xml
fiji/components/com/sun/solaris/ZoneSS.xml
fiji/components/com/sun/solaris/zone_util.tar.xml
fiji/resources/
fiji/resources/com/
fiji/resources/com/sun/
fiji/resources/com/sun/solaris/
fiji/resources/com/sun/solaris/zone_util.tar
gui/
gui/pluginUI.xml
gui/solaris.gif
plugin-descriptor.xml

Testing the Solution

Before you make your solution available across your environment or for others to use, you should test the solution. The following ideas might help you decide what to test: