Skip to content

Commit

Permalink
block cmd: use coreapi
Browse files Browse the repository at this point in the history
License: MIT
Signed-off-by: Łukasz Magiera <[email protected]>
  • Loading branch information
magik6k committed Aug 2, 2018
1 parent 83f22d5 commit 97ffa39
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 110 deletions.
169 changes: 62 additions & 107 deletions core/commands/block.go
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
package commands

import (
"bytes"
"context"
"errors"
"fmt"
"io"
"io/ioutil"
"os"

util "github.com/ipfs/go-ipfs/blocks/blockstoreutil"
e "github.com/ipfs/go-ipfs/core/commands/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"

"gx/ipfs/QmNueRyPRQiV7PUEpnP4GgGLuK1rKQLaRW7sfPvUetYig1/go-ipfs-cmds"
mh "gx/ipfs/QmPnFwZ2JXKnXgMw8CdBPxn7FWh6LLdjUjxV1fKHuJnkr8/go-multihash"
blocks "gx/ipfs/QmVzK524a2VWLqyvtBeiHKsUAWYgeAk4DBeZoY7vpNPNRx/go-block-format"
cid "gx/ipfs/QmYVNvtQkeZ6AKSwDrjQTs432QtL6umrrK41EBq3cu7iSP/go-cid"
"gx/ipfs/QmdE4gMduCKCGAcczM2F5ioYDfdeKuPix138wrES1YSr7f/go-ipfs-cmdkit"
)

Expand Down Expand Up @@ -63,15 +59,27 @@ on raw IPFS blocks. It outputs the following to stdout:
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) {
b, err := getBlockForKey(req.Context, env, req.Arguments[0])
api, err := GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

p, err := coreiface.ParsePath(req.Arguments[0])
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

b, err := api.Block().Stat(req.Context, p)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

err = cmds.EmitOnce(res, &BlockStat{
Key: b.Cid().String(),
Size: len(b.RawData()),
Key: b.Path().Cid().String(),
Size: b.Size(),
})
if err != nil {
log.Error(err)
Expand Down Expand Up @@ -103,13 +111,25 @@ It outputs to stdout, and <key> is a base58 encoded multihash.
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) {
b, err := getBlockForKey(req.Context, env, req.Arguments[0])
api, err := GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

p, err := coreiface.ParsePath(req.Arguments[0])
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

r, err := api.Block().Get(req.Context, p)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

err = res.Emit(bytes.NewReader(b.RawData()))
err = res.Emit(r)
if err != nil {
log.Error(err)
}
Expand Down Expand Up @@ -137,7 +157,7 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
cmdkit.IntOption("mhlen", "multihash hash length").WithDefault(-1),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
n, err := GetNode(env)
api, err := GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
Expand All @@ -149,18 +169,6 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
return
}

data, err := ioutil.ReadAll(file)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

err = file.Close()
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

mhtype, _ := req.Options["mhtype"].(string)
mhtval, ok := mh.Names[mhtype]
if !ok {
Expand All @@ -169,8 +177,11 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
return
}

var pref cid.Prefix
pref.Version = 1
mhlen, ok := req.Options["mhlen"].(int)
if !ok {
res.SetError("missing option \"mhlen\"", cmdkit.ErrNormal)
return
}

format, formatSet := req.Options["format"].(string)
if !formatSet {
Expand All @@ -181,50 +192,15 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
}
}

if format == "v0" {
pref.Version = 0
}
formatval, ok := cid.Codecs[format]
if !ok {
res.SetError(fmt.Errorf("unrecognized format: '%s'", format), cmdkit.ErrNormal)
return
}
if mhtval != mh.SHA2_256 && pref.Version == 0 {
res.SetError(errors.New("cannot generate CIDv0 with non-sha256 hash function"), cmdkit.ErrNormal)
return
}

pref.Codec = formatval
pref.MhType = mhtval

mhlen, ok := req.Options["mhlen"].(int)
if !ok {
res.SetError("missing option \"mhlen\"", cmdkit.ErrNormal)
return
}
pref.MhLength = mhlen

