Index: fedd/fedd_client.py
===================================================================
--- fedd/fedd_client.py	(revision a3ad8bda151c4074b1e9fa5731eea8514bf0c1c2)
+++ fedd/fedd_client.py	(revision 7b26c3985748b75ac1a921dc69392e6c386151b9)
@@ -265,7 +265,14 @@
     print>>out, "Description: %s" % dict['desc']
     sys.exit(dict.get('code', 20))
-# Base class that will do a the SOAP/XMLRPC exchange for a request.
+# Base class for the various client operations.  It includes some commonly used
+# functions and classes the most important of which are the exception classes
+# and the service calling classes.
 class fedd_rpc:
+
     class RPCException:
+	"""
+	An error during the RPC exchange.  It unifies errors from both SOAP and
+	XMLPRC calls.
+	"""
         def __init__(self, fb):
             self.desc = fb.get('desc', None)
@@ -273,13 +280,19 @@
             self.errstr = fb.get('errstr', None)
 
-    def __init__(self, pre): 
+    class caller(service_caller):
+	"""
+	The caller is used by fedd_rpc.do_rpc to make the rpc call.  The extra
+	stashed information is used to parse responses a little.
+	"""
+	def __init__(self, pre):
+	    self.ResponseBody="%sResponseBody" % pre
+	    self.method = pre
+	    service_caller.__init__(self, self.method)
+
+    def __init__(self): 
         """
         Specialize the class for the pre method
         """
-        self.RequestBody="%sRequestBody" % pre
-        self.ResponseBody="%sResponseBody" % pre
-        self.method = pre
-
-        self.caller = service_caller(self.method)
+        self.caller = fedd_rpc.caller
         self.RPCException = fedd_rpc.RPCException
 
@@ -333,8 +346,11 @@
 
     def do_rpc(self, req_dict, url, transport, cert, trusted, tracefile=None,
-            serialize_only=False):
+            serialize_only=False, caller=None):
         """
         The work of sending and parsing the RPC as either XMLRPC or SOAP
         """
+
+	if caller is None: 
+	    raise RuntimeError("Must provide caller to do_rpc")
 
         context = None
@@ -355,5 +371,5 @@
             else:
                 try:
