Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tahoe invite.3 #418

Merged
merged 1 commit into from Aug 9, 2017
Merged

Tahoe invite.3 #418

merged 1 commit into from Aug 9, 2017

Conversation

meejah
Copy link
Contributor

@meejah meejah commented May 29, 2017

As per gridsync/gridsync#42 this branch updates tahoe-invite.2 to use a "bare" wormhole object and do the client and server "abilities" messages before exchanging the actual configuration.

Note that this actually depends on wormhole "master" as that includes the new wormhole.wormhole.create() method among others.

Before merging:

  • make wormhole.tahoe-lafs.org a CNAME to wormhole.leastauthority.com
  • depend on a new release of magic-wormhole (with .get_welcome() etc)

@meejah
Copy link
Contributor Author

meejah commented May 29, 2017

The only remaining tweak here (besides some squashing and depending on a wormhole release with the new API) would be I think deciding on the APPID and relay-URI to burn into tahoe -- we'd talked about putting this at e.g. wormhole.tahoe-lafs.org. https://LeastAuthority.com is fine to volunteer to continue to run a wormhole server so this would be a Simple Matter of DNS (right, @exarkun?)

@crwood
Copy link
Member

crwood commented May 29, 2017

For what it's worth, Gridsync currently expects an appid of tahoe-lafs.org/tahoe-lafs/v1 for accepting invites to join a grid (which, to me, seems generic enough). If, for some reason, a different appid would be more suitable, however, I would gladly switch to it instead.

Also, +1 to wormhole.tahoe-lafs.org for the domain.

@crwood
Copy link
Member

crwood commented May 29, 2017

Would it be more appropriate to make the magic-wormhole dependency a setuptools "extra" (pip install-able via tahoe-lafs[invite] or similar) instead of a strict requirement?

@exarkun
Copy link
Member

exarkun commented May 29, 2017

we'd talked about putting this at e.g. wormhole.tahoe-lafs.org. https://LeastAuthority.com is fine to volunteer to continue to run a wormhole server so this would be a Simple Matter of DNS (right, @exarkun?)

I think making wormhole.tahoe-lafs.org a CNAME for wormhole.leastauthority.com (which is already set up and points at a wormhole server) would do it, right? That should be the work of a couple minutes at most.

@codecov-io
Copy link

codecov-io commented May 30, 2017

Codecov Report

Merging #418 into master will increase coverage by 0.11%.
The diff coverage is 96.61%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #418      +/-   ##
==========================================
+ Coverage   87.98%   88.09%   +0.11%     
==========================================
  Files         147      148       +1     
  Lines       27835    27951     +116     
  Branches     3973     3986      +13     
==========================================
+ Hits        24491    24624     +133     
+ Misses       2626     2615      -11     
+ Partials      718      712       -6
Impacted Files Coverage Δ
src/allmydata/_auto_deps.py 91.66% <ø> (ø) ⬆️
src/allmydata/scripts/common.py 94.73% <100%> (+0.45%) ⬆️
src/allmydata/scripts/runner.py 81.08% <50%> (+0.34%) ⬆️
src/allmydata/scripts/tahoe_invite.py 96.55% <96.55%> (ø)
src/allmydata/scripts/create_node.py 98.98% <97.82%> (+0.57%) ⬆️
src/allmydata/web/status.py 82.86% <0%> (+0.11%) ⬆️
src/allmydata/immutable/upload.py 95.53% <0%> (+0.27%) ⬆️
src/allmydata/mutable/servermap.py 94.19% <0%> (+0.48%) ⬆️
... and 2 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b2f7d8d...798bf57. Read the comment docs.

@meejah
Copy link
Contributor Author

meejah commented May 31, 2017

Hmm. My coverage tool says 100% of the diff is covered...Does codecov not update its comment when more commits are added?

@meejah
Copy link
Contributor Author

meejah commented May 31, 2017

Ah, it does update. but still seems confused? or there's some Heisen-coverage?

@warner
Copy link
Member

warner commented Jun 1, 2017

CNAME sounds good to me: tahoe source code will use tahoe-lafs.org URLs, but I'm happy with having LAE run the service itself (I figured we'd run it on the same www.tahoe-lafs.org host as our Trac server, but I imagine it'll be more reliable if LAE runs it on whatever professional stuff they use).

