예제 #1
0
 def test_referenceable(self):
     t1 = Tub()
     t1.setServiceParent(self.s)
     portnum = allocate_tcp_port()
     t1.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
     t1.setLocation("127.0.0.1:%d" % portnum)
     r1 = Referenceable()
     # the serialized blob can't keep the reference alive, so you must
     # arrange for that separately
     t1.registerReference(r1)
     t2 = Tub()
     t2.setServiceParent(self.s)
     obj = ("graph tangly", r1)
     d = t1.serialize(obj)
     del r1; del obj
     def _done(data):
         self.failUnless("their-reference" in data)
         return data
     d.addCallback(_done)
     d.addCallback(lambda data: t2.unserialize(data))
     def _check(obj2):
         self.failUnlessEqual(obj2[0], "graph tangly")
         self.failUnless(isinstance(obj2[1], RemoteReference))
     d.addCallback(_check)
     return d
예제 #2
0
파일: tac.py 프로젝트: dannyob/consensobot
def get_tub(application):
    myserver = RemoteControl(application)
    tub = Tub(certFile=os.path.join(consenso.directories.foolscap_dir, "pb2server.pem"))
    tub.listenOn("tcp:12345")
    tub.setLocation("localhost:12345")
    tub.registerReference(myserver, "remote-control", furlFile=furlfile)
    return tub
예제 #3
0
    def test_referenceable(self):
        t1 = Tub()
        t1.setServiceParent(self.s)
        l = t1.listenOn("tcp:0:interface=127.0.0.1")
        t1.setLocation("127.0.0.1:%d" % l.getPortnum())
        r1 = Referenceable()
        # the serialized blob can't keep the reference alive, so you must
        # arrange for that separately
        t1.registerReference(r1)
        t2 = Tub()
        t2.setServiceParent(self.s)
        obj = ("graph tangly", r1)
        d = t1.serialize(obj)
        del r1
        del obj

        def _done(data):
            self.failUnless("their-reference" in data)
            return data

        d.addCallback(_done)
        d.addCallback(lambda data: t2.unserialize(data))

        def _check(obj2):
            self.failUnlessEqual(obj2[0], "graph tangly")
            self.failUnless(isinstance(obj2[1], RemoteReference))

        d.addCallback(_check)
        return d
예제 #4
0
def get_tub(application):
    myserver = RemoteControl(application)
    tub = Tub(certFile=os.path.join(consenso.directories.foolscap_dir,
                                    "pb2server.pem"))
    tub.listenOn("tcp:12345")
    tub.setLocation("localhost:12345")
    tub.registerReference(myserver, "remote-control", furlFile=furlfile)
    return tub
예제 #5
0
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 = JSONStatsGatherer(self.basedir, verbose)
        self.stats_gatherer.setServiceParent(self)

        try:
            with open(os.path.join(self.basedir, "location")) as f:
                location = f.read().strip()
        except EnvironmentError:
            raise ValueError("Unable to find 'location' in BASEDIR, please rebuild your stats-gatherer")
        try:
            with open(os.path.join(self.basedir, "port")) as f:
                port = f.read().strip()
        except EnvironmentError:
            raise ValueError("Unable to find 'port' in BASEDIR, please rebuild your stats-gatherer")

        self.tub.listenOn(port)
        self.tub.setLocation(location)
        ff = os.path.join(self.basedir, self.furl_file)
        self.gatherer_furl = self.tub.registerReference(self.stats_gatherer,
                                                        furlFile=ff)
예제 #6
0
    def test_unreachable_client(self):
        # A "client-only" Tub has no location set. It should still be
        # possible to connect to objects in other (location-bearing) server
        # Tubs, and objects in the client Tub can still be sent to (and used
        # by) the server Tub.

        client_tub = Tub()
        client_tub.setServiceParent(self.s)
        server_tub = Tub()
        server_tub.setServiceParent(self.s)

        portnum = allocate_tcp_port()
        server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
        server_tub.setLocation("tcp:127.0.0.1:%d" % portnum)
        s = Receiver() # no FURL, not directly reachable
        r = Receiver()
        furl = server_tub.registerReference(r)

        d = client_tub.getReference(furl)
        d.addCallback(lambda rref: rref.callRemote("call", s))
        d.addCallback(lambda res: self.failUnlessEqual(res, 1))
        d.addCallback(lambda _: self.failIfEqual(r.obj, None))
        def _inspect_obj(_):
            self.failUnlessEqual(r.obj.getSturdyRef().getURL(), None)
        d.addCallback(_inspect_obj)
        d.addCallback(lambda _: r.obj.callRemote("call", 2))
        d.addCallback(lambda _: self.failUnlessEqual(s.obj, 2))
        return d
예제 #7
0
    def test_furlfile(self):
        cfn = "test_tub.FurlFile.test_furlfile.certfile"
        t1 = Tub(certFile=cfn)
        t1.setServiceParent(self.s)
        l = t1.listenOn("tcp:0:interface=127.0.0.1")
        t1.setLocation("127.0.0.1:%d" % l.getPortnum())
        port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum()
        r1 = Referenceable()
        ffn = "test_tub.FurlFile.test_furlfile.furlfile"
        furl1 = t1.registerReference(r1, furlFile=ffn)
        d = defer.maybeDeferred(t1.disownServiceParent)

        self.failUnless(os.path.exists(ffn))
        self.failUnlessEqual(furl1, open(ffn,"r").read().strip())

        def _take2(res):
            t2 = Tub(certFile=cfn)
            t2.setServiceParent(self.s)
            l = t2.listenOn(port1)
            t2.setLocation("127.0.0.1:%d" % l.getPortnum())
            r2 = Referenceable()
            furl2 = t2.registerReference(r2, furlFile=ffn)
            self.failUnlessEqual(furl1, furl2)
            return t2.disownServiceParent()
        d.addCallback(_take2)
        return d
예제 #8
0
    def test_unreachable_gift(self):
        client_tub = Tub()
        client_tub.setServiceParent(self.s)
        server_tub = Tub()
        server_tub.setServiceParent(self.s)
        recipient_tub = Tub()
        recipient_tub.setServiceParent(self.s)

        portnum = allocate_tcp_port()
        server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
        server_tub.setLocation("tcp:127.0.0.1:%d" % portnum)
        s = Receiver()  # no FURL, not directly reachable
        r = Receiver()
        furl = server_tub.registerReference(r)

        d = client_tub.getReference(furl)
        d.addCallback(lambda rref: rref.callRemote("call", s))
        d.addCallback(lambda res: self.assertEqual(res, 1))
        d.addCallback(lambda _: recipient_tub.getReference(furl))
        # when server_tub tries to send the lame 's' rref to recipient_tub,
        # the RemoteReferenceTracker won't have a FURL, so it will be
        # serialized as a (their-reference furl="") sequence. Then
        # recipient_tub will try to resolve it, and will throw a
        # NoLocationHintsError. It might be more natural to send
        # (their-reference furl=None), but the constraint schema on
        # their-references forbids non-strings. It might also seem
        # appropriate to raise a Violation (i.e. server_tub is bad for trying
        # to send it, rather than foisting the problem off to recipient_tub),
        # but that causes the connection explode and fall out of sync.
        d.addCallback(lambda rref: self.shouldFail(
            NoLocationHintsError, "gift_me", None, rref.callRemote, "gift_me"))
        return d
