提交 32ceaa61 作者: Stephen Whitmore

Resolves paths in 'pin rm' without network lookup.

Fixes ipfs/go-ipfs#2155 by turning the hash path arguments into keys
and unpinning directly, rather than running a full core.Resolve on
them. This lets users fail fast when they try to remove pins that
they don't have locally.

Note that this will only work when the path is of the form <hash> or
/ipfs/<hash>. Given e.g. /ipfs/<hash>/foo, foo's key cannot be known
without first resolving <hash>, which may involve talking to the
network.

License: MIT
Signed-off-by: 's avatarStephen Whitmore <noffle@ipfs.io>
上级 bc49bee6
...@@ -60,22 +60,21 @@ func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ...@@ -60,22 +60,21 @@ func Pin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool)
func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]key.Key, error) { func Unpin(n *core.IpfsNode, ctx context.Context, paths []string, recursive bool) ([]key.Key, error) {
dagnodes := make([]*merkledag.Node, 0) var unpinned []key.Key
for _, fpath := range paths { for _, p := range paths {
dagnode, err := core.Resolve(ctx, n, path.Path(fpath)) p, err := path.ParsePath(p)
if err != nil { if err != nil {
return nil, err return nil, err
} }
dagnodes = append(dagnodes, dagnode)
}
var unpinned []key.Key k, err := core.ResolveToKey(ctx, n, p)
for _, dagnode := range dagnodes { if err != nil {
k, _ := dagnode.Key() return nil, err
}
ctx, cancel := context.WithCancel(ctx) ctx, cancel := context.WithCancel(ctx)
defer cancel() defer cancel()
err := n.Pinning.Unpin(ctx, k, recursive) err = n.Pinning.Unpin(ctx, k, recursive)
if err != nil { if err != nil {
return nil, err return nil, err
} }
......
...@@ -6,6 +6,7 @@ import ( ...@@ -6,6 +6,7 @@ import (
context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context" context "github.com/ipfs/go-ipfs/Godeps/_workspace/src/golang.org/x/net/context"
key "github.com/ipfs/go-ipfs/blocks/key"
merkledag "github.com/ipfs/go-ipfs/merkledag" merkledag "github.com/ipfs/go-ipfs/merkledag"
path "github.com/ipfs/go-ipfs/path" path "github.com/ipfs/go-ipfs/path"
) )
...@@ -55,3 +56,31 @@ func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (*merkledag.Node, er ...@@ -55,3 +56,31 @@ func Resolve(ctx context.Context, n *IpfsNode, p path.Path) (*merkledag.Node, er
// ok, we have an ipfs path now (or what we'll treat as one) // ok, we have an ipfs path now (or what we'll treat as one)
return n.Resolver.ResolvePath(ctx, p) return n.Resolver.ResolvePath(ctx, p)
} }
// ResolveToKey resolves a path to a key.
//
// It first checks if the path is already in the form of just a key (<key> or
// /ipfs/<key>) and returns immediately if so. Otherwise, it falls back onto
// Resolve to perform resolution of the dagnode being referenced.
func ResolveToKey(ctx context.Context, n *IpfsNode, p path.Path) (key.Key, error) {
// If the path is simply a key, parse and return it. Parsed paths are already
// normalized (read: prepended with /ipfs/ if needed), so segment[1] should
// always be the key.
if p.IsJustAKey() {
return key.B58KeyDecode(p.Segments()[1]), nil
}
// Fall back onto regular dagnode resolution.
dagnode, err := Resolve(ctx, n, p)
if err != nil {
return key.Key(""), err
}
// Extract and return the node's key.
k, err := dagnode.Key()
if err != nil {
return key.Key(""), err
}
return k, nil
}
...@@ -279,6 +279,13 @@ test_expect_success "test add nopin dir" ' ...@@ -279,6 +279,13 @@ test_expect_success "test add nopin dir" '
' '
FICTIONAL_HASH="QmXV4f9v8a56MxWKBhP3ETsz4EaafudU1cKfPaaJnenc48"
test_launch_ipfs_daemon
test_expect_success "test unpinning a hash that's not pinned" "
test_expect_code 1 ipfs pin rm $FICTIONAL_HASH --timeout=5s
"
test_kill_ipfs_daemon
# test_kill_ipfs_daemon # test_kill_ipfs_daemon
test_done test_done
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论