mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2024-12-21 05:53:12 +00:00
96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
|
|
from twisted.application import service
|
|
import os.path
|
|
from foolscap import Tub
|
|
from allmydata.util.iputil import get_local_ip_for
|
|
from allmydata.util import idlib
|
|
from twisted.python import log
|
|
|
|
class Node(service.MultiService):
|
|
# this implements common functionality of both Client nodes and the Queen
|
|
# node.
|
|
NODETYPE = "unknown NODETYPE"
|
|
PORTNUMFILE = None
|
|
CERTFILE = None
|
|
LOCAL_IP_FILE = "local_ip"
|
|
NODEIDFILE = "my_nodeid"
|
|
|
|
def __init__(self, basedir="."):
|
|
service.MultiService.__init__(self)
|
|
self.basedir = os.path.abspath(basedir)
|
|
assert self.CERTFILE, "Your node.Node subclass must provide CERTFILE"
|
|
certfile = os.path.join(self.basedir, self.CERTFILE)
|
|
if os.path.exists(certfile):
|
|
f = open(certfile, "rb")
|
|
self.tub = Tub(certData=f.read())
|
|
f.close()
|
|
else:
|
|
self.tub = Tub()
|
|
f = open(certfile, "wb")
|
|
f.write(self.tub.getCertData())
|
|
f.close()
|
|
self.nodeid = idlib.a2b(self.tub.tubID)
|
|
f = open(os.path.join(self.basedir, self.NODEIDFILE), "w")
|
|
f.write(idlib.b2a(self.nodeid) + "\n")
|
|
f.close()
|
|
self.short_nodeid = self.tub.tubID[:4] # ready for printing
|
|
portnum = 0
|
|
assert self.PORTNUMFILE, "Your node.Node subclass must provide PORTNUMFILE"
|
|
self._portnumfile = os.path.join(self.basedir, self.PORTNUMFILE)
|
|
if os.path.exists(self._portnumfile):
|
|
portnum = int(open(self._portnumfile, "r").read())
|
|
self.tub.listenOn("tcp:%d" % portnum)
|
|
# we must wait until our service has started before we can find out
|
|
# our IP address and thus do tub.setLocation, and we can't register
|
|
# any services with the Tub until after that point
|
|
self.tub.setServiceParent(self)
|
|
|
|
AUTHKEYSFILEBASE = "authorized_keys."
|
|
for f in os.listdir(self.basedir):
|
|
if f.startswith(AUTHKEYSFILEBASE):
|
|
keyfile = os.path.join(self.basedir, f)
|
|
portnum = int(f[len(AUTHKEYSFILEBASE):])
|
|
from allmydata import manhole
|
|
m = manhole.AuthorizedKeysManhole(portnum, keyfile)
|
|
m.setServiceParent(self)
|
|
self.log("AuthorizedKeysManhole listening on %d" % portnum)
|
|
|
|
def log(self, msg):
|
|
log.msg(self.short_nodeid + ": " + msg)
|
|
|
|
def _setup_tub(self, local_ip):
|
|
# we can't get a dynamically-assigned portnum until our Tub is
|
|
# running, which means after startService.
|
|
l = self.tub.getListeners()[0]
|
|
portnum = l.getPortnum()
|
|
local_ip_filename = os.path.join(self.basedir, self.LOCAL_IP_FILE)
|
|
if os.path.exists(local_ip_filename):
|
|
f = open(local_ip_filename, "r")
|
|
local_ip = f.read()
|
|
f.close()
|
|
self.tub.setLocation("%s:%d" % (local_ip, portnum))
|
|
if not os.path.exists(self._portnumfile):
|
|
# record which port we're listening on, so we can grab the same
|
|
# one next time
|
|
f = open(self._portnumfile, "w")
|
|
f.write("%d\n" % portnum)
|
|
f.close()
|
|
self.tub.setLocation("%s:%d" % (local_ip, l.getPortnum()))
|
|
return self.tub
|
|
|
|
def tub_ready(self):
|
|
# called when the Tub is available for registerReference
|
|
pass
|
|
|
|
def add_service(self, s):
|
|
s.setServiceParent(self)
|
|
return s
|
|
|
|
def startService(self):
|
|
# note: this class can only be started and stopped once.
|
|
service.MultiService.startService(self)
|
|
local_ip = get_local_ip_for()
|
|
self._setup_tub(local_ip)
|
|
self.tub_ready()
|
|
self.log("%s running" % self.NODETYPE)
|