예제 #9
0
    def test_retry(self):
        tubC = Tub(certData=self.tubB.getCertData())
        connects = []
        target = HelperTarget("bob")
        url = self.tubB.registerReference(target, "target")
        portb = self.tub_ports[1]
        d1 = defer.Deferred()
        notifiers = [d1]
        self.services.remove(self.tubB)

        # This will fail, since tubB is not listening anymore. Wait until it's
        # moved to the "waiting" state.
        yield self.tubB.stopService()
        rc = self.tubA.connectTo(url, self._connected, notifiers, connects)
        yield self.poll(lambda: rc.getReconnectionInfo().state == "waiting")
        self.failUnlessEqual(len(connects), 0)

        # now start tubC listening on the same port that tubB used to, which
        # should allow the connection to complete (since they both use the same
        # certData)

        self.services.append(tubC)
        tubC.startService()
        tubC.listenOn("tcp:%d:interface=127.0.0.1" % portb)
        tubC.setLocation("tcp:127.0.0.1:%d" % portb)
        url2 = tubC.registerReference(target, "target")
        assert url2 == url
        yield d1

        self.failUnlessEqual(len(connects), 1)
        rc.stopConnecting()
예제 #10
0
    def test_unreachable_gift(self):
        client_tub = Tub()
        client_tub.setServiceParent(self.s)
        server_tub = Tub()
        server_tub.setServiceParent(self.s)
        recipient_tub = Tub()
        recipient_tub.setServiceParent(self.s)

        portnum = allocate_tcp_port()
        server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
        server_tub.setLocation("tcp:127.0.0.1:%d" % portnum)
        s = Receiver() # no FURL, not directly reachable
        r = Receiver()
        furl = server_tub.registerReference(r)

        d = client_tub.getReference(furl)
        d.addCallback(lambda rref: rref.callRemote("call", s))
        d.addCallback(lambda res: self.failUnlessEqual(res, 1))
        d.addCallback(lambda _: recipient_tub.getReference(furl))
        # when server_tub tries to send the lame 's' rref to recipient_tub,
        # the RemoteReferenceTracker won't have a FURL, so it will be
        # serialized as a (their-reference furl="") sequence. Then
        # recipient_tub will try to resolve it, and will throw a
        # NoLocationHintsError. It might be more natural to send
        # (their-reference furl=None), but the constraint schema on
        # their-references forbids non-strings. It might also seem
        # appropriate to raise a Violation (i.e. server_tub is bad for trying
        # to send it, rather than foisting the problem off to recipient_tub),
        # but that causes the connection explode and fall out of sync.
        d.addCallback(lambda rref:
                      self.shouldFail(NoLocationHintsError, "gift_me", None,
                                      rref.callRemote, "gift_me"))
        return d
예제 #11
0
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
예제 #12
0
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 = JSONStatsGatherer(self.basedir, verbose)
        self.stats_gatherer.setServiceParent(self)

        try:
            with open(os.path.join(self.basedir, "location")) as f:
                location = f.read().strip()
        except EnvironmentError:
            raise ValueError("Unable to find 'location' in BASEDIR, please rebuild your stats-gatherer")
        try:
            with open(os.path.join(self.basedir, "port")) as f:
                port = f.read().strip()
        except EnvironmentError:
            raise ValueError("Unable to find 'port' in BASEDIR, please rebuild your stats-gatherer")

        self.tub.listenOn(port)
        self.tub.setLocation(location)
        ff = os.path.join(self.basedir, self.furl_file)
        self.gatherer_furl = self.tub.registerReference(self.stats_gatherer,
                                                        furlFile=ff)
예제 #13
0
    def test_furlfile(self):
        cfn = "test_tub.FurlFile.test_furlfile.certfile"
        t1 = Tub(certFile=cfn)
        t1.setServiceParent(self.s)
        l = t1.listenOn("tcp:0:interface=127.0.0.1")
        t1.setLocation("127.0.0.1:%d" % l.getPortnum())
        port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum()
        r1 = Referenceable()
        ffn = "test_tub.FurlFile.test_furlfile.furlfile"
        furl1 = t1.registerReference(r1, furlFile=ffn)
        d = defer.maybeDeferred(t1.disownServiceParent)

        self.failUnless(os.path.exists(ffn))
        self.failUnlessEqual(furl1, open(ffn, "r").read().strip())

        def _take2(res):
            t2 = Tub(certFile=cfn)
            t2.setServiceParent(self.s)
            l = t2.listenOn(port1)
            t2.setLocation("127.0.0.1:%d" % l.getPortnum())
            r2 = Referenceable()
            furl2 = t2.registerReference(r2, furlFile=ffn)
            self.failUnlessEqual(furl1, furl2)
            return t2.disownServiceParent()

        d.addCallback(_take2)
        return d
예제 #14
0
    def test_retry(self):
        tubC = Tub(certData=self.tubB.getCertData())
        connects = []
        target = HelperTarget("bob")
        url = self.tubB.registerReference(target, "target")
        portb = self.tub_ports[1]
        d1 = defer.Deferred()
        notifiers = [d1]
        self.services.remove(self.tubB)

        # This will fail, since tubB is not listening anymore. Wait until it's
        # moved to the "waiting" state.
        yield self.tubB.stopService()
        rc = self.tubA.connectTo(url, self._connected, notifiers, connects)
        yield self.poll(lambda: rc.getReconnectionInfo().state == "waiting")
        self.failUnlessEqual(len(connects), 0)

        # now start tubC listening on the same port that tubB used to, which
        # should allow the connection to complete (since they both use the same
        # certData)

        self.services.append(tubC)
        tubC.startService()
        tubC.listenOn("tcp:%d:interface=127.0.0.1" % portb)
        tubC.setLocation("tcp:127.0.0.1:%d" % portb)
        url2 = tubC.registerReference(target, "target")
        assert url2 == url
        yield d1

        self.failUnlessEqual(len(connects), 1)
        rc.stopConnecting()
