mirror of
https://github.com/ipfs/kubo.git
synced 2025-08-06 03:19:47 +08:00
feat: support optional pin names (#10261)
This commit is contained in:
@ -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()
|
||||
|
@ -57,6 +57,28 @@ var addPinCmd = &cmds.Command{
|
||||
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{
|
||||
@ -64,6 +86,7 @@ var addPinCmd = &cmds.Command{
|
||||
},
|
||||
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{},
|
||||
@ -75,6 +98,7 @@ var addPinCmd = &cmds.Command{
|
||||
|
||||
// set recursive flag
|
||||
recursive, _ := req.Options[pinRecursiveOptionName].(bool)
|
||||
name, _ := req.Options[pinNameOptionName].(string)
|
||||
showProgress, _ := req.Options[pinProgressOptionName].(bool)
|
||||
|
||||
if err := req.ParseBodyArgs(); err != nil {
|
||||
@ -87,7 +111,7 @@ var addPinCmd = &cmds.Command{
|
||||
}
|
||||
|
||||
if !showProgress {
|
||||
added, err := pinAddMany(req.Context, api, enc, req.Arguments, recursive)
|
||||
added, err := pinAddMany(req.Context, api, enc, req.Arguments, recursive, name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -105,7 +129,7 @@ var addPinCmd = &cmds.Command{
|
||||
|
||||
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)
|
||||
ch <- pinResult{pins: added, err: err}
|
||||
}()
|
||||
|
||||
@ -181,7 +205,7 @@ var addPinCmd = &cmds.Command{
|
||||
},
|
||||
}
|
||||
|
||||
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) {
|
||||
added := make([]string, len(paths))
|
||||
for i, b := range paths {
|
||||
p, err := cmdutils.PathOrCidPath(b)
|
||||
@ -194,7 +218,7 @@ func pinAddMany(ctx context.Context, api coreiface.CoreAPI, enc cidenc.Encoder,
|
||||
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 {
|
||||
return nil, err
|
||||
}
|
||||
added[i] = enc.Encode(rp.RootCid())
|
||||
@ -281,6 +305,7 @@ const (
|
||||
pinTypeOptionName = "type"
|
||||
pinQuietOptionName = "quiet"
|
||||
pinStreamOptionName = "stream"
|
||||
pinNamesOptionName = "names"
|
||||
)
|
||||
|
||||
var listPinCmd = &cmds.Command{
|
||||
@ -294,6 +319,7 @@ respectively.
|
||||
`,
|
||||
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.
|
||||
@ -302,10 +328,13 @@ Use --type=<type> to specify the type of pinned keys to list.
|
||||
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.
|
||||
@ -334,6 +363,7 @@ Example:
|
||||
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)
|
||||
@ -343,6 +373,7 @@ Example:
|
||||
|
||||
typeStr, _ := req.Options[pinTypeOptionName].(string)
|
||||
stream, _ := req.Options[pinStreamOptionName].(bool)
|
||||
displayNames, _ := req.Options[pinNamesOptionName].(bool)
|
||||
|
||||
switch typeStr {
|
||||
case "all", "direct", "indirect", "recursive":
|
||||
@ -356,7 +387,7 @@ Example:
|
||||
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}
|
||||
return nil
|
||||
}
|
||||
} else {
|
||||
@ -368,7 +399,7 @@ Example:
|
||||
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)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
@ -402,8 +433,10 @@ Example:
|
||||
if stream {
|
||||
if quiet {
|
||||
fmt.Fprintf(w, "%s\n", out.PinLsObject.Cid)
|
||||
} else {
|
||||
} else if out.PinLsObject.Name == "" {
|
||||
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)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@ -411,8 +444,10 @@ Example:
|
||||
for k, v := range out.PinLsList.Keys {
|
||||
if quiet {
|
||||
fmt.Fprintf(w, "%s\n", k)
|
||||
} else {
|
||||
} else if v.Name == "" {
|
||||
fmt.Fprintf(w, "%s %s\n", k, v.Type)
|
||||
} else {
|
||||
fmt.Fprintf(w, "%s %s %s\n", k, v.Type, v.Name)
|
||||
}
|
||||
}
|
||||
|
||||
@ -437,11 +472,13 @@ type PinLsList struct {
|
||||
// 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"`
|
||||
}
|
||||
|
||||
@ -502,7 +539,7 @@ func pinLsKeys(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fu
|
||||
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 {
|
||||
enc, err := cmdenv.GetCidEncoder(req)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -520,7 +557,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun
|
||||
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))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@ -532,6 +569,7 @@ func pinLsAll(req *cmds.Request, typeStr string, api coreiface.CoreAPI, emit fun
|
||||
err = emit(PinLsOutputWrapper{
|
||||
PinLsObject: PinLsObject{
|
||||
Type: p.Type(),
|
||||
Name: p.Name(),
|
||||
Cid: enc.Encode(p.Path().RootCid()),
|
||||
},
|
||||
})
|
||||
@ -748,15 +786,15 @@ func pinVerify(ctx context.Context, n *core.IpfsNode, opts pinVerifyOpts, enc ci
|
||||
out := make(chan any)
|
||||
go func() {
|
||||
defer close(out)
|
||||
for p := range n.Pinning.RecursiveKeys(ctx) {
|
||||
for p := range n.Pinning.RecursiveKeys(ctx, false) {
|
||||
if p.Err != nil {
|
||||
out <- PinVerifyRes{Err: p.Err.Error()}
|
||||
return
|
||||
}
|
||||
pinStatus := checkPin(p.C)
|
||||
pinStatus := checkPin(p.Pin.Key)
|
||||
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}:
|
||||
case <-ctx.Done():
|
||||
return
|
||||
}
|
||||
|
Reference in New Issue
Block a user