@cryptotaxi247 / kubo / commits / 99feecfdc

cmds/pin: use coreapi/pin

License: MIT Signed-off-by: Overbool <overbool.xu@gmail.com>

Overbool committed Dec 13, 2018 at 23:02 UTC 99feecfdccc3ec4801ce21633cc7ee49315f4ee9
5 files changed +134 -122
core/commands/pin.go
+80 -33
@@ -10,9 +10,9 @@ import (
10 core "github.com/ipfs/go-ipfs/core"
11 cmdenv "github.com/ipfs/go-ipfs/core/commands/cmdenv"
12 e "github.com/ipfs/go-ipfs/core/commands/e"
13 + coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
14 iface "github.com/ipfs/go-ipfs/core/coreapi/interface"
15 options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
15 - corerepo "github.com/ipfs/go-ipfs/core/corerepo"
16 pin "github.com/ipfs/go-ipfs/pin"
17
18 cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
@@ -88,30 +88,26 @@ var addPinCmd = &cmds.Command{
88 return err
89 }
90
91 - enc, err := cmdenv.GetCidEncoder(req)
92 - if err != nil {
93 - return err
94 - }
95 -
91 if !showProgress {
97 - added, err := corerepo.Pin(n.Pinning, api, req.Context, req.Arguments, recursive)
92 + added, err := pinAddMany(req.Context, api, req.Arguments, recursive)
93 if err != nil {
94 return err
95 }
101 - return cmds.EmitOnce(res, &AddPinOutput{Pins: cidsToStrings(added, enc)})
96 +
97 + return cmds.EmitOnce(res, &AddPinOutput{Pins: added})
98 }
99
100 v := new(dag.ProgressTracker)
101 ctx := v.DeriveContext(req.Context)
102
103 type pinResult struct {
108 - pins []cid.Cid
104 + pins []string
105 err error
106 }
107
108 ch := make(chan pinResult, 1)
109 go func() {
114 - added, err := corerepo.Pin(n.Pinning, api, ctx, req.Arguments, recursive)
110 + added, err := pinAddMany(req.Context, api, req.Arguments, recursive)
111 ch <- pinResult{pins: added, err: err}
112 }()
113
@@ -130,7 +126,7 @@ var addPinCmd = &cmds.Command{
126 return err
127 }
128 }
133 - return res.Emit(&AddPinOutput{Pins: cidsToStrings(val.pins, enc)})
129 + return res.Emit(&AddPinOutput{Pins: val.pins})
130 case <-ticker.C:
131 if err := res.Emit(&AddPinOutput{Progress: v.Value()}); err != nil {
132 return err
@@ -187,6 +183,28 @@ var addPinCmd = &cmds.Command{
183 },
184 }
185
186 +func pinAddMany(ctx context.Context, api coreiface.CoreAPI, paths []string, recursive bool) ([]string, error) {
187 + added := make([]string, len(paths))
188 + for i, b := range paths {
189 + p, err := coreiface.ParsePath(b)
190 + if err != nil {
191 + return nil, err
192 + }
193 +
194 + rp, err := api.ResolvePath(ctx, p)
195 + if err != nil {
196 + return nil, err
197 + }
198 +
199 + if err := api.Pin().Add(ctx, p, options.Pin.Recursive(recursive)); err != nil {
200 + return nil, err
201 + }
202 + added[i] = rp.Cid().String()
203 + }
204 +
205 + return added, nil
206 +}
207 +
208 var rmPinCmd = &cmds.Command{
209 Helptext: cmdkit.HelpText{
210 Tagline: "Remove pinned objects from local storage.",
@@ -204,11 +222,6 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
222 },
223 Type: PinOutput{},
224 Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
207 - n, err := cmdenv.GetNode(env)
208 - if err != nil {
209 - return err
210 - }
211 -
225 api, err := cmdenv.GetApi(env, req)
226 if err != nil {
227 return err
@@ -226,20 +239,62 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
239 return err
240 }
241
229 - removed, err := corerepo.Unpin(n.Pinning, api, req.Context, req.Arguments, recursive)
230 - if err != nil {
231 - return err
242 + for _, b := range req.Arguments {
243 + p, err := coreiface.ParsePath(b)
244 + if err != nil {
245 + return err
246 + }
247 +
248 + rp, err := api.ResolvePath(req.Context, p)
249 + if err != nil {
250 + return err
251 + }
252 +
253 + if err := api.Pin().Rm(req.Context, rp, options.Pin.RmRecursive(recursive)); err != nil {
254 + if err := res.Emit(&PinOutput{
255 + Pins: []string{rp.Cid().String()},
256 + Error: err.Error(),
257 + }); err != nil {
258 + return err
259 + }
260 + continue
261 + }
262 +
263 + if err := res.Emit(&PinOutput{
264 + Pins: []string{rp.Cid().String()},
265 + }); err != nil {
266 + return err
267 + }
268 }
269
234 - return cmds.EmitOnce(res, &PinOutput{cidsToStrings(removed, enc)})
270 + return nil
271 },
236 - Encoders: cmds.EncoderMap{
237 - cmds.Text: cmds.MakeTypedEncoder(func(req *cmds.Request, w io.Writer, out *PinOutput) error {
238 - for _, k := range out.Pins {
239 - fmt.Fprintf(w, "unpinned %s\n", k)
272 + PostRun: cmds.PostRunMap{
273 + cmds.CLI: func(res cmds.Response, re cmds.ResponseEmitter) error {
274 + failed := false
275 + for {
276 + out, err := res.Next()
277 + if err == io.EOF {
278 + break
279 + } else if err != nil {
280 + return err
281 + }
282 + r := out.(*PinOutput)
283 + if r.Pins == nil && r.Error != "" {
284 + return fmt.Errorf("aborted: %s", r.Error)
285 + } else if r.Error != "" {
286 + failed = true
287 + fmt.Fprintf(os.Stderr, "cannot unpin %s: %s\n", r.Pins[0], r.Error)
288 + } else {
289 + fmt.Fprintf(os.Stdout, "unpinned %s\n", r.Pins[0])
290 + }
291 + }
292 +
293 + if failed {
294 + return fmt.Errorf("some hash not unpinned")
295 }
296 return nil
242 - }),
297 + },
298 },
299 }
300
@@ -652,11 +707,3 @@ func (r PinVerifyRes) Format(out io.Writer) {
707 }
708 }
709 }
655 -
656 -func cidsToStrings(cs []cid.Cid, enc cidenc.Encoder) []string {
657 - out := make([]string, 0, len(cs))
658 - for _, c := range cs {
659 - out = append(out, enc.Encode(c))
660 - }
661 - return out
662 -}
core/coreapi/interface/options/pin.go
+35 -1
@@ -8,12 +8,23 @@ type PinLsSettings struct {
8 Type string
9 }
10
11 +// PinRmSettings represents the settings of pin rm command
12 +type PinRmSettings struct {
13 + Recursive bool
14 + Force bool
15 +}
16 +
17 type PinUpdateSettings struct {
18 Unpin bool
19 }
20
21 type PinAddOption func(*PinAddSettings) error
16 -type PinLsOption func(settings *PinLsSettings) error
22 +
23 +// PinRmOption pin rm option func
24 +type PinRmOption func(*PinRmSettings) error
25 +
26 +// PinLsOption pin ls option func
27 +type PinLsOption func(*PinLsSettings) error
28 type PinUpdateOption func(*PinUpdateSettings) error
29
30 func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) {
@@ -31,6 +42,21 @@ func PinAddOptions(opts ...PinAddOption) (*PinAddSettings, error) {
42 return options, nil
43 }
44
45 +// PinRmOptions pin rm options
46 +func PinRmOptions(opts ...PinRmOption) (*PinRmSettings, error) {
47 + options := &PinRmSettings{
48 + Recursive: true,
49 + }
50 +
51 + for _, opt := range opts {
52 + if err := opt(options); err != nil {
53 + return nil, err
54 + }
55 + }
56 +
57 + return options, nil
58 +}
59 +
60 func PinLsOptions(opts ...PinLsOption) (*PinLsSettings, error) {
61 options := &PinLsSettings{
62 Type: "all",
@@ -102,6 +128,14 @@ func (pinOpts) Recursive(recursive bool) PinAddOption {
128 }
129 }
130
131 +// RmRecursive is an option for Pin.Rm
132 +func (pinOpts) RmRecursive(recursive bool) PinRmOption {
133 + return func(settings *PinRmSettings) error {
134 + settings.Recursive = recursive
135 + return nil
136 + }
137 +}
138 +
139 // Type is an option for Pin.Ls which allows to specify which pin types should
140 // be returned
141 //
core/coreapi/interface/pin.go
+1 -1
@@ -43,7 +43,7 @@ type PinAPI interface {
43 Ls(context.Context, ...options.PinLsOption) ([]Pin, error)
44
45 // Rm removes pin for object specified by the path
46 - Rm(context.Context, Path) error
46 + Rm(context.Context, Path, ...options.PinRmOption) error
47
48 // Update changes one pin to another, skipping checks for matching paths in
49 // the old tree
core/coreapi/pin.go
+18 -7
@@ -12,26 +12,27 @@ import (
12
13 cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
14 offline "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline"
15 + merkledag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag"
16 )
17
18 type PinAPI CoreAPI
19
20 func (api *PinAPI) Add(ctx context.Context, p coreiface.Path, opts ...caopts.PinAddOption) error {
20 - settings, err := caopts.PinAddOptions(opts...)
21 + dagNode, err := api.core().ResolveNode(ctx, p)
22 if err != nil {
22 - return err
23 + return fmt.Errorf("pin: %s", err)
24 }
25
25 - rp, err := api.core().ResolvePath(ctx, p)
26 + settings, err := caopts.PinAddOptions(opts...)
27 if err != nil {
28 return err
29 }
30
31 defer api.blockstore.PinLock().Unlock()
32
32 - _, err = corerepo.Pin(api.pinning, api.core(), ctx, []string{rp.Cid().String()}, settings.Recursive)
33 + err = api.pinning.Pin(ctx, dagNode, settings.Recursive)
34 if err != nil {
34 - return err
35 + return fmt.Errorf("pin: %s", err)
36 }
37
38 return api.pinning.Flush()
@@ -52,12 +53,22 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreif
53 return api.pinLsAll(settings.Type, ctx)
54 }
55
55 -func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path) error {
56 - _, err := corerepo.Unpin(api.pinning, api.core(), ctx, []string{p.String()}, true)
56 +// Rm pin rm api
57 +func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path, opts ...caopts.PinRmOption) error {
58 + rp, err := api.core().ResolvePath(ctx, p)
59 if err != nil {
60 return err
61 }
62
63 + settings, err := caopts.PinRmOptions(opts...)
64 + if err != nil {
65 + return err
66 + }
67 +
68 + if err = api.pinning.Unpin(ctx, rp.Cid(), settings.Recursive); err != nil {
69 + return err
70 + }
71 +
72 return api.pinning.Flush()
73 }
74
core/corerepo/pinning.go
-80
@@ -1,80 +0,0 @@
1 -/*
2 -Package corerepo provides pinning and garbage collection for local
3 -IPFS block services.
4 -
5 -IPFS nodes will keep local copies of any object that have either been
6 -added or requested locally. Not all of these objects are worth
7 -preserving forever though, so the node administrator can pin objects
8 -they want to keep and unpin objects that they don't care about.
9 -
10 -Garbage collection sweeps iterate through the local block store
11 -removing objects that aren't pinned, which frees storage space for new
12 -objects.
13 -*/
14 -package corerepo
15 -
16 -import (
17 - "context"
18 - "fmt"
19 - "github.com/ipfs/go-ipfs/pin"
20 -
21 - "github.com/ipfs/go-ipfs/core/coreapi/interface"
22 -
23 - "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
24 -)
25 -
26 -func Pin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
27 - out := make([]cid.Cid, len(paths))
28 -
29 - for i, fpath := range paths {
30 - p, err := iface.ParsePath(fpath)
31 - if err != nil {
32 - return nil, err
33 - }
34 -
35 - dagnode, err := api.ResolveNode(ctx, p)
36 - if err != nil {
37 - return nil, fmt.Errorf("pin: %s", err)
38 - }
39 - err = pinning.Pin(ctx, dagnode, recursive)
40 - if err != nil {
41 - return nil, fmt.Errorf("pin: %s", err)
42 - }
43 - out[i] = dagnode.Cid()
44 - }
45 -
46 - err := pinning.Flush()
47 - if err != nil {
48 - return nil, err
49 - }
50 -
51 - return out, nil
52 -}
53 -
54 -func Unpin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
55 - unpinned := make([]cid.Cid, len(paths))
56 -
57 - for i, p := range paths {
58 - p, err := iface.ParsePath(p)
59 - if err != nil {
60 - return nil, err
61 - }
62 -
63 - k, err := api.ResolvePath(ctx, p)
64 - if err != nil {
65 - return nil, err
66 - }
67 -
68 - err = pinning.Unpin(ctx, k.Cid(), recursive)
69 - if err != nil {
70 - return nil, err
71 - }
72 - unpinned[i] = k.Cid()
73 - }
74 -
75 - err := pinning.Flush()
76 - if err != nil {
77 - return nil, err
78 - }
79 - return unpinned, nil
80 -}