예제 #15
0
    def test_tubid_check(self):
        t1 = Tub() # gets a new key
        t1.setServiceParent(self.s)
        l = t1.listenOn("tcp:0:interface=127.0.0.1")
        t1.setLocation("127.0.0.1:%d" % l.getPortnum())
        port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum()
        r1 = Referenceable()
        ffn = "test_tub.FurlFile.test_tubid_check.furlfile"
        furl1 = t1.registerReference(r1, furlFile=ffn)
        d = defer.maybeDeferred(t1.disownServiceParent)

        self.failUnless(os.path.exists(ffn))
        self.failUnlessEqual(furl1, open(ffn,"r").read().strip())

        def _take2(res):
            t2 = Tub() # gets a different key
            t2.setServiceParent(self.s)
            l = t2.listenOn(port1)
            t2.setLocation("127.0.0.1:%d" % l.getPortnum())
            r2 = Referenceable()
            self.failUnlessRaises(WrongTubIdError,
                                  t2.registerReference, r2, furlFile=ffn)
            return t2.disownServiceParent()
        d.addCallback(_take2)
        return d
예제 #16
0
    def test_tubid_check(self):
        t1 = Tub()  # gets a new key
        t1.setServiceParent(self.s)
        l = t1.listenOn("tcp:0:interface=127.0.0.1")
        t1.setLocation("127.0.0.1:%d" % l.getPortnum())
        port1 = "tcp:%d:interface=127.0.0.1" % l.getPortnum()
        r1 = Referenceable()
        ffn = "test_tub.FurlFile.test_tubid_check.furlfile"
        furl1 = t1.registerReference(r1, furlFile=ffn)
        d = defer.maybeDeferred(t1.disownServiceParent)

        self.failUnless(os.path.exists(ffn))
        self.failUnlessEqual(furl1, open(ffn, "r").read().strip())

        def _take2(res):
            t2 = Tub()  # gets a different key
            t2.setServiceParent(self.s)
            l = t2.listenOn(port1)
            t2.setLocation("127.0.0.1:%d" % l.getPortnum())
            r2 = Referenceable()
            self.failUnlessRaises(WrongTubIdError,
                                  t2.registerReference,
                                  r2,
                                  furlFile=ffn)
            return t2.disownServiceParent()

        d.addCallback(_take2)
        return d
예제 #17
0
    def test_unreachable_client(self):
        # A "client-only" Tub has no location set. It should still be
        # possible to connect to objects in other (location-bearing) server
        # Tubs, and objects in the client Tub can still be sent to (and used
        # by) the server Tub.

        client_tub = Tub()
        client_tub.setServiceParent(self.s)
        server_tub = Tub()
        server_tub.setServiceParent(self.s)

        portnum = allocate_tcp_port()
        server_tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
        server_tub.setLocation("tcp:127.0.0.1:%d" % portnum)
        s = Receiver()  # no FURL, not directly reachable
        r = Receiver()
        furl = server_tub.registerReference(r)

        d = client_tub.getReference(furl)
        d.addCallback(lambda rref: rref.callRemote("call", s))
        d.addCallback(lambda res: self.assertEqual(res, 1))
        d.addCallback(lambda _: self.assertNotEqual(r.obj, None))

        def _inspect_obj(_):
            self.assertEqual(r.obj.getSturdyRef().getURL(), None)

        d.addCallback(_inspect_obj)
        d.addCallback(lambda _: r.obj.callRemote("call", 2))
        d.addCallback(lambda _: self.assertEqual(s.obj, 2))
        return d
예제 #18
0
    def test_empty_location(self):
        # bug #129: a FURL with no location hints causes a synchronous
        # exception in Tub.getReference(), instead of an errback'ed Deferred.

        tubA = Tub()
        tubA.setServiceParent(self.s)
        tubB = Tub()
        tubB.setServiceParent(self.s)

        # This is a hack to get a FURL with empty location hints. The correct
        # way to make a Tub unreachable is to not call .setLocation() at all.
        tubB.setLocation("")
        r = Receiver(tubB)
        furl = tubB.registerReference(r)
        # the buggy behavior is that the following call raises an exception
        d = tubA.getReference(furl)
        # whereas it ought to return a Deferred
        self.assertTrue(isinstance(d, defer.Deferred))

        def _check(f):
            self.assertTrue(isinstance(f, failure.Failure), f)
            self.assertTrue(f.check(NoLocationHintsError), f)

        d.addBoth(_check)
        return d
예제 #19
0
 def _testPersist_1(self, res, s1, s2, t1, public_url, port):
     self.services.remove(s1)
     s3 = Tub(certData=s1.getCertData())
     s3.startService()
     self.services.append(s3)
     t2 = Target()
     newport = allocate_tcp_port()
     s3.listenOn("tcp:%d:interface=127.0.0.1" % newport)
     s3.setLocation("127.0.0.1:%d" % newport)
     s3.registerReference(t2, "name")
     # now patch the URL to replace the port number
     newurl = re.sub(":%d/" % port, ":%d/" % newport, public_url)
     d = s2.getReference(newurl)
     d.addCallback(lambda rr: rr.callRemote("add", a=1, b=2))
     d.addCallback(self.failUnlessEqual, 3)
     d.addCallback(self._testPersist_2, t1, t2)
     return d
예제 #20
0
 def _testPersist_1(self, res, s1, s2, t1, public_url, port):
     self.services.remove(s1)
     s3 = Tub(certData=s1.getCertData())
     s3.startService()
     self.services.append(s3)
     t2 = Target()
     newport = allocate_tcp_port()
     s3.listenOn("tcp:%d:interface=127.0.0.1" % newport)
     s3.setLocation("127.0.0.1:%d" % newport)
     s3.registerReference(t2, "name")
     # now patch the URL to replace the port number
     newurl = re.sub(":%d/" % port, ":%d/" % newport, public_url)
     d = s2.getReference(newurl)
     d.addCallback(lambda rr: rr.callRemote("add", a=1, b=2))
     d.addCallback(self.failUnlessEqual, 3)
     d.addCallback(self._testPersist_2, t1, t2)
     return d
