Table of Contents
How to use ProtoGeni
ProtoGeni is currently driven via various XMLRPC interfaces (see the Component Manager API and the Slice Authority API). Typically, users interact with the ProtoGeni XMLRPC servers using python or perl, but any language that supports XMLRPC will suffice. Our ProtoGeni includes a set of test scripts in the protogeni/test directory for examples. These test scripts are intended both to test the system and to provide a demonstration of how to use ProtoGeni.
For the slides presented by Robert Ricci at GEC6 as a ProtoGeni tutorial, see the attachments section at the bottom of this page.
Getting Ready
Before running the test scripts or creating your own, there are a few things you will need to do to make sure everything runs smoothly.
SSL Certificate
Currently, only registered Emulab users can use the ProtoGeni system. Since the interface is via XMLRPC over SSL, it is necessary for Emulab users to create an encrypted SSL key. This is done through the WWW interface on your Emulab, by logging in, then following the My Emulab link in the upper left. Click on the Profile tab, and then click the Generate SSL Cert link on the far left. A secure pass-phrase must be supplied by the user.
The new SSL certificate is saved as $HOME/.ssl/encrypted.pem on ops. The test scripts look for the certificate in this location, but a command line argument allows you to override this. In addition, as a convenience, the test scripts will look for your pass-phrase in $HOME/.ssl/password so that you do not need to type your pass-phrase repeatedly.
Configuration
If you have problems running the test scripts, and the error you get from python is:
M2Crypto.SSL.Checker.WrongHost: Peer certificate commonName does not match host, expected boss.emulab.net, got www.emulab.net
then you have tripped over a python problem we have not fixed yet. The solution is to create $HOME/.protogeni-config.py and put this in it.
XMLRPC_SERVER = { "ch" : "www.emulab.net",
"default" : "www.emulab.net" }
Note that this assumes Utah's Emulab is your Slice Authority.
SSH Keys
ProtoGENI nodes only allow login if you have SSH keys set up.
You must follow these instructions to log onto your ProtoGENI nodes.
Most ProtoGENI resources will expect you to authenticate with ssh. You should generate an ssh key pair before you allocate any resources (that way, the nodes you reserve will already be able to validate you when they start up). For instance:
$ ssh-keygen -f protogeni-key Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again: Your identification has been saved in protogeni-key. Your public key has been saved in protogeni-key.pub. The key fingerprint is: 01:23:45:67:89:ab:cd:ef:01:23:45:67:89:ab:cd:ef user@host
(Key generation might not be necessary if you already have a valid ssh key pair you want to reuse.)
The next step is to publish your public key (i.e. the file protogeni-key.pub in the example above). If you upload it to the local slice authority (i.e. Emulab), it can easily be forwarded to appropriate experimental nodes you allocate. Uploading is done through the WWW interface:
- Log in to the appropriate Emulab (e.g. http://www.emulab.net/).
- Follow the My Emulab link in the upper left of every page.
- Select the Profile tab (the rightmost of the three).
- Follow the Edit SSH Keys link (the second one in the box on the left).
- Use the Browse button on that page to enter the filename you saved your public key to (protogeni-key.pub in the example above), and then select Add New Keys.
At this point, the slice authority should have your new authentication information recorded. You can verify that things have worked properly by running the lookupuser.py test script and checking that the contents of the protogeni-key.pub file are included in the output: these are the same keys that createsliver.py will pass on to the nodes in the slivers it requests.
Using ssh-agent to manage your private keys is optional, but highly recommended. (The most obvious difference it makes is that it will greatly reduce the number of times you need to type your passphrase.)
Using the Test Scripts
The test scripts are written in python and take a common set of command line options, in addition to per-script options. The scripts are fairly simple as they are intended to test the system. They are installed on your ops (users) node in /usr/testbed/protogeni/test.
Specific Examples
The following sections describe in more detail the essential operations. Please see the Glossary of Terms if you have trouble following the tutorial. Feel free to send us email if you have problems or questions.
Creating a Slice
The first thing you must do is create a slice. Actually, the first thing you need to do is request a credential from your Slice Authority that allows you to create a slice. Within the test scripts, this is accomplished with get_self_credential(), which returns a blob of XML that you pass to subsequent RPC calls at your Slice Authority. Once you have your credential, the following code fragment demonstrates how to create a slice, as long as it does not already exist.
params = {}
params["credential"] = mycredential
params["type"] = "Slice"
params["hrn"] = "MySlice"
rval,response = do_method("sa", "Register", params)
if rval:
Fatal("Could not get my slice")
pass
myslice = response["value"]
In the above python code, do_method() is a utility routine that invokes the XMLRPC server on your local boss node. The first argument is which server to invoke, and the second argument is the method name. The final argument is the array of parameters to the method. Each of the ProtoGeni sites hosts at least two servers. One is the Slice Authority (sa) and the other is the Component Manager (cm).
The return value is a blob of XML representing a signed credential for the new slice. You use this credential to invoke operations on the new slice. At this point the slice is simply an empty container; no resources have been allocated.
The default expiration time of your new slice is fairly short; on the order of hours. Your slice and slivers will be terminated automatically unless you renew them before they expire. See the section on Renewing your Sliver below.
Discovering Resources
Once you have a slice, you need to populate it with resources. Before you can do that, you need to find out what ProtoGeni sites exist and what resources that are willing to make available to you. This is a two step process; first you ask the Clearing House for a list of Component Managers:
params = {}
params["credential"] = mycredential
rval,response = do_method("ch", "ListComponents", params)
if rval:
Fatal("Could not get a list of components from the Clearing House")
pass
managers = response["value"]
The return value is a list of structures describing the various Component Managers. Within the structure is the URL of the XMLRPC interface. You can use the URL to invoke the DiscoverResources method at each of the Component Managers in the list. For example:
for manager in managers:
url = manager["url"]
params = {}
params["credential"] = mycredential
params["available"] = True
rval,response = do_method(None, "DiscoverResources", params, url)
if rval:
Fatal("Could not get a list of resources");
pass
advertisement = response["value"]
pass
Each Component Manager will return an rspec advertisement describing all of the available resources. The advertisement is an XML blob.
Requesting a Ticket for Resources
Once you have a slice and a list of advertisements, you then request Tickets for specific resources. While not discussed here, you first need to create a request rspec describing the resources you want. Then you need to make that request at each of the Component Managers that host the resources you want. As a small example, lets take a simple rspec that requests a single node at your local Component Manager:
<rspec xmlns="http://protogeni.net/resources/rspec/0.1">
<node virtual_id="mypc"
component_uuid="urn:publicid:IDN+emulab.net+node+pc111"
component_manager_uuid="urn:publicid:IDN+emulab.net+authority+cm"
virtualization_type="emulab-vnode">
</node>
</rspec>
This rspec requests a single node, pc111. Note that in the rspec, you would replace "emulab.net" with the domain of your own ProtoGeni? site. The reason for including the component_manager_uuid in the rspec is because typically, your rspec would include resources from many different components, and the component_manager_uuid is a hint to each Component Manager that it can ignore those sections that are intended for other managers. The virtual_id is a symbolic name of your choice, to reference this particular node. Since ProtoGeni is hosted on Emulab, the virtual_id is used to construct a DNS CNAME for your nodes.
The following code fragment requests a ticket, using the slice credential requested earlier, and the rspec fragment above.
params = {}
params["credential"] = myslice
params["rspec"] = rspec
rval,response = do_method("cm", "GetTicket", params)
if rval:
Fatal("Could not get ticket")
pass
myticket = response["value"]
The ticket is another blob of XML, representing a signed promise to deliver your resources when you redeem the ticket. The ticket expires very quickly though, so you need to redeem the ticket within a short time. The exact time of expiration is within the XML blob.
Redeeming your Ticket
Once you have a ticket (or multiple tickets), you need to redeem them at each of the component managers. Redeeming ticket creates a Sliver. Continuing the example from above, you need to redeem the single ticket at your local manager. Before you do that though, you will probably want to ask your Slice Authority for a copy of your ssh public keys so that you can pass them along when you redeem your tickets. This will allow you to log into your nodes once you have them. While you can probably construct the keys arguments on your own, its easier to just ask your Slice Authority for them:
params = {}
params["credential"] = mycredential
rval,response = do_method("sa", "GetKeys", params)
if rval:
Fatal("Could not get my keys")
pass
mykeys = response["value"]
You now have an XML blob of your keys in the format that the Component Manager likes. Next redeem your ticket:
params = {}
params["credential"] = myslice
params["ticket"] = myticket
params["keys"] = mykeys
rval,response = do_method("cm", "RedeemTicket", params)
if rval:
Fatal("Could not redeem ticket")
pass
mysliver,manifest = response["value"]
RedeemTicket returns two blobs of XML. The first is another credential that you can use to operate on the newly created sliver. As with all credentials, this is a signed XML document that has been issued to you and is valid at this Component Manager. The second return value is an rspec Manifest describing in more detail the resources contained in the sliver.
Note that your new sliver will be automatically terminated when the expiration time of the slice is reached. See the section on Renewing your Sliver below.
Starting your Sliver
After redeeming your tickets, you need to start all of your slivers. This is because the resources have been allocated, but they have not been initialized yet. Starting your sliver will boot your nodes and create your links:
params = {}
params["credential"] = mysliver
rval,response = do_method("cm", "StartSliver", params)
if rval:
Fatal("Could not start sliver")
pass
StartSliver returns immediately, so you will have to poll the Component Manager to determine when the sliver is fully initialized. This is done with the method
params = {}
params["credential"] = mysliver
rval,response = do_method("cm", "SliverStatus", params)
if rval:
Fatal("Could not get sliver status")
pass
status = response["value"]
The return value is a structure, described in detail in the SliverStatus API. Once the sliver is ready, you can log into your nodes if you have provided your ssh keys as described above. Your login ID is the same as your Emulab identity.
Renewing your Sliver
By default, your slice and any slivers will expire in a fairly short time, on the order of hours. More specifically, each Component Manager and your Slice Authority will automatically terminate your slivers and slice, unless you use the renew operation before that happens. For short lived slices, this happens without any notification, but for long lived (expiration previously set to longer then 24 hours), you will receive an email warning before expiration to give you a chance to renew (extend) your slice and slivers.
When you create a new slice at your Slice Authority, a default expiration time is assigned; the slice credential you get back has an expiration time equal to the slice expiration. In other words, when the slice expires, so does your credential and any slivers. In addition, the expiration time in the slice credential is an upper bound on the valid_until field of the rspec. If you do not specify a valid_until in the rspec, your slivers will expire when the slice credential says they should. This is to prevent the situation where the slice expires at the Slice Authority (and you can no longer get a credential for it), but there are still slivers out in the wild.
Aside: The above reasoning also explains why you cannot delete a slice at the Slice Authority before it expires. Since the SA has no knowledge of existing slivers, you could get into a situation whereby there were existing slivers, but no way to request the slice credential (from the SA) to control (say, delete) those slivers. While this may seem odd, remember that if you have a registered slice that is not doing anything, you can just use it (and renew it).
In order to create a long lived sliver, you need a long lived slice and a slice credential for that slice, when you create your slivers, or when you renew your existing slivers. This is demonstrated in the following code fragment. You can also find the equivalent code in the renewsliver test script.
The first step in extending your slice is to use your existing slice credential (before it expires) to invoke the RenewSlice at your Slice Authority:
expiration = time.strftime("%Y%m%dT%H:%M:%S",
time.gmtime(time.time() + (60 * int(minutes))))
params = {}
params["credential"] = myslice
params["expiration"] = expiration
rval,response = do_method("sa", "RenewSlice", params)
if rval:
Fatal("Could not renew slice at the SA")
pass
Now that your slice has been extended, you need to request a new slice credential that reflects the modified expiration time:
params = {}
params["credential"] = myslice
params["type"] = "Slice"
params["urn"] = slice_urn
rval,response = do_method("sa", "GetCredential", params)
if rval:
Fatal("Could not get Slice credential")
pass
myslice = response["value"]
Your slice credential can then be used to extend your sliver on the Component Manager. Not that each CM must be contacted individually:
params = {}
params["credential"] = myslice
rval,response = do_method("cm", "RenewSlice", params)
if rval:
Fatal("Could not renew slice at the CM")
pass
Deleting your Sliver
When you are done with your sliver, you will want to delete it so that the resources are released. This is done with the method:
params = {}
params["credential"] = mysliver
rval,response = do_method("cm", "DeleteSliver", params)
if rval:
Fatal("Could not delete sliver")
pass
TODO
- Update to version 2 API when it goes live.
- Add multi-component manager example.
- Add links and or/tunnels.
Attachments
- tutorial.pdf (0.9 MB) -
Slides presented by Rob Ricci at GEC6 giving a ProtoGENI tutorial.
, added by ricci on 11/23/09 17:55:03.