Maybe we can factor things to make the tahoe invite command delegate the work to an internal API, and then the gridsync frontend can import the tahoe code and invoke that same internal API. That way we don't need to express everything (all the error messages) through a shell command, nor committing to a stable CLI interface, but we avoid the fragility of duplicate code.

@meejah
Copy link
Contributor Author

meejah commented Jun 1, 2017

Maybe we can factor things to make the tahoe invite command delegate the work to an internal API, and then the gridsync frontend can import the tahoe code and invoke that same internal API. That way we don't need to express everything (all the error messages) through a shell command, nor committing to a stable CLI interface, but we avoid the fragility of duplicate code.

This is a good idea in general, so I'll do this.

However, I don't think it will help GridSync specifically, as it's written in Python3 and tahoe doesn't support that. There's some slim chance we could make "just this one API" able to be imported in py3 which seems fragile.

Also, the API which would help gridsync would be the "client" side (i.e. tahoe create-node --join <code>). That said, possibly the Least Authority S4 sign-up side code could benefit from a library version of tahoe invite.

The use-cases I expect for tahoe invite would be friend-net style grids (i.e. rare, manual inviting), or perhaps "small company" ones. It can also serve as a "lowest common denominator" for other commercial entities to integrate via and also demo code of what the "server" side needs to communicate via wormhole.

Is it worth making a "more machine-readable" version of the output? Perhaps; that could be a future --json or similar option?

@meejah meejah force-pushed the tahoe-invite.3 branch 2 times, most recently from 9f462e9 to 8f6ad97 Compare June 6, 2017 04:04
@meejah
Copy link
Contributor Author

meejah commented Jun 9, 2017

p.s. I think this is worth having in Tahoe before doing any "grid manager" or "accounting" things for at least two reasons:

  • it's useful now, on its own
  • we can use the wormhole functionality for other tahoe things (immediately: for magic-folder invites and joins) too

Copy link
Member

@exarkun exarkun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! This looks really good. I left some comments inline.

One other thing that's on my mind is how to structure the code so that the versioning scheme can actually be used easily. I think it would be better for future changes if we didn't assume server-v1 and client-v1 in very many places - or if those places were explicitly about v1. I don't have any specific suggestions for how to re-arrange the code to accommodate that idea, though. Perhaps just something to think about.

Lastly, what about long-form/prose documentation for this new feature? The split nature of the feature, between invite and join, suggests something that it would be nice to explain in a single cohesive document. The usage docs included with each command are nice references but I don't think they'll help users who don't already have a decent idea of what the feature is.

@@ -91,6 +91,9 @@
"PyYAML >= 3.11",

"six >= 1.10.0",

# for 'tahoe invite' and 'tahoe join'
"magic-wormhole", # XXX for now, we need master!
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you going to hold off merging this until the next magic-wormhole release?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I was hoping we'd have a "real" magic-wormhole release before this gets merged. But, I could just depend on master and make sure we don't do a tahoe-lafs release before magic-wormhole?


wh = wormhole.create(
appid=u"tahoe-lafs.org/lafs",
relay_url=u"ws://wormhole.leastauthority.com:4000/v1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose this is still meant to change - but not until wormhole.tahoe-lafs.org gets configured? Though I don't see the harm in merging this as-is if setting up that alternate name takes too long. It would be a simple matter to update it in the future after DNS configuration is done.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, these two strings would probably make good global constants somewhere.


print >>out, " received server introduction"
assert u'abilities' in server_intro
assert u'server-v1' in server_intro['abilities']
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than assert, what do you think about doing a regular if and presenting a more presentable failure to the user? The traceback is likely to be meaningless to 99% of potential users.

Also, Tahoe-LAFS should include some documentation explaining what the server-v1 ability corresponds to. This will be pretty boring, I think, but it will set the stage for someone to write something interesting for server-v2.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yup, good catch

for k, v in remote_config.items():
if k not in ['happy', 'needed', 'total', 'introducer']:
print >>out, " --{}={}".format(k, v)
config[k] = v
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bit confusing. The config doesn't actually map to tahoe create command line arguments, right? This is more of a metaphor to try to explain things to the user?

I don't see an obvious problem with letting the server any supported configuration option... but part of me still wants to err on the side of a whitelist. Perhaps because I don't have a deep understanding of every single current Tahoe-LAFS option so I'm not confident it's safe to expose them all to the server. Or perhaps just out of fear of what new behaviors might arise as folks add new configuration options.

Or, from another angle, if the client lets any option be set, the server won't actually know which options it can set on the client. If a new config option is added to Tahoe-LAFS but client-v1 is still in use, a server will have no way to know whether it's talking to a client that supports that option or not. It might be harmless to set it for everyone or the server might actually care about doing something different for older clients. So ... I'd go with a whitelist and bump the client version somehow (either the number or add an item to the corresponding object that tells the server what the client's whitelist is).

