-
-
Notifications
You must be signed in to change notification settings - Fork 3k
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
Rework mutable namespace resolution to handle recursion #1208
Changes from all commits
02cb5f3
03260a9
04a9698
3ead244
c2ff028
e643f72
416d454
e4447b3
1e6594d
c9fceeb
ce015d2
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
package commands | ||
|
||
import ( | ||
"io" | ||
"strings" | ||
|
||
cmds "github.com/ipfs/go-ipfs/commands" | ||
namesys "github.com/ipfs/go-ipfs/namesys" | ||
util "github.com/ipfs/go-ipfs/util" | ||
) | ||
|
||
var DNSCmd = &cmds.Command{ | ||
Helptext: cmds.HelpText{ | ||
Tagline: "DNS link resolver", | ||
ShortDescription: ` | ||
Multihashes are hard to remember, but domain names are usually easy to | ||
remember. To create memorable aliases for multihashes, DNS TXT | ||
records can point to other DNS links, IPFS objects, IPNS keys, etc. | ||
This command resolves those links to the referenced object. | ||
`, | ||
LongDescription: ` | ||
Multihashes are hard to remember, but domain names are usually easy to | ||
remember. To create memorable aliases for multihashes, DNS TXT | ||
records can point to other DNS links, IPFS objects, IPNS keys, etc. | ||
This command resolves those links to the referenced object. | ||
|
||
For example, with this DNS TXT record: | ||
|
||
ipfs.io. TXT "dnslink=/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy ..." | ||
|
||
The resolver will give: | ||
|
||
> ipfs dns ipfs.io | ||
/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy | ||
|
||
And with this DNS TXT record: | ||
|
||
ipfs.ipfs.io. TXT "dnslink=/dns/ipfs.io ..." | ||
|
||
The resolver will give: | ||
|
||
> ipfs dns ipfs.io | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i think this needs to be There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. may want to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Thu, May 14, 2015 at 09:21:34PM -0700, Juan Batiz-Benet wrote:
So two questions:
|
||
/dns/ipfs.io | ||
> ipfs dns --recursive | ||
/ipfs/QmRzTuh2Lpuz7Gr39stNr6mTFdqAghsZec1JoUnfySUzcy | ||
`, | ||
}, | ||
|
||
Arguments: []cmds.Argument{ | ||
cmds.StringArg("domain-name", true, false, "The domain-name name to resolve.").EnableStdin(), | ||
}, | ||
Options: []cmds.Option{ | ||
cmds.BoolOption("recursive", "r", "Resolve until the result is not a DNS link"), | ||
}, | ||
Run: func(req cmds.Request, res cmds.Response) { | ||
|
||
recursive, _, _ := req.Option("recursive").Bool() | ||
name := req.Arguments()[0] | ||
resolver := namesys.NewDNSResolver() | ||
|
||
depth := 1 | ||
if recursive { | ||
depth = namesys.DefaultDepthLimit | ||
} | ||
output, err := resolver.ResolveN(req.Context().Context, name, depth) | ||
if err != nil { | ||
res.SetError(err, cmds.ErrNormal) | ||
return | ||
} | ||
res.SetOutput(&ResolvedPath{output}) | ||
}, | ||
Marshalers: cmds.MarshalerMap{ | ||
cmds.Text: func(res cmds.Response) (io.Reader, error) { | ||
output, ok := res.Output().(*ResolvedPath) | ||
if !ok { | ||
return nil, util.ErrCast() | ||
} | ||
return strings.NewReader(output.Path.String()), nil | ||
}, | ||
}, | ||
Type: ResolvedPath{}, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
package commands | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
"strings" | ||
|
||
cmds "github.com/ipfs/go-ipfs/commands" | ||
namesys "github.com/ipfs/go-ipfs/namesys" | ||
u "github.com/ipfs/go-ipfs/util" | ||
) | ||
|
||
var ipnsCmd = &cmds.Command{ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. very minor thing-- i think we'll later want this to be something like |
||
Helptext: cmds.HelpText{ | ||
Tagline: "Gets the value currently published at an IPNS name", | ||
ShortDescription: ` | ||
IPNS is a PKI namespace, where names are the hashes of public keys, and | ||
the private key enables publishing new (signed) values. In resolve, the | ||
default value of <name> is your own identity public key. | ||
`, | ||
LongDescription: ` | ||
IPNS is a PKI namespace, where names are the hashes of public keys, and | ||
the private key enables publishing new (signed) values. In resolve, the | ||
default value of <name> is your own identity public key. | ||
|
||
|
||
Examples: | ||
|
||
Resolve the value of your identity: | ||
|
||
> ipfs name resolve | ||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy | ||
|
||
Resolve the value of another name: | ||
|
||
> ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n | ||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy | ||
|
||
`, | ||
}, | ||
|
||
Arguments: []cmds.Argument{ | ||
cmds.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID.").EnableStdin(), | ||
}, | ||
Options: []cmds.Option{ | ||
cmds.BoolOption("recursive", "r", "Resolve until the result is not an IPNS name"), | ||
}, | ||
Run: func(req cmds.Request, res cmds.Response) { | ||
|
||
n, err := req.Context().GetNode() | ||
if err != nil { | ||
res.SetError(err, cmds.ErrNormal) | ||
return | ||
} | ||
|
||
if !n.OnlineMode() { | ||
err := n.SetupOfflineRouting() | ||
if err != nil { | ||
res.SetError(err, cmds.ErrNormal) | ||
return | ||
} | ||
} | ||
|
||
var name string | ||
|
||
if len(req.Arguments()) == 0 { | ||
if n.Identity == "" { | ||
res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal) | ||
return | ||
} | ||
name = n.Identity.Pretty() | ||
|
||
} else { | ||
name = req.Arguments()[0] | ||
} | ||
|
||
recursive, _, _ := req.Option("recursive").Bool() | ||
depth := 1 | ||
if recursive { | ||
depth = namesys.DefaultDepthLimit | ||
} | ||
|
||
resolver := namesys.NewRoutingResolver(n.Routing) | ||
output, err := resolver.ResolveN(n.Context(), name, depth) | ||
if err != nil { | ||
res.SetError(err, cmds.ErrNormal) | ||
return | ||
} | ||
|
||
// TODO: better errors (in the case of not finding the name, we get "failed to find any peer in table") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. failed to find any peers in table means that bootstrapping was not successful, not that a lookup necessarily resulted in 'not found' |
||
|
||
res.SetOutput(&ResolvedPath{output}) | ||
}, | ||
Marshalers: cmds.MarshalerMap{ | ||
cmds.Text: func(res cmds.Response) (io.Reader, error) { | ||
output, ok := res.Output().(*ResolvedPath) | ||
if !ok { | ||
return nil, u.ErrCast() | ||
} | ||
return strings.NewReader(output.Path.String()), nil | ||
}, | ||
}, | ||
Type: ResolvedPath{}, | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,11 @@ | ||
package commands | ||
|
||
import ( | ||
"errors" | ||
"io" | ||
"strings" | ||
|
||
cmds "github.com/ipfs/go-ipfs/commands" | ||
namesys "github.com/ipfs/go-ipfs/namesys" | ||
path "github.com/ipfs/go-ipfs/path" | ||
u "github.com/ipfs/go-ipfs/util" | ||
) | ||
|
@@ -14,37 +14,46 @@ type ResolvedPath struct { | |
Path path.Path | ||
} | ||
|
||
var resolveCmd = &cmds.Command{ | ||
var ResolveCmd = &cmds.Command{ | ||
Helptext: cmds.HelpText{ | ||
Tagline: "Gets the value currently published at an IPNS name", | ||
Tagline: "Resolve the value of names to IPFS", | ||
ShortDescription: ` | ||
IPNS is a PKI namespace, where names are the hashes of public keys, and | ||
the private key enables publishing new (signed) values. In resolve, the | ||
default value of <name> is your own identity public key. | ||
There are a number of mutable name protocols that can link among | ||
themselves and into IPNS. This command accepts any of these | ||
identifiers and resolves them to the referenced item. | ||
`, | ||
LongDescription: ` | ||
IPNS is a PKI namespace, where names are the hashes of public keys, and | ||
the private key enables publishing new (signed) values. In resolve, the | ||
default value of <name> is your own identity public key. | ||
|
||
There are a number of mutable name protocols that can link among | ||
themselves and into IPNS. For example IPNS references can (currently) | ||
point at IPFS object, and DNS links can point at other DNS links, IPNS | ||
entries, or IPFS objects. This command accepts any of these | ||
identifiers and resolves them to the referenced item. | ||
|
||
Examples: | ||
|
||
Resolve the value of your identity: | ||
|
||
> ipfs name resolve | ||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy | ||
> ipfs resolve /ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy | ||
/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj | ||
|
||
Resolve the value of another name: | ||
|
||
> ipfs resolve /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n | ||
/ipns/QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy | ||
|
||
Resolve te value of another name: | ||
Resolve the value of another name recursively: | ||
|
||
> ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n | ||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy | ||
> ipfs resolve -r /ipns/QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n | ||
/ipfs/Qmcqtw8FfrVSBaRmbWwHxt3AuySBhJLcvmFYi3Lbc4xnwj | ||
|
||
`, | ||
}, | ||
|
||
Arguments: []cmds.Argument{ | ||
cmds.StringArg("name", false, false, "The IPNS name to resolve. Defaults to your node's peerID.").EnableStdin(), | ||
cmds.StringArg("name", true, false, "The name to resolve.").EnableStdin(), | ||
}, | ||
Options: []cmds.Option{ | ||
cmds.BoolOption("recursive", "r", "Resolve until the result is an IPFS name"), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe this should default to true? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. no, i think you're right. it should default to false. |
||
}, | ||
Run: func(req cmds.Request, res cmds.Response) { | ||
|
||
|
@@ -62,27 +71,19 @@ Resolve te value of another name: | |
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ahhh nevermind, this is just |
||
|
||
var name string | ||
|
||
if len(req.Arguments()) == 0 { | ||
if n.Identity == "" { | ||
res.SetError(errors.New("Identity not loaded!"), cmds.ErrNormal) | ||
return | ||
} | ||
name = n.Identity.Pretty() | ||
|
||
} else { | ||
name = req.Arguments()[0] | ||
name := req.Arguments()[0] | ||
recursive, _, _ := req.Option("recursive").Bool() | ||
depth := 1 | ||
if recursive { | ||
depth = namesys.DefaultDepthLimit | ||
} | ||
|
||
output, err := n.Namesys.Resolve(n.Context(), name) | ||
output, err := n.Namesys.ResolveN(n.Context(), name, depth) | ||
if err != nil { | ||
res.SetError(err, cmds.ErrNormal) | ||
return | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. do we return better errors now? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On Thu, May 07, 2015 at 10:51:49PM -0700, Juan Batiz-Benet wrote:
Without a daemon: $ ipfs /ipfs/QmNonExistentKey With a daemon running, the DNS errors are the same, and the IPFS/IPNS $ ipfs /ipfs/QmNonExistentKey What sort of better errors were you looking for? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm-- we probably should make the differing ones the same. This is odd:
cmdslib should just error out... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
should probably be
in both cases. |
||
} | ||
|
||
// TODO: better errors (in the case of not finding the name, we get "failed to find any peer in table") | ||
|
||
res.SetOutput(&ResolvedPath{output}) | ||
}, | ||
Marshalers: cmds.MarshalerMap{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍 to this command :)