@cryptotaxi247 / kubo / commits / f0781d811

initial implementation of repo-gc command

Jeromy committed Jan 14, 2015 at 00:01 UTC f0781d81197745e73814dbf0e2c985fe1658d645
3 files changed +107 -2
core/commands/mount_unix.go
+1 -1
@@ -9,11 +9,11 @@ import (
9 "time"
10
11 cmds "github.com/jbenet/go-ipfs/commands"
12 - config "github.com/jbenet/go-ipfs/repo/config"
12 core "github.com/jbenet/go-ipfs/core"
13 ipns "github.com/jbenet/go-ipfs/fuse/ipns"
14 mount "github.com/jbenet/go-ipfs/fuse/mount"
15 rofs "github.com/jbenet/go-ipfs/fuse/readonly"
16 + config "github.com/jbenet/go-ipfs/repo/config"
17 )
18
19 // amount of time to wait for mount errors
core/commands/repo.go new
+104
@@ -0,0 +1,104 @@
1 +package commands
2 +
3 +import (
4 + "bytes"
5 + "fmt"
6 + "io"
7 + cmds "github.com/jbenet/go-ipfs/commands"
8 + "github.com/jbenet/go-ipfs/core"
9 + u "github.com/jbenet/go-ipfs/util"
10 +)
11 +
12 +var RepoCmd = &cmds.Command{
13 + Helptext: cmds.HelpText{
14 + Tagline: "Manipulate the IPFS repo",
15 + ShortDescription: `
16 +'ipfs repo' is a plumbing command used to manipulate the repo.
17 +`,
18 + },
19 +
20 + Subcommands: map[string]*cmds.Command{
21 + "gc": repoGcCmd,
22 + },
23 +}
24 +
25 +type KeyRemoved struct {
26 + Key u.Key
27 +}
28 +
29 +var repoGcCmd = &cmds.Command{
30 + Helptext: cmds.HelpText{
31 + Tagline: "Perform a garbage collection sweep on the repo",
32 + ShortDescription: `
33 +'ipfs repo gc' is a plumbing command that will sweep the local
34 +set of stored objects and remove ones that are not pinned in
35 +order to reclaim hard disk space.
36 +`,
37 + },
38 +
39 + Options: []cmds.Option{
40 + cmds.BoolOption("quiet", "q", "Write minimal output"),
41 + },
42 + Run: func(req cmds.Request) (interface{}, error) {
43 + n, err := req.Context().GetNode()
44 + if err != nil {
45 + return nil, err
46 + }
47 +
48 + keychan, err := n.Blockstore.AllKeysChan(req.Context().Context, 0, 1<<16)
49 + if err != nil {
50 + return nil, err
51 + }
52 +
53 + outChan := make(chan interface{})
54 + go GarbageCollectBlockstore(n, keychan, outChan)
55 + return outChan, nil
56 + },
57 + Type: KeyRemoved{},
58 + Marshalers: cmds.MarshalerMap{
59 + cmds.Text: func(res cmds.Response) (io.Reader, error) {
60 + outChan, ok := res.Output().(chan interface{})
61 + if !ok {
62 + return nil, u.ErrCast()
63 + }
64 +
65 + quiet, _, err := res.Request().Option("quiet").Bool()
66 + if err != nil {
67 + return nil, err
68 + }
69 +
70 + marshal := func(v interface{}) (io.Reader, error) {
71 + obj, ok := v.(*KeyRemoved)
72 + if !ok {
73 + return nil, u.ErrCast()
74 + }
75 +
76 + var buf *bytes.Buffer
77 + if quiet {
78 + buf = bytes.NewBufferString(string(obj.Key) + "\n")
79 + } else {
80 + buf = bytes.NewBufferString(fmt.Sprintf("removed %s\n", obj.Key))
81 + }
82 + return buf, nil
83 + }
84 +
85 + return &cmds.ChannelMarshaler{
86 + Channel: outChan,
87 + Marshaler: marshal,
88 + }, nil
89 + },
90 + },
91 +}
92 +
93 +func GarbageCollectBlockstore(n *core.IpfsNode, keychan <-chan u.Key, output chan interface{}) {
94 + defer close(output)
95 + for k := range keychan {
96 + if !n.Pinning.IsPinned(k) {
97 + err := n.Blockstore.DeleteBlock(k)
98 + if err != nil {
99 + log.Errorf("Error removing key from blockstore: %s", err)
100 + }
101 + output <- &KeyRemoved{k}
102 + }
103 + }
104 +}
core/commands/root.go
+2 -1
@@ -79,9 +79,10 @@ var rootSubcommands = map[string]*cmds.Command{
79 "name": NameCmd,
80 "object": ObjectCmd,
81 "pin": PinCmd,
82 + "ping": PingCmd,
83 "refs": RefsCmd,
84 + "repo": RepoCmd,
85 "swarm": SwarmCmd,
84 - "ping": PingCmd,
86 "update": UpdateCmd,
87 "version": VersionCmd,
88 }