예제 #21
0
class GatheringBase(service.MultiService, Referenceable):
    # requires self.furlFile and self.tacFile to be set on the class, both of
    # which should be relative to the basedir.
    use_local_addresses = True

    def __init__(self, basedir):
        if basedir is None:
            # This instance was created by a gatherer.tac file. Confirm that
            # we're running from the right directory (the one with the .tac
            # file), otherwise we'll put the logfiles in the wrong place.
            basedir = os.getcwd()
            tac = os.path.join(basedir, self.tacFile)
            if not os.path.exists(tac):
                raise RuntimeError("running in the wrong directory")
        self.basedir = basedir
        service.MultiService.__init__(self)

    def startService(self):
        service.MultiService.startService(self)
        certFile = os.path.join(self.basedir, "gatherer.pem")
        self._tub = Tub(certFile=certFile)
        self._tub.setServiceParent(self)
        local_addresses = ["127.0.0.1"]
        local_address = get_local_ip_for()
        if self.use_local_addresses and local_address:
            local_addresses.insert(0, local_address)

        portnumfile = os.path.join(self.basedir, "portnum")
        try:
            desired_portnum = int(open(portnumfile, "r").read())
        except (EnvironmentError, ValueError):
            desired_portnum = 0
        l = self._tub.listenOn("tcp:%d" % desired_portnum)

        got_portnum = l.getPortnum()
        f = open(portnumfile, "w")
        f.write("%d\n" % got_portnum)
        f.close()

        # we can't do setLocation until we have two things:
        #  portnum: this requires listenOn, if portnum=0 also startService
        #  localip: this just requires a call to get_local_ip_for
        # so it is safe to do everything in startService, after the upcall

        local_addresses = [ "%s:%d" % (addr, got_portnum,)
                            for addr in local_addresses ]
        assert len(local_addresses) >= 1
        location = ",".join(local_addresses)
        self._tub.setLocation(location)

        self.tub_ready()

    def tub_ready(self):
        furlFile = os.path.join(self.basedir, self.furlFile)
        self.my_furl = self._tub.registerReference(self, furlFile=furlFile)
        if self.verbose:
            print "Gatherer waiting at:", self.my_furl
예제 #22
0
 def _take2(res):
     t2 = Tub(certFile=cfn)
     t2.setServiceParent(self.s)
     l = t2.listenOn(port1)
     t2.setLocation("127.0.0.1:%d" % l.getPortnum())
     r2 = Referenceable()
     furl2 = t2.registerReference(r2, furlFile=ffn)
     self.failUnlessEqual(furl1, furl2)
     return t2.disownServiceParent()
예제 #23
0
 def _take2(res):
     t2 = Tub(certFile=cfn)
     t2.setServiceParent(self.s)
     l = t2.listenOn(port1)
     t2.setLocation("127.0.0.1:%d" % l.getPortnum())
     r2 = Referenceable()
     furl2 = t2.registerReference(r2, furlFile=ffn)
     self.failUnlessEqual(furl1, furl2)
     return t2.disownServiceParent()
예제 #24
0
파일: gatherer.py 프로젝트: samucc/foolscap
class GatheringBase(service.MultiService, Referenceable):
    # requires self.furlFile and self.tacFile to be set on the class, both of
    # which should be relative to the basedir.
    use_local_addresses = True

    def __init__(self, basedir):
        if basedir is None:
            # This instance was created by a gatherer.tac file. Confirm that
            # we're running from the right directory (the one with the .tac
            # file), otherwise we'll put the logfiles in the wrong place.
            basedir = os.getcwd()
            tac = os.path.join(basedir, self.tacFile)
            if not os.path.exists(tac):
                raise RuntimeError("running in the wrong directory")
        self.basedir = basedir
        service.MultiService.__init__(self)

    def startService(self):
        service.MultiService.startService(self)
        certFile = os.path.join(self.basedir, "gatherer.pem")
        self._tub = Tub(certFile=certFile)
        self._tub.setServiceParent(self)
        local_addresses = ["127.0.0.1"]
        local_address = get_local_ip_for()
        if self.use_local_addresses and local_address:
            local_addresses.insert(0, local_address)

        portnumfile = os.path.join(self.basedir, "portnum")
        try:
            desired_portnum = int(open(portnumfile, "r").read())
        except (EnvironmentError, ValueError):
            desired_portnum = 0
        l = self._tub.listenOn("tcp:%d" % desired_portnum)

        got_portnum = l.getPortnum()
        f = open(portnumfile, "w")
        f.write("%d\n" % got_portnum)
        f.close()

        # we can't do setLocation until we have two things:
        #  portnum: this requires listenOn, if portnum=0 also startService
        #  localip: this just requires a call to get_local_ip_for
        # so it is safe to do everything in startService, after the upcall

        local_addresses = [ "%s:%d" % (addr, got_portnum,)
                            for addr in local_addresses ]
        assert len(local_addresses) >= 1
        location = ",".join(local_addresses)
        self._tub.setLocation(location)

        self.tub_ready()

    def tub_ready(self):
        furlFile = os.path.join(self.basedir, self.furlFile)
        self.my_furl = self._tub.registerReference(self, furlFile=furlFile)
        if self.verbose:
            print "Gatherer waiting at:", self.my_furl
예제 #25
0
 def createSpecificServer(self, certData,
                          negotiationClass=negotiate.Negotiation):
     tub = Tub(certData=certData)
     tub.negotiationClass = negotiationClass
     tub.startService()
     self.services.append(tub)
     l = tub.listenOn("tcp:0")
     tub.setLocation("127.0.0.1:%d" % l.getPortnum())
     target = Target()
     return tub, target, tub.registerReference(target), l.getPortnum()
예제 #26
0
 def makeTub(self, hint_type):
     tubA = Tub(certData=certData_low)
     tubA.setServiceParent(self.s)
     tubB = Tub(certData=certData_high)
     tubB.setServiceParent(self.s)
     portnum = util.allocate_tcp_port()
     tubA.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
     tubA.setLocation("%s:127.0.0.1:%d" % (hint_type, portnum))
     furl = tubA.registerReference(Target())
     return furl, tubB
예제 #27
0
 def makeTub(self, hint_type):
     tubA = Tub(certData=certData_low)
     tubA.setServiceParent(self.s)
     tubB = Tub(certData=certData_high)
     tubB.setServiceParent(self.s)
     portnum = util.allocate_tcp_port()
     tubA.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
     tubA.setLocation("%s:127.0.0.1:%d" % (hint_type, portnum))
     furl = tubA.registerReference(Target())
     return furl, tubB
예제 #28
0
 def createSpecificServer(self, certData,
                          negotiationClass=negotiate.Negotiation):
     tub = Tub(certData=certData)
     tub.negotiationClass = negotiationClass
     tub.startService()
     self.services.append(tub)
     l = tub.listenOn("tcp:0")
     tub.setLocation("127.0.0.1:%d" % l.getPortnum())
     target = Target()
     return tub, target, tub.registerReference(target), l.getPortnum()
예제 #29
0
class GatheringBase(service.MultiService, Referenceable):
    # requires self.furlFile and self.tacFile to be set on the class, both of
    # which should be relative to the basedir.
    use_local_addresses = True

    def __init__(self, basedir):
        service.MultiService.__init__(self)
        if basedir is None:
            # This instance was created by a gatherer.tac file. Confirm that
            # we're running from the right directory (the one with the .tac
            # file), otherwise we'll put the logfiles in the wrong place.
            basedir = os.getcwd()
            tac = os.path.join(basedir, self.tacFile)
            if not os.path.exists(tac):
                raise RuntimeError("running in the wrong directory")
        self.basedir = basedir
        certFile = os.path.join(self.basedir, "gatherer.pem")
        portfile = os.path.join(self.basedir, "port")
        locationfile = os.path.join(self.basedir, "location")
        furlFile = os.path.join(self.basedir, self.furlFile)

        # Foolscap-0.11.0 was the last release that used
        # automatically-determined listening addresses and ports. New ones
        # (created with "flogtool create-gatherer" or
        # "create-incident-gathererer" now require --location and --port
        # arguments to provide these values. If you really don't want to
        # create a new one, you can write "tcp:3117" (or some other port
        # number of your choosing) to BASEDIR/port, and "tcp:$HOSTNAME:3117"
        # (with your hostname or IP address) to BASEDIR/location

        if (not os.path.exists(portfile) or
            not os.path.exists(locationfile)):
            raise ObsoleteGatherer("Please create a new gatherer, with both "
                                   "--port and --location")
        try:
            with open(portfile, "r") as f:
                port = f.read().strip()
        except EnvironmentError:
            raise ObsoleteGatherer("Please create a new gatherer, with both "
                                   "--port and --location")
        try:
            with open(locationfile, "r") as f:
                location = f.read().strip()
        except EnvironmentError:
            raise ObsoleteGatherer("Please create a new gatherer, with both "
                                   "--port and --location")

        self._tub = Tub(certFile=certFile)
        self._tub.setServiceParent(self)
        self._tub.listenOn(port)
        self._tub.setLocation(location)

        self.my_furl = self._tub.registerReference(self, furlFile=furlFile)
        if self.verbose:
            print "Gatherer waiting at:", self.my_furl
예제 #30
0
파일: common.py 프로젝트: byrgazov/foolscap
 def createSpecificServer(self, certData,
                          negotiationClass=negotiate.Negotiation):
     tub = Tub(certData=certData)
     tub.negotiationClass = negotiationClass
     tub.startService()
     self.services.append(tub)
     portnum = allocate_tcp_port()
     tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
     tub.setLocation("127.0.0.1:%d" % portnum)
     target = Target()
     return tub, target, tub.registerReference(target), portnum
예제 #31
0
 def TODO_testNonweakrefable(self):
     # what happens when we register a non-Referenceable? We don't really
     # need this yet, but as registerReference() becomes more generalized
     # into just plain register(), we'll want to provide references to
     # Copyables and ordinary data structures too. Let's just test that
     # this doesn't cause an error.
     target = []
     tub = Tub()
     tub.setLocation("bogus:1234567")
     url = tub.registerReference(target)
     del url
예제 #32
0
def new_tahoe_configuration(deploy_config, bucketname, key_prefix, publichost, privatehost, introducer_port, storageserver_port):
    """
    Create brand new secrets and configuration for use by an
    introducer/storage pair.
    """
    base_name = dict(
        organizationName=b"Least Authority Enterprises",
        organizationalUnitName=b"S4",
        emailAddress=bucketname,
    )

    keypair = KeyPair.generate(size=2048)
    introducer_certificate = keypair.selfSignedCert(
        serialNumber=1,
        commonName=b"introducer",
        **base_name
    )
    storage_certificate = keypair.selfSignedCert(
        serialNumber=1,
        commonName=b"storage",
        **base_name
    )
    def pem(key, cert):
        return b"\n".join((key.dump(FILETYPE_PEM), cert.dump(FILETYPE_PEM)))

    introducer_tub = Tub(certData=pem(keypair, introducer_certificate))
    introducer_tub.setLocation("{}:{}".format(publichost, introducer_port))
    storage_tub = Tub(certData=pem(keypair, storage_certificate))

    return marshal_tahoe_configuration(
        introducer_pem=introducer_tub.getCertData().strip(),

        storage_pem=storage_tub.getCertData().strip(),
        storage_privkey=keyutil.make_keypair()[0] + b"\n",

        introducer_port=introducer_port,
        storageserver_port=storageserver_port,

        bucket_name=bucketname,
        key_prefix=key_prefix,
        publichost=publichost,
        privatehost=privatehost,
        # The object of the reference is irrelevant.  The furl will
        # get hooked up to something else when Tahoe really runs.
        # Just need to pass something _weak referenceable_!  Which
        # rules out a lot of things...
        introducer_furl=introducer_tub.registerReference(introducer_tub),

        s3_access_key_id=deploy_config.s3_access_key_id,
        s3_secret_key=deploy_config.s3_secret_key,

        log_gatherer_furl=deploy_config.log_gatherer_furl,
        stats_gatherer_furl=deploy_config.stats_gatherer_furl,
    )
예제 #33
0
 def TODO_testNonweakrefable(self):
     # what happens when we register a non-Referenceable? We don't really
     # need this yet, but as registerReference() becomes more generalized
     # into just plain register(), we'll want to provide references to
     # Copyables and ordinary data structures too. Let's just test that
     # this doesn't cause an error.
     target = []
     tub = Tub()
     tub.setLocation("bogus:1234567")
     url = tub.registerReference(target)
     del url
예제 #34
0
 def createSpecificServer(self, certData,
                          negotiationClass=negotiate.Negotiation):
     tub = Tub(certData=certData)
     tub.negotiationClass = negotiationClass
     tub.startService()
     self.services.append(tub)
     portnum = allocate_tcp_port()
     tub.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
     tub.setLocation("127.0.0.1:%d" % portnum)
     target = Target()
     return tub, target, tub.registerReference(target), portnum
예제 #35
0
def makeService(config, reactor=reactor):
    parent = MultiService()
    basedir = FilePath(os.path.expanduser(config["basedir"]))
    basedir.makedirs(ignoreExistingDirectory=True)
    basedir.chmod(0o700)

    data = Data(basedir.child("config.json"))

    certFile = basedir.child("tub.data").path
    tub = Tub(certFile=certFile)
    tub.setOption("keepaliveTimeout", 60) # ping after 60s of idle
    tub.setOption("disconnectTimeout", 5*60) # disconnect/reconnect after 5m
    tub.listenOn("tcp:6319:interface=127.0.0.1")
    tub.setLocation("tcp:127.0.0.1:6319")
    tub.setServiceParent(parent)

    acme_path = basedir.asTextMode()
    acme_key = maybe_key(acme_path)
    cert_store = FlancerCertificateStore(data, basedir)
    staging = not config["really"]
    if staging:
        print("STAGING mode")
        le_url = LETSENCRYPT_STAGING_DIRECTORY
    else:
        print("REAL CERTIFICATE mode")
        le_url = LETSENCRYPT_DIRECTORY
    client_creator = partial(Client.from_url, reactor=reactor,
                             url=le_url,
                             key=acme_key, alg=RS256)
    r = FlancerResponder(tub, data)
    issuer = AcmeIssuingService(cert_store, client_creator, reactor, [r])
    issuer.setServiceParent(parent)

    if "dyndns_furl" in data:
        start_dyndns_canary(tub, data["dyndns_furl"].encode("ascii"))

    c = Controller(tub, data, issuer)
    tub.registerReference(c, furlFile=basedir.child("controller.furl").path)

    #TimerService(5*60.0, f.timerUpdateStats).setServiceParent(parent)
    return parent
