pin.go 3.14 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 29 30 31
		cmds.Argument{"ipfs-path", cmds.ArgString, true, true,
			"Path to object(s) to be pinned"},
	},
	Options: []cmds.Option{
32
		cmds.BoolOption("recursive", "r", "Recursively pin the object linked to by the specified object(s)"),
33
	},
34
	Run: func(req cmds.Request) (interface{}, error) {
35 36 37 38 39 40
		n := req.Context().Node

		// set recursive flag
		opt, _ := req.Option("recursive")
		recursive, _ := opt.(bool) // false if cast fails.

41
		paths, err := internal.CastToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
42
		if err != nil {
43
			return nil, err
44 45
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
46
		_, err = pin(n, paths, recursive)
47
		if err != nil {
48
			return nil, err
49 50 51
		}

		// TODO: create some output to show what got pinned
52
		return nil, nil
53 54 55
	},
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
56
var rmPinCmd = &cmds.Command{
57 58
	Description: "Unpin an object from local storage",
	Help: `Removes the pin from the given object allowing it to be garbage
59
collected if needed.
Brian Tiger Chow's avatar
Brian Tiger Chow committed
60
`,
61

62
	Arguments: []cmds.Argument{
63 64 65 66
		cmds.Argument{"ipfs-path", cmds.ArgString, true, true,
			"Path to object(s) to be unpinned"},
	},
	Options: []cmds.Option{
67
		cmds.BoolOption("recursive", "r", "Recursively unpin the object linked to by the specified object(s)"),
68
	},
69
	Run: func(req cmds.Request) (interface{}, error) {
70 71 72 73 74 75
		n := req.Context().Node

		// set recursive flag
		opt, _ := req.Option("recursive")
		recursive, _ := opt.(bool) // false if cast fails.

76
		paths, err := internal.CastToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
77
		if err != nil {
78
			return nil, err
79 80
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
81
		_, err = unpin(n, paths, recursive)
82
		if err != nil {
83
			return nil, err
84 85 86
		}

		// TODO: create some output to show what got unpinned
87
		return nil, nil
88 89
	},
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115

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
116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141

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
}