pin.go 3.21 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 8
	"github.com/jbenet/go-ipfs/core"
	"github.com/jbenet/go-ipfs/merkledag"
9 10 11
)

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

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

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

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

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

52
		_, err = pin(n, req.Arguments(), recursive)
53
		if err != nil {
54
			return nil, err
55 56 57
		}

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

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

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

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

92
		_, err = unpin(n, req.Arguments(), recursive)
93
		if err != nil {
94
			return nil, err
95 96 97
		}

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

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

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
}