source: trunk/src/allmydata/scripts/tahoe_invite.py

Last change on this file was aea748a, checked in by Itamar Turner-Trauring <itamar@…>, at 2023-03-24T16:03:43Z

Fix lint.

  • Property mode set to 100644
File size: 3.5 KB
Line 
1"""
2Ported to Python 3.
3"""
4
5from twisted.python import usage
6from twisted.internet import defer, reactor
7
8from allmydata.util.encodingutil import argv_to_abspath
9from allmydata.util import jsonbytes as json
10from allmydata.scripts.common import get_default_nodedir, get_introducer_furl
11from allmydata.scripts.types_ import SubCommands
12from allmydata.client import read_config
13
14
15class InviteOptions(usage.Options):
16    synopsis = "[options] <nickname>"
17    description = "Create a client-only Tahoe-LAFS node (no storage server)."
18
19    optParameters = [
20        ("shares-needed", None, None, "How many shares are needed to reconstruct files from this node"),
21        ("shares-happy", None, None, "Distinct storage servers new node will upload shares to"),
22        ("shares-total", None, None, "Total number of shares new node will upload"),
23    ]
24
25    def parseArgs(self, *args):
26        if len(args) != 1:
27            raise usage.UsageError(
28                "Provide a single argument: the new node's nickname"
29            )
30        self['nick'] = args[0].strip()
31
32
33@defer.inlineCallbacks
34def _send_config_via_wormhole(options, config):
35    out = options.stdout
36    err = options.stderr
37    relay_url = options.parent['wormhole-server']
38    print("Connecting to '{}'...".format(relay_url), file=out)
39    wh = options.parent.wormhole.create(
40        appid=options.parent['wormhole-invite-appid'],
41        relay_url=relay_url,
42        reactor=reactor,
43    )
44    yield wh.get_welcome()
45    print("Connected to wormhole server", file=out)
46
47    # must call allocate_code before get_code will ever succeed
48    wh.allocate_code()
49    code = yield wh.get_code()
50    print("Invite Code for client: {}".format(code), file=out)
51
52    wh.send_message(json.dumps_bytes({
53        u"abilities": {
54            u"server-v1": {},
55        }
56    }))
57
58    client_intro = yield wh.get_message()
59    print("  received client introduction", file=out)
60    client_intro = json.loads(client_intro)
61    if not u'abilities' in client_intro:
62        print("No 'abilities' from client", file=err)
63        defer.returnValue(1)
64    if not u'client-v1' in client_intro[u'abilities']:
65        print("No 'client-v1' in abilities from client", file=err)
66        defer.returnValue(1)
67
68    print("  transmitting configuration", file=out)
69    wh.send_message(json.dumps_bytes(config))
70    yield wh.close()
71
72
73@defer.inlineCallbacks
74def invite(options):
75    if options.parent['node-directory']:
76        basedir = argv_to_abspath(options.parent['node-directory'])
77    else:
78        basedir = get_default_nodedir()
79    config = read_config(basedir, u"")
80    out = options.stdout
81    err = options.stderr
82
83    try:
84        introducer_furl = get_introducer_furl(basedir, config)
85    except Exception as e:
86        print("Can't find introducer FURL for node '{}': {}".format(basedir, str(e)), file=err)
87        raise SystemExit(1)
88
89    nick = options['nick']
90
91    remote_config = {
92        "shares-needed": options["shares-needed"] or config.get_config('client', 'shares.needed'),
93        "shares-total": options["shares-total"] or config.get_config('client', 'shares.total'),
94        "shares-happy": options["shares-happy"] or config.get_config('client', 'shares.happy'),
95        "nickname": nick,
96        "introducer": introducer_furl,
97    }
98
99    yield _send_config_via_wormhole(options, remote_config)
100    print("Completed successfully", file=out)
101
102
103subCommands : SubCommands = [
104    ("invite", None, InviteOptions,
105     "Invite a new node to this grid"),
106]
107
108dispatch = {
109    "invite": invite,
110}
Note: See TracBrowser for help on using the repository browser.