From 89fc7f2a3083de2ecd66ec7d1865e6cc8f591f24 Mon Sep 17 00:00:00 2001 From: Iaroslav Gridin Date: Thu, 17 Sep 2020 17:17:10 +0300 Subject: [PATCH] Support named pins [ipfs/go-ipfs#4757] --- options/block.go | 10 ++++++++++ options/object.go | 10 ++++++++++ options/pin.go | 39 ++++++++++++++++++++++----------------- options/unixfs.go | 11 +++++++++++ pin.go | 24 +++++++++++++++--------- tests/block.go | 4 ++-- tests/pin.go | 20 +++++++++++--------- tests/unixfs.go | 2 +- 8 files changed, 82 insertions(+), 38 deletions(-) diff --git a/options/block.go b/options/block.go index 043dfde..b566cc3 100644 --- a/options/block.go +++ b/options/block.go @@ -11,6 +11,7 @@ type BlockPutSettings struct { MhType uint64 MhLength int Pin bool + PinPath string } type BlockRmSettings struct { @@ -26,6 +27,7 @@ func BlockPutOptions(opts ...BlockPutOption) (*BlockPutSettings, cid.Prefix, err MhType: mh.SHA2_256, MhLength: -1, Pin: false, + PinPath: "default/", } for _, opt := range opts { @@ -116,6 +118,14 @@ func (blockOpts) Pin(pin bool) BlockPutOption { } } +// PinPath is an option for Block.Put which specifies under which path to pin the block, default is "added/" +func (blockOpts) PinPath(pinPath string) BlockPutOption { + return func(settings *BlockPutSettings) error { + settings.PinPath = pinPath + 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 { diff --git a/options/object.go b/options/object.go index e484a9f..3847e3a 100644 --- a/options/object.go +++ b/options/object.go @@ -8,6 +8,7 @@ type ObjectPutSettings struct { InputEnc string DataType string Pin bool + PinPath string } type ObjectAddLinkSettings struct { @@ -37,6 +38,7 @@ func ObjectPutOptions(opts ...ObjectPutOption) (*ObjectPutSettings, error) { InputEnc: "json", DataType: "text", Pin: false, + PinPath: "added/", } for _, opt := range opts { @@ -114,6 +116,14 @@ func (objectOpts) Pin(pin bool) ObjectPutOption { } } +// PinPath is an option for Object.Put which specifies under which path to pin the object, default is "added/" +func (objectOpts) PinPath(pinPath string) ObjectPutOption { + return func(settings *ObjectPutSettings) error { + settings.PinPath = pinPath + return nil + } +} + // Create is an option for Object.AddLink which specifies whether create required // directories for the child func (objectOpts) Create(create bool) ObjectAddLinkOption { diff --git a/options/pin.go b/options/pin.go index 5014a2d..9ac5b16 100644 --- a/options/pin.go +++ b/options/pin.go @@ -5,11 +5,14 @@ import "fmt" // PinAddSettings represent the settings for PinAPI.Add type PinAddSettings struct { Recursive bool + PinPath string } // PinLsSettings represent the settings for PinAPI.Ls type PinLsSettings struct { - Type string + Type string + Recursive bool + PinPath string } // PinIsPinnedSettings represent the settings for PinAPI.IsPinned @@ -24,7 +27,7 @@ type PinRmSettings struct { // PinUpdateSettings represent the settings for PinAPI.Update type PinUpdateSettings struct { - Unpin bool + } // PinAddOption is the signature of an option for PinAPI.Add @@ -47,6 +50,7 @@ type PinUpdateOption func(*PinUpdateSettings) error func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { options := &PinAddSettings{ Recursive: true, + PinPath: "default/", } for _, opt := range opts { @@ -59,11 +63,13 @@ func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) { return options, nil } + // PinLsOptions compile a series of PinLsOption into a ready to use // PinLsSettings and set the default values. func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) { options := &PinLsSettings{ - Type: "all", + Type: "all", + Recursive: false, } for _, opt := range opts { @@ -112,9 +118,7 @@ func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) { // PinUpdateOptions compile a series of PinUpdateOption into a ready to use // PinUpdateSettings and set the default values. func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { - options := &PinUpdateSettings{ - Unpin: true, - } + options := &PinUpdateSettings{} for _, opt := range opts { err := opt(options) @@ -129,6 +133,7 @@ func PinUpdateOptions(opts ...PinUpdateOption) (*PinUpdateSettings, error) { type pinOpts struct { Ls pinLsOpts IsPinned pinIsPinnedOpts + Recursively bool } // Pin provide an access to all the options for the Pin API. @@ -142,8 +147,8 @@ func (pinLsOpts) All() PinLsOption { return Pin.Ls.pinType("all") } -// Recursive is an option for Pin.Ls which will make it only return recursive -// pins +// Recursive is an option for Pin.Ls which will make it only return recursive (non +// direct) pins func (pinLsOpts) Recursive() PinLsOption { return Pin.Ls.pinType("recursive") } @@ -160,6 +165,15 @@ func (pinLsOpts) Indirect() PinLsOption { return Pin.Ls.pinType("indirect") } +// Recursive is an option for Pin.Ls which allows to specify whether +// argument should be recursively searched for pins +func (pinLsOpts) RecursiveList(recursive bool) PinLsOption { + return func(settings *PinLsSettings) error { + settings.Recursive = recursive + return nil + } +} + // Type is an option for Pin.Ls which will make it only return pins of the given // type. // @@ -272,12 +286,3 @@ func (pinOpts) RmRecursive(recursive bool) PinRmOption { return nil } } - -// Unpin is an option for Pin.Update which specifies whether to remove the old pin. -// Default is true. -func (pinOpts) Unpin(unpin bool) PinUpdateOption { - return func(settings *PinUpdateSettings) error { - settings.Unpin = unpin - return nil - } -} diff --git a/options/unixfs.go b/options/unixfs.go index 3fd96f7..b78a52e 100644 --- a/options/unixfs.go +++ b/options/unixfs.go @@ -29,6 +29,7 @@ type UnixfsAddSettings struct { Layout Layout Pin bool + PinPath string OnlyHash bool FsCache bool NoCopy bool @@ -59,6 +60,7 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix, Layout: BalancedLayout, Pin: false, + PinPath: "added", OnlyHash: false, FsCache: false, NoCopy: false, @@ -221,6 +223,15 @@ func (unixfsOpts) Pin(pin bool) UnixfsAddOption { } } +// PinPath tells the adder the pin path to use +func (unixfsOpts) PinPath(pinPath string) UnixfsAddOption { + return func(settings *UnixfsAddSettings) error { + settings.PinPath = pinPath + return nil + } +} + + // HashOnly will make the adder calculate data hash without storing it in the // blockstore or announcing it to the network func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption { diff --git a/pin.go b/pin.go index 4c1788c..868aae9 100644 --- a/pin.go +++ b/pin.go @@ -11,7 +11,10 @@ import ( type Pin interface { // Path to the pinned object Path() path.Resolved - + + // Pinpath of pinned object + PinPath() string + // Type of the pin Type() string @@ -23,6 +26,9 @@ type Pin interface { type PinStatus interface { // Ok indicates whether the pin has been verified to be correct Ok() bool + + // Pinpath of pinned object + PinPath() string // BadNodes returns any bad (usually missing) nodes from the pin BadNodes() []BadPinNode @@ -41,22 +47,22 @@ type BadPinNode interface { type PinAPI interface { // Add creates new pin, be default recursive - pinning the whole referenced // tree - Add(context.Context, path.Path, ...options.PinAddOption) error + Add(context.Context, string, path.Path, ...options.PinAddOption) error // Ls returns list of pinned objects on this node - Ls(context.Context, ...options.PinLsOption) (<-chan Pin, error) - - // IsPinned returns whether or not the given cid is pinned - // and an explanation of why its pinned - IsPinned(context.Context, path.Path, ...options.PinIsPinnedOption) (string, bool, error) + Ls(context.Context, string, ...options.PinLsOption) (<-chan Pin, error) // Rm removes pin for object specified by the path - Rm(context.Context, path.Path, ...options.PinRmOption) error + Rm(context.Context, string, ...options.PinRmOption) error // Update changes one pin to another, skipping checks for matching paths in // the old tree - Update(ctx context.Context, from path.Path, to path.Path, opts ...options.PinUpdateOption) error + Update(ctx context.Context, from string, to path.Path, opts ...options.PinUpdateOption) error // Verify verifies the integrity of pinned objects Verify(context.Context) (<-chan PinStatus, error) + + // IsPinned returns whether or not the given cid is pinned + // and an explanation of why its pinned + IsPinned(context.Context, path.Path, ...options.PinIsPinnedOption) (string, bool, error) } diff --git a/tests/block.go b/tests/block.go index 1f72525..64048c6 100644 --- a/tests/block.go +++ b/tests/block.go @@ -237,7 +237,7 @@ func (tp *TestSuite) TestBlockPin(t *testing.T) { t.Fatal(err) } - if pins, err := api.Pin().Ls(ctx); err != nil || len(pins) != 0 { + if pins, err := api.Pin().Ls(ctx, ""); err != nil || len(pins) != 0 { t.Fatal("expected 0 pins") } @@ -251,7 +251,7 @@ func (tp *TestSuite) TestBlockPin(t *testing.T) { t.Fatal(err) } - pins, err := accPins(api.Pin().Ls(ctx)) + pins, err := accPins(api.Pin().Ls(ctx, "", opt.Pin.RecursiveList(true))) if err != nil { t.Fatal(err) } diff --git a/tests/pin.go b/tests/pin.go index 476bbea..7c7b517 100644 --- a/tests/pin.go +++ b/tests/pin.go @@ -15,6 +15,8 @@ import ( ipld "github.com/ipfs/go-ipld-format" ) +var testPrefix = "test/" + func (tp *TestSuite) TestPin(t *testing.T) { tp.hasApi(t, func(api iface.CoreAPI) error { if api.Pin() == nil { @@ -44,7 +46,7 @@ func (tp *TestSuite) TestPinAdd(t *testing.T) { t.Fatal(err) } - err = api.Pin().Add(ctx, p) + err = api.Pin().Add(ctx, testPrefix, p) if err != nil { t.Fatal(err) } @@ -63,12 +65,12 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { t.Fatal(err) } - err = api.Pin().Add(ctx, p) + err = api.Pin().Add(ctx, testPrefix, p) if err != nil { t.Fatal(err) } - list, err := accPins(api.Pin().Ls(ctx)) + list, err := accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.Ls.Recursive())) if err != nil { t.Fatal(err) } @@ -87,12 +89,12 @@ func (tp *TestSuite) TestPinSimple(t *testing.T) { assertIsPinned(t, ctx, api, p, "recursive") - err = api.Pin().Rm(ctx, p) + err = api.Pin().Rm(ctx, testPrefix+p.Cid().String()) if err != nil { t.Fatal(err) } - list, err = accPins(api.Pin().Ls(ctx)) + list, err = accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.Ls.Recursive())) if err != nil { t.Fatal(err) } @@ -144,7 +146,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Fatal(err) } - list, err := accPins(api.Pin().Ls(ctx)) + list, err := accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.RecursiveList(true))) if err != nil { t.Fatal(err) } @@ -153,7 +155,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected pin list len: %d", len(list)) } - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Direct())) + list, err = accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.RecursiveList(true), opt.Pin.Ls.Direct())) if err != nil { t.Fatal(err) } @@ -166,7 +168,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpfsPath(nd3.Cid()).String()) } - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Recursive())) + list, err = accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.RecursiveList(true), opt.Pin.Ls.Recursive())) if err != nil { t.Fatal(err) } @@ -179,7 +181,7 @@ func (tp *TestSuite) TestPinRecursive(t *testing.T) { t.Errorf("unexpected path, %s != %s", list[0].Path().String(), path.IpldPath(nd2.Cid()).String()) } - list, err = accPins(api.Pin().Ls(ctx, opt.Pin.Ls.Indirect())) + list, err = accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.RecursiveList(true), opt.Pin.Ls.Indirect())) if err != nil { t.Fatal(err) } diff --git a/tests/unixfs.go b/tests/unixfs.go index 1ed80e8..e366c63 100644 --- a/tests/unixfs.go +++ b/tests/unixfs.go @@ -542,7 +542,7 @@ func (tp *TestSuite) TestAddPinned(t *testing.T) { t.Fatal(err) } - pins, err := accPins(api.Pin().Ls(ctx)) + pins, err := accPins(api.Pin().Ls(ctx, testPrefix, opt.Pin.RecursiveList(true))) if err != nil { t.Fatal(err) }