class KeyGeneratorService(service.MultiService): furl_file = 'key_generator.furl' def __init__(self, basedir='.', display_furl=True, default_key_size=2048): service.MultiService.__init__(self) self.basedir = basedir self.tub = Tub(certFile=os.path.join(self.basedir, 'key_generator.pem')) self.tub.setOption("expose-remote-exception-types", False) self.tub.setServiceParent(self) self.key_generator = KeyGenerator(default_key_size=default_key_size) self.key_generator.setServiceParent(self) portnum = self.get_portnum() self.listener = self.tub.listenOn(portnum or 'tcp:0') d = self.tub.setLocationAutomatically() if portnum is None: d.addCallback(self.save_portnum) d.addCallback(self.tub_ready, display_furl) d.addErrback(log.err) def get_portnum(self): portnumfile = os.path.join(self.basedir, 'portnum') if os.path.exists(portnumfile): return file(portnumfile, 'rb').read().strip() def save_portnum(self, junk): portnum = self.listener.getPortnum() portnumfile = os.path.join(self.basedir, 'portnum') file(portnumfile, 'wb').write('%d\n' % (portnum,)) def tub_ready(self, junk, display_furl): kgf = os.path.join(self.basedir, self.furl_file) self.keygen_furl = self.tub.registerReference(self.key_generator, furlFile=kgf) if display_furl: print 'key generator at:', self.keygen_furl
class AppServer(service.MultiService): def __init__(self, basedir=".", stdout=sys.stdout): service.MultiService.__init__(self) self.basedir = os.path.abspath(basedir) try: umask = open(os.path.join(basedir, "umask")).read().strip() self.umask = int(umask, 8) # octal string like 0022 except EnvironmentError: self.umask = None port = open(os.path.join(basedir, "port")).read().strip() self.tub = Tub(certFile=os.path.join(basedir, "tub.pem")) self.tub.listenOn(port) self.tub.setServiceParent(self) self.tub.registerNameLookupHandler(self.lookup) print >> stdout, "Server Running" self.ready_observers = OneShotObserverList() # make sure we log any problems self.when_ready().addErrback(log.err) def when_ready(self): # return a Deferred that fires (with this AppServer instance) when # the service is running and the location is set. return self.ready_observers.whenFired() def startService(self): if self.umask is not None: os.umask(self.umask) service.MultiService.startService(self) d = self.setMyLocation() d.addBoth(self.ready_observers.fire) def setMyLocation(self): location = open(os.path.join(self.basedir, "location")).read().strip() if location: self.tub.setLocation(location) return defer.succeed(self) d = self.tub.setLocationAutomatically() d.addCallback(lambda ign: self) return d def lookup(self, name): # walk through our configured services, see if we know about this one services = load_service_data(self.basedir)["services"] s = services.get(name) if not s: return None service_basedir = os.path.join(self.basedir, s["relative_basedir"]) service_type = s["type"] service_args = s["args"] s = build_service(service_basedir, self.tub, service_type, service_args) s.setServiceParent(self) return s
class AppServer(service.MultiService): def __init__(self, basedir=".", stdout=sys.stdout): service.MultiService.__init__(self) self.basedir = os.path.abspath(basedir) try: umask = open(os.path.join(basedir, "umask")).read().strip() self.umask = int(umask, 8) # octal string like 0022 except EnvironmentError: self.umask = None port = open(os.path.join(basedir, "port")).read().strip() self.tub = Tub(certFile=os.path.join(basedir, "tub.pem")) self.tub.listenOn(port) self.tub.setServiceParent(self) self.tub.registerNameLookupHandler(self.lookup) print >>stdout, "Server Running" self.ready_observers = OneShotObserverList() # make sure we log any problems self.when_ready().addErrback(log.err) def when_ready(self): # return a Deferred that fires (with this AppServer instance) when # the service is running and the location is set. return self.ready_observers.whenFired() def startService(self): if self.umask is not None: os.umask(self.umask) service.MultiService.startService(self) d = self.setMyLocation() d.addBoth(self.ready_observers.fire) def setMyLocation(self): location = open(os.path.join(self.basedir, "location")).read().strip() if location: self.tub.setLocation(location) return defer.succeed(self) d = self.tub.setLocationAutomatically() d.addCallback(lambda ign: self) return d def lookup(self, name): # walk through our configured services, see if we know about this one service_basedir = os.path.join(self.basedir, "services", name) if not os.path.exists(service_basedir): return None service_type_f = os.path.join(service_basedir, "service_type") service_type = open(service_type_f).read().strip() service_args_f = os.path.join(service_basedir, "service_args") service_args = eval(open(service_args_f).read().strip()) s = build_service(service_basedir, self.tub, service_type, service_args) s.setServiceParent(self) return s
def test_set_location_automatically(self): t = Tub() l = t.listenOn("tcp:0") t.setServiceParent(self.s) d = t.setLocationAutomatically() d.addCallback(lambda res: t.registerReference(Referenceable())) def _check(furl): sr = SturdyRef(furl) portnum = l.getPortnum() for lh in sr.locationHints: self.failUnlessEqual(lh.split(":")[1], str(portnum), lh) self.failUnless("127.0.0.1:%d" % portnum in sr.locationHints) d.addCallback(_check) return d
def test_set_location_automatically(self): t = Tub() l = t.listenOn("tcp:0") t.setServiceParent(self.s) d = t.setLocationAutomatically() d.addCallback(lambda res: t.registerReference(Referenceable())) def _check(furl): sr = SturdyRef(furl) portnum = l.getPortnum() for lh in sr.locationHints: self.failUnlessEqual(lh[2], portnum, lh) self.failUnless(("tcp", "127.0.0.1", portnum) in sr.locationHints) d.addCallback(_check) return d
class KeyGeneratorService(service.MultiService): furl_file = 'key_generator.furl' def __init__(self, basedir='.', display_furl=True, default_key_size=2048): service.MultiService.__init__(self) self.basedir = basedir fileutil.make_dirs(self.basedir) self.tub = Tub( certFile=os.path.join(self.basedir, 'key_generator.pem')) self.tub.setOption("expose-remote-exception-types", False) self.tub.setServiceParent(self) self.key_generator = KeyGenerator(default_key_size=default_key_size) self.key_generator.setServiceParent(self) portnum = self.get_portnum() self.listener = self.tub.listenOn(portnum or 'tcp:0') d = self.tub.setLocationAutomatically() if portnum is None: d.addCallback(self.save_portnum) d.addCallback(self.tub_ready, display_furl) d.addErrback(log.err) def get_portnum(self): portnumfile = os.path.join(self.basedir, 'portnum') if os.path.exists(portnumfile): return file(portnumfile, 'rb').read().strip() def save_portnum(self, junk): portnum = self.listener.getPortnum() portnumfile = os.path.join(self.basedir, 'portnum') file(portnumfile, 'wb').write('%d\n' % (portnum, )) def tub_ready(self, junk, display_furl): kgf = os.path.join(self.basedir, self.furl_file) self.keygen_furl = self.tub.registerReference(self.key_generator, furlFile=kgf) if display_furl: print 'key generator at:', self.keygen_furl
class StatsGathererService(service.MultiService): furl_file = "stats_gatherer.furl" def __init__(self, basedir=".", verbose=False): service.MultiService.__init__(self) self.basedir = basedir self.tub = Tub(certFile=os.path.join(self.basedir, "stats_gatherer.pem")) self.tub.setServiceParent(self) self.tub.setOption("logLocalFailures", True) self.tub.setOption("logRemoteFailures", True) self.tub.setOption("expose-remote-exception-types", False) self.stats_gatherer = PickleStatsGatherer(self.basedir, verbose) self.stats_gatherer.setServiceParent(self) portnumfile = os.path.join(self.basedir, "portnum") try: portnum = open(portnumfile, "r").read() except EnvironmentError: portnum = None self.listener = self.tub.listenOn(portnum or "tcp:0") d = self.tub.setLocationAutomatically() if portnum is None: d.addCallback(self.save_portnum) d.addCallback(self.tub_ready) d.addErrback(log.err) def save_portnum(self, junk): portnum = self.listener.getPortnum() portnumfile = os.path.join(self.basedir, 'portnum') open(portnumfile, 'wb').write('%d\n' % (portnum,)) def tub_ready(self, ignored): ff = os.path.join(self.basedir, self.furl_file) self.gatherer_furl = self.tub.registerReference(self.stats_gatherer, furlFile=ff)
class CancelPendingDeliveries(unittest.TestCase, StallMixin): def tearDown(self): dl = [defer.succeed(None)] if self.tubA.running: dl.append(defer.maybeDeferred(self.tubA.stopService)) if self.tubB.running: dl.append(defer.maybeDeferred(self.tubB.stopService)) d = defer.DeferredList(dl) d.addCallback(flushEventualQueue) return d def test_cancel_pending_deliveries(self): # when a Tub is stopped, any deliveries that were pending should be # discarded. TubA sends remote_one+remote_two (and we hope they # arrive in the same chunk). TubB responds to remote_one by shutting # down. remote_two should be discarded. The bug was that remote_two # would cause an unhandled error on the TubB side. self.tubA = Tub() self.tubB = Tub() self.tubA.startService() self.tubB.startService() self.tubB.listenOn("tcp:0") d = self.tubB.setLocationAutomatically() r = Receiver(self.tubB) d.addCallback(lambda res: self.tubB.registerReference(r)) d.addCallback(lambda furl: self.tubA.getReference(furl)) def _go(rref): # we want these two to get sent and received in the same hunk rref.callRemoteOnly("one") rref.callRemoteOnly("two") return r.done_d d.addCallback(_go) # let remote_two do its log.err before we move on to the next test d.addCallback(self.stall, 1.0) return d