mirror of
https://github.com/tahoe-lafs/tahoe-lafs.git
synced 2025-01-23 04:48:43 +00:00
110 lines
3.3 KiB
Python
110 lines
3.3 KiB
Python
|
import json
|
||
|
from os.path import join
|
||
|
|
||
|
from twisted.python import usage
|
||
|
from twisted.internet import defer, reactor
|
||
|
|
||
|
from wormhole import wormhole
|
||
|
|
||
|
from allmydata.util import configutil
|
||
|
from allmydata.util.encodingutil import argv_to_abspath
|
||
|
from allmydata.scripts.common import get_default_nodedir, get_introducer_furl
|
||
|
|
||
|
|
||
|
class InviteOptions(usage.Options):
|
||
|
synopsis = "[options] <nickname>"
|
||
|
description = "Create a client-only Tahoe-LAFS node (no storage server)."
|
||
|
|
||
|
optParameters = [
|
||
|
("shares-needed", None, None, "How many shares are needed to reconstruct files from this node"),
|
||
|
("shares-happy", None, None, "Distinct storage servers new node will upload shares to"),
|
||
|
("shares-total", None, None, "Total number of shares new node will upload"),
|
||
|
]
|
||
|
|
||
|
def parseArgs(self, *args):
|
||
|
if len(args) != 1:
|
||
|
raise usage.UsageError(
|
||
|
"Provide a single argument: the new node's nickname"
|
||
|
)
|
||
|
self['nick'] = args[0].strip()
|
||
|
|
||
|
|
||
|
@defer.inlineCallbacks
|
||
|
def _send_config_via_wormhole(options, config):
|
||
|
out = options.stdout
|
||
|
err = options.stderr
|
||
|
relay_url = options.parent['wormhole-server']
|
||
|
print >>out, "Connecting to '{}'...".format(relay_url)
|
||
|
wh = wormhole.create(
|
||
|
appid=options.parent['wormhole-invite-appid'],
|
||
|
relay_url=relay_url,
|
||
|
reactor=reactor,
|
||
|
)
|
||
|
yield wh.get_welcome()
|
||
|
print >>out, "Connected to wormhole server"
|
||
|
|
||
|
# must call allocate_code before get_code will ever succeed
|
||
|
wh.allocate_code()
|
||
|
code = yield wh.get_code()
|
||
|
print >>out, "Invite Code for client: {}".format(code)
|
||
|
|
||
|
wh.send_message(json.dumps({
|
||
|
u"abilities": {
|
||
|
u"server-v1": {},
|
||
|
}
|
||
|
}))
|
||
|
|
||
|
client_intro = yield wh.get_message()
|
||
|
print >>out, " received client introduction"
|
||
|
client_intro = json.loads(client_intro)
|
||
|
if not u'abilities' in client_intro:
|
||
|
print >>err, "No 'abilities' from client"
|
||
|
defer.returnValue(1)
|
||
|
if not u'client-v1' in client_intro[u'abilities']:
|
||
|
print >>err, "No 'client-v1' in abilities from client"
|
||
|
defer.returnValue(1)
|
||
|
|
||
|
print >>out, " transmitting configuration"
|
||
|
wh.send_message(json.dumps(config))
|
||
|
yield wh.close()
|
||
|
|
||
|
|
||
|
@defer.inlineCallbacks
|
||
|
def invite(options):
|
||
|
if options.parent['node-directory']:
|
||
|
basedir = argv_to_abspath(options.parent['node-directory'])
|
||
|
else:
|
||
|
basedir = get_default_nodedir()
|
||
|
config = configutil.get_config(join(basedir, 'tahoe.cfg'))
|
||
|
out = options.stdout
|
||
|
err = options.stderr
|
||
|
|
||
|
try:
|
||
|
introducer_furl = get_introducer_furl(basedir, config)
|
||
|
except Exception as e:
|
||
|
print >>err, "Can't find introducer FURL for node '{}': {}".format(basedir, str(e))
|
||
|
raise SystemExit(1)
|
||
|
|
||
|
nick = options['nick']
|
||
|
|
||
|
remote_config = {
|
||
|
"shares-needed": options["shares-needed"] or config.get('client', 'shares.needed'),
|
||
|
"shares-total": options["shares-total"] or config.get('client', 'shares.total'),
|
||
|
"shares-happy": options["shares-happy"] or config.get('client', 'shares.happy'),
|
||
|
"nickname": nick,
|
||
|
"introducer": introducer_furl,
|
||
|
}
|
||
|
|
||
|
yield _send_config_via_wormhole(options, remote_config)
|
||
|
print >>out, "Completed successfully"
|
||
|
|
||
|
|
||
|
subCommands = [
|
||
|
("invite", None, InviteOptions,
|
||
|
"Invite a new node to this grid"),
|
||
|
]
|
||
|
|
||
|
dispatch = {
|
||
|
"invite": invite,
|
||
|
}
|