Index: fedd/federation/split.py
===================================================================
--- fedd/federation/split.py	(revision 5d3f2390d0bf55a90f3cb9b8f7d6d5c25c8dbac9)
+++ fedd/federation/split.py	(revision 5d3f2390d0bf55a90f3cb9b8f7d6d5c25c8dbac9)
@@ -0,0 +1,154 @@
+#!/usr/local/bin/python
+
+import os,sys
+import subprocess
+import tempfile
+import logging
+
+from util import *
+from fedid import fedid
+from remote_service import xmlrpc_handler, soap_handler
+from service_error import *
+from authorizer import authorizer
+
+
+class nullHandler(logging.Handler):
+    def emit(self, record): pass
+
+fl = logging.getLogger("fedd.splitter")
+fl.addHandler(nullHandler())
+
+class split_local:
+    def __init__(self, config=None, auth=None):
+	"""
+	Intialize the various attributes, most from the config object
+	"""
+	self.debug = config.getboolean("splitter", "debug")
+	self.muxmax = config.getint("splitter", "muxmax", 3)
+	self.tclsh = config.get("splitter", "tclsh", 
+		"/usr/local/bin/otclsh")
+	self.tcl_splitter = config.get("splitter", "tcl_splitter",
+		"/usr/testbed/lib/ns2ir/parse.tcl")
+	access_db = config.get("splitter", "access_db", None)
+	allow_any = config.getboolean("splitter", "allow_any", False)
+
+	self.log = logging.getLogger("fedd.splitter")
+	set_log_level(config, "splitter", self.log)
+	self.trace_file = sys.stderr
+
+	set_log_level(config, "splitter", self.log)
+
+	if auth:
+	    self.auth= auth
+	else:
+	    self.auth = authorizer()
+	    self.log.warning("[splitter] No authorizer passed in, " +\
+		    "using local one")
+
+	if access_db and allow_any: 
+	    raise service_error(service_error.internal, 
+		    "Cannot specify both an access database and allow_any " +\
+			    "for splitter")
+	
+	if access_db:
+	    try:
+		read_simple_accessdb(access_db, self.auth, 'split')
+	    except IOError, e:
+		raise service_error(service_error.internal,
+			"Error reading accessDB %s: %s" % (access_db, e))
+	    except ValueError:
+		raise service_error(service_error.internal, "%s" % e)
+	elif allow_any:
+	    auth.set_global_attribute("split")
+
+
+	# Dispatch tables
+	self.soap_services = {\
+		'Ns2Split': soap_handler("Ns2Split", self.run_splitter),
+	}
+
+	self.xmlrpc_services = {\
+		'Ns2Split': xmlrpc_handler('Ns2Split', self.run_splitter),
+	}
+
+    def run_splitter(self, req, fid):
+	"""
+	The external interface to experiment creation called from the
+	dispatcher.
+
+	Creates a working directory, splits the incoming description using the
+	splitter script and parses out the avrious subsections using the
+	lcasses above.  Once each sub-experiment is created, use pooled threads
+	to instantiate them and start it all up.
+	"""
+
+	if not self.auth.check_attribute(fid, 'split'):
+	    raise service_error(service_error.access, "Access Denied")
+
+	try:
+	    tmpdir = tempfile.mkdtemp(prefix="split-")
+	except IOError:
+	    raise service_error(service_error.internal, "Cannot create tmp dir")
+
+	tclfile = tmpdir + "/experiment.tcl"
+	pid = "dummy"
+	gid = "dummy"
+	eid = "dummy"
+
+	req = req.get('Ns2SplitRequestBody', None)
+	if not req:
+	    raise service_error(service_error.req,
+		    "Bad request format (no Ns2SplitRequestBody)")
+	# The tcl parser needs to read a file so put the content into that file
+	descr=req.get('description', None)
+	if descr:
+	    file_content=descr.get('ns2description', None)
+	    if file_content:
+		try:
+		    f = open(tclfile, 'w')
+		    f.write(file_content)
+		    f.close()
+		except IOError:
+		    raise service_error(service_error.internal,
+			    "Cannot write temp experiment description")
+	    else:
+		raise service_error(service_error.req, 
+			"Only ns2descriptions supported")
+	else:
+	    raise service_error(service_error.req, "No description")
+
+	master = req.get('master', None)
+	if master == None:
+	    raise service_error(service_error.req, "No master testbed label")
+	
+	include_fedkit = req.get('include_fedkit', None)
+	if include_fedkit == None:
+	    raise service_error(service_error.req, 
+		    "No federation kit inclusion directive")
+	
+	
+	tclcmd = [self.tclsh, self.tcl_splitter, '-s', '-x', 
+	    str(self.muxmax), '-m', master]
+	if include_fedkit: tclcmd.append('-k')
+	tclcmd.extend([pid, gid, eid, tclfile])
+	self.log.debug("Calling splitter %s" % " ".join(tclcmd))
+	tclparser = subprocess.Popen(tclcmd, stdout=subprocess.PIPE)
+
+	out = ""
+	# Package up the split data
+	for line in tclparser.stdout:
+	    out += line
+
+	# Walk up tmpdir, deleting as we go
+	for path, dirs, files in os.walk(tmpdir, topdown=False):
+	    for f in files:
+		os.remove(os.path.join(path, f))
+	    for d in dirs:
+		os.rmdir(os.path.join(path, d))
+	os.rmdir(tmpdir)
+
+	resp = { 'output' : out }
+
+	return resp
+
+
