Index: fedd/federation/experiment_control.py
===================================================================
--- fedd/federation/experiment_control.py	(revision cc8d8e971b7119cdebf6c0a7ae1d1da299531ce6)
+++ fedd/federation/experiment_control.py	(revision 6c57fe9deaa34079254d04e9785091c1e9717115)
@@ -18,6 +18,6 @@
 import xml.parsers.expat
 
-from threading import *
-from subprocess import *
+from threading import Lock, Thread, Condition
+from subprocess import call, Popen, PIPE
 
 from urlparse import urlparse
@@ -232,6 +232,5 @@
                 or config.get("globals", "trusted_certs")
 
-	# XXX:
-	self.repodir = '/usr/local/etc/fedd/repo'
+	self.repodir = config.get("experiment_control", "repodir")
 
         self.exp_stem = "fed-stem"
@@ -2152,5 +2151,5 @@
 	    self.caller = caller
 
-	def __call__(self, uri, aid, topo):
+	def __call__(self, uri, aid, topo, attrs=None):
 	    req = {
 		    'allocID': { 'fedid' : aid }, 
@@ -2159,6 +2158,7 @@
 		    },
 		}
-
-	    print "calling %s"  % uri
+	    if attrs:
+		req['fedAttr'] = attrs
+
 	    r = self.caller(uri, req, self.cert_file, self.cert_pwd,
 		    self.trusted_certs)
@@ -2170,5 +2170,5 @@
 
     def new_allocate_resources(self, allocated, master, eid, expid, expcert, 
-            tbparams, topo, tmpdir, alloc_log=None):
+            tbparams, topo, tmpdir, alloc_log=None, attrs=None):
         started = { }           # Testbeds where a sub-experiment started 
                                 # successfully
@@ -2203,5 +2203,5 @@
 			trusted_certs=self.trusted_certs,
 			caller=self.call_StartSegment), 
-                    args=(uri, aid, topo[tb]), name=tb,
+                    args=(uri, aid, topo[tb], attrs), name=tb,
                     pdata=thread_pool, trace_file=self.trace_file)
             threads.append(t)
@@ -2294,4 +2294,18 @@
         to instantiate them and start it all up.
         """
+
+	def add_kit(e, kit):
+	    """
+	    Add a Software object created from the list of (install, location)
+	    tuples passed as kit  to the software attribute of an object e.  We
+	    do this enough to break out the code, but it's kind of a hack to
+	    avoid changing the old tuple rep.
+	    """
+
+	    s = [ topdl.Software(install=i, location=l) for i, l in kit]
+
+	    if isinstance(e.software, list): e.software.extend(s)
+	    else: e.software = s 
+
 
         if not self.auth.check_attribute(fid, 'create'):
@@ -2463,5 +2477,12 @@
 		    reverse=True)
 	    ips = ip_allocator(int(ip_addr("10.0.0.0")), 2 **24)
-	    for s in subs:
+	    ifs = { }
+	    hosts = [ ]
+	    # The config urlpath
+	    configpath = "/%s/config" % expid
+	    # The config file system location
+	    configdir ="%s%s" % ( self.repodir, configpath)
+
+	    for idx, s in enumerate(subs):
 		a = ips.allocate(len(s.interfaces)+2)
 		if a :
@@ -2479,10 +2500,28 @@
 			    topdl.Attribute('ip4_address', 
 				"%s" % ip_addr(base)))
+		    hname = i.element.name[0]
+		    if ifs.has_key(hname):
+			hosts.append("%s\t%s-%s %s-%d" % \
+				(ip_addr(base), hname, s.name, hname,
+				    ifs[hname]))
+		    else:
+			ifs[hname] = 0
+			hosts.append("%s\t%s-%s %s-%d %s" % \
+				(ip_addr(base), hname, s.name, hname,
+				    ifs[hname], hname))
+
+		    ifs[hname] += 1
 		    base += 1
-
+	    # save config files
+	    try:
+		os.makedirs(configdir)
+	    except IOError, e:
+		raise service_error(
+			"Cannot create config directory: %s" % e)
 	    # Find the testbeds to look up
 	    testbeds = set([ a.value for e in top.elements \
 		    for a in e.attribute \
 			if a.attribute == 'testbed'] )
+
 
 	    # Make per testbed topologies.  Copy the main topo and remove
@@ -2510,5 +2549,39 @@
 		topo[tb].make_indices()
 
-
+		for e in topo[tb].elements:
+		    if tb == master:
+			cmd = 'sudo -H /usr/local/federation/bin/make_hosts /proj/%s/exp/%s/tmp/hosts >& /tmp/federate' % (tbparams[tb].get('project', 'project'), eid)
+		    else:
+			cmd = "sudo -H /bin/sh /usr/local/federation/bin/federate.sh >& /tmp/federate"
+		    scmd = e.get_attribute('startup')
+		    if scmd:
+			cmd = "%s \\$USER '%s'" % (cmd, scmd)
+
+		    e.set_attribute('startup', cmd)
+		    if self.fedkit: add_kit(e, self.fedkit)
+
+	    # Copy configuration files into the remote file store
+	    try:
+		f = open("%s/hosts" % configdir, "w")
+		f.write('\n'.join(hosts))
+		f.close()
+	    except IOError, e:
+		raise service_error(service_error.internal, 
+			"Cannot write hosts file: %s" % e)
+	    try:
+		self.copy_file("%s" % gw_pubkey, "%s/%s" % \
+			(configdir, gw_pubkey_base))
+		self.copy_file("%s" % gw_secretkey, "%s/%s" % \
+			(configdir, gw_secretkey_base))
+	    except IOError, e:
+		raise service_error(service_error.internal, 
+			"Cannot copy keyfiles: %s" % e)
+
+	    # Allow the individual testbeds to access the configuration files.
+	    for tb in tbparams.keys():
+		asignee = tbparams[tb]['allocID']['fedid']
+		for f in ("hosts", gw_secretkey_base, gw_pubkey_base):
+		    self.auth.set_attribute(asignee, "%s/%s" % (configpath, f))
+		    print "assigned %s/%s" % (configpath, f)
 
 	    # Now, for each substrate in the main topology, find those that
@@ -2516,21 +2589,24 @@
 	    # into the copies of those substrates on the sub topologies.
 	    for s in top.substrates:
-		tests = { }
+		# tbs will contain an ip address on this subsrate that is in
+		# each testbed.
+		tbs = { }
 		for i in s.interfaces:
 		    e = i.element
 		    tb = e.get_attribute('testbed')
-		    if tb and not tests.has_key(tb):
+		    if tb and not tbs.has_key(tb):
 			for i in e.interface:
 			    if s in i.subs:
-				tests[tb]= \
-					i.get_attribute('ip4_address')
-		if len(tests) < 2:
+				tbs[tb]= i.get_attribute('ip4_address')
+		if len(tbs) < 2:
 		    continue
 
 		# More than one testbed is on this substrate.  Insert
-		# some portals into the subtopologies.
-
-		for st in tests.keys():
-		    for dt in [ t for t in tests.keys() if t != st]:
+		# some portals into the subtopologies.  st == source testbed,
+		# dt == destination testbed.
+		segment_substrate = { }
+		for st in tbs.keys():
+		    segment_substrate[st] = { }
+		    for dt in [ t for t in tbs.keys() if t != st]:
 			myname =  "%stunnel" % dt
 			desthost  =  "%stunnel" % st
@@ -2541,51 +2617,70 @@
 			ddomain = ".%s.%s%s" % (eid, dproject,
 				tbparams[dt].get('domain', ".example.com"))
-			boss = tbparams[master].get('boss', "boss")
-			fs = tbparams[master].get('fs', "fs")
-			event_server = "%s%s" % \
-				(tbparams[st].get('eventserver', "event_server"),
-					tbparams[dt].get('domain', "example.com"))
-			remote_event_server = "%s%s" % \
-				(tbparams[dt].get('eventserver', "event_server"),
-					tbparams[dt].get('domain', "example.com"))
-			seer_control = "%s%s" % \
-				(tbparams[st].get('control', "control"), sdomain)
-			local_key_dir = "/proj/%s/exp/%s/tmp" % ( sproject, eid)
-			remote_conf_dir = "/proj/%s/exp/%s/tmp" % ( dproject, eid)
-			conf_file = "%s%s.gw.conf" % (myname, sdomain)
-			remote_conf_file = "%s%s.gw.conf" % (desthost, ddomain)
-			# translate to lower case so the `hostname` hack for specifying
-			# configuration files works.
-			conf_file = conf_file.lower();
-			remote_conf_file = remote_conf_file.lower();
+			mdomain = "%s.%s%s" % (eid, 
+				tbparams[master].get('project', 'project'),
+				tbparams[master].get('domain', '.example.com'))
+			# XXX: active and type need to be unkludged
 			active = ("%s" % (st == master))
-			portal = topdl.Computer(**{
-				'name': "%stunnel" % dt,
-				'attribute' : [{
-				    'attribute': n,
-				    'value': v,
-				    } for n, v in (\
-					    ('gateway', 'true'),
-					    ('boss', boss),
-					    ('fs', fs),
-					    ('event_server', event_server),
-					    ('remote_event_server', remote_event_server),
-					    ('seer_control', seer_control),
-					    ('local_key_dir', local_key_dir),
-					    ('remote_conf_dir', remote_conf_dir),
-					    ('conf_file', conf_file),
-					    ('remote_conf_file', remote_conf_file),
-					    ('remote_script_dir', "/usr/local/federation/bin"),
-					    ('local_script_dir', "/usr/local/federation/bin"),
-					    )],
-				'interface': [{
-				    'substrate': s.name,
-				    'attribute': [ { 
-					'attribute': 'ip4_addreess', 
-					'value': tests[dt],
-					}, ],
-				    }, ],
-				})
+			if not segment_substrate[st].has_key(dt):
+			    # Put a substrate and a segment for the connected
+			    # testbed in there.
+			    tsubstrate = \
+				    topdl.Substrate(name='%s-%s' % (st, dt))
+			    segment_element = topdl.Segment(
+				    id= tbparams[dt]['allocID'],
+				    type='emulab',
+				    uri = self.tbmap.get(dt, None),
+				    interface=[ 
+					topdl.Interface(
+					    substrate=tsubstrate.name),
+					],
+				    attribute = [
+					topdl.Attribute(attribute=n, value=v)
+					    for n, v in (\
+						('domain', ddomain),
+						('experiment', "%s/%s" % \
+							(dproject, eid)),)
+					],
+				    )
+			    segment_substrate[st][dt] = tsubstrate
+			    topo[st].substrates.append(tsubstrate)
+			    topo[st].elements.append(segment_element)
+			portal = topdl.Computer(
+				name="%stunnel" % dt,
+				attribute=[ 
+				    topdl.Attribute(attribute=n,value=v)
+					for n, v in (\
+					    ('portal', 'true'),
+					    ('masterdomain', mdomain),
+					    ('experiment', "%s/%s" % \
+						    (sproject, eid)),
+					    ('peer', "%s.%s" % \
+						    (desthost, ddomain)),
+					    ('scriptdir', 
+						"/usr/local/federation/bin"),
+					    ('active', "%s" % active),
+					    ('type', 'both'), 
+					    ('startup', 'sudo -H /usr/local/federation/bin/fed-tun.pl -f /proj/%s/exp/%s/tmp/%s%s.gw.conf >& /tmp/bridge.log' % (sproject, eid, myname.lower(), sdomain.lower())))
+				    ],
+				interface=[
+				    topdl.Interface(
+					substrate=s.name,
+					attribute=[ 
+					    topdl.Attribute(
+						attribute='ip4_addreess', 
+						value=tbs[dt]
+					    )
+					]),
+				    topdl.Interface(
+					substrate=\
+					    segment_substrate[st][dt].name
+					),
+				    ],
+				)
+			if self.fedkit: add_kit(portal, self.fedkit)
+			if self.gatewaykit: add_kit(portal, self.gatewaykit)
+
 			topo[st].elements.append(portal)
+
 	    # Connect the gateway nodes into the topologies and clear out
 	    # substrates that are not in the topologies
@@ -2626,4 +2721,5 @@
 		try:
 		    f = open("%s/%s" % (softdir, dest) , "w")
+		    self.log.debug("Writing %s/%s" % (softdir,dest) )
 		    data = u.read(4096)
 		    while data:
@@ -2644,5 +2740,5 @@
 		for tb in tbparams.keys():
 		    self.auth.set_attribute(tbparams[tb]['allocID']['fedid'], 
-			    "%s/%s" % ( path, dest))
+			    "/%s/%s" % ( path, dest))
 
 	    # Convert the software locations in the segments into the local
@@ -2650,5 +2746,6 @@
 	    for soft in [ s for tb in topo.values() \
 		    for e in tb.elements \
-			for s in e.software ]:
+			if getattr(e, 'software', False) \
+			    for s in e.software ]:
 		if softmap.has_key(soft.location):
 		    soft.location = softmap[soft.location]
@@ -2709,8 +2806,28 @@
         alloc_log.addHandler(h)
         
+	# XXX
+	url_base = 'https://users.isi.deterlab.net:23232'
+	attrs = [ 
+		{
+		    'attribute': 'ssh_pubkey', 
+		    'value': '%s/%s/config/%s' % \
+			    (url_base, expid, gw_pubkey_base)
+		},
+		{
+		    'attribute': 'ssh_secretkey', 
+		    'value': '%s/%s/config/%s' % \
+			    (url_base, expid, gw_secretkey_base)
+		},
+		{
+		    'attribute': 'hosts', 
+		    'value': '%s/%s/config/hosts' % \
+			    (url_base, expid)
+		},
+	    ]
+
         # Start a thread to do the resource allocation
         t  = Thread(target=self.new_allocate_resources,
                 args=(allocated, master, eid, expid, expcert, tbparams, 
-                    topo, tmpdir, alloc_log),
+                    topo, tmpdir, alloc_log, attrs),
                 name=eid)
         t.start()
@@ -2774,6 +2891,9 @@
 
     def get_handler(self, path, fid):
-        print "in get_handler %s %s" % (path, fid)
-        return ("/users/faber/test.html", "text/html")
+	print "%s" %  path
+	if self.auth.check_attribute(fid, path):
+	    return ("%s/%s" % (self.repodir, path), "application/binary")
+	else:
+	    return (None, None)
 
     def get_vtopo(self, req, fid):
