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
-}