@cryptotaxi247 / kubo / commits / 5d25fc1f1

unix-friendly output for 'ipfs dht' commands (#2560)

* Cleans up 'ipfs dht findpeer' output License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Adds more docs for 'ipfs dht put'. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Write pretty peer ids for ipfs dht put. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Writes pretty peer ids for ipfs dht query. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Suppresses unrecognized event type for FinalPeer. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Improves helptext on dht commands. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Adds 'ipfs dht findpeer' sharness test. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Adds sharness tests for remaining DHT commands. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Uses bash tests rather than 'test' command. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Removes commented code. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Removes unneeded init_ipfs. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Tweaks iptb setup. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Tweaks wording on dht 'put' and 'get'. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Removes extraneous ). License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Removes apostrophe. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Tests the expected peer addresses. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Gets peer id using iptb. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Checks explicitly for common put/findprovs peers. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Sorts expected/actual findpeer results. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io> * Fix disconnect argument description License: MIT Signed-off-by: Richard Littauer <richard.littauer@gmail.com> * Fixes sort order in t0170-dht.sh. License: MIT Signed-off-by: Stephen Whitmore <noffle@ipfs.io>

Stephen Whitmore committed Apr 27, 2016 at 09:31 UTC 5d25fc1f16a4060e98deff007a0bda0759d4745e
2 files changed +120 -28
core/commands/dht.go
+55 -28
@@ -35,15 +35,15 @@ var DhtCmd = &cmds.Command{
35
36 var queryDhtCmd = &cmds.Command{
37 Helptext: cmds.HelpText{
38 - Tagline: "Find the closest peers to a given key by querying through the DHT.",
39 - ShortDescription: ``,
38 + Tagline: "Find the closest Peer IDs to a given Peer ID by querying the DHT.",
39 + ShortDescription: "Outputs a list of newline-delimited Peer IDs.",
40 },
41
42 Arguments: []cmds.Argument{
43 cmds.StringArg("peerID", true, true, "The peerID to run the query against."),
44 },
45 Options: []cmds.Option{
46 - cmds.BoolOption("verbose", "v", "Write extra information."),
46 + cmds.BoolOption("verbose", "v", "Write debug information."),
47 },
48 Run: func(req cmds.Request, res cmds.Response) {
49 n, err := req.InvocContext().GetNode()
@@ -94,6 +94,14 @@ var queryDhtCmd = &cmds.Command{
94 return nil, u.ErrCast()
95 }
96
97 + pfm := pfuncMap{
98 + notif.PeerResponse: func(obj *notif.QueryEvent, out io.Writer, verbose bool) {
99 + for _, p := range obj.Responses {
100 + fmt.Fprintf(out, "%s\n", p.ID.Pretty())
101 + }
102 + },
103 + }
104 +
105 marshal := func(v interface{}) (io.Reader, error) {
106 obj, ok := v.(*notif.QueryEvent)
107 if !ok {
@@ -103,7 +111,7 @@ var queryDhtCmd = &cmds.Command{
111 verbose, _, _ := res.Request().Option("v").Bool()
112
113 buf := new(bytes.Buffer)
106 - printEvent(obj, buf, verbose, nil)
114 + printEvent(obj, buf, verbose, pfm)
115 return buf, nil
116 }
117
@@ -119,17 +127,15 @@ var queryDhtCmd = &cmds.Command{
127
128 var findProvidersDhtCmd = &cmds.Command{
129 Helptext: cmds.HelpText{
122 - Tagline: "Run a 'FindProviders' query through the DHT.",
123 - ShortDescription: `
124 -FindProviders will return a list of peers who are able to provide the value requested.
125 -`,
130 + Tagline: "Find peers in the DHT that can provide a specific value, given a key.",
131 + ShortDescription: "Outputs a list of newline-delimited provider Peer IDs.",
132 },
133
134 Arguments: []cmds.Argument{
135 cmds.StringArg("key", true, true, "The key to find providers for."),
136 },
137 Options: []cmds.Option{
132 - cmds.BoolOption("verbose", "v", "Write extra information."),
138 + cmds.BoolOption("verbose", "v", "Write debug information."),
139 },
140 Run: func(req cmds.Request, res cmds.Response) {
141 n, err := req.InvocContext().GetNode()
@@ -222,12 +228,15 @@ FindProviders will return a list of peers who are able to provide the value requ
228
229 var findPeerDhtCmd = &cmds.Command{
230 Helptext: cmds.HelpText{
225 - Tagline: "Run a 'FindPeer' query through the DHT.",
226 - ShortDescription: ``,
231 + Tagline: "Query the DHT for all of the multiaddresses associated with a Peer ID.",
232 + ShortDescription: "Outputs a list of newline-delimited multiaddresses.",
233 },
234
235 Arguments: []cmds.Argument{
230 - cmds.StringArg("peerID", true, true, "The peer to search for."),
236 + cmds.StringArg("peerID", true, true, "The ID of the peer to search for."),
237 + },
238 + Options: []cmds.Option{
239 + cmds.BoolOption("verbose", "v", "Write debug information."),
240 },
241 Run: func(req cmds.Request, res cmds.Response) {
242 n, err := req.InvocContext().GetNode()
@@ -285,12 +294,13 @@ var findPeerDhtCmd = &cmds.Command{
294 return nil, u.ErrCast()
295 }
296
297 + verbose, _, _ := res.Request().Option("v").Bool()
298 +
299 pfm := pfuncMap{
300 notif.FinalPeer: func(obj *notif.QueryEvent, out io.Writer, verbose bool) {
301 pi := obj.Responses[0]
291 - fmt.Fprintf(out, "%s\n", pi.ID)
302 for _, a := range pi.Addrs {
293 - fmt.Fprintf(out, "\t%s\n", a)
303 + fmt.Fprintf(out, "%s\n", a)
304 }
305 },
306 }
@@ -301,7 +311,7 @@ var findPeerDhtCmd = &cmds.Command{
311 }
312
313 buf := new(bytes.Buffer)
304 - printEvent(obj, buf, true, pfm)
314 + printEvent(obj, buf, verbose, pfm)
315 return buf, nil
316 }
317
@@ -317,9 +327,11 @@ var findPeerDhtCmd = &cmds.Command{
327
328 var getValueDhtCmd = &cmds.Command{
329 Helptext: cmds.HelpText{
320 - Tagline: "Run a 'GetValue' query through the DHT.",
330 + Tagline: "Given a key, query the DHT for its best value.",
331 ShortDescription: `
322 -GetValue will return the value stored in the DHT at the given key.
332 +Outputs the best value for the given key.
333 +
334 +There may be several different values for a given key stored in the DHT; in this context 'best' means the record that is most desirable. There is no one metric for 'best': it depends entirely on the key type. For IPNS, 'best' is the record that is both valid and has the highest sequence number (freshest). Different key types can specify other 'best' rules.
335 `,
336 },
337
@@ -327,7 +339,7 @@ GetValue will return the value stored in the DHT at the given key.
339 cmds.StringArg("key", true, true, "The key to find a value for."),
340 },
341 Options: []cmds.Option{
330 - cmds.BoolOption("verbose", "v", "Write extra information."),
342 + cmds.BoolOption("verbose", "v", "Write debug information."),
343 },
344 Run: func(req cmds.Request, res cmds.Response) {
345 n, err := req.InvocContext().GetNode()
@@ -420,9 +432,17 @@ GetValue will return the value stored in the DHT at the given key.
432
433 var putValueDhtCmd = &cmds.Command{
434 Helptext: cmds.HelpText{
423 - Tagline: "Run a 'PutValue' query through the DHT.",
435 + Tagline: "Write a key/value pair to the DHT.",
436 ShortDescription: `
425 -PutValue will store the given key value pair in the DHT.
437 +Given a key of the form /foo/bar and a value of any form, this will write that value to the DHT with that key.
438 +
439 +Keys have two parts: a keytype (foo) and the key name (bar). IPNS uses the /ipns keytype, and expects the key name to be a Peer ID. IPNS entries are specifically formatted (protocol buffer).
440 +
441 +You may only use keytypes that are supported in your ipfs binary: currently this is only /ipns. Unless you have a relatively deep understanding of the go-ipfs DHT internals, you likely want to be using 'ipfs name publish' instead of this.
442 +
443 +Value is arbitrary text. Standard input can be used to provide value.
444 +
445 +NOTE: a value may NOT exceed 2048 bytes.
446 `,
447 },
448
@@ -431,7 +451,7 @@ PutValue will store the given key value pair in the DHT.
451 cmds.StringArg("value", true, false, "The value to store.").EnableStdin(),
452 },
453 Options: []cmds.Option{
434 - cmds.BoolOption("verbose", "v", "Write extra information."),
454 + cmds.BoolOption("verbose", "v", "Write debug information."),
455 },
456 Run: func(req cmds.Request, res cmds.Response) {
457 n, err := req.InvocContext().GetNode()
@@ -493,7 +513,7 @@ PutValue will store the given key value pair in the DHT.
513 }
514 },
515 notif.Value: func(obj *notif.QueryEvent, out io.Writer, verbose bool) {
496 - fmt.Fprintf(out, "storing value at %s\n", obj.ID)
516 + fmt.Fprintf(out, "%s\n", obj.ID.Pretty())
517 },
518 }
519
@@ -546,13 +566,17 @@ func printEvent(obj *notif.QueryEvent, out io.Writer, verbose bool, override pfu
566 fmt.Fprint(out, obj.Extra)
567 }
568 case notif.PeerResponse:
549 - fmt.Fprintf(out, "* %s says use ", obj.ID)
550 - for _, p := range obj.Responses {
551 - fmt.Fprintf(out, "%s ", p.ID)
569 + if verbose {
570 + fmt.Fprintf(out, "* %s says use ", obj.ID)
571 + for _, p := range obj.Responses {
572 + fmt.Fprintf(out, "%s ", p.ID)
573 + }
574 + fmt.Fprintln(out)
575 }
553 - fmt.Fprintln(out)
576 case notif.QueryError:
555 - fmt.Fprintf(out, "error: %s\n", obj.Extra)
577 + if verbose {
578 + fmt.Fprintf(out, "error: %s\n", obj.Extra)
579 + }
580 case notif.DialingPeer:
581 if verbose {
582 fmt.Fprintf(out, "dialing peer: %s\n", obj.ID)
@@ -561,8 +585,11 @@ func printEvent(obj *notif.QueryEvent, out io.Writer, verbose bool, override pfu
585 if verbose {
586 fmt.Fprintf(out, "adding peer to query: %s\n", obj.ID)
587 }
588 + case notif.FinalPeer:
589 default:
565 - fmt.Fprintf(out, "unrecognized event type: %d\n", obj.Type)
590 + if verbose {
591 + fmt.Fprintf(out, "unrecognized event type: %d\n", obj.Type)
592 + }
593 }
594 }
595
test/sharness/t0170-dht.sh new
+65
@@ -0,0 +1,65 @@
1 +#!/bin/sh
2 +
3 +test_description="Test dht command"
4 +
5 +. lib/test-lib.sh
6 +
7 +# start iptb + wait for peering
8 +NUM_NODES=5
9 +test_expect_success 'init iptb' '
10 + iptb init -n $NUM_NODES --bootstrap=none --port=0 &&
11 + startup_cluster $NUM_NODES
12 +'
13 +
14 +test_expect_success 'peer ids' '
15 + PEERID_0=$(iptb get id 0) &&
16 + PEERID_2=$(iptb get id 2)
17 +'
18 +
19 +# ipfs dht findpeer <peerID>
20 +test_expect_success 'findpeer' '
21 + ipfsi 1 dht findpeer $PEERID_0 | sort >actual &&
22 + echo "$(ipfsi 0 id -f "<addrs>" | cut -d / -f 1-5 | sort >expected)"
23 + test_cmp actual expected
24 +'
25 +
26 +# ipfs dht put <key> <value>
27 +test_expect_success 'put' '
28 + ipfsi 1 dht put planet pluto | sort >putted &&
29 + [ -s putted ] ||
30 + test_fsh cat putted
31 +'
32 +
33 +# ipfs dht findprovs <key>
34 +test_expect_success 'findprovs' '
35 + ipfsi 4 dht findprovs planet | sort >provs &&
36 + sort provs putted | uniq -d >actual &&
37 + [ -s actual ] ||
38 + test_fsh cat actual
39 +'
40 +
41 +# ipfs dht get <key>
42 +test_expect_success 'get' '
43 + ipfsi 0 dht put bar foo >actual &&
44 + ipfsi 4 dht get -v bar >actual &&
45 + egrep "error: record key does not have selectorfunc" actual > /dev//null ||
46 + test_fsh cat actual
47 +'
48 +
49 +# ipfs dht query <peerID>
50 +## We query 3 different keys, to statisically lower the chance that the queryer
51 +## turns out to be the closest to what a key hashes to.
52 +test_expect_success 'query' '
53 + ipfsi 3 dht query banana >actual &&
54 + ipfsi 3 dht query apple >>actual &&
55 + ipfsi 3 dht query pear >>actual &&
56 + PEERS=$(wc -l actual | cut -d '"'"' '"'"' -f 1) &&
57 + [ -s actual ] ||
58 + test_fsh cat actual
59 +'
60 +
61 +test_expect_success 'stop iptb' '
62 + iptb stop
63 +'
64 +
65 +test_done