pin.go 3.31 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 14
	Description: "Keeps objects stored locally",

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

var addPinCmd = &cmds.Command{
22
	Description: "Pins objects to local storage",
23 24
	Help: `Retrieves the object named by <ipfs-path> and stores it locally
on disk.
Brian Tiger Chow's avatar
Brian Tiger Chow committed
25
`,
26

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

		// set recursive flag
40 41 42 43 44 45 46
		recursive, found, err := req.Option("recursive").Bool()
		if err != nil {
			return nil, err
		}
		if !found {
			recursive = false
		}
47

48
		paths, err := internal.CastToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
49
		if err != nil {
50
			return nil, err
51 52
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
53
		_, err = pin(n, paths, recursive)
54
		if err != nil {
55
			return nil, err
56 57 58
		}

		// TODO: create some output to show what got pinned
59
		return nil, nil
60 61 62
	},
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
63
var rmPinCmd = &cmds.Command{
64 65
	Description: "Unpin an object from local storage",
	Help: `Removes the pin from the given object allowing it to be garbage
66
collected if needed.
Brian Tiger Chow's avatar
Brian Tiger Chow committed
67
`,
68

69
	Arguments: []cmds.Argument{
70
		cmds.StringArg("ipfs-path", true, true, "Path to object(s) to be unpinned"),
71 72
	},
	Options: []cmds.Option{
73
		cmds.BoolOption("recursive", "r", "Recursively unpin the object linked to by the specified object(s)"),
74
	},
75
	Run: func(req cmds.Request) (interface{}, error) {
76 77 78 79
		n, err := req.Context().GetNode()
		if err != nil {
			return nil, err
		}
80 81

		// set recursive flag
82 83 84 85 86 87 88
		recursive, found, err := req.Option("recursive").Bool()
		if err != nil {
			return nil, err
		}
		if !found {
			recursive = false // default
		}
89

90
		paths, err := internal.CastToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
91
		if err != nil {
92
			return nil, err
93 94
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
95
		_, err = unpin(n, paths, recursive)
96
		if err != nil {
97
			return nil, err
98 99 100
		}

		// TODO: create some output to show what got unpinned
101
		return nil, nil
102 103
	},
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129

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
130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155

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
}