@cryptotaxi247 / kubo / commits / ae1eb0d79

block put --pin option

License: MIT Signed-off-by: Łukasz Magiera <magik6k@gmail.com>

Łukasz Magiera committed Feb 4, 2019 at 18:05 UTC ae1eb0d79d93e523705360c5e01a70de9d8ae7db
4 files changed +66 -2
core/commands/block.go
+7 -1
@@ -146,6 +146,7 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
146 cmdkit.StringOption(blockFormatOptionName, "f", "cid format for blocks to be created with."),
147 cmdkit.StringOption(mhtypeOptionName, "multihash hash function").WithDefault("sha2-256"),
148 cmdkit.IntOption(mhlenOptionName, "multihash hash length").WithDefault(-1),
149 + cmdkit.BoolOption(pinOptionName, "pin added blocks recursively").WithDefault(false),
150 },
151 Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
152 api, err := cmdenv.GetApi(env, req)
@@ -178,7 +179,12 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
179 }
180 }
181
181 - p, err := api.Block().Put(req.Context, file, options.Block.Hash(mhtval, mhlen), options.Block.Format(format))
182 + pin, _ := req.Options[pinOptionName].(bool)
183 +
184 + p, err := api.Block().Put(req.Context, file,
185 + options.Block.Hash(mhtval, mhlen),
186 + options.Block.Format(format),
187 + options.Block.Pin(pin))
188 if err != nil {
189 return err
190 }
core/coreapi/block.go
+10 -1
@@ -10,6 +10,7 @@ import (
10 util "github.com/ipfs/go-ipfs/blocks/blockstoreutil"
11 coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
12 caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
13 + pin "github.com/ipfs/go-ipfs/pin"
14
15 cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
16 blocks "gx/ipfs/QmWoXtvgC8inqFkAATB7cp2Dax7XBi9VDvSg9RCCZufmRk/go-block-format"
@@ -23,7 +24,7 @@ type BlockStat struct {
24 }
25
26 func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.BlockPutOption) (coreiface.BlockStat, error) {
26 - _, pref, err := caopts.BlockPutOptions(opts...)
27 + settings, pref, err := caopts.BlockPutOptions(opts...)
28 if err != nil {
29 return nil, err
30 }
@@ -43,11 +44,19 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
44 return nil, err
45 }
46
47 + if settings.Pin {
48 + defer api.blockstore.PinLock().Unlock()
49 + }
50 +
51 err = api.blocks.AddBlock(b)
52 if err != nil {
53 return nil, err
54 }
55
56 + if settings.Pin {
57 + api.pinning.PinWithMode(b.Cid(), pin.Recursive)
58 + }
59 +
60 return &BlockStat{path: coreiface.IpldPath(b.Cid()), size: len(data)}, nil
61 }
62
core/coreapi/interface/options/block.go
+11
@@ -10,6 +10,7 @@ type BlockPutSettings struct {
10 Codec string
11 MhType uint64
12 MhLength int
13 + Pin bool
14 }
15
16 type BlockRmSettings struct {
@@ -24,6 +25,7 @@ func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, err
25 Codec: "",
26 MhType: mh.SHA2_256,
27 MhLength: -1,
28 + Pin: false,
29 }
30
31 for _, opt := range opts {
@@ -105,6 +107,15 @@ func (blockOpts) Hash(mhType uint64, mhLen int) BlockPutOption {
107 }
108 }
109
110 +// Pin is an option for Block.Put which specifies whether to (recursively) pin
111 +// added blocks
112 +func (blockOpts) Pin(pin bool) BlockPutOption {
113 + return func(settings *BlockPutSettings) error {
114 + settings.Pin = pin
115 + return nil
116 + }
117 +}
118 +
119 // Force is an option for Block.Rm which, when set to true, will ignore
120 // non-existing blocks
121 func (blockOpts) Force(force bool) BlockRmOption {
core/coreapi/interface/tests/block.go
+38
@@ -26,6 +26,7 @@ func (tp *provider) TestBlock(t *testing.T) {
26 t.Run("TestBlockGet", tp.TestBlockGet)
27 t.Run("TestBlockRm", tp.TestBlockRm)
28 t.Run("TestBlockStat", tp.TestBlockStat)
29 + t.Run("TestBlockPin", tp.TestBlockPin)
30 }
31
32 func (tp *provider) TestBlockPut(t *testing.T) {
@@ -203,3 +204,40 @@ func (tp *provider) TestBlockStat(t *testing.T) {
204 t.Error("length doesn't match")
205 }
206 }
207 +
208 +func (tp *provider) TestBlockPin(t *testing.T) {
209 + ctx, cancel := context.WithCancel(context.Background())
210 + defer cancel()
211 + api, err := tp.makeAPI(ctx)
212 + if err != nil {
213 + t.Error(err)
214 + }
215 +
216 + _, err = api.Block().Put(ctx, strings.NewReader(`Hello`))
217 + if err != nil {
218 + t.Fatal(err)
219 + }
220 +
221 + if pins, err := api.Pin().Ls(ctx); err != nil || len(pins) != 0 {
222 + t.Fatal("expected 0 pins")
223 + }
224 +
225 + res, err := api.Block().Put(ctx, strings.NewReader(`Hello`), opt.Block.Pin(true))
226 + if err != nil {
227 + t.Fatal(err)
228 + }
229 +
230 + pins, err := api.Pin().Ls(ctx)
231 + if err != nil {
232 + return
233 + }
234 + if len(pins) != 1 {
235 + t.Fatal("expected 1 pin")
236 + }
237 + if pins[0].Type() != "recursive" {
238 + t.Error("expected a recursive pin")
239 + }
240 + if pins[0].Path().String() != res.Path().String() {
241 + t.Error("pin path didn't match")
242 + }
243 +}