bcid, err := pref.Sum(data)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

b, err := blocks.NewBlockWithCid(data, bcid)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

err = n.Blocks.AddBlock(b)
p, err := api.Block().Put(req.Context, file, options.Block.Hash(mhtval, mhlen), options.Block.Format(format))
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

err = cmds.EmitOnce(res, &BlockStat{
Key: b.Cid().String(),
Size: len(data),
Key: p.Path().Cid().String(),
Size: p.Size(),
})
if err != nil {
log.Error(err)
Expand All @@ -243,29 +219,6 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
Type: BlockStat{},
}

func getBlockForKey(ctx context.Context, env cmds.Environment, skey string) (blocks.Block, error) {
if len(skey) == 0 {
return nil, fmt.Errorf("zero length cid invalid")
}

n, err := GetNode(env)
if err != nil {
return nil, err
}

c, err := cid.Decode(skey)
if err != nil {
return nil, err
}

b, err := n.Blocks.GetBlock(ctx, c)
if err != nil {
return nil, err
}

return b, nil
}

var blockRmCmd = &cmds.Command{
Helptext: cmdkit.HelpText{
Tagline: "Remove IPFS block(s).",
Expand All @@ -282,38 +235,40 @@ It takes a list of base58 encoded multihashes to remove.
cmdkit.BoolOption("quiet", "q", "Write minimal output."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) {
n, err := GetNode(env)
api, err := GetApi(env)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
hashes := req.Arguments

force, _ := req.Options["force"].(bool)
quiet, _ := req.Options["quiet"].(bool)
cids := make([]*cid.Cid, 0, len(hashes))
for _, hash := range hashes {
c, err := cid.Decode(hash)

// TODO: use batching coreapi when done
for _, b := range req.Arguments {
p, err := coreiface.ParsePath(b)
if err != nil {
err = fmt.Errorf("invalid content id: %s (%s)", hash, err)
res.SetError(err, cmdkit.ErrNormal)
return
}

cids = append(cids, c)
}
ch, err := util.RmBlocks(n.Blockstore, n.Pinning, cids, util.RmBlocksOpts{
Quiet: quiet,
Force: force,
})
rp, err := api.ResolvePath(req.Context, p)
if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}

if err != nil {
res.SetError(err, cmdkit.ErrNormal)
return
}
err = api.Block().Rm(req.Context, rp, options.Block.Force(force))
if err != nil && !quiet {
res.Emit(&util.RemovedBlock{
Hash: rp.Cid().String(),
Error: err.Error(),
})
}

err = res.Emit(ch)
if err != nil {
log.Error(err)
res.Emit(&util.RemovedBlock{
Hash: rp.Cid().String(),
})
}
},
PostRun: cmds.PostRunMap{
Expand Down
4 changes: 2 additions & 2 deletions core/coreapi/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ type BlockStat struct {
size int
}

func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.ResolvedPath, error) {
func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.BlockStat, error) {
settings, err := caopts.BlockPutOptions(opts...)
if err != nil {
return nil, err
Expand Down Expand Up @@ -65,7 +65,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
return nil, err
}

return coreiface.IpldPath(b.Cid()), nil
return &BlockStat{path: coreiface.IpldPath(b.Cid()), size: len(data)}, nil
}

func (api *BlockAPI) Get(ctx context.Context, p coreiface.Path) (io.Reader, error) {
Expand Down
2 changes: 1 addition & 1 deletion core/coreapi/interface/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type BlockStat interface {
// BlockAPI specifies the interface to the block layer
type BlockAPI interface {
// Put imports raw block data, hashing it using specified settings.
Put(context.Context, io.Reader, ...options.BlockPutOption) (ResolvedPath, error)
Put(context.Context, io.Reader, ...options.BlockPutOption) (BlockStat, error)

// Get attempts to resolve the path and return a reader for data in the block
Get(context.Context, Path) (io.Reader, error)
Expand Down

0 comments on commit 97ffa39

Please sign in to comment.