2 from twisted.application import service
4 from foolscap import Tub
5 from allmydata.util.iputil import get_local_addresses
6 from allmydata.util import idlib
7 from twisted.python import log
9 class Node(service.MultiService):
10 # this implements common functionality of both Client nodes and the Queen
12 NODETYPE = "unknown NODETYPE"
15 LOCAL_IP_FILE = "local_ip"
16 NODEIDFILE = "my_nodeid"
18 def __init__(self, basedir="."):
19 service.MultiService.__init__(self)
20 self.basedir = os.path.abspath(basedir)
21 assert self.CERTFILE, "Your node.Node subclass must provide CERTFILE"
22 certfile = os.path.join(self.basedir, self.CERTFILE)
23 if os.path.exists(certfile):
24 f = open(certfile, "rb")
25 self.tub = Tub(certData=f.read())
29 f = open(certfile, "wb")
30 f.write(self.tub.getCertData())
32 self.nodeid = idlib.a2b(self.tub.tubID)
33 f = open(os.path.join(self.basedir, self.NODEIDFILE), "w")
34 f.write(idlib.b2a(self.nodeid) + "\n")
36 self.short_nodeid = self.tub.tubID[:4] # ready for printing
38 assert self.PORTNUMFILE, "Your node.Node subclass must provide PORTNUMFILE"
39 self._portnumfile = os.path.join(self.basedir, self.PORTNUMFILE)
40 if os.path.exists(self._portnumfile):
41 portnum = int(open(self._portnumfile, "r").read())
42 self.tub.listenOn("tcp:%d" % portnum)
43 # we must wait until our service has started before we can find out
44 # our IP address and thus do tub.setLocation, and we can't register
45 # any services with the Tub until after that point
46 self.tub.setServiceParent(self)
48 AUTHKEYSFILEBASE = "authorized_keys."
49 for f in os.listdir(self.basedir):
50 if f.startswith(AUTHKEYSFILEBASE):
51 keyfile = os.path.join(self.basedir, f)
52 portnum = int(f[len(AUTHKEYSFILEBASE):])
53 from allmydata import manhole
54 m = manhole.AuthorizedKeysManhole(portnum, keyfile)
55 m.setServiceParent(self)
56 self.log("AuthorizedKeysManhole listening on %d" % portnum)
59 log.msg(self.short_nodeid + ": " + msg)
61 def _setup_tub(self, local_addresses):
62 # we can't get a dynamically-assigned portnum until our Tub is
63 # running, which means after startService.
64 l = self.tub.getListeners()[0]
65 portnum = l.getPortnum()
66 local_ip_filename = os.path.join(self.basedir, self.LOCAL_IP_FILE)
67 if os.path.exists(local_ip_filename):
68 f = open(local_ip_filename, "r")
71 if local_ip not in local_addresses:
72 local_addresses.append(local_ip)
73 if not os.path.exists(self._portnumfile):
74 # record which port we're listening on, so we can grab the same
76 f = open(self._portnumfile, "w")
77 f.write("%d\n" % portnum)
79 location = ",".join(["%s:%d" % (ip, portnum)
80 for ip in local_addresses])
81 self.log("Tub location set to %s" % location)
82 self.tub.setLocation(location)
86 # called when the Tub is available for registerReference
89 def add_service(self, s):
90 s.setServiceParent(self)
93 def startService(self):
94 # note: this class can only be started and stopped once.
95 service.MultiService.startService(self)
96 local_addresses = get_local_addresses()
97 self._setup_tub(local_addresses)
99 self.log("%s running" % self.NODETYPE)