1
0
mirror of https://github.com/ipfs/kubo.git synced 2025-06-01 16:05:47 +08:00
Files
kubo/core/commands/block.go
Steven Allen b7484c1bca gx: update go-ipfs-cmds to the final release
License: MIT
Signed-off-by: Steven Allen <steven@stebalien.com>
2018-09-19 14:36:08 -07:00

269 lines
6.6 KiB
Go

package commands
import (
"errors"
"fmt"
"io"
"os"
util "github.com/ipfs/go-ipfs/blocks/blockstoreutil"
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
e "github.com/ipfs/go-ipfs/core/commands/e"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
cmds "gx/ipfs/QmPXR4tNdLbp8HsZiPMjpsgqphX9Vhw2J6Jh5MKH2ovW3D/go-ipfs-cmds"
mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
cmdkit "gx/ipfs/QmSP88ryZkHSRn1fnngAaV2Vcn63WUJzAavnRM9CVdU1Ky/go-ipfs-cmdkit"
)
type BlockStat struct {
Key string
Size int
}
func (bs BlockStat) String() string {
return fmt.Sprintf("Key: %s\nSize: %d\n", bs.Key, bs.Size)
}
var BlockCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Interact with raw IPFS blocks.",
ShortDescription: `
'ipfs block' is a plumbing command used to manipulate raw IPFS blocks.
Reads from stdin or writes to stdout, and <key> is a base58 encoded
multihash.
`,
},
Subcommands: map[string]*cmds.Command{
"stat": blockStatCmd,
"get": blockGetCmd,
"put": blockPutCmd,
"rm": blockRmCmd,
},
}
var blockStatCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Print information of a raw IPFS block.",
ShortDescription: `
'ipfs block stat' is a plumbing command for retrieving information
on raw IPFS blocks. It outputs the following to stdout:
Key - the base58 encoded multihash
Size - the size of the block in bytes
`,
},
Arguments: []cmdkit.Argument{
cmdkit.StringArg("key", true, false, "The base58 multihash of an existing block to stat.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
if err != nil {
return err
}
p, err := coreiface.ParsePath(req.Arguments[0])
if err != nil {
return err
}
b, err := api.Block().Stat(req.Context, p)
if err != nil {
return err
}
return cmds.EmitOnce(res, &BlockStat{
Key: b.Path().Cid().String(),
Size: b.Size(),
})
},
Type: BlockStat{},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
bs, ok := v.(*BlockStat)
if !ok {
return e.TypeErr(bs, v)
}
_, err := fmt.Fprintf(w, "%s", bs)
return err
}),
},
}
var blockGetCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Get a raw IPFS block.",
ShortDescription: `
'ipfs block get' is a plumbing command for retrieving raw IPFS blocks.
It outputs to stdout, and <key> is a base58 encoded multihash.
`,
},
Arguments: []cmdkit.Argument{
cmdkit.StringArg("key", true, false, "The base58 multihash of an existing block to get.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
if err != nil {
return err
}
p, err := coreiface.ParsePath(req.Arguments[0])
if err != nil {
return err
}
r, err := api.Block().Get(req.Context, p)
if err != nil {
return err
}
return res.Emit(r)
},
}
var blockPutCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Store input as an IPFS block.",
ShortDescription: `
'ipfs block put' is a plumbing command for storing raw IPFS blocks.
It reads from stdin, and <key> is a base58 encoded multihash.
By default CIDv0 is going to be generated. Setting 'mhtype' to anything other
than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
`,
},
Arguments: []cmdkit.Argument{
cmdkit.FileArg("data", true, false, "The data to be stored as an IPFS block.").EnableStdin(),
},
Options: []cmdkit.Option{
cmdkit.StringOption("format", "f", "cid format for blocks to be created with."),
cmdkit.StringOption("mhtype", "multihash hash function").WithDefault("sha2-256"),
cmdkit.IntOption("mhlen", "multihash hash length").WithDefault(-1),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
if err != nil {
return err
}
file, err := req.Files.NextFile()
if err != nil {
return err
}
mhtype, _ := req.Options["mhtype"].(string)
mhtval, ok := mh.Names[mhtype]
if !ok {
return fmt.Errorf("unrecognized multihash function: %s", mhtype)
}
mhlen, ok := req.Options["mhlen"].(int)
if !ok {
return errors.New("missing option \"mhlen\"")
}
format, formatSet := req.Options["format"].(string)
if !formatSet {
if mhtval != mh.SHA2_256 || (mhlen != -1 && mhlen != 32) {
format = "protobuf"
} else {
format = "v0"
}
}
p, err := api.Block().Put(req.Context, file, options.Block.Hash(mhtval, mhlen), options.Block.Format(format))
if err != nil {
return err
}
return cmds.EmitOnce(res, &BlockStat{
Key: p.Path().Cid().String(),
Size: p.Size(),
})
},
Encoders: cmds.EncoderMap{
cmds.Text: cmds.MakeEncoder(func(req *cmds.Request, w io.Writer, v interface{}) error {
bs, ok := v.(*BlockStat)
if !ok {
return e.TypeErr(bs, v)
}
_, err := fmt.Fprintf(w, "%s\n", bs.Key)
return err
}),
},
Type: BlockStat{},
}
var blockRmCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Remove IPFS block(s).",
ShortDescription: `
'ipfs block rm' is a plumbing command for removing raw ipfs blocks.
It takes a list of base58 encoded multihashes to remove.
`,
},
Arguments: []cmdkit.Argument{
cmdkit.StringArg("hash", true, true, "Bash58 encoded multihash of block(s) to remove."),
},
Options: []cmdkit.Option{
cmdkit.BoolOption("force", "f", "Ignore nonexistent blocks."),
cmdkit.BoolOption("quiet", "q", "Write minimal output."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
if err != nil {
return err
}
force, _ := req.Options["force"].(bool)
quiet, _ := req.Options["quiet"].(bool)
// TODO: use batching coreapi when done
for _, b := range req.Arguments {
p, err := coreiface.ParsePath(b)
if err != nil {
return err
}
rp, err := api.ResolvePath(req.Context, p)
if err != nil {
return err
}
err = api.Block().Rm(req.Context, rp, options.Block.Force(force))
if err != nil {
err := res.Emit(&util.RemovedBlock{
Hash: rp.Cid().String(),
Error: err.Error(),
})
if err != nil {
return err
}
}
if !quiet {
err := res.Emit(&util.RemovedBlock{
Hash: rp.Cid().String(),
})
if err != nil {
return err
}
}
}
return nil
},
PostRun: cmds.PostRunMap{
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
return util.ProcRmOutput(res.Next, os.Stdout, os.Stderr)
},
},
Type: util.RemovedBlock{},
}