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 repo verify command #2924

Merged
merged 2 commits into from
Jul 6, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 95 additions & 6 deletions core/commands/repo.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,19 @@ package commands
import (
"bytes"
"fmt"
"io"
"os"
"path/filepath"
"strings"

bstore "github.com/ipfs/go-ipfs/blocks/blockstore"
cmds "github.com/ipfs/go-ipfs/commands"
corerepo "github.com/ipfs/go-ipfs/core/corerepo"
config "github.com/ipfs/go-ipfs/repo/config"
fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
lockfile "github.com/ipfs/go-ipfs/repo/fsrepo/lock"

u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
"io"
"os"
"path/filepath"
)

type RepoVersion struct {
Expand All @@ -31,6 +35,7 @@ var RepoCmd = &cmds.Command{
"stat": repoStatCmd,
"fsck": RepoFsckCmd,
"version": repoVersionCmd,
"verify": repoVerifyCmd,
},
}

Expand Down Expand Up @@ -207,16 +212,100 @@ daemons are running.
return
}

s := "Lockfiles have been removed."
log.Info(s)
res.SetOutput(&MessageOutput{s + "\n"})
res.SetOutput(&MessageOutput{"Lockfiles have been removed.\n"})
},
Type: MessageOutput{},
Marshalers: cmds.MarshalerMap{
cmds.Text: MessageTextMarshaler,
},
}

type VerifyProgress struct {
Message string
Progress int
}

var repoVerifyCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Verify all blocks in repo are not corrupted.",
},
Run: func(req cmds.Request, res cmds.Response) {
nd, err := req.InvocContext().GetNode()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}

out := make(chan interface{})
Copy link
Member

Choose a reason for hiding this comment

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

buffer of 1?

Copy link
Member

Choose a reason for hiding this comment

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

i guess dont need it, but usually good to do it for cases like this

go func() {
defer close(out)
bs := bstore.NewBlockstore(nd.Repo.Datastore())

bs.RuntimeHashing(true)

keys, err := bs.AllKeysChan(req.Context())
if err != nil {
log.Error(err)
return
}

var fails int
var i int
Copy link
Member

@jbenet jbenet Aug 27, 2016

Choose a reason for hiding this comment

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

use total, not i

for k := range keys {
_, err := bs.Get(k)
if err != nil {
out <- &VerifyProgress{
Message: fmt.Sprintf("block %s was corrupt (%s)", k, err),
}
fails++
}
i++
out <- &VerifyProgress{Progress: i}
}
if fails == 0 {
out <- &VerifyProgress{Message: "verify complete, all blocks validated."}
} else {
out <- &VerifyProgress{Message: "verify complete, some blocks were corrupt."}
}
}()

res.SetOutput((<-chan interface{})(out))
},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
out := res.Output().(<-chan interface{})

marshal := func(v interface{}) (io.Reader, error) {
obj, ok := v.(*VerifyProgress)
if !ok {
return nil, u.ErrCast()
}

buf := new(bytes.Buffer)
if obj.Message != "" {
if strings.Contains(obj.Message, "blocks were corrupt") {
return nil, fmt.Errorf(obj.Message)
}
if len(obj.Message) < 20 {
obj.Message += " "
}
fmt.Fprintln(buf, obj.Message)
return buf, nil
}

fmt.Fprintf(buf, "%d blocks processed.\r", obj.Progress)
return buf, nil
}

return &cmds.ChannelMarshaler{
Channel: out,
Marshaler: marshal,
Res: res,
}, nil
},
},
}

var repoVersionCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Show the repo version.",
Expand Down
5 changes: 5 additions & 0 deletions test/sharness/t0084-repo-read-rehash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,9 @@ test_expect_success 'getting modified block fails' '
grep "block in storage has different hash than requested" err_msg
'

test_expect_success "block shows up in repo verify" '
test_expect_code 1 ipfs repo verify > verify_out &&
grep "$H_BLOCK2" verify_out
'
Copy link
Member

Choose a reason for hiding this comment

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

this needs much more robust testing!!

  • it needs a case with hundreds of objects that all check out fine
  • manipulate one object at random, verify should now fail
  • fix the object, verify should now pass again


test_done