예제 #36
0
 def createDuplicateServer(self, oldtub):
     tub = Tub(certData=oldtub.getCertData())
     tub.startService()
     self.services.append(tub)
     tub.incarnation = oldtub.incarnation
     tub.incarnation_string = oldtub.incarnation_string
     tub.slave_table = oldtub.slave_table.copy()
     tub.master_table = oldtub.master_table.copy()
     l = tub.listenOn("tcp:0")
     tub.setLocation("127.0.0.1:%d" % l.getPortnum())
     target = Target()
     return tub, target, tub.registerReference(target), l.getPortnum()
예제 #37
0
 def createDuplicateServer(self, oldtub):
     tub = Tub(certData=oldtub.getCertData())
     tub.startService()
     self.services.append(tub)
     tub.incarnation = oldtub.incarnation
     tub.incarnation_string = oldtub.incarnation_string
     tub.slave_table = oldtub.slave_table.copy()
     tub.master_table = oldtub.master_table.copy()
     l = tub.listenOn("tcp:0")
     tub.setLocation("127.0.0.1:%d" % l.getPortnum())
     target = Target()
     return tub, target, tub.registerReference(target), l.getPortnum()
예제 #38
0
 def test_duplicate(self):
     basedir = "test_registration"
     os.makedirs(basedir)
     ff = os.path.join(basedir, "duplicate.furl")
     t1 = HelperTarget()
     tub = Tub()
     tub.setLocation("bogus:1234567")
     u1 = tub.registerReference(t1, "name", furlFile=ff)
     u2 = tub.registerReference(t1, "name", furlFile=ff)
     self.failUnlessEqual(u1, u2)
     self.failUnlessRaises(WrongNameError,
                           tub.registerReference, t1, "newname", furlFile=ff)
예제 #39
0
 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
예제 #40
0
 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
예제 #41
0
 def test_duplicate(self):
     basedir = "test_registration"
     os.makedirs(basedir)
     ff = os.path.join(basedir, "duplicate.furl")
     t1 = HelperTarget()
     tub = Tub()
     tub.setLocation("bogus:1234567")
     u1 = tub.registerReference(t1, "name", furlFile=ff)
     u2 = tub.registerReference(t1, "name", furlFile=ff)
     self.failUnlessEqual(u1, u2)
     self.failUnlessRaises(WrongNameError,
                           tub.registerReference,
                           t1,
                           "newname",
                           furlFile=ff)
예제 #42
0
    def test_referenceable(self):
        t1 = Tub()
        t1.setServiceParent(self.s)

        portnum = allocate_tcp_port()

        t1.listenOn('tcp:%d:interface=127.0.0.1' % portnum)
        t1.setLocation('127.0.0.1:%d' % portnum)

        r1 = Referenceable()

        # the serialized blob can't keep the reference alive, so you must
        # arrange for that separately

        t1.registerReference(r1)

        t2 = Tub()
        t2.setServiceParent(self.s)

        obj = ('graph tangly', r1)
        d = t1.serialize(obj)

        del r1, obj

        def _done(data):
            self.assertIn(b'their-reference', data)
            return data

        d.addCallback(_done)
        d.addCallback(t2.unserialize)

        def _check(obj2):
            self.assertEqual(obj2[0], 'graph tangly')
            self.assertTrue(isinstance(obj2[1], RemoteReference))

        return d.addCallback(_check)
예제 #43
0
class Failed(unittest.TestCase):
    def setUp(self):
        self.services = []

    def tearDown(self):
        d = defer.DeferredList([s.stopService() for s in self.services])
        d.addCallback(flushEventualQueue)
        return d

    @defer.inlineCallbacks
    def test_bad_hints(self):
        self.tubA = Tub()
        self.tubA.startService()
        self.services.append(self.tubA)
        self.tubB = Tub()
        self.tubB.startService()
        self.services.append(self.tubB)
        portnum = allocate_tcp_port()
        self.tubB.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
        bad1 = "no-colon"
        bad2 = "unknown:foo"
        bad3 = "tcp:300.300.300.300:333"
        self.tubB.setLocation(bad1, bad2, bad3)

        target = HelperTarget("bob")
        url = self.tubB.registerReference(target)
        rc = self.tubA.connectTo(url, None)
        ri = rc.getReconnectionInfo()
        self.assertEqual(ri.state, "connecting")

        d = defer.Deferred()
        reactor.callLater(1.0, d.callback, None)
        yield d

        # now look at the details
        ri = rc.getReconnectionInfo()
        self.assertEqual(ri.state, "waiting")
        ci = ri.connectionInfo
        self.assertEqual(ci.connected, False)
        self.assertEqual(ci.winningHint, None)
        s = ci.connectorStatuses
        self.assertEqual(set(s.keys()), set([bad1, bad2, bad3]))
        self.assertEqual(s[bad1], "bad hint: no colon")
        self.assertEqual(s[bad2], "bad hint: no handler registered")
        self.assertIn("DNS lookup failed", s[bad3])
        ch = ci.connectionHandlers
        self.assertEqual(ch, {bad2: None, bad3: "tcp"})
예제 #44
0
class TubFailures(ExamineFailuresMixin, ShouldFailMixin, unittest.TestCase):
    def setUp(self):
        self.s = service.MultiService()
        self.s.startService()
        self.target_tub = Tub()
        self.target_tub.setServiceParent(self.s)
        l = self.target_tub.listenOn("tcp:0:interface=127.0.0.1")
        self.target_tub.setLocation("127.0.0.1:%d" % l.getPortnum())
        self.source_tub = Tub()
        self.source_tub.setServiceParent(self.s)

    def tearDown(self):
        return self.s.stopService()

    def setupTarget(self, target):
        furl = self.target_tub.registerReference(target)
        d = self.source_tub.getReference(furl)
        return d


    def test_raise_not_exposed(self):
        self.source_tub.setOption("expose-remote-exception-types", False)
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr:
                      self.shouldFail(RemoteException, "one", None,
                                      rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, True)
        return d

    def test_raise_yes_exposed(self):
        self.source_tub.setOption("expose-remote-exception-types", True)
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr:
                      self.shouldFail(ValueError, "one", None,
                                      rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, False)
        return d

    def test_raise_default(self):
        # current default is to expose exceptions. This may change in the
        # future.
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr:
                      self.shouldFail(ValueError, "one", None,
                                      rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, False)
        return d
