Contents |
API Examples
API documentation is included in this documentation package. Additionally, there are several examples located in the "bin" directory of the distribution. These examples provide a basic overview of the APIs and how to use them and also show some simple client/server implementations.
Basic API Use Example: apiexample.py
This is intended to be an interactive example (i.e. cut-and-paste the lines into a Python shell running under SAFplus Platform). It presents an overview of the highest layer of APIs and shows how cluster information can be retrieved, software can be installed, and an upgrade started.
It can be run in any SAFplus-connected python shell. To get to an SAFplus-connected Python shell, either use the shell embedded in the SAFplus Platform web server (browse to /shell), or run one from the command line. To run from the command line (recommended because you get a full-featured standard python shell) do the following:
Set up paths to get ARD libraries:
$ export PYTHONPATH={ardDir}/lib:{ardDir}/bin $ export PATH={ardDir}/bin:$PATH
Run Python. Make SURE to specify ARD's embedded Python, and not your distribution's installed version!
$ {ASP_Dir}/bin/asp_run {ardDir}/bin/python2.5
Now at the Python prompt, run this line FIRST to hook into the SAFplus Platform AMF:
>> import amfpy; amfpy.initializeAmf()
At this point you can use all ARD Python services, as shown in the following script:
apiexample.py
# Standard Python modules import os import time
# ARD Python API example code, including deployment and upgrade: import upgrade; import clusterinfo; import aspApp; import aspAmf; import appdeploy
# Hook into the various services ci = clusterinfo.ci # The clusterinfo.ci objects reflect the entire state of the cluster amf = aspAmf.Session() # The aspAmf.Session class lets you modify the cluster state
# Example of getting the node names print [x.name for x in ci.nodeList]
# Get the name of the node in slot 1 print ci.nodes[1].name
# Example of getting the sg started/stopped status print "Running Service Groups:" for x in clusterinfo.ci.sgList: if x.isRunning(): print x.name
# Example of getting SU status and of traversing the entity hierarchy print "Active Service Units:" for x in clusterinfo.ci.suList: if x.isActive(): print "%s is active for service group %s and is running on node %s (slot: %d)" % (x.name,x.sg.name,x.node.name,x.node.slot)
# Example of stopping and restarting an entity su = ci.suList[0] print "Stopping %s" % su.name amf.Shutdown(su) # Now we must reload the clusterinfo to reflect changes. ci.load() su = ci.entities[su.name] # and reload our temporary. Its best to access your entities by name in case the list order changes if su.isRunning(): print "SU %s is still running" % su.name else: print "SU %s is stopped" % su.name amf.Startup(su) ci.load() su = ci.entities[su.name] # its best to access your entities by name in case the list order changes if su.isRunning(): print "SU %s is running" % su.name else: print "SU %s is still stopped" % su.name
# Initialize the Application bundle DB & pass the bundle repository directory. Note that you should only create 1 of these per bundle repository directory or you will have 2 entities managing the same data. appDb = aspApp.AppDb(os.getenv("ASP_DIR","/tmp") + "/apps") ci.setAppDb(appDb) # Hook them up (so clusterinfo knows about application versions) myNode = "ctrlI0"
# Set additional data that SAFplus Platform may not know into the node # This info is necessary to deploy software # (it also can be entered via the GUI, or via etc/clustercfg.xml file) # You need to change these values to correctly reflect your setup if ci.entities[myNode].localUser == 'unknown': ci.entities[myNode].setIntraclusterAccess("192.168.66.130","root","clovis","/root/ocmsdemo7") # The above example sets 1 node. For the application deployment example # below to work, you must set all of the nodes to the correct values.
# Add 2 bundle files into the system. Of course you must modify the path to # point to valid bundle files. appDb.NewAppFile("/code/vipapp1.4.0.0.tgz") appDb.NewAppFile("/code/vipapp1.4.0.1.tgz") # Note that if you want AppDb to automatically find them again, # you must copy them into the repository (the directory you specified # when creating "appDb").
# Show all bundles and versions print [(x.name,x.version) for x in appDb.AppList()]
# Find all "live" nodes # Of course, you can't deploy to nodes that aren't powered up! liveNodes = filter(lambda x: x.isRunning(),ci.nodeList) print [x.name for x in liveNodes]
# Get an application appFile = appDb.apps['virtualIp'].version['1.4.0.0'] print "Name: ", appFile.name, "Located At: ", appFile.dir, "Version: ", appFile.version
Deploy the application:
# Tweak the configuration for just this deployment # If I didn't copy the configuration, I would be modifying it in RAM # which would affect other deployments I do within this Python session. import copy newCfg = copy.deepcopy(appFile.cfg) # For example, set failback parameter to True: newCfg.virtualIp.modifiers.failBack = True
# Really Deploy import appdeploy (sgList,(errors,notes)) = appdeploy.deploy(appFile.dir,newCfg,liveNodes,abortIfCantAccess=True,copy=True,deploy=True) # Did you get a pexpect exception? You probably forgot to specify the node # intracluster access data as shown above. Or you may have specified # incorrect information. myNewSg = sgList[0] mySgName = myNewSg.name print "Deployed application and created SG %s" % mySgName # Reload the AMF information model ci.load()
# Reaccess via ci global to get refreshed data. mySg = ci.entities[mySgName] # Let's start it up amf.Startup(mySg) # Give it time to come up # I reaccess through ci each time to get refreshed data. while not ci.entities[mySgName].isRunning(): time.sleep(5) ci.refresh() print "It is running"
Let's do an upgrade!
# Start the upgrade manager... umgr = upgrade.UpgradeMgr() umgr.add(mySg) # Add my Service Group to it. upSg = umgr.entities[mySgName] # Get my sg's upgrade entity upSg.upMethod = upgrade.RollingUpgrade print mySg.appVer.version
# Start the upgrade... upSg.Upgrade(appDb.apps['virtualIp'].version['1.4.0.1']) ci.load() # Reload the database. mySg = ci.entities[mySg.name] # Get the new SG object print mySg.appVer.version
XML client/server example
This example is located in the "bin" directory and consists of 2 files "xmlclientexample.py" and "xmlserverexample.py". It implements a simple XML-RPC client server application that demonstrates how the ARD can interface with 3rd party off-box element management systems. Please look at these files to see how it works.
HTTP client/server example
This example is located in the "bin" directory and consists of 2 files "httpclientexample.py" and "httpserverexample.py". It implements a simple http server application that demonstrates how the ARD can interface with 3rd party off-box element management systems. The intention behind this example is to show a client-server application communicating via http not a human browseable web site (the main ARD GUI application demonstrates how a web-based EMS can be constructed).