Also, the handling of introducer points in the direction of another reason for a whitelist. Perhaps a new sensitive value will be added to the configuration at some point. Without knowing about each key being set, the client has no way to elide that new sensitive value from the logs.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does map to options, but it turns out the only thing not in that list is --nickname so yeah probably just whitelisting it (er, well explicitly pulling out the ones that are ok) is best.

from allmydata.util import configutil


INVITE_SEPARATOR = "+"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This appears to be unused.

@@ -80,7 +83,7 @@ def validate_where_options(o):
else:
# no --location and --port? expect --listen= (maybe the default), and
# --listen=tcp requires --hostname. But --listen=none is special.
if o['listen'] != "none":
if o['listen'] != "none" and o.get('join', None) is None:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this implies that "a dict with some keys, you know what they are, right?" as a data-type is failing validate_where_options. It would be pretty cool to introduce something a little bit better defined here.

Not necessarily part of (or blocking) this PR, since the problem is clearly pre-existing...

@@ -221,7 +225,9 @@ def write_node_config(c, config):
c.write("\n")

c.write("[node]\n")
nickname = argv_to_unicode(config.get("nickname") or "")
nickname = config.get("nickname") or u""
if not isinstance(nickname, unicode):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When is it not? Is it only for the u"" default above? If so, I suggest b"" as a default and drop the conditional (ie, unconditionally decode).


wh = wormhole.create(
appid=u"tahoe-lafs.org/lafs",
relay_url=u"ws://wormhole.tahoe-lafs.org:4000/v1",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh. And here is the wormhole.tahoe-lafs.org name. :) That's a good argument in favor of making this a constant somewhere and sharing it with the other application code that needs it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah :) I now made it a global option. maybe overkill? but might be useful when testing etc...

"--total", "1",
"foo",
)
self.assertTrue(rc != 0)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertNotEqual?