예제 #45
0
 def makeTub(self, hint_type, listener_test_options={}, extra_hint=None):
     tubA = Tub(certData=certData_low)
     tubA.setServiceParent(self.s)
     tubB = Tub(certData=certData_high)
     tubB.setServiceParent(self.s)
     self._tubA, self._tubB = tubA, tubB
     portnum = util.allocate_tcp_port()
     self._portnum = portnum
     port = "tcp:%d:interface=127.0.0.1" % portnum
     hint = "%s:127.0.0.1:%d" % (hint_type, portnum)
     if extra_hint:
         hint = hint + "," + extra_hint
     tubA.listenOn(port, _test_options=listener_test_options)
     tubA.setLocation(hint)
     self._target = Target()
     furl = tubA.registerReference(self._target)
     return furl, tubB, hint
예제 #46
0
 def makeTub(self, hint_type, listener_test_options={}, extra_hint=None):
     tubA = Tub(certData=certData_low)
     tubA.setServiceParent(self.s)
     tubB = Tub(certData=certData_high)
     tubB.setServiceParent(self.s)
     self._tubA, self._tubB = tubA, tubB
     portnum = util.allocate_tcp_port()
     self._portnum = portnum
     port = "tcp:%d:interface=127.0.0.1" % portnum
     hint = "%s:127.0.0.1:%d" % (hint_type, portnum)
     if extra_hint:
         hint = hint + "," + extra_hint
     tubA.listenOn(port, _test_options=listener_test_options)
     tubA.setLocation(hint)
     self._target = Target()
     furl = tubA.registerReference(self._target)
     return furl, tubB, hint
예제 #47
0
class Failed(unittest.TestCase):
    def setUp(self):
        self.services = []
    def tearDown(self):
        d = defer.DeferredList([s.stopService() for s in self.services])
        d.addCallback(flushEventualQueue)
        return d

    @defer.inlineCallbacks
    def test_bad_hints(self):
        self.tubA = Tub()
        self.tubA.startService()
        self.services.append(self.tubA)
        self.tubB = Tub()
        self.tubB.startService()
        self.services.append(self.tubB)
        portnum = allocate_tcp_port()
        self.tubB.listenOn("tcp:%d:interface=127.0.0.1" % portnum)
        bad1 = "no-colon"
        bad2 = "unknown:foo"
        bad3 = "tcp:300.300.300.300:333"
        self.tubB.setLocation(bad1, bad2, bad3)

        target = HelperTarget("bob")
        url = self.tubB.registerReference(target)
        rc = self.tubA.connectTo(url, None)
        ri = rc.getReconnectionInfo()
        self.assertEqual(ri.state, "connecting")

        d = defer.Deferred()
        reactor.callLater(1.0, d.callback, None)
        yield d

        # now look at the details
        ri = rc.getReconnectionInfo()
        self.assertEqual(ri.state, "waiting")
        ci = ri.connectionInfo
        self.assertEqual(ci.connected, False)
        self.assertEqual(ci.winningHint, None)
        s = ci.connectorStatuses
        self.assertEqual(set(s.keys()), set([bad1, bad2, bad3]))
        self.assertEqual(s[bad1], "bad hint: no colon")
        self.assertEqual(s[bad2], "bad hint: no handler registered")
        self.assertIn("DNS lookup failed", s[bad3])
        ch = ci.connectionHandlers
        self.assertEqual(ch, {bad2: None, bad3: "tcp"})
예제 #48
0
 def testStrong(self):
     t1 = HelperTarget()
     tub = Tub()
     tub.setLocation("bogus:1234567")
     u1 = tub.registerReference(t1)
     del u1
     results = []
     w1 = weakref.ref(t1, results.append)
     del t1
     gc.collect()
     # t1 should still be alive
     self.failUnless(w1())
     self.failUnlessEqual(results, [])
     tub.unregisterReference(w1())
     gc.collect()
     # now it should be dead
     self.failIf(w1())
     self.failUnlessEqual(len(results), 1)
예제 #49
0
 def testStrong(self):
     t1 = HelperTarget()
     tub = Tub()
     tub.setLocation("bogus:1234567")
     u1 = tub.registerReference(t1)
     del u1
     results = []
     w1 = weakref.ref(t1, results.append)
     del t1
     gc.collect()
     # t1 should still be alive
     self.failUnless(w1())
     self.failUnlessEqual(results, [])
     tub.unregisterReference(w1())
     gc.collect()
     # now it should be dead
     self.failIf(w1())
     self.failUnlessEqual(len(results), 1)
예제 #50
0
class TubFailures(ExamineFailuresMixin, ShouldFailMixin, unittest.TestCase):
    def setUp(self):
        self.s = service.MultiService()
        self.s.startService()
        self.target_tub = Tub()
        self.target_tub.setServiceParent(self.s)
        l = self.target_tub.listenOn("tcp:0:interface=127.0.0.1")
        self.target_tub.setLocation("127.0.0.1:%d" % l.getPortnum())
        self.source_tub = Tub()
        self.source_tub.setServiceParent(self.s)

    def tearDown(self):
        return self.s.stopService()

    def setupTarget(self, target):
        furl = self.target_tub.registerReference(target)
        d = self.source_tub.getReference(furl)
        return d

    def test_raise_not_exposed(self):
        self.source_tub.setOption("expose-remote-exception-types", False)
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr: self.shouldFail(RemoteException, "one", None,
                                                 rr.callRemote, "fail"))
        d.addCallback(self._examine_raise, True)
        return d

    def test_raise_yes_exposed(self):
        self.source_tub.setOption("expose-remote-exception-types", True)
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr: self.shouldFail(ValueError, "one", None, rr.
                                                 callRemote, "fail"))
        d.addCallback(self._examine_raise, False)
        return d

    def test_raise_default(self):
        # current default is to expose exceptions. This may change in the
        # future.
        d = self.setupTarget(TargetWithoutInterfaces())
        d.addCallback(lambda rr: self.shouldFail(ValueError, "one", None, rr.
                                                 callRemote, "fail"))
        d.addCallback(self._examine_raise, False)
        return d
