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

feat: support optional pin names #10261

Merged
merged 7 commits into from
Jan 4, 2024
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion client/rpc/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
type pin struct {
path path.ImmutablePath
typ string
name string
err error
}

Expand All @@ -37,6 +38,10 @@
return p.path
}

func (p pin) Name() string {
return p.name

Check warning on line 42 in client/rpc/pin.go

View check run for this annotation

Codecov / codecov/patch

client/rpc/pin.go#L41-L42

Added lines #L41 - L42 were not covered by tests
}

func (p pin) Type() string {
return p.typ
}
Expand All @@ -53,6 +58,7 @@

type pinLsObject struct {
Cid string
Name string
Type string
}

Expand Down Expand Up @@ -102,7 +108,7 @@
}

select {
case ch <- pin{typ: out.Type, path: path.FromCid(c)}:
case ch <- pin{typ: out.Type, name: out.Name, path: path.FromCid(c)}:
case <-ctx.Done():
return
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/ipfs/kubo/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@

// pin recursively because this might already be pinned
// and doing a direct pin would throw an error in that case
err = nd.Pinning.Pin(ctx, emptyDir, true)
err = nd.Pinning.Pin(ctx, emptyDir, true, "")

Check warning on line 255 in cmd/ipfs/kubo/init.go

View check run for this annotation

Codecov / codecov/patch

cmd/ipfs/kubo/init.go#L255

Added line #L255 was not covered by tests
if err != nil {
return err
}
Expand Down
2 changes: 1 addition & 1 deletion core/commands/dag/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -152,7 +152,7 @@ func dagImport(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment
ret.PinErrorMsg = err.Error()
} else if nd, err := blockDecoder.DecodeNode(req.Context, block); err != nil {
ret.PinErrorMsg = err.Error()
} else if err := node.Pinning.Pin(req.Context, nd, true); err != nil {
} else if err := node.Pinning.Pin(req.Context, nd, true, ""); err != nil {
ret.PinErrorMsg = err.Error()
} else if err := node.Pinning.Flush(req.Context); err != nil {
ret.PinErrorMsg = err.Error()
Expand Down
66 changes: 52 additions & 14 deletions core/commands/pin/pin.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,13 +57,36 @@
Helptext: cmds.HelpText{
Tagline: "Pin objects to local storage.",
ShortDescription: "Stores an IPFS object(s) from a given path locally to disk.",
LongDescription: `
Create a pin for the given object, protecting resolved CID from being garbage
collected.

An optional name can be provided, and read back via 'ipfs pin ls --names'.

Be mindful of defaults:

Default pin type is 'recursive' (entire DAG).
Pass -r=false to create a direct pin for a single block.
Use 'pin ls -t recursive' to only list roots of recursively pinned DAGs
(significantly faster when many big DAGs are pinned recursively)

Default pin name is empty. Pass '--name' to 'pin add' to set one
and use 'pin ls --names' to see it.
Pin add is idempotent: pinning CID which is already pinned won't change
the name, value passed with '--name' with the original pin is preserved.
To rename pin, use 'pin rm' and 'pin add --name'.

If daemon is running, any missing blocks will be retrieved from the network.
It may take some time. Pass '--progress' to track the progress.
`,
},

Arguments: []cmds.Argument{
cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be pinned.").EnableStdin(),
},
Options: []cmds.Option{
cmds.BoolOption(pinRecursiveOptionName, "r", "Recursively pin the object linked to by the specified object(s).").WithDefault(true),
cmds.StringOption(pinNameOptionName, "n", "An optional name for created pin(s)."),
cmds.BoolOption(pinProgressOptionName, "Show progress"),
},
Type: AddPinOutput{},
Expand All @@ -75,6 +98,7 @@

// set recursive flag
recursive, _ := req.Options[pinRecursiveOptionName].(bool)
name, _ := req.Options[pinNameOptionName].(string)

Check warning on line 101 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L101

Added line #L101 was not covered by tests
showProgress, _ := req.Options[pinProgressOptionName].(bool)

if err := req.ParseBodyArgs(); err != nil {
Expand All @@ -87,7 +111,7 @@
}

if !showProgress {
added, err := pinAddMany(req.Context, api, enc, req.Arguments, recursive)
added, err := pinAddMany(req.Context, api, enc, req.Arguments, recursive, name)

Check warning on line 114 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L114

Added line #L114 was not covered by tests
if err != nil {
return err
}
Expand All @@ -105,7 +129,7 @@

ch := make(chan pinResult, 1)
go func() {
added, err := pinAddMany(ctx, api, enc, req.Arguments, recursive)
added, err := pinAddMany(ctx, api, enc, req.Arguments, recursive, name)

Check warning on line 132 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L132

Added line #L132 was not covered by tests
ch <- pinResult{pins: added, err: err}
}()

Expand Down Expand Up @@ -181,7 +205,7 @@
},
}

func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool) ([]string, error) {
func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder, paths []string, recursive bool, name string) ([]string, error) {

Check warning on line 208 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L208

Added line #L208 was not covered by tests
added := make([]string, len(paths))
for i, b := range paths {
p, err := cmdutils.PathOrCidPath(b)
Expand All @@ -194,7 +218,7 @@
return nil, err
}

if err := api.Pin().Add(ctx, rp, options.Pin.Recursive(recursive)); err != nil {
if err := api.Pin().Add(ctx, rp, options.Pin.Recursive(recursive), options.Pin.Name(name)); err != nil {

Check warning on line 221 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L221

Added line #L221 was not covered by tests
return nil, err
}
added[i] = enc.Encode(rp.RootCid())
Expand Down Expand Up @@ -281,6 +305,7 @@
pinTypeOptionName = "type"
pinQuietOptionName = "quiet"
pinStreamOptionName = "stream"
pinNamesOptionName = "names"
)

var listPinCmd = &cmds.Command{
Expand All @@ -294,6 +319,7 @@
`,
LongDescription: `
Returns a list of objects that are pinned locally.

By default, all pinned objects are returned, but the '--type' flag or
arguments can restrict that to a specific pin type or to some specific objects
respectively.
Expand All @@ -302,10 +328,13 @@
Valid values are:
* "direct": pin that specific object.
* "recursive": pin that specific object, and indirectly pin all its
descendants
descendants
* "indirect": pinned indirectly by an ancestor (like a refcount)
* "all"

By default, pin names are not included (returned as empty).
Pass '--names' flag to return pin names (set with '--name' from 'pin add').

With arguments, the command fails if any of the arguments is not a pinned
object. And if --type=<type> is additionally used, the command will also fail
if any of the arguments is not of the specified type.
Expand Down Expand Up @@ -334,6 +363,7 @@
cmds.StringOption(pinTypeOptionName, "t", "The type of pinned keys to list. Can be \"direct\", \"indirect\", \"recursive\", or \"all\".").WithDefault("all"),
cmds.BoolOption(pinQuietOptionName, "q", "Write just hashes of objects."),
cmds.BoolOption(pinStreamOptionName, "s", "Enable streaming of pins as they are discovered."),
cmds.BoolOption(pinNamesOptionName, "n", "Enable displaying pin names (slower)."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env, req)
Expand All @@ -343,6 +373,7 @@

typeStr, _ := req.Options[pinTypeOptionName].(string)
stream, _ := req.Options[pinStreamOptionName].(bool)
displayNames, _ := req.Options[pinNamesOptionName].(bool)

Check warning on line 376 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L376

Added line #L376 was not covered by tests

switch typeStr {
case "all", "direct", "indirect", "recursive":
Expand All @@ -356,7 +387,7 @@
lgcList := map[string]PinLsType{}
if !stream {
emit = func(v PinLsOutputWrapper) error {
lgcList[v.PinLsObject.Cid] = PinLsType{Type: v.PinLsObject.Type}
lgcList[v.PinLsObject.Cid] = PinLsType{Type: v.PinLsObject.Type, Name: v.PinLsObject.Name}

Check warning on line 390 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L390

Added line #L390 was not covered by tests
return nil
}
} else {
Expand All @@ -368,7 +399,7 @@
if len(req.Arguments) > 0 {
err = pinLsKeys(req, typeStr, api, emit)
} else {
err = pinLsAll(req, typeStr, api, emit)
err = pinLsAll(req, typeStr, displayNames, api, emit)

Check warning on line 402 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L402

Added line #L402 was not covered by tests
}
if err != nil {
return err
Expand Down Expand Up @@ -402,17 +433,21 @@
if stream {
if quiet {
fmt.Fprintf(w, "%s\n", out.PinLsObject.Cid)
} else {
} else if out.PinLsObject.Name == "" {

Check warning on line 436 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L436

Added line #L436 was not covered by tests
fmt.Fprintf(w, "%s %s\n", out.PinLsObject.Cid, out.PinLsObject.Type)
} else {
fmt.Fprintf(w, "%s %s %s\n", out.PinLsObject.Cid, out.PinLsObject.Type, out.PinLsObject.Name)

Check warning on line 439 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L438-L439

Added lines #L438 - L439 were not covered by tests
}
return nil
}

for k, v := range out.PinLsList.Keys {
if quiet {
fmt.Fprintf(w, "%s\n", k)
} else {
} else if v.Name == "" {

Check warning on line 447 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L447

Added line #L447 was not covered by tests
fmt.Fprintf(w, "%s %s\n", k, v.Type)
} else {
fmt.Fprintf(w, "%s %s %s\n", k, v.Type, v.Name)

Check warning on line 450 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L449-L450

Added lines #L449 - L450 were not covered by tests
}
}

Expand All @@ -437,11 +472,13 @@
// PinLsType contains the type of a pin
type PinLsType struct {
Type string
Name string
}

// PinLsObject contains the description of a pin
type PinLsObject struct {
Cid string `json:",omitempty"`
Name string `json:",omitempty"`
Type string `json:",omitempty"`
}

Expand Down Expand Up @@ -502,7 +539,7 @@
return nil
}

func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error {
func pinLsAll(req *cmds.Request, typeStr string, detailed bool, api coreiface.CoreAPI, emit func(value PinLsOutputWrapper) error) error {

Check warning on line 542 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L542

Added line #L542 was not covered by tests
enc, err := cmdenv.GetCidEncoder(req)
if err != nil {
return err
Expand All @@ -520,7 +557,7 @@
panic("unhandled pin type")
}

pins, err := api.Pin().Ls(req.Context, opt)
pins, err := api.Pin().Ls(req.Context, opt, options.Pin.Ls.Detailed(detailed))

Check warning on line 560 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L560

Added line #L560 was not covered by tests
if err != nil {
return err
}
Expand All @@ -532,6 +569,7 @@
err = emit(PinLsOutputWrapper{
PinLsObject: PinLsObject{
Type: p.Type(),
Name: p.Name(),

Check warning on line 572 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L572

Added line #L572 was not covered by tests
Cid: enc.Encode(p.Path().RootCid()),
},
})
Expand Down Expand Up @@ -748,15 +786,15 @@
out := make(chan any)
go func() {
defer close(out)
for p := range n.Pinning.RecursiveKeys(ctx) {
for p := range n.Pinning.RecursiveKeys(ctx, false) {

Check warning on line 789 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L789

Added line #L789 was not covered by tests
if p.Err != nil {
out <- PinVerifyRes{Err: p.Err.Error()}
return
}
pinStatus := checkPin(p.C)
pinStatus := checkPin(p.Pin.Key)

Check warning on line 794 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L794

Added line #L794 was not covered by tests
if !pinStatus.Ok || opts.includeOk {
select {
case out <- PinVerifyRes{Cid: enc.Encode(p.C), PinStatus: pinStatus}:
case out <- PinVerifyRes{Cid: enc.Encode(p.Pin.Key), PinStatus: pinStatus}:

Check warning on line 797 in core/commands/pin/pin.go

View check run for this annotation

Codecov / codecov/patch

core/commands/pin/pin.go#L797

Added line #L797 was not covered by tests
case <-ctx.Done():
return
}
Expand Down
2 changes: 1 addition & 1 deletion core/coreapi/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
}

if settings.Pin {
if err = api.pinning.PinWithMode(ctx, b.Cid(), pin.Recursive); err != nil {
if err = api.pinning.PinWithMode(ctx, b.Cid(), pin.Recursive, ""); err != nil {
return nil, err
}
if err := api.pinning.Flush(ctx); err != nil {
Expand Down
4 changes: 2 additions & 2 deletions core/coreapi/dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ func (adder *pinningAdder) Add(ctx context.Context, nd ipld.Node) error {
return err
}

if err := adder.pinning.PinWithMode(ctx, nd.Cid(), pin.Recursive); err != nil {
if err := adder.pinning.PinWithMode(ctx, nd.Cid(), pin.Recursive, ""); err != nil {
return err
}

Expand All @@ -51,7 +51,7 @@ func (adder *pinningAdder) AddMany(ctx context.Context, nds []ipld.Node) error {
for _, nd := range nds {
c := nd.Cid()
if cids.Visit(c) {
if err := adder.pinning.PinWithMode(ctx, c, pin.Recursive); err != nil {
if err := adder.pinning.PinWithMode(ctx, c, pin.Recursive, ""); err != nil {
return err
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/coreapi/object.go
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj
}

if options.Pin {
if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive); err != nil {
if err := api.pinning.PinWithMode(ctx, dagnode.Cid(), pin.Recursive, ""); err != nil {
return path.ImmutablePath{}, err
}

Expand Down
Loading
Loading