From d146ef7e09618c4072ee86b092018c85c99eba9d Mon Sep 17 00:00:00 2001 From: Brian Warner <warner@allmydata.com> Date: Tue, 5 Feb 2008 17:32:27 -0700 Subject: [PATCH] webish: add extra introducer data (version, timestamps) to Welcome page --- src/allmydata/interfaces.py | 1 + src/allmydata/introducer.py | 12 +++--- src/allmydata/test/test_system.py | 6 +-- src/allmydata/test/test_web.py | 11 +++++- src/allmydata/web/welcome.xhtml | 17 ++++++-- src/allmydata/webish.py | 65 ++++++++++++++++++++++--------- 6 files changed, 79 insertions(+), 33 deletions(-) diff --git a/src/allmydata/interfaces.py b/src/allmydata/interfaces.py index b9e50abc..1c7276ce 100644 --- a/src/allmydata/interfaces.py +++ b/src/allmydata/interfaces.py @@ -123,6 +123,7 @@ class IIntroducerClient(Interface): trying to connect to. Each RemoteServiceConnector has the following public attributes:: + service_name: the type of service provided, like 'storage' announcement_time: when we first heard about this service last_connect_time: when we last established a connection last_loss_time: when we last lost a connection diff --git a/src/allmydata/introducer.py b/src/allmydata/introducer.py index c8f70720..7519ec4a 100644 --- a/src/allmydata/introducer.py +++ b/src/allmydata/introducer.py @@ -113,7 +113,7 @@ class RemoteServiceConnector: self._nodeid_s = idlib.shortnodeid_b2a(self._nodeid) self._index = (self._nodeid, service_name) - self._service_name = service_name + self.service_name = service_name self.log("attempting to connect to %s" % self._nodeid_s) self.announcement_time = time.time() @@ -121,8 +121,8 @@ class RemoteServiceConnector: self.rref = None self.remote_host = None self.last_connect_time = None - self.version = None - self.oldest_supported = None + self.version = ver + self.oldest_supported = oldest def log(self, *args, **kwargs): return self._ic.log(*args, **kwargs) @@ -138,12 +138,12 @@ class RemoteServiceConnector: def _got_service(self, rref): self.last_connect_time = time.time() - self.remote_host = str(rref.tracker.broker.transport.getPeer()) + self.remote_host = rref.tracker.broker.transport.getPeer() self.rref = rref self.log("connected to %s" % self._nodeid_s) - self._ic.add_connection(self._nodeid, self._service_name, rref) + self._ic.add_connection(self._nodeid, self.service_name, rref) rref.notifyOnDisconnect(self._lost, rref) @@ -152,7 +152,7 @@ class RemoteServiceConnector: self.last_loss_time = time.time() self.rref = None self.remote_host = None - self._ic.remove_connection(self._nodeid, self._service_name, rref) + self._ic.remove_connection(self._nodeid, self.service_name, rref) diff --git a/src/allmydata/test/test_system.py b/src/allmydata/test/test_system.py index a9c90d68..15a7c62c 100644 --- a/src/allmydata/test/test_system.py +++ b/src/allmydata/test/test_system.py @@ -1023,10 +1023,10 @@ class SystemTest(testutil.SignalMixin, testutil.PollMixin, unittest.TestCase): public = "uri/" + self._root_directory_uri d = getPage(base) def _got_welcome(page): - expected = "Connected Peers: <span>%d</span>" % (self.numclients) + expected = "Connected Storage Servers: <span>%d</span>" % (self.numclients) self.failUnless(expected in page, - "I didn't see the right 'connected peers' message " - "in: %s" % page + "I didn't see the right 'connected storage servers'" + " message in: %s" % page ) expected = "My nodeid: <span>%s</span>" % (b32encode(self.clients[0].nodeid).lower(),) self.failUnless(expected in page, diff --git a/src/allmydata/test/test_web.py b/src/allmydata/test/test_web.py index 6d241e90..374d336a 100644 --- a/src/allmydata/test/test_web.py +++ b/src/allmydata/test/test_web.py @@ -13,6 +13,14 @@ from allmydata.interfaces import IURI, INewDirectoryURI, IReadonlyNewDirectoryUR # create a fake uploader/downloader, and a couple of fake dirnodes, then # create a webserver that works against them +class FakeIntroducerClient: + def get_all_connectors(self): + return {} + def get_all_connections_for(self, service_name): + return frozenset() + def get_all_peerids(self): + return frozenset() + class FakeClient(service.MultiService): nodeid = "fake_nodeid" basedir = "fake_basedir" @@ -23,10 +31,9 @@ class FakeClient(service.MultiService): 'zfec': "fake", } introducer_furl = "None" + introducer_client = FakeIntroducerClient() def connected_to_introducer(self): return False - def get_all_peerids(self): - return [] def create_node_from_uri(self, uri): u = IURI(uri) diff --git a/src/allmydata/web/welcome.xhtml b/src/allmydata/web/welcome.xhtml index 73ad3c9d..cf32acb8 100644 --- a/src/allmydata/web/welcome.xhtml +++ b/src/allmydata/web/welcome.xhtml @@ -25,15 +25,26 @@ tool</a> may also be useful.</div> <div>Helper: <span n:render="string" n:data="helper_furl" /></div> <div>Connected to helper?: <span n:render="string" n:data="connected_to_helper" /></div> -<div>Known+Connected Peers: <span n:render="string" n:data="num_peers" /></div> +<div>Known Storage Servers: <span n:render="string" n:data="known_storage_servers" /></div> +<div>Connected Storage Servers: <span n:render="string" n:data="connected_storage_servers" /></div> <div> -<table n:render="sequence" n:data="peers" border="1"> +<table n:render="sequence" n:data="services" border="1"> <tr n:pattern="header"> <td>PeerID</td> + <td>Connected?</td> + <td>Since</td> + <td>Announced</td> + <td>Version</td> + <td>Service Name</td> </tr> - <tr n:pattern="item" n:render="row"> + <tr n:pattern="item" n:render="service_row"> <td><tt><n:slot name="peerid"/></tt></td> + <td><tt><n:slot name="connected"/></tt></td> + <td><tt><n:slot name="since"/></tt></td> + <td><tt><n:slot name="announced"/></tt></td> + <td><tt><n:slot name="version"/></tt></td> + <td><tt><n:slot name="service_name"/></tt></td> </tr> <tr n:pattern="empty"><td>no peers!</td></tr> </table> diff --git a/src/allmydata/webish.py b/src/allmydata/webish.py index 71b524c8..f4d426a8 100644 --- a/src/allmydata/webish.py +++ b/src/allmydata/webish.py @@ -1,14 +1,13 @@ -from base64 import b32encode -import os.path +import time, os.path from twisted.application import service, strports, internet from twisted.web import static, resource, server, html, http from twisted.python import log -from twisted.internet import defer +from twisted.internet import defer, address from twisted.internet.interfaces import IConsumer from nevow import inevow, rend, loaders, appserver, url, tags as T from nevow.static import File as nevow_File # TODO: merge with static.File? -from allmydata.util import fileutil +from allmydata.util import fileutil, idlib import simplejson from allmydata.interfaces import IDownloadTarget, IDirectoryNode, IFileNode, \ IMutableFileNode @@ -1314,7 +1313,7 @@ class Root(rend.Page): return get_package_versions_string() def data_my_nodeid(self, ctx, data): - return b32encode(IClient(ctx).nodeid).lower() + return idlib.nodeid_b2a(IClient(ctx).nodeid) def data_introducer_furl(self, ctx, data): return IClient(ctx).introducer_furl def data_connected_to_introducer(self, ctx, data): @@ -1339,22 +1338,50 @@ class Root(rend.Page): return "yes" return "no" - def data_num_peers(self, ctx, data): - #client = inevow.ISite(ctx)._client - client = IClient(ctx) - return len(list(client.get_all_peerids())) + def data_known_storage_servers(self, ctx, data): + ic = IClient(ctx).introducer_client + servers = [c + for c in ic.get_all_connectors().values() + if c.service_name == "storage"] + return len(servers) + + def data_connected_storage_servers(self, ctx, data): + ic = IClient(ctx).introducer_client + return len(ic.get_all_connections_for("storage")) + + def data_services(self, ctx, data): + ic = IClient(ctx).introducer_client + c = [ (service_name, nodeid, rsc) + for (nodeid, service_name), rsc + in ic.get_all_connectors().items() ] + c.sort() + return c + + def render_service_row(self, ctx, data): + (service_name, nodeid, rsc) = data + ctx.fillSlots("peerid", idlib.nodeid_b2a(nodeid)) + if rsc.rref: + rhost = rsc.remote_host + if nodeid == IClient(ctx).nodeid: + rhost_s = "(loopback)" + elif isinstance(rhost, address.IPv4Address): + rhost_s = "%s:%d" % (rhost.host, rhost.port) + else: + rhost_s = str(rhost) + connected = "Yes: to " + rhost_s + since = rsc.last_connect_time + else: + connected = "No" + since = rsc.last_loss_time - def data_peers(self, ctx, data): - d = [] - client = IClient(ctx) - for nodeid in sorted(client.get_all_peerids()): - row = (b32encode(nodeid).lower(),) - d.append(row) - return d + TIME_FORMAT = "%H:%M:%S %d-%b-%Y" + ctx.fillSlots("connected", connected) + ctx.fillSlots("since", time.strftime(TIME_FORMAT, time.localtime(since))) + ctx.fillSlots("announced", time.strftime(TIME_FORMAT, + time.localtime(rsc.announcement_time))) + ctx.fillSlots("version", rsc.version) + ctx.fillSlots("service_name", rsc.service_name) - def render_row(self, ctx, data): - (nodeid_a,) = data - ctx.fillSlots("peerid", nodeid_a) return ctx.tag # this is a form where users can download files by URI -- 2.45.2