@cryptotaxi247 / kubo / commits / c53154cd2

add repo verify command

License: MIT Signed-off-by: Jeromy <why@ipfs.io>

Jeromy committed Jun 30, 2016 at 18:09 UTC c53154cd2bcfe0a33a231e04da32dd0366484ace
1 file changed +89 -6
core/commands/repo.go
+89 -6
@@ -3,15 +3,18 @@ package commands
3 import (
4 "bytes"
5 "fmt"
6 + "io"
7 + "os"
8 + "path/filepath"
9 +
10 + bstore "github.com/ipfs/go-ipfs/blocks/blockstore"
11 cmds "github.com/ipfs/go-ipfs/commands"
12 corerepo "github.com/ipfs/go-ipfs/core/corerepo"
13 config "github.com/ipfs/go-ipfs/repo/config"
14 fsrepo "github.com/ipfs/go-ipfs/repo/fsrepo"
15 lockfile "github.com/ipfs/go-ipfs/repo/fsrepo/lock"
16 +
17 u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
12 - "io"
13 - "os"
14 - "path/filepath"
18 )
19
20 type RepoVersion struct {
@@ -31,6 +34,7 @@ var RepoCmd = &cmds.Command{
34 "stat": repoStatCmd,
35 "fsck": RepoFsckCmd,
36 "version": repoVersionCmd,
37 + "verify": repoVerifyCmd,
38 },
39 }
40
@@ -207,9 +211,7 @@ daemons are running.
211 return
212 }
213
210 - s := "Lockfiles have been removed."
211 - log.Info(s)
212 - res.SetOutput(&MessageOutput{s + "\n"})
214 + res.SetOutput(&MessageOutput{"Lockfiles have been removed.\n"})
215 },
216 Type: MessageOutput{},
217 Marshalers: cmds.MarshalerMap{
@@ -217,6 +219,87 @@ daemons are running.
219 },
220 }
221
222 +type VerifyProgress struct {
223 + Message string
224 + Progress int
225 +}
226 +
227 +var repoVerifyCmd = &cmds.Command{
228 + Helptext: cmds.HelpText{
229 + Tagline: "Verify all blocks in repo are not corrupted.",
230 + },
231 + Run: func(req cmds.Request, res cmds.Response) {
232 + nd, err := req.InvocContext().GetNode()
233 + if err != nil {
234 + res.SetError(err, cmds.ErrNormal)
235 + return
236 + }
237 +
238 + out := make(chan interface{})
239 + go func() {
240 + defer close(out)
241 + bs := bstore.NewBlockstore(nd.Repo.Datastore())
242 +
243 + bs.RuntimeHashing(true)
244 +
245 + keys, err := bs.AllKeysChan(req.Context())
246 + if err != nil {
247 + log.Error(err)
248 + return
249 + }
250 +
251 + var fails int
252 + var i int
253 + for k := range keys {
254 + _, err := bs.Get(k)
255 + if err != nil {
256 + out <- &VerifyProgress{
257 + Message: fmt.Sprintf("block %s was corrupt (%s)", k, err),
258 + }
259 + fails++
260 + }
261 + i++
262 + out <- &VerifyProgress{Progress: i}
263 + }
264 + if fails == 0 {
265 + out <- &VerifyProgress{Message: "verify complete, all blocks validated."}
266 + }
267 + }()
268 +
269 + res.SetOutput((<-chan interface{})(out))
270 + },
271 + Marshalers: cmds.MarshalerMap{
272 + cmds.Text: func(res cmds.Response) (io.Reader, error) {
273 + out := res.Output().(<-chan interface{})
274 +
275 + marshal := func(v interface{}) (io.Reader, error) {
276 + obj, ok := v.(*VerifyProgress)
277 + if !ok {
278 + return nil, u.ErrCast()
279 + }
280 +
281 + buf := new(bytes.Buffer)
282 + if obj.Message != "" {
283 + if len(obj.Message) < 20 {
284 + obj.Message += " "
285 + }
286 + fmt.Fprintln(buf, obj.Message)
287 + return buf, nil
288 + }
289 +
290 + fmt.Fprintf(buf, "%d blocks processed.\r", obj.Progress)
291 + return buf, nil
292 + }
293 +
294 + return &cmds.ChannelMarshaler{
295 + Channel: out,
296 + Marshaler: marshal,
297 + Res: res,
298 + }, nil
299 + },
300 + },
301 +}
302 +
303 var repoVersionCmd = &cmds.Command{
304 Helptext: cmds.HelpText{
305 Tagline: "Show the repo version.",