Index: fedd/federation/protogeni_access.py
===================================================================
--- fedd/federation/protogeni_access.py	(revision 88469590af4ce8ec7cb4b141a0da5b56c6a64cfb)
+++ fedd/federation/protogeni_access.py	(revision dd3e38b06e0ccf8e3c36912b77a08f390069ae8d)
@@ -4,4 +4,5 @@
 import stat # for chmod constants
 import re
+import time
 import string
 import copy
@@ -76,4 +77,7 @@
 	self.staging_host = config.get("access", "staging_host") \
 		or "ops.emulab.net"
+
+	self.renewal_interval = config.get("access", "renewal") or (3 * 60 * 60)
+	self.renewal_interval = int(self.renewal_interval)
 
 	self.ch_url = config.get("access", "ch_url")
@@ -131,7 +135,10 @@
 	self.start_segment = proxy_protogeni_segment.start_segment
 	self.stop_segment = proxy_protogeni_segment.stop_segment
+	self.renew_segment = proxy_protogeni_segment.renew_segment
 
 	self.call_SetValue = service_caller('SetValue')
 	self.call_GetValue = service_caller('GetValue')
+
+	self.RenewSlices()
 
         self.soap_services = {\
@@ -212,5 +219,4 @@
 
             # Access line (t, p, u) -> (a, pw) line
-	    # XXX: you are here
             m = access_re.match(line)
             if m != None:
@@ -1114,2 +1120,41 @@
 	stopper(self, user, staging, slice_cred, cf, cpw)
 	return { 'allocID': req['allocID'] }
+
+    def RenewSlices(self):
+	self.log.info("Scanning for slices to renew")
+	self.state_lock.acquire()
+	aids = self.allocation.keys()
+	self.state_lock.release()
+
+	for aid in aids:
+	    self.state_lock.acquire()
+	    if self.allocation.has_key(aid):
+		name = self.allocation[aid].get('slice_name', None)
+		scred = self.allocation[aid].get('slice_credential', None)
+		cf, user, ssh_key, cpw = self.allocation[aid]['credentials']
+	    else:
+		name = None
+		scred = None
+	    self.state_lock.release()
+
+	    # There's a ProtoGENI slice associated with the segment; renew it.
+	    if name and scred:
+		renewer = self.renew_segment(log=self.log, 
+			debug=self.create_debug, keyfile=ssh_key,
+			cm_url = self.cm_url, sa_url = self.sa_url,
+			ch_url = self.ch_url)
+		new_scred = renewer(name, scred, self.renewal_interval, cf, cpw)
+		if new_scred:
+		    self.log.info("Slice %s renewed until %s GMT" % \
+			    (name, time.asctime(time.gmtime(\
+				time.time()+self.renewal_interval))))
+		    self.state_lock.acquire()
+		    if self.allocation.has_key(aid):
+			self.allocation[aid]['slice_credential'] = new_scred
+		    self.state_lock.release()
+		else:
+		    self.log.info("Failed to renew slice %s " % name)
+
+	# Let's do this all again soon.  (4 tries before the slices time out)	
+	t = Timer(self.renewal_interval/4, self.RenewSlices)
+	t.start()
Index: fedd/federation/proxy_protogeni_segment.py
===================================================================
--- fedd/federation/proxy_protogeni_segment.py	(revision 88469590af4ce8ec7cb4b141a0da5b56c6a64cfb)
+++ fedd/federation/proxy_protogeni_segment.py	(revision dd3e38b06e0ccf8e3c36912b77a08f390069ae8d)
@@ -91,6 +91,6 @@
     # name) has an entry with the allocated machine in hostname and the
     # interfaces in 'interfaces'.  I love having XML parser code lying around.
-    def manifest_to_dict(self, manifest):
-	if self.debug: 
+    def manifest_to_dict(self, manifest, ignore_debug=False):
+	if self.debug and not ignore_debug: 
 	    self.log.debug("Returning null manifest dict")
 	    return { }
@@ -388,4 +388,7 @@
 		    print >>script, "sudo perl -I%s/lib %s/bin/import_key.pl /users/%s/.ssh/authorized_keys /root/.ssh/authorized_keys" % (fed_dir, fed_dir, user)
 		    # XXX: debug
+		    # start routing on nodes
+		    print >>script, "sudo perl %s/bin/protogeni_routing.pl" % \
+			    fed_dir
 		    if e.get_attribute('startup'):
 			print >>script, "%s \\$USER '%s'" % \
@@ -541,6 +544,5 @@
 
 	# With manifest in hand, we can export the portal node names.
-	nodes = self.manifest_to_dict(manifest)
-	print nodes
+	nodes = self.manifest_to_dict(manifest, ignore_debug=True)
 	self.export_store_info(export_certfile, nodes, parent.ssh_port,
 		connInfo)
@@ -589,4 +591,5 @@
 	else:
 	    parent.state_lock.acquire()
+	    parent.allocation[aid]['slice_name'] = slicename
 	    parent.allocation[aid]['slice_credential'] = slice_cred
 	    parent.allocation[aid]['sliver_credential'] = sliver_cred
@@ -644,2 +647,55 @@
 	return rv
 
+class renew_segment(segment_base):
+    def __init__(self, log=None, debug=False, keyfile=None,
+	    ch_url=None, sa_url=None, cm_url=None):
+	segment_base.__init__(self, log=log, keyfile=keyfile, debug=debug,
+		ch_url=cm_url, sa_url=sa_url, cm_url=cm_url)
+
+    def __call__(self, name, scred, interval, certfile, certpw):
+	ctxt = fedd_ssl_context(my_cert=certfile, password=certpw)
+	try:
+	    expiration = time.strftime("%Y%m%dT%H:%M:%S",
+		    time.gmtime(time.time() + interval))
+	    cred = self.pg_call(self.sa_url, 'GetCredential', {}, ctxt)
+
+	    param = {
+		    'credential': scred,
+		    'expiration': expiration
+		    }
+	    r = self.pg_call(self.sa_url, 'RenewSlice', param, ctxt)
+	    param = {
+		    'credential': cred,
+		    'hrn': name,
+		    'type': 'Slice',
+		    }
+	    slice = self.pg_call(self.sa_url, 'Resolve', param, ctxt)
+	    uuid = slice.get('uuid', None)
+	    if uuid == None:
+		sys.exit('No uuid for %s' % slicename)
+
+	    print 'Calling GetCredential (uuid)'
+	    param = {
+		    'credential': cred,
+		    'uuid': uuid,
+		    'type': 'Slice',
+		    }
+	    new_scred = self.pg_call(self.sa_url, 'GetCredential', param, ctxt)
+	    f = open('./new_slice_cred', 'w')
+	    print >>f, new_scred
+	    f.close()
+
+	except self.ProtoGENIError, e:
+	    self.log.error("Failed to extend slice %s: %s" % (name, e))
+	    return None
+	try:
+	    print 'Calling RenewSlice (CM)'
+	    param = {
+		    'credential': new_scred,
+		    }
+	    r = self.pg_call(self.cm_url, 'RenewSlice', param, ctxt)
+	except self.ProtoGENIError, e:
+	    self.log.warn("Failed to renew sliver for %s: %s" % (name, e))
+
+	return new_scred
+    
