pin.go 3.43 KB
Newer Older
1 2 3 4 5 6
package commands

import (
	"fmt"

	cmds "github.com/jbenet/go-ipfs/commands"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
7
	"github.com/jbenet/go-ipfs/core"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
8
	"github.com/jbenet/go-ipfs/core/commands2/internal"
Brian Tiger Chow's avatar
Brian Tiger Chow committed
9
	"github.com/jbenet/go-ipfs/merkledag"
10 11 12
)

var pinCmd = &cmds.Command{
13
	Helptext: cmds.HelpText{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
14
		Tagline: "Pin (and unpin) objects to local storage",
15
	},
16

Brian Tiger Chow's avatar
Brian Tiger Chow committed
17 18 19 20 21 22 23
	Subcommands: map[string]*cmds.Command{
		"add": addPinCmd,
		"rm":  rmPinCmd,
	},
}

var addPinCmd = &cmds.Command{
24 25 26 27
	Helptext: cmds.HelpText{
		Tagline: "Pins objects to local storage",
		ShortDescription: `
Retrieves the object named by <ipfs-path> and stores it locally
28
on disk.
Brian Tiger Chow's avatar
Brian Tiger Chow committed
29
`,
30
	},
31

32
	Arguments: []cmds.Argument{
33
		cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be pinned"),
34 35
	},
	Options: []cmds.Option{
36
		cmds.BoolOption("recursive", "r", "Recursively pin the object linked to by the specified object(s)"),
37
	},
38
	Run: func(req cmds.Request) (interface{}, error) {
39 40 41 42
		n, err := req.Context().GetNode()
		if err != nil {
			return nil, err
		}
43 44

		// set recursive flag
45 46 47 48 49 50 51
		recursive, found, err := req.Option("recursive").Bool()
		if err != nil {
			return nil, err
		}
		if !found {
			recursive = false
		}
52

53
		paths, err := internal.CastToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
54
		if err != nil {
55
			return nil, err
56 57
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
58
		_, err = pin(n, paths, recursive)
59
		if err != nil {
60
			return nil, err
61 62 63
		}

		// TODO: create some output to show what got pinned
64
		return nil, nil
65 66 67
	},
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
68
var rmPinCmd = &cmds.Command{
69 70 71 72
	Helptext: cmds.HelpText{
		Tagline: "Unpin an object from local storage",
		ShortDescription: `
Removes the pin from the given object allowing it to be garbage
73
collected if needed.
Brian Tiger Chow's avatar
Brian Tiger Chow committed
74
`,
75
	},
76

77
	Arguments: []cmds.Argument{
78
		cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be unpinned"),
79 80
	},
	Options: []cmds.Option{
81
		cmds.BoolOption("recursive", "r", "Recursively unpin the object linked to by the specified object(s)"),
82
	},
83
	Run: func(req cmds.Request) (interface{}, error) {
84 85 86 87
		n, err := req.Context().GetNode()
		if err != nil {
			return nil, err
		}
88 89

		// set recursive flag
90 91 92 93 94 95 96
		recursive, found, err := req.Option("recursive").Bool()
		if err != nil {
			return nil, err
		}
		if !found {
			recursive = false // default
		}
97

98
		paths, err := internal.CastToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
99
		if err != nil {
100
			return nil, err
101 102
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
103
		_, err = unpin(n, paths, recursive)
104
		if err != nil {
105
			return nil, err
106 107 108
		}

		// TODO: create some output to show what got unpinned
109
		return nil, nil
110 111
	},
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137

func pin(n *core.IpfsNode, paths []string, recursive bool) ([]*merkledag.Node, error) {

	dagnodes := make([]*merkledag.Node, 0)
	for _, path := range paths {
		dagnode, err := n.Resolver.ResolvePath(path)
		if err != nil {
			return nil, fmt.Errorf("pin error: %v", err)
		}
		dagnodes = append(dagnodes, dagnode)
	}

	for _, dagnode := range dagnodes {
		err := n.Pinning.Pin(dagnode, recursive)
		if err != nil {
			return nil, fmt.Errorf("pin: %v", err)
		}
	}

	err := n.Pinning.Flush()
	if err != nil {
		return nil, err
	}

	return dagnodes, nil
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163

func unpin(n *core.IpfsNode, paths []string, recursive bool) ([]*merkledag.Node, error) {

	dagnodes := make([]*merkledag.Node, 0)
	for _, path := range paths {
		dagnode, err := n.Resolver.ResolvePath(path)
		if err != nil {
			return nil, err
		}
		dagnodes = append(dagnodes, dagnode)
	}

	for _, dagnode := range dagnodes {
		k, _ := dagnode.Key()
		err := n.Pinning.Unpin(k, recursive)
		if err != nil {
			return nil, err
		}
	}

	err := n.Pinning.Flush()
	if err != nil {
		return nil, err
	}
	return dagnodes, nil
}