mirror of
https://github.com/ipfs/kubo.git
synced 2026-02-25 20:37:53 +08:00
cmds/pin: use coreapi/pin
License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>
This commit is contained in:
parent
04fa5cfb8d
commit
99feecfdcc
@ -10,9 +10,9 @@ import (
|
||||
core "github.com/ipfs/go-ipfs/core"
|
||||
cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
|
||||
e "github.com/ipfs/go-ipfs/core/commands/e"
|
||||
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
iface "github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
|
||||
corerepo "github.com/ipfs/go-ipfs/core/corerepo"
|
||||
pin "github.com/ipfs/go-ipfs/pin"
|
||||
|
||||
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
|
||||
@ -88,30 +88,26 @@ var addPinCmd = &cmds.Command{
|
||||
return err
|
||||
}
|
||||
|
||||
enc, err := cmdenv.GetCidEncoder(req)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if !showProgress {
|
||||
added, err := corerepo.Pin(n.Pinning, api, req.Context, req.Arguments, recursive)
|
||||
added, err := pinAddMany(req.Context, api, req.Arguments, recursive)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cmds.EmitOnce(res, &AddPinOutput{Pins: cidsToStrings(added, enc)})
|
||||
|
||||
return cmds.EmitOnce(res, &AddPinOutput{Pins: added})
|
||||
}
|
||||
|
||||
v := new(dag.ProgressTracker)
|
||||
ctx := v.DeriveContext(req.Context)
|
||||
|
||||
type pinResult struct {
|
||||
pins []cid.Cid
|
||||
pins []string
|
||||
err error
|
||||
}
|
||||
|
||||
ch := make(chan pinResult, 1)
|
||||
go func() {
|
||||
added, err := corerepo.Pin(n.Pinning, api, ctx, req.Arguments, recursive)
|
||||
added, err := pinAddMany(req.Context, api, req.Arguments, recursive)
|
||||
ch <- pinResult{pins: added, err: err}
|
||||
}()
|
||||
|
||||
@ -130,7 +126,7 @@ var addPinCmd = &cmds.Command{
|
||||
return err
|
||||
}
|
||||
}
|
||||
return res.Emit(&AddPinOutput{Pins: cidsToStrings(val.pins, enc)})
|
||||
return res.Emit(&AddPinOutput{Pins: val.pins})
|
||||
case <-ticker.C:
|
||||
if err := res.Emit(&AddPinOutput{Progress: v.Value()}); err != nil {
|
||||
return err
|
||||
@ -187,6 +183,28 @@ var addPinCmd = &cmds.Command{
|
||||
},
|
||||
}
|
||||
|
||||
func pinAddMany(ctx context.Context, api coreiface.CoreAPI, paths []string, recursive bool) ([]string, error) {
|
||||
added := make([]string, len(paths))
|
||||
for i, b := range paths {
|
||||
p, err := coreiface.ParsePath(b)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rp, err := api.ResolvePath(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := api.Pin().Add(ctx, p, options.Pin.Recursive(recursive)); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
added[i] = rp.Cid().String()
|
||||
}
|
||||
|
||||
return added, nil
|
||||
}
|
||||
|
||||
var rmPinCmd = &cmds.Command{
|
||||
Helptext: cmdkit.HelpText{
|
||||
Tagline: "Remove pinned objects from local storage.",
|
||||
@ -204,11 +222,6 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
|
||||
},
|
||||
Type: PinOutput{},
|
||||
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
|
||||
n, err := cmdenv.GetNode(env)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
api, err := cmdenv.GetApi(env, req)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -226,20 +239,62 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
|
||||
return err
|
||||
}
|
||||
|
||||
removed, err := corerepo.Unpin(n.Pinning, api, req.Context, req.Arguments, recursive)
|
||||
if err != nil {
|
||||
return err
|
||||
for _, b := range req.Arguments {
|
||||
p, err := coreiface.ParsePath(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rp, err := api.ResolvePath(req.Context, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := api.Pin().Rm(req.Context, rp, options.Pin.RmRecursive(recursive)); err != nil {
|
||||
if err := res.Emit(&PinOutput{
|
||||
Pins: []string{rp.Cid().String()},
|
||||
Error: err.Error(),
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
if err := res.Emit(&PinOutput{
|
||||
Pins: []string{rp.Cid().String()},
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return cmds.EmitOnce(res, &PinOutput{cidsToStrings(removed, enc)})
|
||||
return nil
|
||||
},
|
||||
Encoders: cmds.EncoderMap{
|
||||
cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
|
||||
for _, k := range out.Pins {
|
||||
fmt.Fprintf(w, "unpinned %s\n", k)
|
||||
PostRun: cmds.PostRunMap{
|
||||
cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
|
||||
failed := false
|
||||
for {
|
||||
out, err := res.Next()
|
||||
if err == io.EOF {
|
||||
break
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
r := out.(*PinOutput)
|
||||
if r.Pins == nil && r.Error != "" {
|
||||
return fmt.Errorf("aborted: %s", r.Error)
|
||||
} else if r.Error != "" {
|
||||
failed = true
|
||||
fmt.Fprintf(os.Stderr, "cannot unpin %s: %s\n", r.Pins[0], r.Error)
|
||||
} else {
|
||||
fmt.Fprintf(os.Stdout, "unpinned %s\n", r.Pins[0])
|
||||
}
|
||||
}
|
||||
|
||||
if failed {
|
||||
return fmt.Errorf("some hash not unpinned")
|
||||
}
|
||||
return nil
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@ -652,11 +707,3 @@ func (r PinVerifyRes) Format(out io.Writer) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func cidsToStrings(cs []cid.Cid, enc cidenc.Encoder) []string {
|
||||
out := make([]string, 0, len(cs))
|
||||
for _, c := range cs {
|
||||
out = append(out, enc.Encode(c))
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
@ -8,12 +8,23 @@ type PinLsSettings struct {
|
||||
Type string
|
||||
}
|
||||
|
||||
// PinRmSettings represents the settings of pin rm command
|
||||
type PinRmSettings struct {
|
||||
Recursive bool
|
||||
Force bool
|
||||
}
|
||||
|
||||
type PinUpdateSettings struct {
|
||||
Unpin bool
|
||||
}
|
||||
|
||||
type PinAddOption func(*PinAddSettings) error
|
||||
type PinLsOption func(settings *PinLsSettings) error
|
||||
|
||||
// PinRmOption pin rm option func
|
||||
type PinRmOption func(*PinRmSettings) error
|
||||
|
||||
// PinLsOption pin ls option func
|
||||
type PinLsOption func(*PinLsSettings) error
|
||||
type PinUpdateOption func(*PinUpdateSettings) error
|
||||
|
||||
func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) {
|
||||
@ -31,6 +42,21 @@ func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) {
|
||||
return options, nil
|
||||
}
|
||||
|
||||
// PinRmOptions pin rm options
|
||||
func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) {
|
||||
options := &PinRmSettings{
|
||||
Recursive: true,
|
||||
}
|
||||
|
||||
for _, opt := range opts {
|
||||
if err := opt(options); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return options, nil
|
||||
}
|
||||
|
||||
func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) {
|
||||
options := &PinLsSettings{
|
||||
Type: "all",
|
||||
@ -102,6 +128,14 @@ func (pinOpts) Recursive(recursive bool) PinAddOption {
|
||||
}
|
||||
}
|
||||
|
||||
// RmRecursive is an option for Pin.Rm
|
||||
func (pinOpts) RmRecursive(recursive bool) PinRmOption {
|
||||
return func(settings *PinRmSettings) error {
|
||||
settings.Recursive = recursive
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
// Type is an option for Pin.Ls which allows to specify which pin types should
|
||||
// be returned
|
||||
//
|
||||
|
||||
@ -43,7 +43,7 @@ type PinAPI interface {
|
||||
Ls(context.Context, ...options.PinLsOption) ([]Pin, error)
|
||||
|
||||
// Rm removes pin for object specified by the path
|
||||
Rm(context.Context, Path) error
|
||||
Rm(context.Context, Path, ...options.PinRmOption) error
|
||||
|
||||
// Update changes one pin to another, skipping checks for matching paths in
|
||||
// the old tree
|
||||
|
||||
@ -12,26 +12,27 @@ import (
|
||||
|
||||
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
|
||||
offline "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline"
|
||||
merkledag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag"
|
||||
)
|
||||
|
||||
type PinAPI CoreAPI
|
||||
|
||||
func (api *PinAPI) Add(ctx context.Context, p coreiface.Path, opts ...caopts.PinAddOption) error {
|
||||
settings, err := caopts.PinAddOptions(opts...)
|
||||
dagNode, err := api.core().ResolveNode(ctx, p)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("pin: %s", err)
|
||||
}
|
||||
|
||||
rp, err := api.core().ResolvePath(ctx, p)
|
||||
settings, err := caopts.PinAddOptions(opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
defer api.blockstore.PinLock().Unlock()
|
||||
|
||||
_, err = corerepo.Pin(api.pinning, api.core(), ctx, []string{rp.Cid().String()}, settings.Recursive)
|
||||
err = api.pinning.Pin(ctx, dagNode, settings.Recursive)
|
||||
if err != nil {
|
||||
return err
|
||||
return fmt.Errorf("pin: %s", err)
|
||||
}
|
||||
|
||||
return api.pinning.Flush()
|
||||
@ -52,12 +53,22 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreif
|
||||
return api.pinLsAll(settings.Type, ctx)
|
||||
}
|
||||
|
||||
func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path) error {
|
||||
_, err := corerepo.Unpin(api.pinning, api.core(), ctx, []string{p.String()}, true)
|
||||
// Rm pin rm api
|
||||
func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path, opts ...caopts.PinRmOption) error {
|
||||
rp, err := api.core().ResolvePath(ctx, p)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
settings, err := caopts.PinRmOptions(opts...)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = api.pinning.Unpin(ctx, rp.Cid(), settings.Recursive); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return api.pinning.Flush()
|
||||
}
|
||||
|
||||
|
||||
@ -1,80 +0,0 @@
|
||||
/*
|
||||
Package corerepo provides pinning and garbage collection for local
|
||||
IPFS block services.
|
||||
|
||||
IPFS nodes will keep local copies of any object that have either been
|
||||
added or requested locally. Not all of these objects are worth
|
||||
preserving forever though, so the node administrator can pin objects
|
||||
they want to keep and unpin objects that they don't care about.
|
||||
|
||||
Garbage collection sweeps iterate through the local block store
|
||||
removing objects that aren't pinned, which frees storage space for new
|
||||
objects.
|
||||
*/
|
||||
package corerepo
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"github.com/ipfs/go-ipfs/pin"
|
||||
|
||||
"github.com/ipfs/go-ipfs/core/coreapi/interface"
|
||||
|
||||
"gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
|
||||
)
|
||||
|
||||
func Pin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
|
||||
out := make([]cid.Cid, len(paths))
|
||||
|
||||
for i, fpath := range paths {
|
||||
p, err := iface.ParsePath(fpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dagnode, err := api.ResolveNode(ctx, p)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("pin: %s", err)
|
||||
}
|
||||
err = pinning.Pin(ctx, dagnode, recursive)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("pin: %s", err)
|
||||
}
|
||||
out[i] = dagnode.Cid()
|
||||
}
|
||||
|
||||
err := pinning.Flush()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return out, nil
|
||||
}
|
||||
|
||||
func Unpin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
|
||||
unpinned := make([]cid.Cid, len(paths))
|
||||
|
||||
for i, p := range paths {
|
||||
p, err := iface.ParsePath(p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
k, err := api.ResolvePath(ctx, p)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = pinning.Unpin(ctx, k.Cid(), recursive)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
unpinned[i] = k.Cid()
|
||||
}
|
||||
|
||||
err := pinning.Flush()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return unpinned, nil
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user