예제 #51
0
파일: tap.py 프로젝트: warner/flancer
def makeService(config, reactor=reactor):
    parent = MultiService()
    basedir = FilePath(os.path.expanduser(config["basedir"]))
    basedir.makedirs(ignoreExistingDirectory=True)
    basedir.chmod(0o700)

    data = Data(basedir.child("config.json"))

    dns_server = DNSServerFactory(verbose=0)
    s1 = UDPServer(int(config["dns-port"]), dns.DNSDatagramProtocol(dns_server),
                   interface=config["dns-interface"])
    s1.setServiceParent(parent)
    s2 = TCPServer(int(config["dns-port"]), dns_server,
                   interface=config["dns-interface"])
    s2.setServiceParent(parent)

    s = Server(data, dns_server)
    s.update_records()

    certFile = basedir.child("tub.data").path
    #furlFile = basedir.child("server.furl").path
    t = Tub(certFile=certFile)
    t.setOption("keepaliveTimeout", 60) # ping after 60s of idle
    t.setOption("disconnectTimeout", 5*60) # disconnect/reconnect after 5m
    #t.setOption("logLocalFailures", True)
    #t.setOption("logRemoteFailures", True)
    #t.unsafeTracebacks = True
    fp = config["foolscap-port"]
    if not fp.startswith("tcp:"):
        raise usage.UsageError("I don't know how to handle non-tcp foolscap-port=")
    port = int(fp.split(":")[1])
    assert port > 1
    t.listenOn(fp)
    t.setLocation("tcp:%s:%d" % (config["hostname"], port))

    c = Controller(data, s)
    cf = t.registerReference(c, furlFile=basedir.child("controller.furl").path)
    furl_prefix = cf[:cf.rfind("/")+1]
    c.set_furl_prefix(furl_prefix)
    t.registerNameLookupHandler(c.lookup)

    t.setServiceParent(parent)
    return parent
예제 #52
0
 def testConnectAuthenticated(self):
     tub = Tub()
     self.startTub(tub)
     target = HelperTarget("bob")
     target.obj = "unset"
     url = tub.registerReference(target)
     # can we connect to a reference on our own Tub?
     d = tub.getReference(url)
     def _connected(ref):
         return ref.callRemote("set", 12)
     d.addCallback(_connected)
     def _check(res):
         self.failUnlessEqual(target.obj, 12)
     d.addCallback(_check)
     def _connect_again(res):
         target.obj = None
         return tub.getReference(url)
     d.addCallback(_connect_again)
     d.addCallback(_connected)
     d.addCallback(_check)
     return d
예제 #53
0
    def test_empty_location(self):
        # bug #129: a FURL with no location hints causes a synchronous
        # exception in Tub.getReference(), instead of an errback'ed Deferred.

        tubA = Tub()
        tubA.setServiceParent(self.s)
        tubB = Tub()
        tubB.setServiceParent(self.s)

        tubB.setLocation("") # this is how you say "unrouteable"
        r = Receiver(tubB)
        furl = tubB.registerReference(r)
        # the buggy behavior is that the following call raises an exception
        d = tubA.getReference(furl)
        # whereas it ought to return a Deferred
        self.failUnless(isinstance(d, defer.Deferred))
        def _check(f):
            self.failUnless(isinstance(f, failure.Failure), f)
            self.failUnless(f.check(NoLocationHintsError), f)
        d.addBoth(_check)
        return d
예제 #54
0
파일: test_tub.py 프로젝트: sajith/foolscap
    def test_future(self):
        tubA = Tub()
        tubA.setServiceParent(self.s)
        tubB = Tub()
        tubB.setServiceParent(self.s)

        # "future:stuff" is interpreted as a "location hint format from the
        # future", which we're supposed to ignore, and are thus left with no
        # hints
        tubB.setLocation("future:stuff")
        r = Receiver(tubB)
        furl = tubB.registerReference(r)
        # the buggy behavior is that the following call raises an exception
        d = tubA.getReference(furl)
        # whereas it ought to return a Deferred
        self.assertTrue(isinstance(d, defer.Deferred))
        def _check(f):
            self.assertTrue(isinstance(f, failure.Failure), f)
            self.assertTrue(f.check(NoLocationHintsError), f)
        d.addBoth(_check)
        return d
예제 #55
0
    def test_future(self):
        tubA = Tub()
        tubA.setServiceParent(self.s)
        tubB = Tub()
        tubB.setServiceParent(self.s)

        # "future:stuff" is interpreted as a "location hint format from the
        # future", which we're supposed to ignore, and are thus left with no
        # hints
        tubB.setLocation("future:stuff")
        r = Receiver(tubB)
        furl = tubB.registerReference(r)
        # the buggy behavior is that the following call raises an exception
        d = tubA.getReference(furl)
        # whereas it ought to return a Deferred
        self.failUnless(isinstance(d, defer.Deferred))
        def _check(f):
            self.failUnless(isinstance(f, failure.Failure), f)
            self.failUnless(f.check(NoLocationHintsError), f)
        d.addBoth(_check)
        return d
예제 #56
0
    def test_lose_and_retry(self):
        tubC = Tub(self.tubB.getCertData())
        connects = []
        d1 = defer.Deferred()
        d2 = defer.Deferred()
        notifiers = [d1, d2]
        target = HelperTarget("bob")
        url = self.tubB.registerReference(target, "target")
        portb = self.tub_ports[1]
        rc = self.tubA.connectTo(url, self._connected, notifiers, connects)
        yield d1
        self.assertEqual(rc.getReconnectionInfo().state, "connected")
        # we are now connected to tubB. Shut it down to force a disconnect.
        self.services.remove(self.tubB)
        yield self.tubB.stopService()

        # wait for at least one retry
        yield self.poll(lambda: rc.getReconnectionInfo().state == "waiting")

        # wait a few seconds more to give the Reconnector a chance to try and
        # fail a few times. It isn't easy to catch the "connecting" state since
        # the target is local and the kernel knows that it's not listening.
        # TODO: add an internal retry counter to the Reconnector that we can
        # poll for tests.
        yield self.stall(2)

        # now start tubC listening on the same port that tubB used to,
        # which should allow the connection to complete (since they both
        # use the same certData)
        self.services.append(tubC)
        tubC.startService()
        tubC.listenOn("tcp:%d:interface=127.0.0.1" % portb)
        tubC.setLocation("tcp:127.0.0.1:%d" % portb)
        url2 = tubC.registerReference(target, "target")
        assert url2 == url
        # this will fire when the second connection has been made
        yield d2

        self.failUnlessEqual(len(connects), 2)
        rc.stopConnecting()
예제 #57
0
    def test_empty_location(self):
        # bug #129: a FURL with no location hints causes a synchronous
        # exception in Tub.getReference(), instead of an errback'ed Deferred.

        tubA = Tub()
        tubA.setServiceParent(self.s)
        tubB = Tub()
        tubB.setServiceParent(self.s)

        # This is a hack to get a FURL with empty location hints. The correct
        # way to make a Tub unreachable is to not call .setLocation() at all.
        tubB.setLocation("")
        r = Receiver(tubB)
        furl = tubB.registerReference(r)
        # the buggy behavior is that the following call raises an exception
        d = tubA.getReference(furl)
        # whereas it ought to return a Deferred
        self.failUnless(isinstance(d, defer.Deferred))
        def _check(f):
            self.failUnless(isinstance(f, failure.Failure), f)
            self.failUnless(f.check(NoLocationHintsError), f)
        d.addBoth(_check)
        return d
예제 #58
0
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)