Commit f0781d81 authored by Jeromy's avatar Jeromy

initial implementation of repo-gc command

parent 99872f61
......@@ -9,11 +9,11 @@ import (
"time"
cmds "github.com/jbenet/go-ipfs/commands"
config "github.com/jbenet/go-ipfs/repo/config"
core "github.com/jbenet/go-ipfs/core"
ipns "github.com/jbenet/go-ipfs/fuse/ipns"
mount "github.com/jbenet/go-ipfs/fuse/mount"
rofs "github.com/jbenet/go-ipfs/fuse/readonly"
config "github.com/jbenet/go-ipfs/repo/config"
)
// amount of time to wait for mount errors
......
package commands
import (
"bytes"
"fmt"
"io"
cmds "github.com/jbenet/go-ipfs/commands"
"github.com/jbenet/go-ipfs/core"
u "github.com/jbenet/go-ipfs/util"
)
var RepoCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Manipulate the IPFS repo",
ShortDescription: `
'ipfs repo' is a plumbing command used to manipulate the repo.
`,
},
Subcommands: map[string]*cmds.Command{
"gc": repoGcCmd,
},
}
type KeyRemoved struct {
Key u.Key
}
var repoGcCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Perform a garbage collection sweep on the repo",
ShortDescription: `
'ipfs repo gc' is a plumbing command that will sweep the local
set of stored objects and remove ones that are not pinned in
order to reclaim hard disk space.
`,
},
Options: []cmds.Option{
cmds.BoolOption("quiet", "q", "Write minimal output"),
},
Run: func(req cmds.Request) (interface{}, error) {
n, err := req.Context().GetNode()
if err != nil {
return nil, err
}
keychan, err := n.Blockstore.AllKeysChan(req.Context().Context, 0, 1<<16)
if err != nil {
return nil, err
}
outChan := make(chan interface{})
go GarbageCollectBlockstore(n, keychan, outChan)
return outChan, nil
},
Type: KeyRemoved{},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
outChan, ok := res.Output().(chan interface{})
if !ok {
return nil, u.ErrCast()
}
quiet, _, err := res.Request().Option("quiet").Bool()
if err != nil {
return nil, err
}
marshal := func(v interface{}) (io.Reader, error) {
obj, ok := v.(*KeyRemoved)
if !ok {
return nil, u.ErrCast()
}
var buf *bytes.Buffer
if quiet {
buf = bytes.NewBufferString(string(obj.Key) + "\n")
} else {
buf = bytes.NewBufferString(fmt.Sprintf("removed %s\n", obj.Key))
}
return buf, nil
}
return &cmds.ChannelMarshaler{
Channel: outChan,
Marshaler: marshal,
}, nil
},
},
}
func GarbageCollectBlockstore(n *core.IpfsNode, keychan <-chan u.Key, output chan interface{}) {
defer close(output)
for k := range keychan {
if !n.Pinning.IsPinned(k) {
err := n.Blockstore.DeleteBlock(k)
if err != nil {
log.Errorf("Error removing key from blockstore: %s", err)
}
output <- &KeyRemoved{k}
}
}
}
......@@ -79,9 +79,10 @@ var rootSubcommands = map[string]*cmds.Command{
"name": NameCmd,
"object": ObjectCmd,
"pin": PinCmd,
"ping": PingCmd,
"refs": RefsCmd,
"repo": RepoCmd,
"swarm": SwarmCmd,
"ping": PingCmd,
"update": UpdateCmd,
"version": VersionCmd,
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment