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

Add arguments to 'ipfs pin ls' #2208

Merged
merged 8 commits into from
Jan 21, 2016
Merged

Add arguments to 'ipfs pin ls' #2208

merged 8 commits into from
Jan 21, 2016

Conversation

chriscool
Copy link
Contributor

This makes it possible to pass path arguments to ipfs pin ls to know if some specific objects are pinned.

To enable that IsPinnedWithType(key.Key, string) (string, bool, error) is added to the Pinner interface.

The benefits are that test/bin/ipfs-pin-stat can be removed, and t0081 is now faster (around 18 seconds now, versus 50 seconds before this PR on my machine).

@chriscool chriscool added the RFCR label Jan 16, 2016
if typeStr == "direct" || typeStr == "all" {
for _, k := range n.Pinning.DirectKeys() {

if (argCount > 0) {
Copy link
Member

Choose a reason for hiding this comment

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

[style] I would just inline len(req.Arguments()) here instead of declaring an extra variable for 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.

Ok, will do.

@whyrusleeping
Copy link
Member

A few comments there, and also make sure to run go fmt on your code, go allows parentheses on if statements, but theyre not part of the official style so we always leave them off (and go fmt automatically removes them)

@chriscool
Copy link
Contributor Author

Ok, I will push something cleaned up using go fmt soon.
Thanks!

@chriscool
Copy link
Contributor Author

Done!

@chriscool
Copy link
Contributor Author

The Travis CI build failure is the usual "no output received for 10 minutes".

@@ -1,30 +0,0 @@
#!/bin/sh
Copy link
Member

Choose a reason for hiding this comment

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

curious why this test is no longer needed?

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 was not a test. It was a script used only by t0081.
Now we can do the same thing with ipfs pin ls <arg>... so this script is not needed any more.

Copy link
Member

Choose a reason for hiding this comment

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

oh ok i see it now.

@jbenet
Copy link
Member

jbenet commented Jan 17, 2016

comments above, LGTM otherwise

@chriscool
Copy link
Contributor Author

Ok, here is a new version. I think all the comments have been taken into account.

@chriscool
Copy link
Contributor Author

The Travis CI an Circle CI failures are timeouts: "command make test_sharness_expensive took more than 10 minutes since last output"

keys, err = pinLsKeys(req.Arguments(), typeStr, req.Context(), n)
} else {
if !typeStrFound {
typeStr = "recursive"
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 the default for typeStr should be the same in both cases (either "all" or "recursive") i fear that having them be different will confuse users?

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, it would be more logical for the default to be the same in both cases, but when there are args it is natural to have the default be "all" and setting it to "all" when there are no args is a bit backward incompatible, so I preferred to avoid it.

Now if you are ok for the default being "all" in both case I can change that.

Copy link
Member

Choose a reason for hiding this comment

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

when there are args it is natural to have the default be "all"

yeah.

setting it to "all" when there are no args is a bit backward incompatible

yeah... :(

i think ipfs pin ls makes sense to default to all, too. we can put a notice and make sure to put it in the changelog. it would be nice to have a "incompatible changes" section that people could see easier.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, I change the default to "all" and put something about that in the changelog.

Looking at CHANGELOG.md on GitHub, it seems that there is nothing about v0.3.11 and v0.4.0 in it. Are we still supposed to update it?

Copy link
Member

Choose a reason for hiding this comment

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

@chriscool yes we are.

@whyrusleeping why was the changelog not updated when you released 0.3.11?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jbenet a rebased version is now available with a new commit that changes the default to "all" and adds entries to the changelog for v0.4.0.

It is more generic to be able to pass a pin type argument.

License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
@chriscool chriscool added the RFM label Jan 18, 2016
License: MIT
Signed-off-by: Christian Couder <chriscool@tuxfamily.org>
@chriscool
Copy link
Contributor Author

There is this error with Circle CI:

expecting success: 
        ipfs cat "$PCOUT/$name" >tpcp_out &&
        ipfs cat "$target" >tpcp_exp &&
        test_cmp tpcp_exp tpcp_out

panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x40 pc=0x5b4fbe]

goroutine 1 [running]:
github.com/ipfs/go-ipfs/repo/fsrepo.(*FSRepo).GetStorageUsage.func1(0xc8200bc7e0, 0x5d, 0x0, 0x0, 0x2b019bdc4270, 0xc82068c0c0, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/repo/fsrepo/fsrepo.go:565 +0x3e
path/filepath.walk(0xc8200bc1e0, 0x52, 0x2b019c202890, 0xc8200b42d0, 0xc8201797c0, 0x0, 0x0)
    /usr/local/go/src/path/filepath/path.go:370 +0x415
path/filepath.walk(0xc8200101ea, 0x48, 0x2b019c202890, 0xc820016af0, 0xc8201797c0, 0x0, 0x0)
    /usr/local/go/src/path/filepath/path.go:374 +0x4fc
path/filepath.Walk(0xc8200101ea, 0x48, 0xc8201797c0, 0x0, 0x0)
    /usr/local/go/src/path/filepath/path.go:396 +0xe1
github.com/ipfs/go-ipfs/repo/fsrepo.(*FSRepo).GetStorageUsage(0xc820018940, 0x2, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/repo/fsrepo/fsrepo.go:567 +0xa7
github.com/ipfs/go-ipfs/repo.(*ref).GetStorageUsage(0xc8200e4780, 0x411358, 0x0, 0x0)
    <autogenerated>:22 +0x5c
github.com/ipfs/go-ipfs/core/corerepo.(*GC).maybeGC(0xc8206e4580, 0x2b019bdc4998, 0xc820018900, 0xc, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/core/corerepo/gc.go:162 +0x65
github.com/ipfs/go-ipfs/core/corerepo.ConditionalGC(0x2b019bdc4998, 0xc820018900, 0xc820116000, 0xc, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/core/corerepo/gc.go:158 +0x86
github.com/ipfs/go-ipfs/core/commands.glob.func18(0x2b019bdc48c0, 0xc820298240, 0x2b019bdc4a28, 0xc820014150)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/core/commands/cat.go:48 +0x2a8
github.com/ipfs/go-ipfs/commands.(*Command).Call(0x1429e40, 0x2b019bdc48c0, 0xc820298240, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/commands/command.go:110 +0x471
main.callCommand(0x2b019bdc4998, 0xc820018840, 0x2b019bdc48c0, 0xc820298240, 0x1429e40, 0x1418e80, 0x0, 0x0, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/cmd/ipfs/main.go:343 +0xa5c
main.(*cmdInvocation).Run(0xc820018800, 0x2b019bdc4998, 0xc820018840, 0x0, 0x0, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/cmd/ipfs/main.go:186 +0x1e5
main.main()
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/cmd/ipfs/main.go:151 +0x65b

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1696 +0x1

goroutine 18 [chan receive]:
github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics.init.1.func2()
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics/metrics.go:321 +0x73
created by github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics.init.1
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/codahale/metrics/metrics.go:328 +0x7b

goroutine 19 [syscall]:
os/signal.loop()
    /usr/local/go/src/os/signal/signal_unix.go:22 +0x18
created by os/signal.init.1
    /usr/local/go/src/os/signal/signal_unix.go:28 +0x37

goroutine 20 [select]:
github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log.(*MirrorWriter).logRoutine(0xc8200ee580)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log/writer.go:71 +0x33c
created by github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log.NewMirrorWriter
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/vendor/QmQg1J6vikuXF9oDvm4wpdeAUvvkVEKW1EYDw9HhTMnP2b/go-log/writer.go:38 +0xe2

goroutine 8 [select, locked to thread]:
runtime.gopark(0x1088c00, 0xc82002c728, 0xecb298, 0x6, 0x43cd18, 0x2)
    /usr/local/go/src/runtime/proc.go:185 +0x163
runtime.selectgoImpl(0xc82002c728, 0x0, 0x18)
    /usr/local/go/src/runtime/select.go:392 +0xa64
runtime.selectgo(0xc82002c728)
    /usr/local/go/src/runtime/select.go:212 +0x12
runtime.ensureSigM.func1()
    /usr/local/go/src/runtime/signal1_unix.go:227 +0x353
runtime.goexit()
    /usr/local/go/src/runtime/asm_amd64.s:1696 +0x1

goroutine 29 [runnable]:
github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess.(*process).doClose.func1(0x0, 0x0, 0x0)
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess/impl-mutex.go:208
created by github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess.(*process).doClose
    /home/ubuntu/.go_project/src/github.com/ipfs/go-ipfs/Godeps/_workspace/src/github.com/jbenet/goprocess/impl-mutex.go:221 +0x309
not ok 50 - output looks good

@jbenet
Copy link
Member

jbenet commented Jan 20, 2016

I've never seen that error. weird. cc @whyrusleeping @rht

@whyrusleeping
Copy link
Member

that panic is because the error is not checked in that function: (repo/fsrepo/fsrepo.go:565)

    err = filepath.Walk(pth, func(p string, f os.FileInfo, err error) error {
        du += uint64(f.Size())
        return nil
    })

@whyrusleeping
Copy link
Member

you can probably ignore it, and we can fix it in another PR (file a bug for it).

Or you can maybe check the error, but i'm not sure how it propogates, so maybe its really best for another PR

@rht
Copy link
Contributor

rht commented Jan 21, 2016

'is it reproducible?' no, I tested locally and didn't see any err, and so it is not deterministic.

Explaining what had possibly happened: between ipfs cat "$PCOUT/$name" >tpcp_out && and ipfs cat "$target" >tpcp_exp &&, a gc from the first ipfs cat happened which finished in the middle of of the next gc.

if err != nil {
return nil, err
}
err = dag.EnumerateChildren(n.Context(), n.DAG, nd, ks)
Copy link
Contributor

Choose a reason for hiding this comment

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

Listing indirect keys recursively appears only in here, while I think it should be the case in pinLsKeys's indirect as well.

Copy link
Contributor

Choose a reason for hiding this comment

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

nvm, this is much like the ipfs ls and ipfs refs/ipfs refs -r case.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

pinLsKeys calls IsPinnedWithType() which does something like the above for indirect keys. See pin/pin.go around line 203.

Copy link
Contributor

Choose a reason for hiding this comment

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

@chriscool IsPinnedWithType() does have hasChild, which is recursive. However dag.EnumerateChildren also adds all the child keys into a key.KeySet. The keyset is what is needed here for recursive ls. It is orthogonal to this PR, but just to point it out (of the possibility of ipfs pin ls -r $hash or ipfs pin refs -r and deduplications).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, then please open another issue to suggest adding the -r flag, and by the way ipfs pin ls also has a --count flag but it is not used.

Copy link
Contributor

Choose a reason for hiding this comment

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

redirect: #2225

@rht
Copy link
Contributor

rht commented Jan 21, 2016

Why is context.Background used in https://github.com/ipfs/go-ipfs/blob/c49dcffce2233689ff1f6dfd003a5545338ebc5e/pin/gc/gc.go#L72-L88 ? I don't know if this would imply dangling gc processes before the next ipfs cat. I find it probably since I have seen an ipfs add exiting early before a disk write (and flush) finishes.

switch pinType {
case "direct", "indirect", "recursive", "internal":
default:
pinType = "indirect through " + pinType
Copy link
Contributor

Choose a reason for hiding this comment

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

To me, it looks like pinLsKeys = ipfs resolve | isPinnedWithType.
I wonder why is this not in IsPinnedWithType?

gc.GC() in pin/gc/gc.go uses a kind of ipfs pin ls --type=all (in Descendants and ColoredSet), so there could be a refactor here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@rht if you ask why the switch pinType { ... } is not part of IsPinnedWithType then my answer is that it would be inefficient for IsPinnedWithType users which are internal functions to have to parse "indirect through XXX" if they want to get XXX.

If there are many IsPinnedWithType users that want "indirect through XXX" then we can add IsPinnedWithTypePretty that just calls IsPinnedWithType and does what the switch pinType { ... } does.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

About refactoring with pin/gc/gc.go it does not look simple to me, and as ipfs pin ls --type=all already existed before this PR, it could have been done before. So it is independent and maybe you can open a new issue to suggest that refactoring.

Copy link
Contributor

Choose a reason for hiding this comment

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

If there are many IsPinnedWithType users that want "indirect through XXX" then we can add IsPinnedWithTypePretty that just calls IsPinnedWithType and does what the switch pinType { ... } does.

It could be the other way around, e.g. scripts parsing the output of ipfs pin ls would use IsPinnedWithType so that rows are mainly space separated.

@chriscool
Copy link
Contributor Author

Issue #2220 should take care of the bug found by the Circle CI run.

}
if typeStr == "indirect" || typeStr == "all" {
ks := key.NewKeySet()
for _, k := range n.Pinning.RecursiveKeys() {
Copy link
Contributor

Choose a reason for hiding this comment

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

ctx: https://github.com/ipfs/go-ipfs/pull/2208/files#r50369858, this line until L340 could be replaced with gc.Descendants.

Copy link
Contributor

Choose a reason for hiding this comment

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

(if you don't mind to put the refactor in this pr; nvm)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in the last commit, thanks for the suggestion.

@chriscool
Copy link
Contributor Author

@rht with the last patch that uses gc.Descendants(), t0080-repo.sh fails so I will remove it.

The error is:

expecting success: 

    ipfs refs "$MBLOCKHASH" >refsout &&
    ipfs refs -r "$HASH_WELCOME_DOCS" >>refsout &&
    sed -i"~" "s/\(.*\)/\1 indirect/g" refsout &&
    ipfs pin ls --type=indirect >indirectpins &&
    test_sort_cmp refsout indirectpins

> diff -u refsout_sorted indirectpins_sorted
--- refsout_sorted  2016-01-21 16:12:03.988386529 +0000
+++ indirectpins_sorted 2016-01-21 16:12:03.988386529 +0000
@@ -1,10 +1,13 @@
 QmPZ9gcCEpqKTo6aq61g2nXGUhM4iCL3ewB6LDXZCtioEB indirect
 QmS4GvdzPvGN2o7UcmtSRemtFBEETRoiGRYPiuqysmke6q indirect
 QmTumTjvcYCAvRRwQ8sDRxh8ezmrcr88YFU7iYNroGGTBZ indirect
+QmUNLLsPACCz1vLxQVkXqqLX5R1X345qqfHbsf67hvA3Nn indirect
 QmVb5AfSF3XdNoujRZRE2EJ3ygioKwYzbnRtzw2nswXP3t indirect
 QmWJRfqw8pP3LPcBWgUEwLkVouoETi8NsZYMnboRaBqxt1 indirect
 QmWdWMdr95FiXpR5gw2mycx5Fz9qgTiWAu4GAZ6LHSvkX5 indirect
 QmY5heUM5qgRubMDD1og9fhCPA6QdkMp3QCwd4s7gJsyE7 indirect
 QmYCvbfNbCwFR45HiNP45rwJgvatpiW38D961L5qAhUM5Y indirect
+QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG indirect
 QmZTR5bcpQD7cFgTorqxZDYaew1Wqgfbd2ud9QqGPAkK2V indirect
+QmaPFp3MR6EtgZt3c3ihyQHkctZ49azUF2d7PvRzBNFbAm indirect
 QmdncfsVm2h5Kqq9hPmU7oAVX2zTSVP3L869tgTbPYnsha indirect

not ok 26 - 'ipfs pin ls --type=indirect' is correct

@rht
Copy link
Contributor

rht commented Jan 21, 2016

ic, it is because gc.Descendants includes the recursive keys.

@jbenet
Copy link
Member

jbenet commented Jan 21, 2016

@whyrusleeping think we should merge it. im a bit wary of merging something with a known crash. since it's not really in this code (i.e unrelated) i'll merge this. 0.4.0 people, please update and warn me if you see any crashing at all.

maybe we can put effort on finding and solving #2220

jbenet added a commit that referenced this pull request Jan 21, 2016
@jbenet jbenet merged commit 9c1375f into master Jan 21, 2016
@jbenet jbenet deleted the add-arguments-to-pin-ls branch January 21, 2016 20:39
@Stebalien Stebalien mentioned this pull request Mar 15, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants