1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-07-01 02:30:39 +08:00

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: Stephen Whitmore <noffle@ipfs.io>
This commit is contained in:
Stephen Whitmore
2016-01-16 03:11:36 +01:00
parent bc49bee623
commit 32ceaa61e8
3 changed files with 44 additions and 9 deletions

View File

@ -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) {
dagnodes := make([]*merkledag.Node, 0)
for _, fpath := range paths {
dagnode, err := core.Resolve(ctx, n, path.Path(fpath))
var unpinned []key.Key
for _, p := range paths {
p, err := path.ParsePath(p)
if err != nil {
return nil, err
}
dagnodes = append(dagnodes, dagnode)
}
var unpinned []key.Key
for _, dagnode := range dagnodes {
k, _ := dagnode.Key()
k, err := core.ResolveToKey(ctx, n, p)
if err != nil {
return nil, err
}
ctx, cancel := context.WithCancel(ctx)
defer cancel()
err := n.Pinning.Unpin(ctx, k, recursive)
err = n.Pinning.Unpin(ctx, k, recursive)
if err != nil {
return nil, err
}

View File

@ -6,6 +6,7 @@ import (
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"
path "github.com/ipfs/go-ipfs/path"
)
@ -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)
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
}

View File

@ -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_done