-                    resp = self.caller.call_soap_service(url, req_dict, 
+                    resp = caller.call_soap_service(url, req_dict, 
                             context=context, tracefile=tracefile)
                 except service_error, e:
@@ -370,5 +386,5 @@
             else:
                 try:
-                    resp = self.caller.call_xmlrpc_service(url, req_dict, 
+                    resp = caller.call_xmlrpc_service(url, req_dict, 
                             context=context, tracefile=tracefile)
                 except service_error, e:
@@ -382,16 +398,16 @@
             raise RuntimeError("Unknown RPC transport: %s" % transport)
 
-        if resp.has_key(self.ResponseBody):
-            return resp[self.ResponseBody]
+        if resp.has_key(caller.ResponseBody):
+            return resp[caller.ResponseBody]
         else:
             raise RuntimeError("No body in response??")
 
 class exp_data_base(fedd_rpc):
-    def __init__(self, op='Info'):
+    def __init__(self):
         """
         Init the various conversions
         """
 
-        fedd_rpc.__init__(self, op)
+        fedd_rpc.__init__(self)
         # List of things one could ask for and what formatting routine is
         # called.
@@ -441,5 +457,5 @@
 class exp_data(exp_data_base):
     def __init__(self): 
-        exp_data_base.__init__(self, 'Info')
+        exp_data_base.__init__(self)
 
     def __call__(self):
@@ -491,5 +507,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('Info'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -542,5 +559,5 @@
 class multi_exp_data(exp_data_base):
     def __init__(self): 
-        exp_data_base.__init__(self, 'MultiInfo')
+        exp_data_base.__init__(self)
 
 
@@ -578,5 +595,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('MultiInfo'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -601,5 +619,5 @@
 class multi_status(exp_data_base):
     def __init__(self): 
-        exp_data_base.__init__(self, 'MultiInfo')
+        exp_data_base.__init__(self)
 
 
@@ -637,5 +655,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('MultiInfo'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -688,10 +707,10 @@
 
 class image(fedd_rpc):
-    def __init__(self, op='Vtopo'): 
+    def __init__(self): 
         """
         Null constructor
         """
 
-        fedd_rpc.__init__(self, op)
+        fedd_rpc.__init__(self)
 
     @staticmethod
@@ -869,5 +888,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('Vtopo'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -885,10 +905,10 @@
 
 class ns_image(image):
-    def __init__(self, op='Ns2Split'): 
+    def __init__(self): 
         """
         Null constructor
         """
 
-        image.__init__(self, 'Ns2Split')
+        image.__init__(self)
 
     def generate_topo_dict(self, splitout):
@@ -1024,5 +1044,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('Ns2Split'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1042,10 +1063,10 @@
 
 class topdl_image(image):
-    def __init__(self, op='Ns2Split'): 
+    def __init__(self): 
         """
         Null constructor
         """
 
-        image.__init__(self, 'Ns2Split')
+        image.__init__(self)
 
     @staticmethod
@@ -1157,5 +1178,5 @@
         """
 
-        fedd_rpc.__init__(self, "Terminate")
+        fedd_rpc.__init__(self)
 
     def __call__(self):
@@ -1219,5 +1240,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('Terminate'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1242,5 +1264,5 @@
         """
 
-        fedd_rpc.__init__(self, "TerminateSegment")
+        fedd_rpc.__init__(self)
 
     def __call__(self):
@@ -1304,5 +1326,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('TerminateSegment'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1323,5 +1346,5 @@
 class new(fedd_rpc):
     def __init__(self): 
-        fedd_rpc.__init__(self, "New")
+        fedd_rpc.__init__(self)
     def __call__(self):
         access_keys = []
@@ -1362,5 +1385,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile, 
+		    caller=self.caller("New"))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1391,10 +1415,9 @@
 class create(fedd_rpc):
     def __init__(self): 
-        fedd_rpc.__init__(self, "Create")
+	fedd_rpc.__init__(self)
     def __call__(self):
         access_keys = []
-        # Process the options using the customized option parser defined above
-        parser = fedd_create_opts(access_keys, self.add_ssh_key,
-                self.add_x509_cert)
+        parser = fedd_create_opts(access_keys, self.add_ssh_key, 
+		self.add_x509_cert)
 
         (opts, args) = parser.parse_args()
@@ -1442,4 +1465,50 @@
         out_certfile = opts.out_certfile
 
+        msg = { }
+
+        if opts.exp_name:
+            msg['experimentID'] = { 'localname': opts.exp_name }
+
+        if opts.debug > 1: print >>sys.stderr, msg
+
+        try:
+            resp_dict = self.do_rpc(msg, 
+                    opts.url, opts.transport, cert, opts.trusted, 
+                    serialize_only=opts.serialize_only,
+                    tracefile=opts.tracefile,
+		    caller=self.caller('New'))
+        except self.RPCException, e:
+            exit_with_fault(\
+                    {'desc': e.desc, 'errstr': e.errstr, 'code': e.code})
+        except RuntimeError, e:
+            sys.exit("Error processing RPC: %s" % e)
+
+        if opts.debug > 1: print >>sys.stderr, resp_dict
+
+        ea = resp_dict.get('experimentAccess', None)
+        if out_certfile and ea and ea.has_key('X509'):
+            try:
+                f = open(out_certfile, "w")
+                print >>f, ea['X509']
+                f.close()
+            except IOError:
+                sys.exit('Could not write to %s' %  out_certfile)
+        eid = resp_dict.get('experimentID', None)
+	e_fedid = None
+	e_local = None
+        if eid:
+            for id in eid:
+                for k in id.keys():
+                    print "%s: %s" % (k, id[k])
+		    if k =='fedid':
+			e_fedid = id[k]
+		    elif k =='localname':
+			e_local = id[k]
+
+        st = resp_dict.get('experimentStatus', None)
+        if st:
+            print "status: %s" % st
+
+
         msg = {
                 'experimentdescription': { 'ns2description': exp_desc },
@@ -1452,6 +1521,10 @@
                 }
 
-        if opts.exp_name:
-            msg['experimentID'] = { 'localname': opts.exp_name }
+	if e_fedid:
+	    msg['experimentID'] = { 'fedid': e_fedid }
+	elif e_local:
+	    msg['experimentID'] = { 'localname': e_local }
+	else:
+	    sys.exit("New did not return an experiment ID??")
 
         if opts.debug > 1: print >>sys.stderr, msg
@@ -1461,5 +1534,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('Create'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1489,5 +1563,5 @@
 class split(fedd_rpc):
     def __init__(self): 
-        fedd_rpc.__init__(self, "Ns2Split")
+        fedd_rpc.__init__(self)
     def __call__(self):
         access_keys = []
@@ -1548,5 +1622,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('Ns2Split'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1564,5 +1639,5 @@
 class access(fedd_rpc):
     def __init__(self):
-        fedd_rpc.__init__(self, "RequestAccess")
+        fedd_rpc.__init__(self)
 
     def print_response_as_testbed(self, resp, label, out=sys.stdout):
@@ -1664,5 +1739,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('RequestAccess'))
         except self.RPCException, e:
             exit_with_fault(\
@@ -1682,5 +1758,5 @@
         """
 
-        fedd_rpc.__init__(self, 'Info')
+        fedd_rpc.__init__(self)
 
     def __call__(self):
@@ -1740,5 +1816,6 @@
                         opts.url, opts.transport, cert, opts.trusted, 
                         serialize_only=opts.serialize_only,
-                        tracefile=opts.tracefile)
+                        tracefile=opts.tracefile,
+			caller=self.caller('Info'))
             except self.RPCException, e:
                 exit_with_fault(\
@@ -1765,5 +1842,5 @@
 class start_segment(fedd_rpc):
     def __init__(self): 
-        fedd_rpc.__init__(self, "StartSegment")
+        fedd_rpc.__init__(self)
     def __call__(self):
         # Process the options using the customized option parser defined above
@@ -1811,5 +1888,6 @@
                     opts.url, opts.transport, cert, opts.trusted, 
                     serialize_only=opts.serialize_only,
-                    tracefile=opts.tracefile)
+                    tracefile=opts.tracefile,
+		    caller=self.caller('StartSegment'))
         except self.RPCException, e:
             exit_with_fault(\
