@cryptotaxi247 / kubo / commits / d1fa4bd9b

copy to old location

Brian Tiger Chow committed Oct 28, 2014 at 23:48 UTC d1fa4bd9b5a3a9ec8620fb67fe052bec3bd314cc
29 files changed +1925
cmd/ipfs/.gitignore new
+1
@@ -0,0 +1 @@
1 +./ipfs
cmd/ipfs/Makefile new
+7
@@ -0,0 +1,7 @@
1 +all: install
2 +
3 +build:
4 + go build
5 +
6 +install: build
7 + go install
cmd/ipfs/README.md new
+29
@@ -0,0 +1,29 @@
1 +# go-ipfs/cmd/ipfs
2 +
3 +This is the ipfs commandline tool. For now, it's the main entry point to using IPFS. Use it.
4 +
5 +```
6 +> go build
7 +> go install
8 +> ipfs
9 +ipfs - global versioned p2p merkledag file system
10 +
11 +Basic commands:
12 +
13 + add <path> Add an object to ipfs.
14 + cat <ref> Show ipfs object data.
15 + ls <ref> List links from an object.
16 + refs <ref> List link hashes from an object.
17 +
18 +Tool commands:
19 +
20 + config Manage configuration.
21 + version Show ipfs version information.
22 + commands List all available commands.
23 +
24 +Advanced Commands:
25 +
26 + mount Mount an ipfs read-only mountpoint.
27 +
28 +Use "ipfs help <command>" for more information about a command.
29 +```
cmd/ipfs/add.go new
+39
@@ -0,0 +1,39 @@
1 +package main
2 +
3 +import (
4 + "fmt"
5 + "path/filepath"
6 +
7 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
8 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
9 + "github.com/jbenet/go-ipfs/core/commands"
10 +)
11 +
12 +// Error indicating the max depth has been exceded.
13 +var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
14 +
15 +var cmdIpfsAdd = &commander.Command{
16 + UsageLine: "add",
17 + Short: "Add an object to ipfs.",
18 + Long: `ipfs add <path>... - Add objects to ipfs.
19 +
20 + Adds contents of <path> to ipfs. Use -r to add directories.
21 + Note that directories are added recursively, to form the ipfs
22 + MerkleDAG. A smarter partial add with a staging area (like git)
23 + remains to be implemented.
24 +`,
25 + Run: addCmd,
26 + Flag: *flag.NewFlagSet("ipfs-add", flag.ExitOnError),
27 +}
28 +
29 +func init() {
30 + cmdIpfsAdd.Flag.Bool("r", false, "add objects recursively")
31 +}
32 +
33 +var addCmd = makeCommand(command{
34 + name: "add",
35 + args: 1,
36 + flags: []string{"r"},
37 + cmdFn: commands.Add,
38 + argFilter: filepath.Abs,
39 +})
cmd/ipfs/block.go new
+58
@@ -0,0 +1,58 @@
1 +package main
2 +
3 +import (
4 + flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsBlock = &commander.Command{
10 + UsageLine: "block",
11 + Short: "manipulate raw ipfs blocks",
12 + Long: `ipfs block - manipulate raw ipfs blocks
13 +
14 + ipfs block get <key> - get and output block named by <key>
15 + ipfs block put - store stdin as a block, outputs <key>
16 +
17 +ipfs block is a plumbing command used to manipulate raw ipfs blocks.
18 +Reads from stdin or writes to stdout, and <key> is a base58 encoded
19 +multihash.`,
20 + // Run: blockGetCmd,
21 + Subcommands: []*commander.Command{
22 + cmdIpfsBlockGet,
23 + cmdIpfsBlockPut,
24 + },
25 + Flag: *flag.NewFlagSet("ipfs-block", flag.ExitOnError),
26 +}
27 +
28 +var cmdIpfsBlockGet = &commander.Command{
29 + UsageLine: "get <key>",
30 + Short: "get and output block named by <key>",
31 + Long: `ipfs get <key> - get and output block named by <key>
32 +
33 +ipfs block get is a plumbing command for retreiving raw ipfs blocks.
34 +It outputs to stdout, and <key> is a base58 encoded multihash.`,
35 + Run: makeCommand(command{
36 + name: "blockGet",
37 + args: 1,
38 + flags: nil,
39 + online: true,
40 + cmdFn: commands.BlockGet,
41 + }),
42 +}
43 +
44 +var cmdIpfsBlockPut = &commander.Command{
45 + UsageLine: "put",
46 + Short: "store stdin as a block, outputs <key>",
47 + Long: `ipfs put - store stdin as a block, outputs <key>
48 +
49 +ipfs block put is a plumbing command for storing raw ipfs blocks.
50 +It reads from stding, and <key> is a base58 encoded multihash.`,
51 + Run: makeCommand(command{
52 + name: "blockPut",
53 + args: 0,
54 + flags: nil,
55 + online: true,
56 + cmdFn: commands.BlockPut,
57 + }),
58 +}
cmd/ipfs/bootstrap.go new
+236
@@ -0,0 +1,236 @@
1 +package main
2 +
3 +import (
4 + "errors"
5 + "strings"
6 +
7 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
8 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
9 + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
10 + mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
11 +
12 + config "github.com/jbenet/go-ipfs/config"
13 + peer "github.com/jbenet/go-ipfs/peer"
14 + u "github.com/jbenet/go-ipfs/util"
15 +)
16 +
17 +var cmdIpfsBootstrap = &commander.Command{
18 + UsageLine: "bootstrap",
19 + Short: "Show a list of bootstrapped addresses.",
20 + Long: `ipfs bootstrap - show, or manipulate bootstrap node addresses
21 +
22 +Running 'ipfs bootstrap' with no arguments will run 'ipfs bootstrap list'.
23 +
24 +Commands:
25 +
26 + list Show the boostrap list.
27 + add <address> Add a node's address to the bootstrap list.
28 + remove <address> Remove an address from the bootstrap list.
29 +
30 +` + bootstrapSecurityWarning,
31 + Run: bootstrapListCmd,
32 + Subcommands: []*commander.Command{
33 + cmdIpfsBootstrapRemove,
34 + cmdIpfsBootstrapAdd,
35 + cmdIpfsBootstrapList,
36 + },
37 + Flag: *flag.NewFlagSet("ipfs-bootstrap", flag.ExitOnError),
38 +}
39 +
40 +var cmdIpfsBootstrapRemove = &commander.Command{
41 + UsageLine: "remove <address | peerid>",
42 + Short: "Remove addresses from the bootstrap list.",
43 + Long: `ipfs bootstrap remove - remove addresses from the bootstrap list
44 +` + bootstrapSecurityWarning,
45 + Run: bootstrapRemoveCmd,
46 + Flag: *flag.NewFlagSet("ipfs-bootstrap-remove", flag.ExitOnError),
47 +}
48 +
49 +var cmdIpfsBootstrapAdd = &commander.Command{
50 + UsageLine: "add <address | peerid>",
51 + Short: "Add addresses to the bootstrap list.",
52 + Long: `ipfs bootstrap add - add addresses to the bootstrap list
53 +` + bootstrapSecurityWarning,
54 + Run: bootstrapAddCmd,
55 + Flag: *flag.NewFlagSet("ipfs-bootstrap-add", flag.ExitOnError),
56 +}
57 +
58 +var cmdIpfsBootstrapList = &commander.Command{
59 + UsageLine: "list",
60 + Short: "Show addresses in the bootstrap list.",
61 + Run: bootstrapListCmd,
62 + Flag: *flag.NewFlagSet("ipfs-bootstrap-list", flag.ExitOnError),
63 +}
64 +
65 +func bootstrapRemoveCmd(c *commander.Command, inp []string) error {
66 +
67 + if len(inp) == 0 {
68 + return errors.New("remove: no address or peerid specified")
69 + }
70 +
71 + toRemove, err := bootstrapInputToPeers(inp)
72 + if err != nil {
73 + return err
74 + }
75 +
76 + cfg, err := getConfig(c)
77 + if err != nil {
78 + return err
79 + }
80 +
81 + keep := []*config.BootstrapPeer{}
82 + remove := []*config.BootstrapPeer{}
83 +
84 + // function to filer what to keep
85 + shouldKeep := func(bp *config.BootstrapPeer) bool {
86 + for _, skipBP := range toRemove {
87 +
88 + // IDs must match to skip.
89 + if bp.PeerID != skipBP.PeerID {
90 + continue
91 + }
92 +
93 + // if Addresses match, or skipBP has no addr (wildcard)
94 + if skipBP.Address == bp.Address || skipBP.Address == "" {
95 + return false
96 + }
97 + }
98 + return true
99 + }
100 +
101 + // filter all the existing peers
102 + for _, currBP := range cfg.Bootstrap {
103 + if shouldKeep(currBP) {
104 + keep = append(keep, currBP)
105 + } else {
106 + remove = append(remove, currBP)
107 + }
108 + }
109 +
110 + // if didn't remove anyone, bail.
111 + if len(keep) == len(cfg.Bootstrap) {
112 + return errors.New("remove: peer given did not match any in list")
113 + }
114 +
115 + // write new config
116 + cfg.Bootstrap = keep
117 + if err := writeConfig(c, cfg); err != nil {
118 + return err
119 + }
120 +
121 + for _, bp := range remove {
122 + u.POut("removed %s\n", bp)
123 + }
124 + return nil
125 +}
126 +
127 +func bootstrapAddCmd(c *commander.Command, inp []string) error {
128 +
129 + if len(inp) == 0 {
130 + return errors.New("add: no address specified")
131 + }
132 +
133 + toAdd, err := bootstrapInputToPeers(inp)
134 + if err != nil {
135 + return err
136 + }
137 +
138 + cfg, err := getConfig(c)
139 + if err != nil {
140 + return err
141 + }
142 +
143 + // function to check whether a peer is already in the list.
144 + combine := func(lists ...[]*config.BootstrapPeer) []*config.BootstrapPeer {
145 +
146 + set := map[string]struct{}{}
147 + final := []*config.BootstrapPeer{}
148 +
149 + for _, list := range lists {
150 + for _, peer := range list {
151 + // if already in the set, continue
152 + _, found := set[peer.String()]
153 + if found {
154 + continue
155 + }
156 +
157 + set[peer.String()] = struct{}{}
158 + final = append(final, peer)
159 + }
160 + }
161 + return final
162 + }
163 +
164 + // combine both lists, removing dups.
165 + cfg.Bootstrap = combine(cfg.Bootstrap, toAdd)
166 + if err := writeConfig(c, cfg); err != nil {
167 + return err
168 + }
169 +
170 + for _, bp := range toAdd {
171 + u.POut("added %s\n", bp)
172 + }
173 + return nil
174 +}
175 +
176 +func bootstrapListCmd(c *commander.Command, inp []string) error {
177 +
178 + cfg, err := getConfig(c)
179 + if err != nil {
180 + return err
181 + }
182 +
183 + for _, bp := range cfg.Bootstrap {
184 + u.POut("%s\n", bp)
185 + }
186 +
187 + return nil
188 +}
189 +
190 +func bootstrapInputToPeers(input []string) ([]*config.BootstrapPeer, error) {
191 + split := func(addr string) (string, string) {
192 + idx := strings.LastIndex(addr, "/")
193 + if idx == -1 {
194 + return "", addr
195 + }
196 + return addr[:idx], addr[idx+1:]
197 + }
198 +
199 + peers := []*config.BootstrapPeer{}
200 + for _, addr := range input {
201 + addrS, peeridS := split(addr)
202 +
203 + // make sure addrS parses as a multiaddr.
204 + if len(addrS) > 0 {
205 + maddr, err := ma.NewMultiaddr(addrS)
206 + if err != nil {
207 + return nil, err
208 + }
209 +
210 + addrS = maddr.String()
211 + }
212 +
213 + // make sure idS parses as a peer.ID
214 + peerid, err := mh.FromB58String(peeridS)
215 + if err != nil {
216 + return nil, err
217 + }
218 +
219 + // construct config entry
220 + peers = append(peers, &config.BootstrapPeer{
221 + Address: addrS,
222 + PeerID: peer.ID(peerid).Pretty(),
223 + })
224 + }
225 + return peers, nil
226 +}
227 +
228 +const bootstrapSecurityWarning = `
229 +SECURITY WARNING:
230 +
231 +The bootstrap command manipulates the "bootstrap list", which contains
232 +the addresses of bootstrap nodes. These are the *trusted peers* from
233 +which to learn about other peers in the network. Only edit this list
234 +if you understand the risks of adding or removing nodes from this list.
235 +
236 +`
cmd/ipfs/cat.go new
+26
@@ -0,0 +1,26 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsCat = &commander.Command{
10 + UsageLine: "cat",
11 + Short: "Show ipfs object data.",
12 + Long: `ipfs cat <ipfs-path> - Show ipfs object data.
13 +
14 + Retrieves the object named by <ipfs-path> and displays the Data
15 + it contains.
16 +`,
17 + Run: catCmd,
18 + Flag: *flag.NewFlagSet("ipfs-cat", flag.ExitOnError),
19 +}
20 +
21 +var catCmd = makeCommand(command{
22 + name: "cat",
23 + args: 1,
24 + flags: nil,
25 + cmdFn: commands.Cat,
26 +})
cmd/ipfs/commands.go new
+74
@@ -0,0 +1,74 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
5 + u "github.com/jbenet/go-ipfs/util"
6 + "strings"
7 + "time"
8 +)
9 +
10 +var cmdIpfsCommands = &commander.Command{
11 + UsageLine: "commands",
12 + Short: "List all available commands.",
13 + Long: `ipfs commands - List all available commands.
14 +
15 + Lists all available commands (and sub-commands) and exits.
16 + `,
17 + Run: commandsCmd,
18 + Subcommands: []*commander.Command{
19 + cmdIpfsCommandsHelp,
20 + },
21 +}
22 +
23 +func commandsCmd(c *commander.Command, args []string) error {
24 + var listCmds func(c *commander.Command)
25 + listCmds = func(c *commander.Command) {
26 + u.POut("%s\n", c.FullSpacedName())
27 + for _, sc := range c.Subcommands {
28 + listCmds(sc)
29 + }
30 + }
31 +
32 + listCmds(c.Parent)
33 + return nil
34 +}
35 +
36 +var cmdIpfsCommandsHelp = &commander.Command{
37 + UsageLine: "help",
38 + Short: "List all available commands' help pages.",
39 + Long: `ipfs commands help - List all available commands's help pages.
40 +
41 + Shows the pages of all available commands (and sub-commands) and exits.
42 + Outputs a markdown document.
43 + `,
44 + Run: commandsHelpCmd,
45 +}
46 +
47 +func commandsHelpCmd(c *commander.Command, args []string) error {
48 + u.POut(referenceHeaderMsg)
49 + u.POut("Generated on %s.\n\n", time.Now().UTC().Format("2006-01-02"))
50 +
51 + var printCmds func(*commander.Command, int)
52 + printCmds = func(c *commander.Command, level int) {
53 + u.POut("%s ", strings.Repeat("#", level))
54 + u.POut("%s\n\n", c.FullSpacedName())
55 + u.POut("```\n")
56 + u.POut("%s\n", c.Long)
57 + u.POut("```\n\n")
58 +
59 + for _, sc := range c.Subcommands {
60 + printCmds(sc, level+1)
61 + }
62 + }
63 +
64 + printCmds(c.Parent.Parent, 1)
65 + return nil
66 +}
67 +
68 +const referenceHeaderMsg = `
69 +# ipfs command reference
70 +
71 +This document lists every ipfs command (including subcommands), along with
72 +its help page. It can be viewed by running 'ipfs commands help'.
73 +
74 +`
cmd/ipfs/config.go new
+143
@@ -0,0 +1,143 @@
1 +package main
2 +
3 +import (
4 + "errors"
5 + "fmt"
6 + "io"
7 + "os"
8 + "os/exec"
9 +
10 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
11 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
12 + config "github.com/jbenet/go-ipfs/config"
13 + u "github.com/jbenet/go-ipfs/util"
14 +)
15 +
16 +var cmdIpfsConfig = &commander.Command{
17 + UsageLine: "config",
18 + Short: "Get/Set ipfs config values",
19 + Long: `ipfs config [<key>] [<value>] - Get/Set ipfs config values.
20 +
21 + ipfs config <key> - Get value of <key>
22 + ipfs config <key> <value> - Set value of <key> to <value>
23 + ipfs config --show - Show config file
24 + ipfs config --edit - Edit config file in $EDITOR
25 +
26 +Examples:
27 +
28 + Get the value of the 'datastore.path' key:
29 +
30 + ipfs config datastore.path
31 +
32 + Set the value of the 'datastore.path' key:
33 +
34 + ipfs config datastore.path ~/.go-ipfs/datastore
35 +
36 +`,
37 + Run: configCmd,
38 + Flag: *flag.NewFlagSet("ipfs-config", flag.ExitOnError),
39 +}
40 +
41 +func init() {
42 + cmdIpfsConfig.Flag.Bool("edit", false, "Edit config file in $EDITOR")
43 + cmdIpfsConfig.Flag.Bool("show", false, "Show config file")
44 +}
45 +
46 +func configCmd(c *commander.Command, inp []string) error {
47 +
48 + confdir, err := getConfigDir(c.Parent)
49 + if err != nil {
50 + return err
51 + }
52 +
53 + filename, err := config.Filename(confdir)
54 + if err != nil {
55 + return err
56 + }
57 +
58 + // if editing, open the editor
59 + if c.Flag.Lookup("edit").Value.Get().(bool) {
60 + return configEditor(filename)
61 + }
62 +
63 + // if showing, cat the file
64 + if c.Flag.Lookup("show").Value.Get().(bool) {
65 + return configCat(filename)
66 + }
67 +
68 + if len(inp) == 0 {
69 + // "ipfs config" run without parameters
70 + u.POut(c.Long)
71 + return nil
72 + }
73 +
74 + // Getter (1 param)
75 + if len(inp) == 1 {
76 + value, err := config.ReadConfigKey(filename, inp[0])
77 + if err != nil {
78 + return fmt.Errorf("Failed to get config value: %s", err)
79 + }
80 +
81 + strval, ok := value.(string)
82 + if ok {
83 + u.POut("%s\n", strval)
84 + return nil
85 + }
86 +
87 + if err := config.Encode(os.Stdout, value); err != nil {
88 + return fmt.Errorf("Failed to encode config value: %s", err)
89 + }
90 + u.POut("\n")
91 + return nil
92 + }
93 +
94 + // Setter (>1 params)
95 + err = config.WriteConfigKey(filename, inp[0], inp[1])
96 + if err != nil {
97 + return fmt.Errorf("Failed to set config value: %s", err)
98 + }
99 +
100 + return nil
101 +}
102 +
103 +func configCat(filename string) error {
104 +
105 + file, err := os.Open(filename)
106 + if err != nil {
107 + return err
108 + }
109 + defer file.Close()
110 +
111 + if _, err = io.Copy(os.Stdout, file); err != nil {
112 + return err
113 + }
114 + u.POut("\n")
115 + return nil
116 +}
117 +
118 +func configEditor(filename string) error {
119 +
120 + editor := os.Getenv("EDITOR")
121 + if editor == "" {
122 + return errors.New("ENV variable $EDITOR not set")
123 + }
124 +
125 + cmd := exec.Command("sh", "-c", editor+" "+filename)
126 + cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
127 + return cmd.Run()
128 +}
129 +
130 +func writeConfig(c *commander.Command, cfg *config.Config) error {
131 +
132 + confdir, err := getConfigDir(c)
133 + if err != nil {
134 + return err
135 + }
136 +
137 + filename, err := config.Filename(confdir)
138 + if err != nil {
139 + return err
140 + }
141 +
142 + return config.WriteConfigFile(filename, cfg)
143 +}
cmd/ipfs/diag.go new
+32
@@ -0,0 +1,32 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 +
6 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
7 + "github.com/jbenet/go-ipfs/core/commands"
8 +)
9 +
10 +var cmdIpfsDiag = &commander.Command{
11 + UsageLine: "net-diag",
12 + Short: "Generate a diagnostics report",
13 + Long: `ipfs net-diag - Generate a diagnostics report.
14 +
15 + Sends out a message to each node in the network recursively
16 + requesting a listing of data about them including number of
17 + connected peers and latencies between them.
18 +`,
19 + Run: diagCmd,
20 + Flag: *flag.NewFlagSet("ipfs-net-diag", flag.ExitOnError),
21 +}
22 +
23 +func init() {
24 + cmdIpfsDiag.Flag.Bool("raw", false, "print raw json output")
25 +}
26 +
27 +var diagCmd = makeCommand(command{
28 + name: "diag",
29 + args: 0,
30 + flags: []string{"raw"},
31 + cmdFn: commands.Diag,
32 +})
cmd/ipfs/equinox.yaml new
+6
@@ -0,0 +1,6 @@
1 +---
2 +equinox-account: CHANGEME
3 +equinox-secret: CHANGEME
4 +equinox-app: CHANGEME
5 +channel: stable
6 +private-key: equinox-priv
cmd/ipfs/gen.go new
+72
@@ -0,0 +1,72 @@
1 +package main
2 +
3 +import (
4 + "fmt"
5 + "os"
6 +
7 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
8 + "github.com/jbenet/go-ipfs/core/commands"
9 + "github.com/jbenet/go-ipfs/daemon"
10 + u "github.com/jbenet/go-ipfs/util"
11 +)
12 +
13 +// command is the descriptor of an ipfs daemon command.
14 +// Used with makeCommand to proxy over commands via the daemon.
15 +type command struct {
16 + name string
17 + args int
18 + flags []string
19 + online bool
20 + cmdFn commands.CmdFunc
21 + argFilter func(string) (string, error)
22 +}
23 +
24 +// commanderFunc is a function that can be passed into the Commander library as
25 +// a command handler. Defined here because commander lacks this definition.
26 +type commanderFunc func(*commander.Command, []string) error
27 +
28 +// makeCommand Wraps a commands.CmdFunc so that it may be safely run by the
29 +// commander library
30 +func makeCommand(cmdDesc command) commanderFunc {
31 + return func(c *commander.Command, inp []string) error {
32 + if len(inp) < cmdDesc.args {
33 + u.POut(c.Long)
34 + return nil
35 + }
36 + confdir, err := getConfigDir(c)
37 + if err != nil {
38 + return err
39 + }
40 +
41 + cmd := daemon.NewCommand()
42 + cmd.Command = cmdDesc.name
43 + if cmdDesc.argFilter != nil {
44 + for _, a := range inp {
45 + s, err := cmdDesc.argFilter(a)
46 + if err != nil {
47 + return err
48 + }
49 + cmd.Args = append(cmd.Args, s)
50 + }
51 + } else {
52 + cmd.Args = inp
53 + }
54 +
55 + for _, a := range cmdDesc.flags {
56 + cmd.Opts[a] = c.Flag.Lookup(a).Value.Get()
57 + }
58 +
59 + err = daemon.SendCommand(cmd, confdir)
60 + if err != nil {
61 + log.Info("Executing command locally: %s", err)
62 + // Do locally
63 + n, err := localNode(confdir, cmdDesc.online)
64 + if err != nil {
65 + return fmt.Errorf("Local node creation failed: %v", err)
66 + }
67 +
68 + return cmdDesc.cmdFn(n, cmd.Args, cmd.Opts, os.Stdout)
69 + }
70 + return nil
71 + }
72 +}
cmd/ipfs/init.go new
+150
@@ -0,0 +1,150 @@
1 +package main
2 +
3 +import (
4 + "encoding/base64"
5 + "errors"
6 + "os"
7 + "path/filepath"
8 +
9 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
10 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
11 + config "github.com/jbenet/go-ipfs/config"
12 + ci "github.com/jbenet/go-ipfs/crypto"
13 + peer "github.com/jbenet/go-ipfs/peer"
14 + updates "github.com/jbenet/go-ipfs/updates"
15 + u "github.com/jbenet/go-ipfs/util"
16 +)
17 +
18 +var cmdIpfsInit = &commander.Command{
19 + UsageLine: "init",
20 + Short: "Initialize ipfs local configuration",
21 + Long: `ipfs init
22 +
23 + Initializes ipfs configuration files and generates a
24 + new keypair.
25 +`,
26 + Run: initCmd,
27 + Flag: *flag.NewFlagSet("ipfs-init", flag.ExitOnError),
28 +}
29 +
30 +func init() {
31 + cmdIpfsInit.Flag.Int("b", 4096, "number of bits for keypair")
32 + cmdIpfsInit.Flag.String("p", "", "passphrase for encrypting keys")
33 + cmdIpfsInit.Flag.Bool("f", false, "force overwrite of existing config")
34 + cmdIpfsInit.Flag.String("d", "", "Change default datastore location")
35 +}
36 +
37 +func initCmd(c *commander.Command, inp []string) error {
38 + configpath, err := getConfigDir(c.Parent)
39 + if err != nil {
40 + return err
41 + }
42 +
43 + u.POut("initializing ipfs node at %s\n", configpath)
44 + filename, err := config.Filename(configpath)
45 + if err != nil {
46 + return errors.New("Couldn't get home directory path")
47 + }
48 +
49 + dspath, ok := c.Flag.Lookup("d").Value.Get().(string)
50 + if !ok {
51 + return errors.New("failed to parse datastore flag")
52 + }
53 +
54 + fi, err := os.Lstat(filename)
55 + force, ok := c.Flag.Lookup("f").Value.Get().(bool)
56 + if !ok {
57 + return errors.New("failed to parse force flag")
58 + }
59 + if fi != nil || (err != nil && !os.IsNotExist(err)) {
60 + if !force {
61 + return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)")
62 + }
63 + }
64 + cfg := new(config.Config)
65 +
66 + cfg.Datastore = config.Datastore{}
67 + if len(dspath) == 0 {
68 + dspath, err = config.DataStorePath("")
69 + if err != nil {
70 + return err
71 + }
72 + }
73 + cfg.Datastore.Path = dspath
74 + cfg.Datastore.Type = "leveldb"
75 +
76 + // Construct the data store if missing
77 + if err := os.MkdirAll(dspath, os.ModePerm); err != nil {
78 + return err
79 + }
80 +
81 + // Check the directory is writeable
82 + if f, err := os.Create(filepath.Join(dspath, "._check_writeable")); err == nil {
83 + os.Remove(f.Name())
84 + } else {
85 + return errors.New("Datastore '" + dspath + "' is not writeable")
86 + }
87 +
88 + cfg.Identity = config.Identity{}
89 +
90 + // setup the node addresses.
91 + cfg.Addresses = config.Addresses{
92 + Swarm: "/ip4/0.0.0.0/tcp/4001",
93 + API: "/ip4/127.0.0.1/tcp/5001",
94 + }
95 +
96 + // setup the node mount points.
97 + cfg.Mounts = config.Mounts{
98 + IPFS: "/ipfs",
99 + IPNS: "/ipns",
100 + }
101 +
102 + nbits, ok := c.Flag.Lookup("b").Value.Get().(int)
103 + if !ok {
104 + return errors.New("failed to get bits flag")
105 + }
106 + if nbits < 1024 {
107 + return errors.New("Bitsize less than 1024 is considered unsafe.")
108 + }
109 +
110 + u.POut("generating key pair\n")
111 + sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits)
112 + if err != nil {
113 + return err
114 + }
115 +
116 + // currently storing key unencrypted. in the future we need to encrypt it.
117 + // TODO(security)
118 + skbytes, err := sk.Bytes()
119 + if err != nil {
120 + return err
121 + }
122 + cfg.Identity.PrivKey = base64.StdEncoding.EncodeToString(skbytes)
123 +
124 + id, err := peer.IDFromPubKey(pk)
125 + if err != nil {
126 + return err
127 + }
128 + cfg.Identity.PeerID = id.Pretty()
129 +
130 + // Use these hardcoded bootstrap peers for now.
131 + cfg.Bootstrap = []*config.BootstrapPeer{
132 + &config.BootstrapPeer{
133 + // mars.i.ipfs.io
134 + PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
135 + Address: "/ip4/104.131.131.82/tcp/4001",
136 + },
137 + }
138 +
139 + // tracking ipfs version used to generate the init folder and adding update checker default setting.
140 + cfg.Version = config.Version{
141 + Check: "error",
142 + Current: updates.Version,
143 + }
144 +
145 + err = config.WriteConfigFile(filename, cfg)
146 + if err != nil {
147 + return err
148 + }
149 + return nil
150 +}
cmd/ipfs/ipfs.go new
+220
@@ -0,0 +1,220 @@
1 +package main
2 +
3 +import (
4 + "errors"
5 + "fmt"
6 + "os"
7 + "runtime/pprof"
8 +
9 + flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
10 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
11 + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
12 +
13 + config "github.com/jbenet/go-ipfs/config"
14 + core "github.com/jbenet/go-ipfs/core"
15 + daemon "github.com/jbenet/go-ipfs/daemon"
16 + updates "github.com/jbenet/go-ipfs/updates"
17 + u "github.com/jbenet/go-ipfs/util"
18 +)
19 +
20 +// The IPFS command tree. It is an instance of `commander.Command`.
21 +var CmdIpfs = &commander.Command{
22 + UsageLine: "ipfs [<flags>] <command> [<args>]",
23 + Short: "global versioned p2p merkledag file system",
24 + Long: `ipfs - global versioned p2p merkledag file system
25 +
26 +Basic commands:
27 +
28 + init Initialize ipfs local configuration.
29 + add <path> Add an object to ipfs.
30 + cat <ref> Show ipfs object data.
31 + ls <ref> List links from an object.
32 + refs <ref> List link hashes from an object.
33 +
34 +Tool commands:
35 +
36 + config Manage configuration.
37 + update Download and apply go-ipfs updates.
38 + version Show ipfs version information.
39 + commands List all available commands.
40 +
41 +Advanced Commands:
42 +
43 + mount Mount an ipfs read-only mountpoint.
44 + serve Serve an interface to ipfs.
45 + net-diag Print network diagnostic
46 +
47 +Plumbing commands:
48 +
49 + block Interact with raw blocks in the datastore
50 + object Interact with raw dag nodes
51 +
52 +
53 +Use "ipfs help <command>" for more information about a command.
54 +`,
55 + Run: ipfsCmd,
56 + Subcommands: []*commander.Command{
57 + cmdIpfsAdd,
58 + cmdIpfsCat,
59 + cmdIpfsLs,
60 + cmdIpfsRefs,
61 + cmdIpfsConfig,
62 + cmdIpfsVersion,
63 + cmdIpfsCommands,
64 + cmdIpfsMount,
65 + cmdIpfsInit,
66 + cmdIpfsServe,
67 + cmdIpfsRun,
68 + cmdIpfsName,
69 + cmdIpfsBootstrap,
70 + cmdIpfsDiag,
71 + cmdIpfsBlock,
72 + cmdIpfsObject,
73 + cmdIpfsUpdate,
74 + cmdIpfsLog,
75 + cmdIpfsPin,
76 + cmdIpfsTour,
77 + },
78 + Flag: *flag.NewFlagSet("ipfs", flag.ExitOnError),
79 +}
80 +
81 +// log is the command logger
82 +var log = u.Logger("cmd/ipfs")
83 +
84 +func init() {
85 + config, err := config.PathRoot()
86 + if err != nil {
87 + fmt.Fprintln(os.Stderr, "Failure initializing the default Config Directory: ", err)
88 + os.Exit(1)
89 + }
90 + CmdIpfs.Flag.String("c", config, "specify config directory")
91 +}
92 +
93 +func ipfsCmd(c *commander.Command, args []string) error {
94 + u.POut(c.Long)
95 + return nil
96 +}
97 +
98 +func main() {
99 + // if debugging, setup profiling.
100 + if u.Debug {
101 + ofi, err := os.Create("cpu.prof")
102 + if err != nil {
103 + fmt.Println(err)
104 + return
105 + }
106 + pprof.StartCPUProfile(ofi)
107 + defer ofi.Close()
108 + defer pprof.StopCPUProfile()
109 + }
110 +
111 + err := CmdIpfs.Dispatch(os.Args[1:])
112 + if err != nil {
113 + if len(err.Error()) > 0 {
114 + fmt.Fprintf(os.Stderr, "ipfs %s: %v\n", os.Args[1], err)
115 + }
116 + os.Exit(1)
117 + }
118 + return
119 +}
120 +
121 +// localNode constructs a node
122 +func localNode(confdir string, online bool) (*core.IpfsNode, error) {
123 + filename, err := config.Filename(confdir)
124 + if err != nil {
125 + return nil, err
126 + }
127 +
128 + cfg, err := config.Load(filename)
129 + if err != nil {
130 + return nil, err
131 + }
132 +
133 + if err := updates.CliCheckForUpdates(cfg, filename); err != nil {
134 + return nil, err
135 + }
136 +
137 + return core.NewIpfsNode(cfg, online)
138 +}
139 +
140 +// Gets the config "-c" flag from the command, or returns
141 +// the default configuration root directory
142 +func getConfigDir(c *commander.Command) (string, error) {
143 +
144 + // use the root cmd (that's where config is specified)
145 + for ; c.Parent != nil; c = c.Parent {
146 + }
147 +
148 + // flag should be defined on root.
149 + param := c.Flag.Lookup("c").Value.Get().(string)
150 + if param != "" {
151 + return u.TildeExpansion(param)
152 + }
153 +
154 + return config.PathRoot()
155 +}
156 +
157 +func getConfig(c *commander.Command) (*config.Config, error) {
158 + confdir, err := getConfigDir(c)
159 + if err != nil {
160 + return nil, err
161 + }
162 +
163 + filename, err := config.Filename(confdir)
164 + if err != nil {
165 + return nil, err
166 + }
167 +
168 + return config.Load(filename)
169 +}
170 +
171 +// cmdContext is a wrapper structure that keeps a node, a daemonlistener, and
172 +// a config directory together. These three are needed for most commands.
173 +type cmdContext struct {
174 + node *core.IpfsNode
175 + daemon *daemon.DaemonListener
176 + configDir string
177 +}
178 +
179 +// setupCmdContext initializes a cmdContext structure from a given command.
180 +func setupCmdContext(c *commander.Command, online bool) (cc cmdContext, err error) {
181 + rootCmd := c
182 + for ; rootCmd.Parent != nil; rootCmd = rootCmd.Parent {
183 + }
184 +
185 + cc.configDir, err = getConfigDir(rootCmd)
186 + if err != nil {
187 + return
188 + }
189 +
190 + cc.node, err = localNode(cc.configDir, online)
191 + if err != nil {
192 + return
193 + }
194 +
195 + cc.daemon, err = setupDaemon(cc.configDir, cc.node)
196 + if err != nil {
197 + return
198 + }
199 +
200 + return
201 +}
202 +
203 +// setupDaemon sets up the daemon corresponding to given node.
204 +func setupDaemon(confdir string, node *core.IpfsNode) (*daemon.DaemonListener, error) {
205 + if node.Config.Addresses.API == "" {
206 + return nil, errors.New("no config.Addresses.API endpoint supplied")
207 + }
208 +
209 + maddr, err := ma.NewMultiaddr(node.Config.Addresses.API)
210 + if err != nil {
211 + return nil, err
212 + }
213 +
214 + dl, err := daemon.NewDaemonListener(node, maddr, confdir)
215 + if err != nil {
216 + return nil, err
217 + }
218 + go dl.Listen()
219 + return dl, nil
220 +}
cmd/ipfs/log.go new
+29
@@ -0,0 +1,29 @@
1 +package main
2 +
3 +import (
4 + flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsLog = &commander.Command{
10 + UsageLine: "log <name> <level> ",
11 + Short: "switch logging levels of a running daemon",
12 + Long: `ipfs log <name> <level> - switch logging levels of a running daemon
13 +
14 + <name> is a the subsystem logging identifier. Use * for all subsystems.
15 + <level> is one of: debug, info, notice, warning, error, critical
16 +
17 +ipfs log is a utility command used to change the logging output of a running daemon.
18 +`,
19 + Run: logCmd,
20 + Flag: *flag.NewFlagSet("ipfs-log", flag.ExitOnError),
21 +}
22 +
23 +var logCmd = makeCommand(command{
24 + name: "log",
25 + args: 2,
26 + flags: nil,
27 + online: true,
28 + cmdFn: commands.Log,
29 +})
cmd/ipfs/ls.go new
+29
@@ -0,0 +1,29 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsLs = &commander.Command{
10 + UsageLine: "ls",
11 + Short: "List links from an object.",
12 + Long: `ipfs ls <ipfs-path> - List links from an object.
13 +
14 + Retrieves the object named by <ipfs-path> and displays the links
15 + it contains, with the following format:
16 +
17 + <link base58 hash> <link size in bytes> <link name>
18 +
19 +`,
20 + Run: lsCmd,
21 + Flag: *flag.NewFlagSet("ipfs-ls", flag.ExitOnError),
22 +}
23 +
24 +var lsCmd = makeCommand(command{
25 + name: "ls",
26 + args: 1,
27 + flags: nil,
28 + cmdFn: commands.Ls,
29 +})
cmd/ipfs/mount_unix.go new
+94
@@ -0,0 +1,94 @@
1 +// +build linux darwin freebsd
2 +
3 +package main
4 +
5 +import (
6 + "fmt"
7 +
8 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
9 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
10 +
11 + core "github.com/jbenet/go-ipfs/core"
12 + ipns "github.com/jbenet/go-ipfs/fuse/ipns"
13 + rofs "github.com/jbenet/go-ipfs/fuse/readonly"
14 +)
15 +
16 +var cmdIpfsMount = &commander.Command{
17 + UsageLine: "mount",
18 + Short: "Mount an ipfs read-only mountpoint.",
19 + Long: `ipfs mount <os-path> - Mount an ipfs read-only mountpoint.
20 +
21 + Mount ipfs at a read-only mountpoint on the OS. All ipfs objects
22 + will be accessible under that directory. Note that the root will
23 + not be listable, as it is virtual. Accessing known paths directly.
24 +
25 +`,
26 + Run: mountCmd,
27 + Flag: *flag.NewFlagSet("ipfs-mount", flag.ExitOnError),
28 +}
29 +
30 +func init() {
31 + cmdIpfsMount.Flag.String("f", "", "specify a mountpoint for ipfs")
32 + cmdIpfsMount.Flag.String("n", "", "specify a mountpoint for ipns")
33 +}
34 +
35 +func mountCmd(c *commander.Command, inp []string) error {
36 +
37 + cc, err := setupCmdContext(c, true)
38 + if err != nil {
39 + return err
40 + }
41 + defer cc.daemon.Close()
42 +
43 + // update fsdir with flag.
44 + fsdir := cc.node.Config.Mounts.IPFS
45 + if val, ok := c.Flag.Lookup("f").Value.Get().(string); ok && val != "" {
46 + fsdir = val
47 + }
48 + fsdone := mountIpfs(cc.node, fsdir)
49 +
50 + // get default mount points
51 + nsdir := cc.node.Config.Mounts.IPNS
52 + if val, ok := c.Flag.Lookup("n").Value.Get().(string); ok && val != "" {
53 + nsdir = val
54 + }
55 + nsdone := mountIpns(cc.node, nsdir, fsdir)
56 +
57 + // wait till mounts are done.
58 + err1 := <-fsdone
59 + err2 := <-nsdone
60 +
61 + if err1 != nil {
62 + return err1
63 + }
64 + return err2
65 +}
66 +
67 +func mountIpfs(node *core.IpfsNode, fsdir string) <-chan error {
68 + done := make(chan error)
69 + fmt.Printf("mounting ipfs at %s\n", fsdir)
70 +
71 + go func() {
72 + err := rofs.Mount(node, fsdir)
73 + done <- err
74 + close(done)
75 + }()
76 +
77 + return done
78 +}
79 +
80 +func mountIpns(node *core.IpfsNode, nsdir, fsdir string) <-chan error {
81 + if nsdir == "" {
82 + return nil
83 + }
84 + done := make(chan error)
85 + fmt.Printf("mounting ipns at %s\n", nsdir)
86 +
87 + go func() {
88 + err := ipns.Mount(node, nsdir, fsdir)
89 + done <- err
90 + close(done)
91 + }()
92 +
93 + return done
94 +}
cmd/ipfs/mount_windows.go new
+19
@@ -0,0 +1,19 @@
1 +package main
2 +
3 +import (
4 + "errors"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
6 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
7 +)
8 +
9 +var cmdIpfsMount = &commander.Command{
10 + UsageLine: "mount",
11 + Short: "Mount an ipfs read-only mountpoint.",
12 + Long: `Not yet implemented on windows.`,
13 + Run: mountCmd,
14 + Flag: *flag.NewFlagSet("ipfs-mount", flag.ExitOnError),
15 +}
16 +
17 +func mountCmd(c *commander.Command, inp []string) error {
18 + return errors.New("mount not yet implemented on windows")
19 +}
cmd/ipfs/name.go new
+57
@@ -0,0 +1,57 @@
1 +package main
2 +
3 +import (
4 + "fmt"
5 +
6 + flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
7 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
8 +)
9 +
10 +var cmdIpfsName = &commander.Command{
11 + UsageLine: "name [publish | resolve]",
12 + Short: "ipfs namespace (ipns) tool",
13 + Long: `ipfs name - Get/Set ipfs config values.
14 +
15 + ipfs name publish [<name>] <ref> - Assign the <ref> to <name>
16 + ipfs name resolve [<name>] - Resolve the <ref> value of <name>
17 +
18 +IPNS is a PKI namespace, where names are the hashes of public keys, and
19 +the private key enables publishing new (signed) values. In both publish
20 +and resolve, the default value of <name> is your own identity public key.
21 +
22 +
23 +Examples:
24 +
25 +Publish a <ref> to your identity name:
26 +
27 + > ipfs name publish QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
28 + published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
29 +
30 +Publish a <ref> to another public key:
31 +
32 + > ipfs name publish QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
33 + published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
34 +
35 +Resolve the value of your identity:
36 +
37 + > ipfs name resolve
38 + QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
39 +
40 +Resolve te value of another name:
41 +
42 + > ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
43 + QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
44 +
45 +`,
46 + Run: nameCmd,
47 + Flag: *flag.NewFlagSet("ipfs-name", flag.ExitOnError),
48 + Subcommands: []*commander.Command{
49 + cmdIpfsPub,
50 + cmdIpfsResolve,
51 + },
52 +}
53 +
54 +func nameCmd(c *commander.Command, args []string) error {
55 + fmt.Println(c.Long)
56 + return nil
57 +}
cmd/ipfs/objects.go new
+112
@@ -0,0 +1,112 @@
1 +package main
2 +
3 +import (
4 + flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsObject = &commander.Command{
10 + UsageLine: "object",
11 + Short: "interact with ipfs objects",
12 + Long: `ipfs object - interact with ipfs objects
13 +
14 + ipfs object data <key> - return the data for this key as raw bytes
15 + ipfs object links <key> - lists (the keys of ?) the links this key points to
16 + ipfs object get <key> - output dag object to stdout
17 + ipfs object put - add dag object from stdin
18 +
19 +ipfs object is a plumbing command used to manipulate dag objects directly.
20 +- <key> is a base58 encoded multihash.
21 +- It reads from stdin or writes to stdout.
22 +- It accepts multiple encodings: --encoding=[ protobuf, json, ... ]`,
23 + Subcommands: []*commander.Command{
24 + cmdIpfsObjectData,
25 + cmdIpfsObjectLinks,
26 + cmdIpfsObjectGet,
27 + cmdIpfsObjectPut,
28 + },
29 + Flag: *flag.NewFlagSet("ipfs-object", flag.ExitOnError),
30 +}
31 +
32 +var cmdIpfsObjectData = &commander.Command{
33 + UsageLine: "data <key>",
34 + Short: "data outputs the raw bytes named by <key>",
35 + Long: `ipfs data <key> - data outputs the raw bytes named by <key>
36 +
37 +ipfs data is a plumbing command for retreiving the raw bytes stored in a dag node.
38 +It outputs to stdout, and <key> is a base58 encoded multihash.`,
39 + Run: makeCommand(command{
40 + name: "objectData",
41 + args: 1,
42 + flags: nil,
43 + online: true,
44 + cmdFn: commands.ObjectData,
45 + }),
46 +}
47 +
48 +var cmdIpfsObjectLinks = &commander.Command{
49 + UsageLine: "links <key>",
50 + Short: "outputs the links pointed to by <key>",
51 + Long: `ipfs links <key> - outputs the links pointed to by <key>
52 +
53 +ipfs block get is a plumbing command for retreiving raw ipfs blocks.
54 +It outputs to stdout, and <key> is a base58 encoded multihash.`,
55 + Run: makeCommand(command{
56 + name: "objectLinks",
57 + args: 1,
58 + flags: nil,
59 + online: true,
60 + cmdFn: commands.ObjectLinks,
61 + }),
62 +}
63 +
64 +func init() {
65 + cmdIpfsObjectGet.Flag.String("encoding", "json", "the encoding to use..")
66 + cmdIpfsObjectPut.Flag.String("encoding", "json", "the encoding to use..")
67 +}
68 +
69 +var cmdIpfsObjectGet = &commander.Command{
70 + UsageLine: "get <key>",
71 + Short: "get and serialize the dag node named by <key>",
72 + Long: `ipfs get <key> - get and output the dag node named by <key>
73 +
74 +ipfs object get is a plumbing command for retreiving dag nodes.
75 +It serialize the dag node to the format specified by the format flag.
76 +It outputs to stdout, and <key> is a base58 encoded multihash.
77 +
78 +Formats:
79 +
80 +This command outputs and accepts data in a variety of encodings: protobuf, json, etc.
81 +Use the --encoding flag
82 +`,
83 + Run: makeCommand(command{
84 + name: "blockGet",
85 + args: 1,
86 + flags: []string{"encoding"},
87 + online: true,
88 + cmdFn: commands.ObjectGet,
89 + }),
90 +}
91 +
92 +var cmdIpfsObjectPut = &commander.Command{
93 + UsageLine: "put",
94 + Short: "store stdin as a dag object, outputs <key>",
95 + Long: `ipfs put - store stdin as a dag object, outputs <key>
96 +
97 +ipfs object put is a plumbing command for storing dag nodes.
98 +It serialize the dag node to the format specified by the format flag.
99 +It reads from stding, and <key> is a base58 encoded multihash.
100 +
101 +Formats:
102 +
103 +This command outputs and accepts data in a variety of encodings: protobuf, json, etc.
104 +Use the --encoding flag`,
105 + Run: makeCommand(command{
106 + name: "blockPut",
107 + args: 0,
108 + flags: []string{"encoding"},
109 + online: true,
110 + cmdFn: commands.ObjectPut,
111 + }),
112 +}
cmd/ipfs/pin.go new
+62
@@ -0,0 +1,62 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsPin = &commander.Command{
10 + UsageLine: "pin",
11 + Short: "",
12 + Long: `ipfs pin [add|rm] - object pinning commands
13 +`,
14 + Subcommands: []*commander.Command{
15 + cmdIpfsSubPin,
16 + cmdIpfsSubUnpin,
17 + },
18 +}
19 +
20 +var cmdIpfsSubPin = &commander.Command{
21 + UsageLine: "add",
22 + Short: "pin an ipfs object to local storage.",
23 + Long: `ipfs pin add <ipfs-path> - pin ipfs object to local storage.
24 +
25 + Retrieves the object named by <ipfs-path> and stores it locally
26 + on disk.
27 +`,
28 + Run: pinSubCmd,
29 + Flag: *flag.NewFlagSet("ipfs-pin", flag.ExitOnError),
30 +}
31 +
32 +var pinSubCmd = makeCommand(command{
33 + name: "pin",
34 + args: 1,
35 + flags: []string{"r", "d"},
36 + cmdFn: commands.Pin,
37 +})
38 +
39 +var cmdIpfsSubUnpin = &commander.Command{
40 + UsageLine: "rm",
41 + Short: "unpin an ipfs object from local storage.",
42 + Long: `ipfs pin rm <ipfs-path> - unpin ipfs object from local storage.
43 +
44 + Removes the pin from the given object allowing it to be garbage
45 + collected if needed.
46 +`,
47 + Run: unpinSubCmd,
48 + Flag: *flag.NewFlagSet("ipfs-unpin", flag.ExitOnError),
49 +}
50 +
51 +var unpinSubCmd = makeCommand(command{
52 + name: "unpin",
53 + args: 1,
54 + flags: []string{"r"},
55 + cmdFn: commands.Unpin,
56 +})
57 +
58 +func init() {
59 + cmdIpfsSubPin.Flag.Bool("r", false, "pin objects recursively")
60 + cmdIpfsSubPin.Flag.Int("d", 1, "recursive depth")
61 + cmdIpfsSubUnpin.Flag.Bool("r", false, "unpin objects recursively")
62 +}
cmd/ipfs/publish.go new
+41
@@ -0,0 +1,41 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsPub = &commander.Command{
10 + UsageLine: "publish",
11 + Short: "publish a <ref> to ipns.",
12 + Long: `ipfs publish [<name>] <ref> - publish a <ref> to ipns.
13 +
14 +IPNS is a PKI namespace, where names are the hashes of public keys, and
15 +the private key enables publishing new (signed) values. In publish, the
16 +default value of <name> is your own identity public key.
17 +
18 +Examples:
19 +
20 +Publish a <ref> to your identity name:
21 +
22 + > ipfs name publish QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
23 + published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
24 +
25 +Publish a <ref> to another public key:
26 +
27 + > ipfs name publish QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
28 + published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
29 +
30 +`,
31 + Run: pubCmd,
32 + Flag: *flag.NewFlagSet("ipfs-publish", flag.ExitOnError),
33 +}
34 +
35 +var pubCmd = makeCommand(command{
36 + name: "publish",
37 + args: 1,
38 + flags: nil,
39 + online: true,
40 + cmdFn: commands.Publish,
41 +})
cmd/ipfs/refs.go new
+36
@@ -0,0 +1,36 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + commands "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsRefs = &commander.Command{
10 + UsageLine: "refs",
11 + Short: "List link hashes from an object.",
12 + Long: `ipfs refs <ipfs-path> - List link hashes from an object..
13 +
14 + Retrieves the object named by <ipfs-path> and displays the link
15 + hashes it contains, with the following format:
16 +
17 + <link base58 hash>
18 +
19 + Note: list all refs recursively with -r.
20 +
21 +`,
22 + Run: refCmd,
23 + Flag: *flag.NewFlagSet("ipfs-refs", flag.ExitOnError),
24 +}
25 +
26 +func init() {
27 + cmdIpfsRefs.Flag.Bool("r", false, "recursive: list refs recursively")
28 + cmdIpfsRefs.Flag.Bool("u", false, "unique: list each ref only once")
29 +}
30 +
31 +var refCmd = makeCommand(command{
32 + name: "refs",
33 + args: 1,
34 + flags: []string{"r", "u"},
35 + cmdFn: commands.Refs,
36 +})
cmd/ipfs/resolve.go new
+42
@@ -0,0 +1,42 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +var cmdIpfsResolve = &commander.Command{
10 + UsageLine: "resolve",
11 + Short: "resolve an ipns name to a <ref>",
12 + Long: `ipfs resolve [<name>] - Resolve an ipns name to a <ref>.
13 +
14 +IPNS is a PKI namespace, where names are the hashes of public keys, and
15 +the private key enables publishing new (signed) values. In resolve, the
16 +default value of <name> is your own identity public key.
17 +
18 +
19 +Examples:
20 +
21 +Resolve the value of your identity:
22 +
23 + > ipfs name resolve
24 + QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
25 +
26 +Resolve te value of another name:
27 +
28 + > ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
29 + QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
30 +
31 +`,
32 + Run: resolveCmd,
33 + Flag: *flag.NewFlagSet("ipfs-resolve", flag.ExitOnError),
34 +}
35 +
36 +var resolveCmd = makeCommand(command{
37 + name: "resolve",
38 + args: 0,
39 + flags: nil,
40 + online: true,
41 + cmdFn: commands.Resolve,
42 +})
cmd/ipfs/run.go new
+36
@@ -0,0 +1,36 @@
1 +package main
2 +
3 +import (
4 + "os"
5 + "os/signal"
6 + "syscall"
7 +
8 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
9 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
10 +)
11 +
12 +var cmdIpfsRun = &commander.Command{
13 + UsageLine: "run",
14 + Short: "run local ifps node.",
15 + Long: `run a local ipfs node with no other interface.
16 +`,
17 + Run: runCmd,
18 + Flag: *flag.NewFlagSet("ipfs-run", flag.ExitOnError),
19 +}
20 +
21 +func runCmd(c *commander.Command, inp []string) error {
22 + cc, err := setupCmdContext(c, true)
23 + if err != nil {
24 + return err
25 + }
26 +
27 + sigc := make(chan os.Signal, 1)
28 + signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
29 + syscall.SIGTERM, syscall.SIGQUIT)
30 +
31 + // wait until we get a signal to exit.
32 + <-sigc
33 +
34 + cc.daemon.Close()
35 + return nil
36 +}
cmd/ipfs/serve.go new
+49
@@ -0,0 +1,49 @@
1 +package main
2 +
3 +import (
4 + "fmt"
5 +
6 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
7 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
8 + ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
9 +
10 + h "github.com/jbenet/go-ipfs/server/http"
11 +)
12 +
13 +var cmdIpfsServe = &commander.Command{
14 + UsageLine: "serve",
15 + Short: "Serve an interface to ipfs",
16 + Subcommands: []*commander.Command{
17 + cmdIpfsServeHTTP,
18 + },
19 + Flag: *flag.NewFlagSet("ipfs-serve", flag.ExitOnError),
20 +}
21 +
22 +var cmdIpfsServeHTTP = &commander.Command{
23 + UsageLine: "http",
24 + Short: "Serve an HTTP API",
25 + Long: `ipfs serve http - Serve an http gateway into ipfs.`,
26 + Run: serveHTTPCmd,
27 + Flag: *flag.NewFlagSet("ipfs-serve-http", flag.ExitOnError),
28 +}
29 +
30 +func init() {
31 + cmdIpfsServeHTTP.Flag.String("address", "/ip4/127.0.0.1/tcp/8080", "Listen Address")
32 +}
33 +
34 +func serveHTTPCmd(c *commander.Command, _ []string) error {
35 + cc, err := setupCmdContext(c, true)
36 + if err != nil {
37 + return err
38 + }
39 + defer cc.daemon.Close()
40 +
41 + address := c.Flag.Lookup("address").Value.Get().(string)
42 + maddr, err := ma.NewMultiaddr(address)
43 + if err != nil {
44 + return err
45 + }
46 +
47 + fmt.Printf("Serving on %s\n", address)
48 + return h.Serve(maddr, cc.node)
49 +}
cmd/ipfs/tour.go new
+134
@@ -0,0 +1,134 @@
1 +// +build linux darwin freebsd
2 +
3 +package main
4 +
5 +import (
6 + "fmt"
7 +
8 + config "github.com/jbenet/go-ipfs/config"
9 + tour "github.com/jbenet/go-ipfs/tour"
10 +
11 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
12 +)
13 +
14 +var cmdIpfsTour = &commander.Command{
15 + UsageLine: "tour [<number>]",
16 + Short: "Take the IPFS Tour.",
17 + Long: `ipfs tour - Take the IPFS Tour.
18 +
19 + ipfs tour [<number>] - Show tour topic. Default to current.
20 + ipfs tour next - Show the next tour topic.
21 + ipfs tour list - Show a list of topics.
22 + ipfs tour restart - Restart the tour.
23 +
24 +This is a tour that takes you through various IPFS concepts,
25 +features, and tools to make sure you get up to speed with
26 +IPFS very quickly. To start, run:
27 +
28 + ipfs tour
29 +`,
30 + Run: tourCmd,
31 + Subcommands: []*commander.Command{
32 + cmdIpfsTourNext,
33 + cmdIpfsTourList,
34 + cmdIpfsTourRestart,
35 + },
36 +}
37 +
38 +var cmdIpfsTourNext = &commander.Command{
39 + UsageLine: "next",
40 + Short: "Show the next IPFS Tour topic.",
41 + Run: tourNextCmd,
42 +}
43 +
44 +var cmdIpfsTourList = &commander.Command{
45 + UsageLine: "list",
46 + Short: "Show a list of IPFS Tour topics.",
47 + Run: tourListCmd,
48 +}
49 +
50 +var cmdIpfsTourRestart = &commander.Command{
51 + UsageLine: "restart",
52 + Short: "Restart the IPFS Tour.",
53 + Run: tourRestartCmd,
54 +}
55 +
56 +func tourCmd(c *commander.Command, inp []string) error {
57 + cfg, err := getConfig(c)
58 + if err != nil {
59 + return err
60 + }
61 +
62 + topic := tour.TopicID(cfg.Tour.Last)
63 + if len(inp) > 0 {
64 + topic = tour.TopicID(inp[0])
65 + }
66 + return tourShow(topic)
67 +}
68 +
69 +func tourNextCmd(c *commander.Command, _ []string) error {
70 + cfg, err := getConfig(c)
71 + if err != nil {
72 + return err
73 + }
74 +
75 + topic := tour.NextTopic(tour.TopicID(cfg.Tour.Last))
76 + if err := tourShow(topic); err != nil {
77 + return err
78 + }
79 +
80 + // if topic didn't change (last) done
81 + if string(topic) == cfg.Tour.Last {
82 + return nil
83 + }
84 +
85 + // topic changed, not last. write it out.
86 + cfg.Tour.Last = string(topic)
87 + return writeConfig(c, cfg)
88 +}
89 +
90 +func tourListCmd(c *commander.Command, _ []string) error {
91 + cfg, err := getConfig(c)
92 + if err != nil {
93 + return err
94 + }
95 + lastid := tour.TopicID(cfg.Tour.Last)
96 +
97 + for _, id := range tour.IDs {
98 + c := ' '
99 + switch {
100 + case id == lastid:
101 + c = '*'
102 + case id.LessThan(lastid):
103 + c = '✓'
104 + }
105 +
106 + t := tour.Topics[id]
107 + fmt.Printf("- %c %-5.5s %s\n", c, id, t.Title)
108 + }
109 + return nil
110 +}
111 +
112 +func tourRestartCmd(c *commander.Command, _ []string) error {
113 + cfg, err := getConfig(c)
114 + if err != nil {
115 + return err
116 + }
117 +
118 + cfg.Tour.Last = ""
119 + return writeConfig(c, cfg)
120 +}
121 +
122 +func tourShow(id tour.ID) error {
123 + t, found := tour.Topics[id]
124 + if !found {
125 + return fmt.Errorf("no topic with id: %s", id)
126 + }
127 +
128 + fmt.Printf("Tour %s - %s\n\n%s\n", t.ID, t.Title, t.Text)
129 + return nil
130 +}
131 +
132 +func lastTour(cfg *config.Config) string {
133 + return ""
134 +}
cmd/ipfs/update.go new
+62
@@ -0,0 +1,62 @@
1 +package main
2 +
3 +import (
4 + flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
5 + commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
6 + "github.com/jbenet/go-ipfs/core/commands"
7 +)
8 +
9 +func init() {
10 + cmdIpfsUpdate.Flag.Bool("force", false, "force shutdown of daemon when updating")
11 +}
12 +
13 +var cmdIpfsUpdate = &commander.Command{
14 + UsageLine: "update",
15 + Short: "check for updates and apply them",
16 + Long: `ipfs update - check for updates and apply them
17 +
18 + ipfs update <version> - apply
19 + ipfs update check - just check
20 + ipfs update log - list the changelogs
21 +
22 +ipfs update is a utility command used to check for updates and apply them.
23 +I wont even try, @jbenet. You do this much better :)`,
24 + Run: makeCommand(command{
25 + name: "updateApply",
26 + args: 0,
27 + flags: []string{"force"},
28 + online: true,
29 + cmdFn: commands.UpdateApply,
30 + }),
31 + Subcommands: []*commander.Command{
32 + cmdIpfsUpdateCheck,
33 + cmdIpfsUpdateLog,
34 + },
35 + Flag: *flag.NewFlagSet("ipfs-update", flag.ExitOnError),
36 +}
37 +
38 +var cmdIpfsUpdateCheck = &commander.Command{
39 + UsageLine: "check",
40 + Short: "",
41 + Long: `ipfs update check <key>`,
42 + Run: makeCommand(command{
43 + name: "updateCheck",
44 + args: 0,
45 + flags: nil,
46 + online: false,
47 + cmdFn: commands.UpdateCheck,
48 + }),
49 +}
50 +
51 +var cmdIpfsUpdateLog = &commander.Command{
52 + UsageLine: "log",
53 + Short: "list the last versions and their changelog",
54 + Long: `ipfs updage log - list the last versions and their changelog`,
55 + Run: makeCommand(command{
56 + name: "updateLog",
57 + args: 0,
58 + flags: nil,
59 + online: false,
60 + cmdFn: commands.UpdateCheck,
61 + }),
62 +}
cmd/ipfs/version.go new
+30
@@ -0,0 +1,30 @@
1 +package main
2 +
3 +import (
4 + "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
5 + updates "github.com/jbenet/go-ipfs/updates"
6 + u "github.com/jbenet/go-ipfs/util"
7 +)
8 +
9 +var cmdIpfsVersion = &commander.Command{
10 + UsageLine: "version",
11 + Short: "Show ipfs version information.",
12 + Long: `ipfs version - Show ipfs version information.
13 +
14 + Returns the current version of ipfs and exits.
15 + `,
16 + Run: versionCmd,
17 +}
18 +
19 +func init() {
20 + cmdIpfsVersion.Flag.Bool("number", false, "show only the number")
21 +}
22 +
23 +func versionCmd(c *commander.Command, _ []string) error {
24 + number := c.Flag.Lookup("number").Value.Get().(bool)
25 + if !number {
26 + u.POut("ipfs version ")
27 + }
28 + u.POut("%s\n", updates.Version)
29 + return nil
30 +}