pin.go 3.32 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{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
13 14 15 16
	// TODO UsageLine: "pin",
	// TODO Short:     "",
	Help: `ipfs pin [add|rm] - object pinning commands
	`,
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{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
24 25 26 27 28 29 30
	// TODO UsageLine: "add",
	// TODO Short:     "pin an ipfs object to local storage.",
	Help: `ipfs pin add <ipfs-path> - pin ipfs object to local storage.

    Retrieves the object named by <ipfs-path> and stores it locally
    on disk.
`,
31 32 33 34 35 36 37 38 39 40 41 42 43 44
	Options: []cmds.Option{
		cmds.Option{[]string{"recursive", "r"}, cmds.Bool},
		cmds.Option{[]string{"depth", "d"}, cmds.Uint},
	},
	Arguments: []cmds.Argument{
		cmds.Argument{"object", cmds.ArgString, true, true},
	},
	Run: func(res cmds.Response, req cmds.Request) {
		n := req.Context().Node

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

Brian Tiger Chow's avatar
Brian Tiger Chow committed
45
		paths, err := internal.ToStrings(req.Arguments())
Brian Tiger Chow's avatar
Brian Tiger Chow committed
46 47 48
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
49 50
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
51
		_, err = pin(n, paths, recursive)
52 53 54 55 56 57 58 59
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
		}

		// TODO: create some output to show what got pinned
	},
}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
60
var rmPinCmd = &cmds.Command{
Brian Tiger Chow's avatar
Brian Tiger Chow committed
61 62 63 64 65 66 67
	// TODO UsageLine: "rm",
	// TODO Short:     "unpin an ipfs object from local storage.",
	Help: `ipfs pin rm <ipfs-path> - unpin ipfs object from local storage.

	Removes the pin from the given object allowing it to be garbage
	collected if needed.
`,
68 69 70 71 72 73 74 75 76 77 78 79 80
	Options: []cmds.Option{
		cmds.Option{[]string{"recursive", "r"}, cmds.Bool},
	},
	Arguments: []cmds.Argument{
		cmds.Argument{"object", cmds.ArgString, true, true},
	},
	Run: func(res cmds.Response, req cmds.Request) {
		n := req.Context().Node

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

Brian Tiger Chow's avatar
Brian Tiger Chow committed
81 82 83 84
		paths, err := internal.ToStrings(req.Arguments())
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
			return
85 86
		}

Brian Tiger Chow's avatar
Brian Tiger Chow committed
87
		_, err = unpin(n, paths, recursive)
88 89 90 91 92 93 94
		if err != nil {
			res.SetError(err, cmds.ErrNormal)
		}

		// TODO: create some output to show what got unpinned
	},
}
Brian Tiger Chow's avatar
Brian Tiger Chow committed
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120

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
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146

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
}