"foo",
)
self.assertTrue(rc != 0)
self.assertTrue(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

assertIn?

@meejah
Copy link
Contributor Author

meejah commented Jun 13, 2017

per @warner's comment about API: you could currently import the allmydata.scripts.tahoe_invite module and run invite() -- but you'd need to supply a proper Options instance. Is it worth factoring out a method that would basically just be a call-through to turn all the relevant options into kwargs?

Since it makes sense to re-factor/re-work the whole "runner" and dispatch code anyway (in a different PR!) perhaps we could supply a slightly easier way to run any particular command "from python" (which would also help the unit-tests).

@meejah
Copy link
Contributor Author

meejah commented Jun 13, 2017

The protocol for client-v1, server-v1 etc was taken from discussion here: gridsync/gridsync#42

@meejah meejah force-pushed the tahoe-invite.3 branch 2 times, most recently from 0e73198 to e717a8a Compare June 13, 2017 23:45
@meejah
Copy link
Contributor Author

meejah commented Jun 13, 2017

Okay, I've squashed and re-based to current master (and changed the URI to wormhole.tahoe-lafs.org, optimistically). I believe I've covered all the comments from the review. Thanks, @exarkun !

This still leaves the "what to depend on" part out though!

@meejah meejah force-pushed the tahoe-invite.3 branch 3 times, most recently from ebb0ab7 to 66c0921 Compare June 14, 2017 18:54
synopsis = "[options] <nickname>"
description = "Create a client-only Tahoe-LAFS node (no storage server)."

optParameters = [
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the sake of being consistent with the standard tahoe create-client/tahoe create-node options, these should probably be changed throughout to --shares-needed, --shares-happy, and --shares-total (instead of just --needed, --happy, and --total).

@crwood
Copy link
Member

crwood commented Jul 4, 2017

While testing this, I noticed that tahoe invite appears to require that the nodedir be explicitly specified (instead of implicitly selecting and/or falling back onto ~/.tahoe):

(venv2) dev ~ % tahoe invite bob
Traceback (most recent call last):
  File "/home/user/venv2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 653, in _runCallbacks
    current.result = callback(current.result, *args, **kw)
  File "/home/user/venv2/local/lib/python2.7/site-packages/allmydata/scripts/runner.py", line 150, in dispatch
    d = defer.maybeDeferred(f, so)
  File "/home/user/venv2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 150, in maybeDeferred
    result = f(*args, **kw)
  File "/home/user/venv2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1532, in unwindGenerator
    return _inlineCallbacks(None, gen, Deferred())
--- <exception caught here> ---
  File "/home/user/venv2/local/lib/python2.7/site-packages/twisted/internet/defer.py", line 1386, in _inlineCallbacks
    result = g.send(result)
  File "/home/user/venv2/local/lib/python2.7/site-packages/allmydata/scripts/tahoe_invite.py", line 34, in invite
    basedir = argv_to_abspath(options.parent['node-directory'])
  File "/home/user/venv2/local/lib/python2.7/site-packages/allmydata/util/encodingutil.py", line 104, in argv_to_abspath
    decoded = argv_to_unicode(s)
  File "/home/user/venv2/local/lib/python2.7/site-packages/allmydata/util/encodingutil.py", line 91, in argv_to_unicode
    precondition(isinstance(s, str), s)
  File "/home/user/venv2/local/lib/python2.7/site-packages/allmydata/util/assertutil.py", line 39, in precondition
    raise AssertionError, "".join(msgbuf)
exceptions.AssertionError: precondition: None <type 'NoneType'>

Running tahoe -d ~/.tahoe invite bob works as expected, however, users arguably shouldn't be required to specify the nodedir if all other commands select ~/.tahoe by default.

print >>out, "Connecting to '{}'".format(relay_url)

wh = wormhole.create(
appid=u"tahoe-lafs.org/lafs",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should probably be changed to tahoe-lafs.org/tahoe-lafs/v1 (so as to be compatible with this and others).

On a related note, we might want to consider now whether this should be bumped up to "v2", or even be made more specific (perhaps so as to distinguish the "grid invites" of now from the "magic-folder invites" of the future -- maybe something like tahoe-lafs.org/tahoe-lafs/invite vs. tahoe-lafs.org/tahoe-lafs/magic-folder/invite?).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we release anything with the "v1" appid in it?

Also, is the appid the right place to do versioning like this, or in the capabilities exchanged as the first messages? I guess the "pro" of doing it in the appid is no possibilities of "crossing the streams" and accidentally receiving a grid-invite as a magic-folder-invite..? (but still, in such a case the capabilities wouldn't match anyway...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(But yes the main point about the appid being wrong/not-matching above needs to be fixed)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did we release anything with the "v1" appid in it?

Nope.. I remember @exarkun suggesting earlier, however, that a version-bump might make for good practice (but don't recall us reaching any sort of consensus on moving forward with that idea -- and may even be mistaken in thinking that he was referring to the appid specifically now that I think about it..). Personally, I have no qualms either way, but wanted to raise the the question here in the event that anyone felt strongly about what the appid should be more generally (since it isn't something we can easily change if/when this PR lands); like you implied, what really matters here is that everything is compatible.

Also, is the appid the right place to do versioning like this, or in the capabilities exchanged as the first messages?

Hmm.. That's a good question. Reducing the possibility of "crossing the streams" by using separate appids where possible is desirable for both security and usability reasons (since an attacker would need to flood channels on both appids instead of just one -- while fewer nameplates in use means potentially fewer characters to type!) and I was already operating under the assumption that we would be doing this later on to isolate magic-folder-invites from grid-invites (or at least I can't really think of any good reasons right now for keeping the appids the same for both types). On that note, I was under the impression -- and please correct me if I'm wrong -- that the capabilities-exchange was intended more so as a means of handling the situation in which we might want/need to change the data-format of a specific invite-type in a way that is not backwards-compatible with the previous one (i.e., as a means of signaling to users more broadly that they need to update their clients) -- in other words, a means of migrating from grid-invite "version 1" to grid-invite "version 2" independently of the appid (and not so much as a means of packing magic-folder-invites in with grid-invites under the same appid).

All that being said, I suppose it doesn't really matter at this point, since we're only handling one "type" of invite right now and the capabilities-exchange gives us a good way -- better than changing the appid, certainly -- of updating its data-format in the unlikely event that we ever need to (and in retrospect I probably should have framed my original comment to more clearly distinguish between a) the question of isolating future invite-"types" and b) the question of versioning since they can be addressed independently of one another).

Maybe, then, we should just omit the "v1" suffix from the current appid altogether (i.e., use tahoe-lafs.org/tahoe-lafs everywhere) and use the capabilities-exchange to handle any/all "versioning"/update-messaging stuff moving forward? Using the appid for versioning seems like a pretty bad idea to me overall (since, in practice, a sender would always have to open at least two wormholes -- one using the "old" appid(s) and one using the "new" -- in order to tell clients on the old one to update).. What do you think?

@crwood
Copy link
Member

crwood commented Jul 4, 2017

After further testing, it looks like create-client --join step is not actually writing the correct encoding parameters to the newly-created tahoe.cfg file (though it does correctly print the parameters)..

To demonstrate, I pointed wormhole.tahoe-lafs.org to a working wormhole server in /etc/hosts, ran a tahoe -d ~/.tahoe invite bob to get an invite code, and then ran tahoe -d ~/.tahoe-bob create-client --join <invite-code>. This is the output I saw:

Opening wormhole with code '7-hydraulic-flagpole'
Connecting to 'ws://wormhole.tahoe-lafs.org:4000/v1'
Connected to wormhole server
  received server introduction
  received configuration
Encoding: 1 of 1 shares, on at least 1 servers
Overriding the following config:
  listen: none
  introducer: [sensitive data; see tahoe.cfg]
  no-storage: True
  nickname: bob
Node created in '/home/user/.tahoe-bob'

Because my shares.* values are all set to 1, the line which reads "Encoding: 1 of 1 shares, on at least 1 servers" is what I would expect to see here, but when I read the newly-created ~/.tahoe-bob/tahoe.cfg file, I see that those parameters are still set to the defaults:

shares.needed = 3
shares.happy = 7
shares.total = 10

(The nickname and introducer.furl values were set correctly, however.)

@meejah meejah force-pushed the tahoe-invite.3 branch 4 times, most recently from db429ed to 43580a9 Compare July 7, 2017 18:13
@meejah
Copy link
Contributor Author

meejah commented Jul 7, 2017

Okay I have cleaned up the deficiencies @crwood found, centralized appid handling and changed the option + json naming to shares-*. This should now be good-to-go except for the CNAME thing that @warner needs to do before merging this for real.

@meejah meejah dismissed exarkun’s stale review July 7, 2017 18:20

I believe I have covered all the things; thanks for the review!

@meejah meejah force-pushed the tahoe-invite.3 branch 2 times, most recently from d8ca7a1 to 4a65fb9 Compare July 18, 2017 21:03
@meejah
Copy link
Contributor Author

meejah commented Aug 1, 2017

re-based this to current master as of today

Copy link
Member

@exarkun exarkun left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some pretty trivial comments inline. Nothing with any particularly wide-ranging consequences, I think.

Address as you see fit and then, as far as I'm concerned, this is good to merge.

"total": 10,
"happy": 7,
"nickname": "bob",
"introducer": "pb://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@example.com:41505"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pb://xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx@example.com:41505/yyyyyyyyyyyyyyyyyyyyyyy perhaps

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, changing

docs/running.rst Outdated
Being Introduced to a Grid
--------------------------

A collection of Tahoe servers is called a Grid and usually has 1 Introducer (but sometimes more, and it's possible to run with zero). The Introducer announces which storage servers constitute the Grid and how to contact them. There is a secret "fURL" you need to know to talk to the Introducer.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Other docs are hard-wrapped at around 80 cols but these docs seem to be paragraph-per-line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, yup. re-wrapped.

print("waiting 5 seconds unil we're maybe ready")
yield task.deferLater(reactor, 5, lambda: None)
print("waiting 10 seconds unil we're maybe ready")
yield task.deferLater(reactor, 10, lambda: None)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha ha 😢

#430 has landed, perhaps it's possible to do better than this for now.

Did this get bumped from 5 to 10 because of changes in this branch or just because time-based wait is inherently unreliable and in your development environment 10 provides a better facsimile of correctness than 5?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The latter :(

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...and yes teaching the tests to properly figure out when "the grid is ready" would be the right answer here. Hopefully #430 will help, I'll try (in a new branch).

relay_url = config.parent['wormhole-server']
print >>out, "Connecting to '{}'".format(relay_url)

wh = wormhole.create(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Probably would be better if the wormhole exchange were factored into a separate function and just called from here.

try:
introducer_furl = config.get('client', 'introducer.furl')
except NoSectionError:
# we're not a client; maybe this is running *on* the introducer?
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have no clue if this is the right heuristic to use to detect the kind of node. It's too bad a heuristic is required, I guess.

If one is required, maybe it could at least be formalized and centralized? A determine_node_type API that this code could use?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, maybe that would be better. There is a helper for that. I don't really care what type of node this is, it's more that there isn't just one way to get "the introducer fURL" -- maybe I really want to add a helper for that ...

client_intro = yield wh.get_message()
print >>out, " received client introduction"
client_intro = json.loads(client_intro)
if not u'abilities' in client_intro:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

u'abilities' not in client_intro


@defer.inlineCallbacks
def test_create_node_join(self):
node_dir = self.mktemp()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having recently tried to maintain some unit tests with no explanatory documentation regarding the case being covered, I think it would be nice to see some docs for that here.

"foo",
)
self.assertNotEqual(rc, 0)
self.assertIn(u"Can't find introducer fURL", out + err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems like the run_cli args and following assertions are the only parts which vary between many of these tests. Perhaps it would be nice to factor out the rest into a helper to reduce future maintenance burden and make the tests themselves easier to read.

def setUp(self):
testutil.SignalMixin.setUp(self)
self.parent = LoggingMultiService()
self.parent.startService()
self._available_port = yield iputil.allocate_tcp_port()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changes in this module look unrelated, just general reliability improvements for the test suite by avoiding random port collisions? If so it might be nice to split this off into a separate pr.

her command running until Bob has done his step as it is waiting until
a secure channel is established before sending the data.

Bob then runs ``tahoe create-client --join <secret code>`` with any
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I forget if there was a discussion about the verb "join" here. I think @warner hinted at preferring something like "accept" (but I can't channel his reasoning). They both make equal sense to me, fwiw. Either you are "joining" a grid to which you were "invited" or you are "accepting" an "invitation" to a grid...

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't have a good reason for preferring one over the other; happy to paint the bikeshed whichever colour @warner wants :)

@meejah meejah force-pushed the tahoe-invite.3 branch 5 times, most recently from 347d38f to f79c500 Compare August 8, 2017 16:41
@meejah
Copy link
Contributor Author

meejah commented Aug 8, 2017

Pulled out the port 1234 stuff: #435

@meejah meejah force-pushed the tahoe-invite.3 branch 2 times, most recently from 4561af5 to 18c1e78 Compare August 8, 2017 23:17
@warner
Copy link
Member

warner commented Aug 8, 2017

BTW, the CNAME step is done.

This opens a wormhole and sends appropriate JSON down
it to a tahoe-gui using a wormhole server running on
tahoe-lafs.org

The other end uses the 'tahoe create-node' command (with
new --join option) to read the configuration JSON from
a 'tahoe invite' command
@warner
Copy link
Member

warner commented Aug 9, 2017

Looks good. I had to restart the travis build for some reason (it completed but then didn't update the ticket). Landing now. Way to go!

@warner warner merged commit 798bf57 into tahoe-lafs:master Aug 9, 2017
@meejah meejah deleted the tahoe-invite.3 branch August 9, 2017 06:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
5 participants