This document demonstrates some uses of the XML-RPC programmatic interface to PlanetLab Central, or PLC API. The examples below are Python code, but the concepts apply to any language with a similar XML-RPC library. A complete PLC API reference is available here. As a last resort, contact PlanetLab Support with any questions.
The URL of the XML-RPC interface to PLC is https://www.planet-lab.org/PLCAPI/
. The following Python code creates an object api_server
whose methods invoke the method of the same name at PLC; the keyword parameter allow_none=True
enables a non-standard extension to XML-RPC that allows null values (None
in Python) to be passed.
import xmlrpclib
api_server = xmlrpclib.ServerProxy('https://www.planet-lab.org/PLCAPI/', allow_none=True)
The first parameter to each XML-RPC call is an authentication structure. The code below shows how to set up this structure for password-based authentication.
# Create an empty dictionary (XML-RPC struct)
auth = {}
# Specify password authentication
auth['AuthMethod'] = 'password'
# Username and password
auth['Username'] = 'my.email.address@example.com'
auth['AuthString'] = 'xxxxxx'
Now we can verify this structure with the PLC API method AuthCheck()
, which returns 1
if the authentication structure is valid.
authorized = api_server.AuthCheck(auth)
if authorized:
print 'We are authorized!'
The GetNodes()
method is the primary source of information about PlanetLab nodes. The first parameter is always an authentication structure. The other two parameters specify how the information returned should be filtered, and if they are not present, GetNodes()
returns everything. The return value is a list containing one structure for each node, and each structure consists of several named fields.
# This may take a while.
all_nodes = api_server.GetNodes(auth)
print all_nodes
If the second parameter is a list of node IDs or hostnames, GetNodes()
will return information only about these nodes. Alternatively, the second parameter can be a structure that specifies values for certain fields, in which case GetNodes()
will return only those nodes whose fields match. Finally, the third parameter specifies which fields to return.
Each construct described in the preceding paragraph is used in the following example.
# Get information about two nodes at Princeton.
princeton_nodes = api_server.GetNodes(auth, ['planetlab-1.cs.princeton.edu', 'planetlab-2.cs.princeton.edu'])
print princeton_nodes
# Get node IDs and hostnames of nodes whose boot state is "boot"
boot_state_filter = {'boot_state': 'boot'}
return_fields = ['node_id', 'hostname']
nodes_in_boot = api_server.GetNodes(auth, boot_state_filter, return_fields)
print nodes_in_boot
If you wish to specify a list of fields but not a list of nodes, pass None
or {}
, the empty structure, as the second argument. In general, you should request as little information as possible, as this will create less load at PLC and make your query run faster.
Note: you must be a PI to create a new slice or change the users of an existing slice. If you are not a PI, ask your PI to create a slice for you and skip ahead to the next section.
The method to create a new slice is AddSlice()
. It takes two parameters: the authentication structure and a structure containing information about your new slice. The "name" field is the name of your new slice. It consists of your site prefix, followed by an underscore, followed by a sequence of letters, digits, and underscores of your choosing. The "url" field is a link to a description of your project. The "description" field describes what your slice is supposed to be doing so that PlanetLab Operations can determine if it is malfunctioning. Finally, the "instantiation" field specifies how your slice will be instantiated on the nodes. If it succeeds, AddSlice()
returns the slice ID of your slice.
The following code uses AddSlice()
to create a new slice.
slice_data = {}
slice_data['name'] = 'mysite_slicename'
slice_data['url'] = 'http://example.com/myproject/'
slice_data['description'] = '''Test slice.
This slice should not generate traffic external to PlanetLab.
'''
slice_data['instantiation'] = 'plc-instantiated'
slice_id = api_server.AddSlice(auth, slice_data)
print slice_id
The method to add a user to a slice is AddPersonToSlice()
. It takes three parameters: an authentication structure, a username, and a slice ID or name. The following code will add you to your new slice.
me = auth['Username']
api_server.AddPersonToSlice(auth, me, slice_id)
Members of a slice can update its description and change the nodes assigned to it. The former is accomplished by the UpdateSlice()
method, which takes an authentication structure, a slice ID or name, and a structure containing the updated fields. The following code changes the slice description.
new_slice_description = '''Test slice.
This slice generates only ICMP traffic between PlanetLab nodes.
'''
new_slice_details = {'description': new_slice_description}
api_server.UpdateSlice(auth, slice_id, new_slice_details)
The AddSliceToNodes()
method causes your slice to be instantiated on the requested nodes, when they are up. It may take a little while before the nodes find out about your slice. The two non-authentication arguments are the slice ID or name and the list of node IDs or hostnames to be added.
api_server.AddSliceToNodes(auth, slice_id, ['planetlab-1.cs.princeton.edu', 'planetlab-2.cs.princeton.edu'])
The GetSlices()
method returns information about slices, including the list of node IDs to which they have been added. In order to get the hostnames of these nodes, you must call GetNodes()
.
node_ids = api_server.GetSlices(auth, [slice_data['name']], ['node_ids'])[0]['node_ids']
node_hostnames = [node['hostname'] for node in api_server.GetNodes(auth, node_ids, ['hostname'])]
print node_hostnames
The PLC API supports the de facto standard XML-RPC introspection and multicall methods described here.
For interactive use, a command-line program called plcsh
extends a Python interpreter to pass authentication structures automatically and support tab completion. To use plcsh
, check out the (historically named) directory plcmdline
:
$ cvs -d :pserver:anon@cvs.planet-lab.org:/cvs checkout plcmdline
To run plcsh
, type
$ cd plcmdline
$ ./plcsh -u my.email.address@example.com -r any
The -r
flag, for "Role", is left over from the previous version of the PLC API, and while it must be specified, its value does not matter. A typical interaction with the shell is given below; note the lack of authentication structures passed as arguments.
deisenst@bach:~/plcmdline$ ./plcsh -u deisenst@cs.princeton.edu -r any
Password: ******
PlanetLab Central API server at https://www.planet-lab.org/PLCAPI/
deisenst@cs.princeton.edu connected as using password authentication
Type "system.listMethods()" or "help(method)" for more information.
[deisenst@cs.princeton.edu ]>>> AuthCheck()
1
[deisenst@cs.princeton.edu ]>>> GetNodes(['planetlab-1.cs.princeton.edu'], ['node_id'])
[{'node_id': 121}]