Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

block put --pin #5969

Merged
merged 1 commit into from Feb 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
@@ -146,6 +146,7 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
cmdkit.StringOption(blockFormatOptionName, "f", "cid format for blocks to be created with."),
cmdkit.StringOption(mhtypeOptionName, "multihash hash function").WithDefault("sha2-256"),
cmdkit.IntOption(mhlenOptionName, "multihash hash length").WithDefault(-1),
cmdkit.BoolOption(pinOptionName, "pin added blocks recursively").WithDefault(false),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env, req)
@@ -178,7 +179,12 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
}
}

p, err := api.Block().Put(req.Context, file, options.Block.Hash(mhtval, mhlen), options.Block.Format(format))
pin, _ := req.Options[pinOptionName].(bool)

p, err := api.Block().Put(req.Context, file,
options.Block.Hash(mhtval, mhlen),
options.Block.Format(format),
options.Block.Pin(pin))
if err != nil {
return err
}
@@ -10,6 +10,7 @@ import (
util "github.com/ipfs/go-ipfs/blocks/blockstoreutil"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
pin "github.com/ipfs/go-ipfs/pin"

cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
blocks "gx/ipfs/QmWoXtvgC8inqFkAATB7cp2Dax7XBi9VDvSg9RCCZufmRk/go-block-format"
@@ -23,7 +24,7 @@ type BlockStat struct {
}

func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.BlockStat, error) {
_, pref, err := caopts.BlockPutOptions(opts...)
settings, pref, err := caopts.BlockPutOptions(opts...)
if err != nil {
return nil, err
}
@@ -43,11 +44,19 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
return nil, err
}

if settings.Pin {
defer api.blockstore.PinLock().Unlock()
}

err = api.blocks.AddBlock(b)
if err != nil {
return nil, err
}

if settings.Pin {
api.pinning.PinWithMode(b.Cid(), pin.Recursive)
}

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

@@ -10,6 +10,7 @@ type BlockPutSettings struct {
Codec string
MhType uint64
MhLength int
Pin bool
}

type BlockRmSettings struct {
@@ -24,6 +25,7 @@ func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, err
Codec: "",
MhType: mh.SHA2_256,
MhLength: -1,
Pin: false,
}

for _, opt := range opts {
@@ -105,6 +107,15 @@ func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption {
}
}

// Pin is an option for Block.Put which specifies whether to (recursively) pin
// added blocks
func (blockOpts) Pin(pin bool) BlockPutOption {
return func(settings *BlockPutSettings) error {
settings.Pin = pin
return nil
}
}

// Force is an option for Block.Rm which, when set to true, will ignore
// non-existing blocks
func (blockOpts) Force(force bool) BlockRmOption {
@@ -26,6 +26,7 @@ func (tp *provider) TestBlock(t *testing.T) {
t.Run("TestBlockGet", tp.TestBlockGet)
t.Run("TestBlockRm", tp.TestBlockRm)
t.Run("TestBlockStat", tp.TestBlockStat)
t.Run("TestBlockPin", tp.TestBlockPin)
}

func (tp *provider) TestBlockPut(t *testing.T) {
@@ -203,3 +204,40 @@ func (tp *provider) TestBlockStat(t *testing.T) {
t.Error("length doesn't match")
}
}

func (tp *provider) TestBlockPin(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
api, err := tp.makeAPI(ctx)
if err != nil {
t.Error(err)
}

_, err = api.Block().Put(ctx, strings.NewReader(`Hello`))
if err != nil {
t.Fatal(err)
}

if pins, err := api.Pin().Ls(ctx); err != nil || len(pins) != 0 {
t.Fatal("expected 0 pins")
}

res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Pin(true))
if err != nil {
t.Fatal(err)
}

pins, err := api.Pin().Ls(ctx)
if err != nil {
return
}
if len(pins) != 1 {
t.Fatal("expected 1 pin")
}
if pins[0].Type() != "recursive" {
t.Error("expected a recursive pin")
}
if pins[0].Path().String() != res.Path().String() {
t.Error("pin path didn't match")
}
}