1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-08-06 03:19:47 +08:00
Files
kubo/core/commands/repo.go
Richard Littauer f52050de80 Added Default false to all remaining options
Specifically, to `repo`, `resolve`, `swarm`, and `version`. Part of #2484.

License: MIT
Signed-off-by: Richard Littauer <richard.littauer@gmail.com>
2016-05-12 12:02:47 -04:00

211 lines
5.2 KiB
Go

package commands
import (
"bytes"
"fmt"
cmds "github.com/ipfs/go-ipfs/commands"
corerepo "github.com/ipfs/go-ipfs/core/corerepo"
config "github.com/ipfs/go-ipfs/repo/config"
lockfile "github.com/ipfs/go-ipfs/repo/fsrepo/lock"
u "gx/ipfs/QmZNVWh8LLjAavuQ2JXuFmuYH3C11xo988vSgp7UQrTRj1/go-ipfs-util"
"io"
"os"
"path/filepath"
)
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,
"stat": repoStatCmd,
"fsck": RepoFsckCmd,
},
}
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.").Default(false),
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
gcOutChan, err := corerepo.GarbageCollectAsync(n, req.Context())
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
outChan := make(chan interface{})
res.SetOutput((<-chan interface{})(outChan))
go func() {
defer close(outChan)
for k := range gcOutChan {
outChan <- k
}
}()
},
Type: corerepo.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.(*corerepo.KeyRemoved)
if !ok {
return nil, u.ErrCast()
}
buf := new(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,
Res: res,
}, nil
},
},
}
var repoStatCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Get stats for the currently used repo.",
ShortDescription: `
'ipfs repo stat' is a plumbing command that will scan the local
set of stored objects and print repo statistics. It outputs to stdout:
NumObjects int Number of objects in the local repo.
RepoPath string The path to the repo being currently used.
RepoSize int Size in bytes that the repo is currently taking.
`,
},
Run: func(req cmds.Request, res cmds.Response) {
n, err := req.InvocContext().GetNode()
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
stat, err := corerepo.RepoStat(n, req.Context())
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
res.SetOutput(stat)
},
Options: []cmds.Option{
cmds.BoolOption("human", "Output RepoSize in MiB.").Default(false),
},
Type: corerepo.Stat{},
Marshalers: cmds.MarshalerMap{
cmds.Text: func(res cmds.Response) (io.Reader, error) {
stat, ok := res.Output().(*corerepo.Stat)
if !ok {
return nil, u.ErrCast()
}
human, _, err := res.Request().Option("human").Bool()
if err != nil {
return nil, err
}
buf := new(bytes.Buffer)
fmt.Fprintf(buf, "NumObjects \t %d\n", stat.NumObjects)
sizeInMiB := stat.RepoSize / (1024 * 1024)
if human && sizeInMiB > 0 {
fmt.Fprintf(buf, "RepoSize (MiB) \t %d\n", sizeInMiB)
} else {
fmt.Fprintf(buf, "RepoSize \t %d\n", stat.RepoSize)
}
fmt.Fprintf(buf, "RepoPath \t %s\n", stat.RepoPath)
return buf, nil
},
},
}
var RepoFsckCmd = &cmds.Command{
Helptext: cmds.HelpText{
Tagline: "Removes repo lockfiles.",
ShortDescription: `
'ipfs repo fsck' is a plumbing command that will remove repo and level db
lockfiles, as well as the api file. This command can only run when no ipfs
daemons are running.
`,
},
Run: func(req cmds.Request, res cmds.Response) {
configRoot := req.InvocContext().ConfigRoot
dsPath, err := config.DataStorePath(configRoot)
if err != nil {
res.SetError(err, cmds.ErrNormal)
return
}
dsLockFile := filepath.Join(dsPath, "LOCK") // TODO: get this lockfile programmatically
repoLockFile := filepath.Join(configRoot, lockfile.LockFile)
apiFile := filepath.Join(configRoot, "api") // TODO: get this programmatically
log.Infof("Removing repo lockfile: %s", repoLockFile)
log.Infof("Removing datastore lockfile: %s", dsLockFile)
log.Infof("Removing api file: %s", apiFile)
err = os.Remove(repoLockFile)
if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmds.ErrNormal)
return
}
err = os.Remove(dsLockFile)
if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmds.ErrNormal)
return
}
err = os.Remove(apiFile)
if err != nil && !os.IsNotExist(err) {
res.SetError(err, cmds.ErrNormal)
return
}
s := "Lockfiles have been removed."
log.Info(s)
res.SetOutput(&MessageOutput{s + "\n"})
},
Type: MessageOutput{},
Marshalers: cmds.MarshalerMap{
cmds.Text: MessageTextMarshaler,
},
}