mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-22 21:21:43 +08:00
1
cmd/ipfs/.gitignore
vendored
1
cmd/ipfs/.gitignore
vendored
@ -1 +0,0 @@
|
||||
./ipfs
|
@ -1,15 +0,0 @@
|
||||
all: install
|
||||
|
||||
build:
|
||||
go build
|
||||
|
||||
install: build
|
||||
go install
|
||||
|
||||
# cpu profiling: `go tool pprof ipfs cpu.prof`
|
||||
# mem profiling: `go tool pprof ipfs ipfs.mprof`
|
||||
|
||||
clean:
|
||||
rm -f cpu.prof
|
||||
rm -f ipfs.mprof
|
||||
rm -f ipfs
|
@ -1,29 +0,0 @@
|
||||
# go-ipfs/cmd/ipfs
|
||||
|
||||
This is the ipfs commandline tool. For now, it's the main entry point to using IPFS. Use it.
|
||||
|
||||
```
|
||||
> go build
|
||||
> go install
|
||||
> ipfs
|
||||
ipfs - global versioned p2p merkledag file system
|
||||
|
||||
Basic commands:
|
||||
|
||||
add <path> Add an object to ipfs.
|
||||
cat <ref> Show ipfs object data.
|
||||
ls <ref> List links from an object.
|
||||
refs <ref> List link hashes from an object.
|
||||
|
||||
Tool commands:
|
||||
|
||||
config Manage configuration.
|
||||
version Show ipfs version information.
|
||||
commands List all available commands.
|
||||
|
||||
Advanced Commands:
|
||||
|
||||
mount Mount an ipfs read-only mountpoint.
|
||||
|
||||
Use "ipfs help <command>" for more information about a command.
|
||||
```
|
@ -1,39 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
// Error indicating the max depth has been exceded.
|
||||
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
|
||||
|
||||
var cmdIpfsAdd = &commander.Command{
|
||||
UsageLine: "add",
|
||||
Short: "Add an object to ipfs.",
|
||||
Long: `ipfs add <path>... - Add objects to ipfs.
|
||||
|
||||
Adds contents of <path> to ipfs. Use -r to add directories.
|
||||
Note that directories are added recursively, to form the ipfs
|
||||
MerkleDAG. A smarter partial add with a staging area (like git)
|
||||
remains to be implemented.
|
||||
`,
|
||||
Run: addCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-add", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsAdd.Flag.Bool("r", false, "add objects recursively")
|
||||
}
|
||||
|
||||
var addCmd = makeCommand(command{
|
||||
name: "add",
|
||||
args: 1,
|
||||
flags: []string{"r"},
|
||||
cmdFn: commands.Add,
|
||||
argFilter: filepath.Abs,
|
||||
})
|
@ -1,58 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsBlock = &commander.Command{
|
||||
UsageLine: "block",
|
||||
Short: "manipulate raw ipfs blocks",
|
||||
Long: `ipfs block - manipulate raw ipfs blocks
|
||||
|
||||
ipfs block get <key> - get and output block named by <key>
|
||||
ipfs block put - store stdin as a block, outputs <key>
|
||||
|
||||
ipfs block is a plumbing command used to manipulate raw ipfs blocks.
|
||||
Reads from stdin or writes to stdout, and <key> is a base58 encoded
|
||||
multihash.`,
|
||||
// Run: blockGetCmd,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsBlockGet,
|
||||
cmdIpfsBlockPut,
|
||||
},
|
||||
Flag: *flag.NewFlagSet("ipfs-block", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsBlockGet = &commander.Command{
|
||||
UsageLine: "get <key>",
|
||||
Short: "get and output block named by <key>",
|
||||
Long: `ipfs get <key> - get and output block named by <key>
|
||||
|
||||
ipfs block get is a plumbing command for retreiving raw ipfs blocks.
|
||||
It outputs to stdout, and <key> is a base58 encoded multihash.`,
|
||||
Run: makeCommand(command{
|
||||
name: "blockGet",
|
||||
args: 1,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.BlockGet,
|
||||
}),
|
||||
}
|
||||
|
||||
var cmdIpfsBlockPut = &commander.Command{
|
||||
UsageLine: "put",
|
||||
Short: "store stdin as a block, outputs <key>",
|
||||
Long: `ipfs put - store stdin as a block, outputs <key>
|
||||
|
||||
ipfs block put is a plumbing command for storing raw ipfs blocks.
|
||||
It reads from stding, and <key> is a base58 encoded multihash.`,
|
||||
Run: makeCommand(command{
|
||||
name: "blockPut",
|
||||
args: 0,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.BlockPut,
|
||||
}),
|
||||
}
|
@ -1,236 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"strings"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
||||
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
var cmdIpfsBootstrap = &commander.Command{
|
||||
UsageLine: "bootstrap",
|
||||
Short: "Show a list of bootstrapped addresses.",
|
||||
Long: `ipfs bootstrap - show, or manipulate bootstrap node addresses
|
||||
|
||||
Running 'ipfs bootstrap' with no arguments will run 'ipfs bootstrap list'.
|
||||
|
||||
Commands:
|
||||
|
||||
list Show the boostrap list.
|
||||
add <address> Add a node's address to the bootstrap list.
|
||||
remove <address> Remove an address from the bootstrap list.
|
||||
|
||||
` + bootstrapSecurityWarning,
|
||||
Run: bootstrapListCmd,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsBootstrapRemove,
|
||||
cmdIpfsBootstrapAdd,
|
||||
cmdIpfsBootstrapList,
|
||||
},
|
||||
Flag: *flag.NewFlagSet("ipfs-bootstrap", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsBootstrapRemove = &commander.Command{
|
||||
UsageLine: "remove <address | peerid>",
|
||||
Short: "Remove addresses from the bootstrap list.",
|
||||
Long: `ipfs bootstrap remove - remove addresses from the bootstrap list
|
||||
` + bootstrapSecurityWarning,
|
||||
Run: bootstrapRemoveCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-bootstrap-remove", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsBootstrapAdd = &commander.Command{
|
||||
UsageLine: "add <address | peerid>",
|
||||
Short: "Add addresses to the bootstrap list.",
|
||||
Long: `ipfs bootstrap add - add addresses to the bootstrap list
|
||||
` + bootstrapSecurityWarning,
|
||||
Run: bootstrapAddCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-bootstrap-add", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsBootstrapList = &commander.Command{
|
||||
UsageLine: "list",
|
||||
Short: "Show addresses in the bootstrap list.",
|
||||
Run: bootstrapListCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-bootstrap-list", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func bootstrapRemoveCmd(c *commander.Command, inp []string) error {
|
||||
|
||||
if len(inp) == 0 {
|
||||
return errors.New("remove: no address or peerid specified")
|
||||
}
|
||||
|
||||
toRemove, err := bootstrapInputToPeers(inp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
keep := []*config.BootstrapPeer{}
|
||||
remove := []*config.BootstrapPeer{}
|
||||
|
||||
// function to filer what to keep
|
||||
shouldKeep := func(bp *config.BootstrapPeer) bool {
|
||||
for _, skipBP := range toRemove {
|
||||
|
||||
// IDs must match to skip.
|
||||
if bp.PeerID != skipBP.PeerID {
|
||||
continue
|
||||
}
|
||||
|
||||
// if Addresses match, or skipBP has no addr (wildcard)
|
||||
if skipBP.Address == bp.Address || skipBP.Address == "" {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// filter all the existing peers
|
||||
for _, currBP := range cfg.Bootstrap {
|
||||
if shouldKeep(currBP) {
|
||||
keep = append(keep, currBP)
|
||||
} else {
|
||||
remove = append(remove, currBP)
|
||||
}
|
||||
}
|
||||
|
||||
// if didn't remove anyone, bail.
|
||||
if len(keep) == len(cfg.Bootstrap) {
|
||||
return errors.New("remove: peer given did not match any in list")
|
||||
}
|
||||
|
||||
// write new config
|
||||
cfg.Bootstrap = keep
|
||||
if err := writeConfig(c, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, bp := range remove {
|
||||
u.POut("removed %s\n", bp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func bootstrapAddCmd(c *commander.Command, inp []string) error {
|
||||
|
||||
if len(inp) == 0 {
|
||||
return errors.New("add: no address specified")
|
||||
}
|
||||
|
||||
toAdd, err := bootstrapInputToPeers(inp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// function to check whether a peer is already in the list.
|
||||
combine := func(lists ...[]*config.BootstrapPeer) []*config.BootstrapPeer {
|
||||
|
||||
set := map[string]struct{}{}
|
||||
final := []*config.BootstrapPeer{}
|
||||
|
||||
for _, list := range lists {
|
||||
for _, peer := range list {
|
||||
// if already in the set, continue
|
||||
_, found := set[peer.String()]
|
||||
if found {
|
||||
continue
|
||||
}
|
||||
|
||||
set[peer.String()] = struct{}{}
|
||||
final = append(final, peer)
|
||||
}
|
||||
}
|
||||
return final
|
||||
}
|
||||
|
||||
// combine both lists, removing dups.
|
||||
cfg.Bootstrap = combine(cfg.Bootstrap, toAdd)
|
||||
if err := writeConfig(c, cfg); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, bp := range toAdd {
|
||||
u.POut("added %s\n", bp)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func bootstrapListCmd(c *commander.Command, inp []string) error {
|
||||
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, bp := range cfg.Bootstrap {
|
||||
u.POut("%s\n", bp)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func bootstrapInputToPeers(input []string) ([]*config.BootstrapPeer, error) {
|
||||
split := func(addr string) (string, string) {
|
||||
idx := strings.LastIndex(addr, "/")
|
||||
if idx == -1 {
|
||||
return "", addr
|
||||
}
|
||||
return addr[:idx], addr[idx+1:]
|
||||
}
|
||||
|
||||
peers := []*config.BootstrapPeer{}
|
||||
for _, addr := range input {
|
||||
addrS, peeridS := split(addr)
|
||||
|
||||
// make sure addrS parses as a multiaddr.
|
||||
if len(addrS) > 0 {
|
||||
maddr, err := ma.NewMultiaddr(addrS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
addrS = maddr.String()
|
||||
}
|
||||
|
||||
// make sure idS parses as a peer.ID
|
||||
peerid, err := mh.FromB58String(peeridS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// construct config entry
|
||||
peers = append(peers, &config.BootstrapPeer{
|
||||
Address: addrS,
|
||||
PeerID: peer.ID(peerid).Pretty(),
|
||||
})
|
||||
}
|
||||
return peers, nil
|
||||
}
|
||||
|
||||
const bootstrapSecurityWarning = `
|
||||
SECURITY WARNING:
|
||||
|
||||
The bootstrap command manipulates the "bootstrap list", which contains
|
||||
the addresses of bootstrap nodes. These are the *trusted peers* from
|
||||
which to learn about other peers in the network. Only edit this list
|
||||
if you understand the risks of adding or removing nodes from this list.
|
||||
|
||||
`
|
@ -1,26 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsCat = &commander.Command{
|
||||
UsageLine: "cat",
|
||||
Short: "Show ipfs object data.",
|
||||
Long: `ipfs cat <ipfs-path> - Show ipfs object data.
|
||||
|
||||
Retrieves the object named by <ipfs-path> and displays the Data
|
||||
it contains.
|
||||
`,
|
||||
Run: catCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-cat", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var catCmd = makeCommand(command{
|
||||
name: "cat",
|
||||
args: 1,
|
||||
flags: nil,
|
||||
cmdFn: commands.Cat,
|
||||
})
|
@ -1,74 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
|
||||
var cmdIpfsCommands = &commander.Command{
|
||||
UsageLine: "commands",
|
||||
Short: "List all available commands.",
|
||||
Long: `ipfs commands - List all available commands.
|
||||
|
||||
Lists all available commands (and sub-commands) and exits.
|
||||
`,
|
||||
Run: commandsCmd,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsCommandsHelp,
|
||||
},
|
||||
}
|
||||
|
||||
func commandsCmd(c *commander.Command, args []string) error {
|
||||
var listCmds func(c *commander.Command)
|
||||
listCmds = func(c *commander.Command) {
|
||||
u.POut("%s\n", c.FullSpacedName())
|
||||
for _, sc := range c.Subcommands {
|
||||
listCmds(sc)
|
||||
}
|
||||
}
|
||||
|
||||
listCmds(c.Parent)
|
||||
return nil
|
||||
}
|
||||
|
||||
var cmdIpfsCommandsHelp = &commander.Command{
|
||||
UsageLine: "help",
|
||||
Short: "List all available commands' help pages.",
|
||||
Long: `ipfs commands help - List all available commands's help pages.
|
||||
|
||||
Shows the pages of all available commands (and sub-commands) and exits.
|
||||
Outputs a markdown document.
|
||||
`,
|
||||
Run: commandsHelpCmd,
|
||||
}
|
||||
|
||||
func commandsHelpCmd(c *commander.Command, args []string) error {
|
||||
u.POut(referenceHeaderMsg)
|
||||
u.POut("Generated on %s.\n\n", time.Now().UTC().Format("2006-01-02"))
|
||||
|
||||
var printCmds func(*commander.Command, int)
|
||||
printCmds = func(c *commander.Command, level int) {
|
||||
u.POut("%s ", strings.Repeat("#", level))
|
||||
u.POut("%s\n\n", c.FullSpacedName())
|
||||
u.POut("```\n")
|
||||
u.POut("%s\n", c.Long)
|
||||
u.POut("```\n\n")
|
||||
|
||||
for _, sc := range c.Subcommands {
|
||||
printCmds(sc, level+1)
|
||||
}
|
||||
}
|
||||
|
||||
printCmds(c.Parent.Parent, 1)
|
||||
return nil
|
||||
}
|
||||
|
||||
const referenceHeaderMsg = `
|
||||
# ipfs command reference
|
||||
|
||||
This document lists every ipfs command (including subcommands), along with
|
||||
its help page. It can be viewed by running 'ipfs commands help'.
|
||||
|
||||
`
|
@ -1,143 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
var cmdIpfsConfig = &commander.Command{
|
||||
UsageLine: "config",
|
||||
Short: "Get/Set ipfs config values",
|
||||
Long: `ipfs config [<key>] [<value>] - Get/Set ipfs config values.
|
||||
|
||||
ipfs config <key> - Get value of <key>
|
||||
ipfs config <key> <value> - Set value of <key> to <value>
|
||||
ipfs config --show - Show config file
|
||||
ipfs config --edit - Edit config file in $EDITOR
|
||||
|
||||
Examples:
|
||||
|
||||
Get the value of the 'datastore.path' key:
|
||||
|
||||
ipfs config datastore.path
|
||||
|
||||
Set the value of the 'datastore.path' key:
|
||||
|
||||
ipfs config datastore.path ~/.go-ipfs/datastore
|
||||
|
||||
`,
|
||||
Run: configCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-config", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsConfig.Flag.Bool("edit", false, "Edit config file in $EDITOR")
|
||||
cmdIpfsConfig.Flag.Bool("show", false, "Show config file")
|
||||
}
|
||||
|
||||
func configCmd(c *commander.Command, inp []string) error {
|
||||
|
||||
confdir, err := getConfigDir(c.Parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filename, err := config.Filename(confdir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if editing, open the editor
|
||||
if c.Flag.Lookup("edit").Value.Get().(bool) {
|
||||
return configEditor(filename)
|
||||
}
|
||||
|
||||
// if showing, cat the file
|
||||
if c.Flag.Lookup("show").Value.Get().(bool) {
|
||||
return configCat(filename)
|
||||
}
|
||||
|
||||
if len(inp) == 0 {
|
||||
// "ipfs config" run without parameters
|
||||
u.POut(c.Long)
|
||||
return nil
|
||||
}
|
||||
|
||||
// Getter (1 param)
|
||||
if len(inp) == 1 {
|
||||
value, err := config.ReadConfigKey(filename, inp[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to get config value: %s", err)
|
||||
}
|
||||
|
||||
strval, ok := value.(string)
|
||||
if ok {
|
||||
u.POut("%s\n", strval)
|
||||
return nil
|
||||
}
|
||||
|
||||
if err := config.Encode(os.Stdout, value); err != nil {
|
||||
return fmt.Errorf("Failed to encode config value: %s", err)
|
||||
}
|
||||
u.POut("\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Setter (>1 params)
|
||||
err = config.WriteConfigKey(filename, inp[0], inp[1])
|
||||
if err != nil {
|
||||
return fmt.Errorf("Failed to set config value: %s", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func configCat(filename string) error {
|
||||
|
||||
file, err := os.Open(filename)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer file.Close()
|
||||
|
||||
if _, err = io.Copy(os.Stdout, file); err != nil {
|
||||
return err
|
||||
}
|
||||
u.POut("\n")
|
||||
return nil
|
||||
}
|
||||
|
||||
func configEditor(filename string) error {
|
||||
|
||||
editor := os.Getenv("EDITOR")
|
||||
if editor == "" {
|
||||
return errors.New("ENV variable $EDITOR not set")
|
||||
}
|
||||
|
||||
cmd := exec.Command("sh", "-c", editor+" "+filename)
|
||||
cmd.Stdin, cmd.Stdout, cmd.Stderr = os.Stdin, os.Stdout, os.Stderr
|
||||
return cmd.Run()
|
||||
}
|
||||
|
||||
func writeConfig(c *commander.Command, cfg *config.Config) error {
|
||||
|
||||
confdir, err := getConfigDir(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
filename, err := config.Filename(confdir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return config.WriteConfigFile(filename, cfg)
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsDiag = &commander.Command{
|
||||
UsageLine: "net-diag",
|
||||
Short: "Generate a diagnostics report",
|
||||
Long: `ipfs net-diag - Generate a diagnostics report.
|
||||
|
||||
Sends out a message to each node in the network recursively
|
||||
requesting a listing of data about them including number of
|
||||
connected peers and latencies between them.
|
||||
`,
|
||||
Run: diagCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-net-diag", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsDiag.Flag.Bool("raw", false, "print raw json output")
|
||||
}
|
||||
|
||||
var diagCmd = makeCommand(command{
|
||||
name: "diag",
|
||||
args: 0,
|
||||
flags: []string{"raw"},
|
||||
cmdFn: commands.Diag,
|
||||
})
|
@ -1,6 +0,0 @@
|
||||
---
|
||||
equinox-account: CHANGEME
|
||||
equinox-secret: CHANGEME
|
||||
equinox-app: CHANGEME
|
||||
channel: stable
|
||||
private-key: equinox-priv
|
@ -1,72 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
"github.com/jbenet/go-ipfs/daemon"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// command is the descriptor of an ipfs daemon command.
|
||||
// Used with makeCommand to proxy over commands via the daemon.
|
||||
type command struct {
|
||||
name string
|
||||
args int
|
||||
flags []string
|
||||
online bool
|
||||
cmdFn commands.CmdFunc
|
||||
argFilter func(string) (string, error)
|
||||
}
|
||||
|
||||
// commanderFunc is a function that can be passed into the Commander library as
|
||||
// a command handler. Defined here because commander lacks this definition.
|
||||
type commanderFunc func(*commander.Command, []string) error
|
||||
|
||||
// makeCommand Wraps a commands.CmdFunc so that it may be safely run by the
|
||||
// commander library
|
||||
func makeCommand(cmdDesc command) commanderFunc {
|
||||
return func(c *commander.Command, inp []string) error {
|
||||
if len(inp) < cmdDesc.args {
|
||||
u.POut(c.Long)
|
||||
return nil
|
||||
}
|
||||
confdir, err := getConfigDir(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cmd := daemon.NewCommand()
|
||||
cmd.Command = cmdDesc.name
|
||||
if cmdDesc.argFilter != nil {
|
||||
for _, a := range inp {
|
||||
s, err := cmdDesc.argFilter(a)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cmd.Args = append(cmd.Args, s)
|
||||
}
|
||||
} else {
|
||||
cmd.Args = inp
|
||||
}
|
||||
|
||||
for _, a := range cmdDesc.flags {
|
||||
cmd.Opts[a] = c.Flag.Lookup(a).Value.Get()
|
||||
}
|
||||
|
||||
err = daemon.SendCommand(cmd, confdir)
|
||||
if err != nil {
|
||||
log.Info("Executing command locally: %s", err)
|
||||
// Do locally
|
||||
n, err := localNode(confdir, cmdDesc.online)
|
||||
if err != nil {
|
||||
return fmt.Errorf("Local node creation failed: %v", err)
|
||||
}
|
||||
|
||||
return cmdDesc.cmdFn(n, cmd.Args, cmd.Opts, os.Stdout)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
}
|
200
cmd/ipfs/init.go
200
cmd/ipfs/init.go
@ -1,200 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
ci "github.com/jbenet/go-ipfs/crypto"
|
||||
imp "github.com/jbenet/go-ipfs/importer"
|
||||
chunk "github.com/jbenet/go-ipfs/importer/chunk"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
updates "github.com/jbenet/go-ipfs/updates"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
var cmdIpfsInit = &commander.Command{
|
||||
UsageLine: "init",
|
||||
Short: "Initialize ipfs local configuration",
|
||||
Long: `ipfs init
|
||||
|
||||
Initializes ipfs configuration files and generates a
|
||||
new keypair.
|
||||
`,
|
||||
Run: initCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-init", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsInit.Flag.Int("b", 4096, "number of bits for keypair")
|
||||
cmdIpfsInit.Flag.String("p", "", "passphrase for encrypting keys")
|
||||
cmdIpfsInit.Flag.Bool("f", false, "force overwrite of existing config")
|
||||
cmdIpfsInit.Flag.String("d", "", "Change default datastore location")
|
||||
}
|
||||
|
||||
var defaultPeers = []*config.BootstrapPeer{
|
||||
&config.BootstrapPeer{
|
||||
// mars.i.ipfs.io
|
||||
PeerID: "QmaCpDMGvV2BGHeYERUEnRQAwe3N8SzbUtfsmvsqQLuvuJ",
|
||||
Address: "/ip4/104.131.131.82/tcp/4001",
|
||||
},
|
||||
}
|
||||
|
||||
func datastoreConfig(dspath string) (config.Datastore, error) {
|
||||
ds := config.Datastore{}
|
||||
if len(dspath) == 0 {
|
||||
var err error
|
||||
dspath, err = config.DataStorePath("")
|
||||
if err != nil {
|
||||
return ds, err
|
||||
}
|
||||
}
|
||||
ds.Path = dspath
|
||||
ds.Type = "leveldb"
|
||||
|
||||
// Construct the data store if missing
|
||||
if err := os.MkdirAll(dspath, os.ModePerm); err != nil {
|
||||
return ds, err
|
||||
}
|
||||
|
||||
// Check the directory is writeable
|
||||
if f, err := os.Create(filepath.Join(dspath, "._check_writeable")); err == nil {
|
||||
os.Remove(f.Name())
|
||||
} else {
|
||||
return ds, errors.New("Datastore '" + dspath + "' is not writeable")
|
||||
}
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
func identityConfig(nbits int) (config.Identity, error) {
|
||||
ident := config.Identity{}
|
||||
fmt.Println("generating key pair...")
|
||||
sk, pk, err := ci.GenerateKeyPair(ci.RSA, nbits)
|
||||
if err != nil {
|
||||
return ident, err
|
||||
}
|
||||
|
||||
// currently storing key unencrypted. in the future we need to encrypt it.
|
||||
// TODO(security)
|
||||
skbytes, err := sk.Bytes()
|
||||
if err != nil {
|
||||
return ident, err
|
||||
}
|
||||
ident.PrivKey = base64.StdEncoding.EncodeToString(skbytes)
|
||||
|
||||
id, err := peer.IDFromPubKey(pk)
|
||||
if err != nil {
|
||||
return ident, err
|
||||
}
|
||||
ident.PeerID = id.Pretty()
|
||||
|
||||
return ident, nil
|
||||
}
|
||||
|
||||
func initCmd(c *commander.Command, inp []string) error {
|
||||
configpath, err := getConfigDir(c.Parent)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
u.POut("initializing ipfs node at %s\n", configpath)
|
||||
filename, err := config.Filename(configpath)
|
||||
if err != nil {
|
||||
return errors.New("Couldn't get home directory path")
|
||||
}
|
||||
|
||||
dspath, ok := c.Flag.Lookup("d").Value.Get().(string)
|
||||
if !ok {
|
||||
return errors.New("failed to parse datastore flag")
|
||||
}
|
||||
|
||||
fi, err := os.Lstat(filename)
|
||||
force, ok := c.Flag.Lookup("f").Value.Get().(bool)
|
||||
if !ok {
|
||||
return errors.New("failed to parse force flag")
|
||||
}
|
||||
if fi != nil || (err != nil && !os.IsNotExist(err)) {
|
||||
if !force {
|
||||
return errors.New("ipfs configuration file already exists!\nReinitializing would overwrite your keys.\n(use -f to force overwrite)")
|
||||
}
|
||||
}
|
||||
cfg := new(config.Config)
|
||||
|
||||
// setup the datastore
|
||||
cfg.Datastore, err = datastoreConfig(dspath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// setup the node addresses.
|
||||
cfg.Addresses = config.Addresses{
|
||||
Swarm: "/ip4/0.0.0.0/tcp/4001",
|
||||
API: "/ip4/127.0.0.1/tcp/5001",
|
||||
}
|
||||
|
||||
// setup the node mount points.
|
||||
cfg.Mounts = config.Mounts{
|
||||
IPFS: "/ipfs",
|
||||
IPNS: "/ipns",
|
||||
}
|
||||
|
||||
nbits, ok := c.Flag.Lookup("b").Value.Get().(int)
|
||||
if !ok {
|
||||
return errors.New("failed to get bits flag")
|
||||
}
|
||||
if nbits < 1024 {
|
||||
return errors.New("Bitsize less than 1024 is considered unsafe.")
|
||||
}
|
||||
|
||||
cfg.Identity, err = identityConfig(nbits)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Use these hardcoded bootstrap peers for now.
|
||||
cfg.Bootstrap = defaultPeers
|
||||
|
||||
// tracking ipfs version used to generate the init folder
|
||||
// and adding update checker default setting.
|
||||
cfg.Version = config.Version{
|
||||
Check: "error",
|
||||
Current: updates.Version,
|
||||
}
|
||||
|
||||
err = config.WriteConfigFile(filename, cfg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
nd, err := core.NewIpfsNode(cfg, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer nd.Close()
|
||||
|
||||
// Set up default file
|
||||
msg := `Hello and Welcome to IPFS!
|
||||
If you're seeing this, that means that you have successfully
|
||||
installed ipfs and are now interfacing with the wonderful
|
||||
world of DAGs and hashes!
|
||||
`
|
||||
reader := bytes.NewBufferString(msg)
|
||||
|
||||
defnd, err := imp.BuildDagFromReader(reader, nd.DAG, nd.Pinning.GetManual(), chunk.DefaultSplitter)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k, _ := defnd.Key()
|
||||
fmt.Printf("Default file key: %s\n", k)
|
||||
|
||||
return nil
|
||||
}
|
240
cmd/ipfs/ipfs.go
240
cmd/ipfs/ipfs.go
@ -1,240 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"os"
|
||||
"runtime/pprof"
|
||||
|
||||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
daemon "github.com/jbenet/go-ipfs/daemon"
|
||||
updates "github.com/jbenet/go-ipfs/updates"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
const heapProfile = "ipfs.mprof"
|
||||
|
||||
// The IPFS command tree. It is an instance of `commander.Command`.
|
||||
var CmdIpfs = &commander.Command{
|
||||
UsageLine: "ipfs [<flags>] <command> [<args>]",
|
||||
Short: "global versioned p2p merkledag file system",
|
||||
Long: `ipfs - global versioned p2p merkledag file system
|
||||
|
||||
Basic commands:
|
||||
|
||||
init Initialize ipfs local configuration.
|
||||
add <path> Add an object to ipfs.
|
||||
cat <ref> Show ipfs object data.
|
||||
ls <ref> List links from an object.
|
||||
refs <ref> List link hashes from an object.
|
||||
|
||||
Tool commands:
|
||||
|
||||
config Manage configuration.
|
||||
update Download and apply go-ipfs updates.
|
||||
version Show ipfs version information.
|
||||
commands List all available commands.
|
||||
|
||||
Advanced Commands:
|
||||
|
||||
mount Mount an ipfs read-only mountpoint.
|
||||
serve Serve an interface to ipfs.
|
||||
net-diag Print network diagnostic
|
||||
|
||||
Plumbing commands:
|
||||
|
||||
block Interact with raw blocks in the datastore
|
||||
object Interact with raw dag nodes
|
||||
|
||||
|
||||
Use "ipfs help <command>" for more information about a command.
|
||||
`,
|
||||
Run: ipfsCmd,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsAdd,
|
||||
cmdIpfsCat,
|
||||
cmdIpfsLs,
|
||||
cmdIpfsRefs,
|
||||
cmdIpfsConfig,
|
||||
cmdIpfsVersion,
|
||||
cmdIpfsCommands,
|
||||
cmdIpfsMount,
|
||||
cmdIpfsInit,
|
||||
cmdIpfsServe,
|
||||
cmdIpfsRun,
|
||||
cmdIpfsName,
|
||||
cmdIpfsBootstrap,
|
||||
cmdIpfsDiag,
|
||||
cmdIpfsBlock,
|
||||
cmdIpfsObject,
|
||||
cmdIpfsUpdate,
|
||||
cmdIpfsLog,
|
||||
cmdIpfsPin,
|
||||
cmdIpfsTour,
|
||||
},
|
||||
Flag: *flag.NewFlagSet("ipfs", flag.ExitOnError),
|
||||
}
|
||||
|
||||
// log is the command logger
|
||||
var log = u.Logger("cmd/ipfs")
|
||||
|
||||
func init() {
|
||||
config, err := config.PathRoot()
|
||||
if err != nil {
|
||||
fmt.Fprintln(os.Stderr, "Failure initializing the default Config Directory: ", err)
|
||||
os.Exit(1)
|
||||
}
|
||||
CmdIpfs.Flag.String("c", config, "specify config directory")
|
||||
}
|
||||
|
||||
func ipfsCmd(c *commander.Command, args []string) error {
|
||||
u.POut(c.Long)
|
||||
return nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
// if debugging, setup profiling.
|
||||
if u.Debug {
|
||||
ofi, err := os.Create("cpu.prof")
|
||||
defer ofi.Close()
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
return
|
||||
}
|
||||
|
||||
pprof.StartCPUProfile(ofi)
|
||||
defer pprof.StopCPUProfile()
|
||||
}
|
||||
|
||||
err := CmdIpfs.Dispatch(os.Args[1:])
|
||||
if err != nil {
|
||||
if len(err.Error()) > 0 {
|
||||
fmt.Fprintf(os.Stderr, "ipfs %s: %v\n", os.Args[1], err)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
if u.Debug {
|
||||
err := writeHeapProfileToFile()
|
||||
if err != nil {
|
||||
log.Critical(err)
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
// localNode constructs a node
|
||||
func localNode(confdir string, online bool) (*core.IpfsNode, error) {
|
||||
filename, err := config.Filename(confdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
cfg, err := config.Load(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := updates.CliCheckForUpdates(cfg, filename); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return core.NewIpfsNode(cfg, online)
|
||||
}
|
||||
|
||||
// Gets the config "-c" flag from the command, or returns
|
||||
// the default configuration root directory
|
||||
func getConfigDir(c *commander.Command) (string, error) {
|
||||
|
||||
// use the root cmd (that's where config is specified)
|
||||
for ; c.Parent != nil; c = c.Parent {
|
||||
}
|
||||
|
||||
// flag should be defined on root.
|
||||
param := c.Flag.Lookup("c").Value.Get().(string)
|
||||
if param != "" {
|
||||
return u.TildeExpansion(param)
|
||||
}
|
||||
|
||||
return config.PathRoot()
|
||||
}
|
||||
|
||||
func getConfig(c *commander.Command) (*config.Config, error) {
|
||||
confdir, err := getConfigDir(c)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
filename, err := config.Filename(confdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return config.Load(filename)
|
||||
}
|
||||
|
||||
// cmdContext is a wrapper structure that keeps a node, a daemonlistener, and
|
||||
// a config directory together. These three are needed for most commands.
|
||||
type cmdContext struct {
|
||||
node *core.IpfsNode
|
||||
daemon *daemon.DaemonListener
|
||||
configDir string
|
||||
}
|
||||
|
||||
// setupCmdContext initializes a cmdContext structure from a given command.
|
||||
func setupCmdContext(c *commander.Command, online bool) (cc cmdContext, err error) {
|
||||
rootCmd := c
|
||||
for ; rootCmd.Parent != nil; rootCmd = rootCmd.Parent {
|
||||
}
|
||||
|
||||
cc.configDir, err = getConfigDir(rootCmd)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cc.node, err = localNode(cc.configDir, online)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
cc.daemon, err = setupDaemon(cc.configDir, cc.node)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// setupDaemon sets up the daemon corresponding to given node.
|
||||
func setupDaemon(confdir string, node *core.IpfsNode) (*daemon.DaemonListener, error) {
|
||||
if node.Config.Addresses.API == "" {
|
||||
return nil, errors.New("no config.Addresses.API endpoint supplied")
|
||||
}
|
||||
|
||||
maddr, err := ma.NewMultiaddr(node.Config.Addresses.API)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
dl, err := daemon.NewDaemonListener(node, maddr, confdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
go dl.Listen()
|
||||
return dl, nil
|
||||
}
|
||||
|
||||
func writeHeapProfileToFile() error {
|
||||
mprof, err := os.Create(heapProfile)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
defer mprof.Close()
|
||||
return pprof.WriteHeapProfile(mprof)
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsLog = &commander.Command{
|
||||
UsageLine: "log <name> <level> ",
|
||||
Short: "switch logging levels of a running daemon",
|
||||
Long: `ipfs log <name> <level> - switch logging levels of a running daemon
|
||||
|
||||
<name> is a the subsystem logging identifier. Use * for all subsystems.
|
||||
<level> is one of: debug, info, notice, warning, error, critical
|
||||
|
||||
ipfs log is a utility command used to change the logging output of a running daemon.
|
||||
`,
|
||||
Run: logCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-log", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var logCmd = makeCommand(command{
|
||||
name: "log",
|
||||
args: 2,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.Log,
|
||||
})
|
@ -1,29 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsLs = &commander.Command{
|
||||
UsageLine: "ls",
|
||||
Short: "List links from an object.",
|
||||
Long: `ipfs ls <ipfs-path> - List links from an object.
|
||||
|
||||
Retrieves the object named by <ipfs-path> and displays the links
|
||||
it contains, with the following format:
|
||||
|
||||
<link base58 hash> <link size in bytes> <link name>
|
||||
|
||||
`,
|
||||
Run: lsCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-ls", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var lsCmd = makeCommand(command{
|
||||
name: "ls",
|
||||
args: 1,
|
||||
flags: nil,
|
||||
cmdFn: commands.Ls,
|
||||
})
|
@ -1,33 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func init() {
|
||||
// this is a hack, but until we need to do it another way, this works.
|
||||
platformFuseChecks = darwinFuseCheckVersion
|
||||
}
|
||||
|
||||
func darwinFuseCheckVersion() error {
|
||||
// on OSX, check FUSE version.
|
||||
if runtime.GOOS != "darwin" {
|
||||
return nil
|
||||
}
|
||||
|
||||
ov, err := syscall.Sysctl("osxfuse.version.number")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if strings.HasPrefix(ov, "2.7.") || strings.HasPrefix(ov, "2.8.") {
|
||||
return nil
|
||||
}
|
||||
|
||||
return fmt.Errorf("osxfuse version %s not supported.\n%s\n%s", ov,
|
||||
"Older versions of osxfuse have kernel panic bugs; please upgrade!",
|
||||
"https://github.com/jbenet/go-ipfs/issues/177")
|
||||
}
|
@ -1,118 +0,0 @@
|
||||
// +build linux darwin freebsd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
ipns "github.com/jbenet/go-ipfs/fuse/ipns"
|
||||
mount "github.com/jbenet/go-ipfs/fuse/mount"
|
||||
rofs "github.com/jbenet/go-ipfs/fuse/readonly"
|
||||
)
|
||||
|
||||
var cmdIpfsMount = &commander.Command{
|
||||
UsageLine: "mount",
|
||||
Short: "Mount an ipfs read-only mountpoint.",
|
||||
Long: `ipfs mount <os-path> - Mount an ipfs read-only mountpoint.
|
||||
|
||||
Mount ipfs at a read-only mountpoint on the OS. All ipfs objects
|
||||
will be accessible under that directory. Note that the root will
|
||||
not be listable, as it is virtual. Accessing known paths directly.
|
||||
|
||||
`,
|
||||
Run: mountCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-mount", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsMount.Flag.String("f", "", "specify a mountpoint for ipfs")
|
||||
cmdIpfsMount.Flag.String("n", "", "specify a mountpoint for ipns")
|
||||
}
|
||||
|
||||
func mountCmd(c *commander.Command, inp []string) error {
|
||||
if err := platformFuseChecks(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cc, err := setupCmdContext(c, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cc.daemon.Close()
|
||||
|
||||
// update fsdir with flag.
|
||||
fsdir := cc.node.Config.Mounts.IPFS
|
||||
if val, ok := c.Flag.Lookup("f").Value.Get().(string); ok && val != "" {
|
||||
fsdir = val
|
||||
}
|
||||
|
||||
// get default mount points
|
||||
nsdir := cc.node.Config.Mounts.IPNS
|
||||
if val, ok := c.Flag.Lookup("n").Value.Get().(string); ok && val != "" {
|
||||
nsdir = val
|
||||
}
|
||||
|
||||
return doMount(cc.node, fsdir, nsdir)
|
||||
}
|
||||
|
||||
func doMount(node *core.IpfsNode, fsdir, nsdir string) error {
|
||||
|
||||
// this sync stuff is so that both can be mounted simultaneously.
|
||||
var fsmount mount.Mount
|
||||
var nsmount mount.Mount
|
||||
var err1 error
|
||||
var err2 error
|
||||
|
||||
done := make(chan struct{})
|
||||
|
||||
go func() {
|
||||
fsmount, err1 = rofs.Mount(node, fsdir)
|
||||
done <- struct{}{}
|
||||
}()
|
||||
|
||||
go func() {
|
||||
nsmount, err2 = ipns.Mount(node, nsdir, fsdir)
|
||||
done <- struct{}{}
|
||||
}()
|
||||
|
||||
<-done
|
||||
<-done
|
||||
|
||||
if err1 != nil || err2 != nil {
|
||||
fsmount.Close()
|
||||
nsmount.Close()
|
||||
if err1 != nil {
|
||||
return err1
|
||||
} else {
|
||||
return err2
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Printf("mounted ipfs at %s\n", fsdir)
|
||||
fmt.Printf("mounted ipns at %s\n", nsdir)
|
||||
|
||||
// setup node state, so that it can be cancelled
|
||||
node.Mounts.Ipfs = fsmount
|
||||
node.Mounts.Ipns = nsmount
|
||||
|
||||
// wait until we kill
|
||||
sigc := make(chan os.Signal, 1)
|
||||
signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
|
||||
syscall.SIGTERM, syscall.SIGQUIT)
|
||||
<-sigc
|
||||
|
||||
fmt.Println("unmounting...")
|
||||
node.Close()
|
||||
return nil
|
||||
}
|
||||
|
||||
var platformFuseChecks = func() error {
|
||||
return nil
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
)
|
||||
|
||||
var cmdIpfsMount = &commander.Command{
|
||||
UsageLine: "mount",
|
||||
Short: "Mount an ipfs read-only mountpoint.",
|
||||
Long: `Not yet implemented on windows.`,
|
||||
Run: mountCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-mount", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func mountCmd(c *commander.Command, inp []string) error {
|
||||
return errors.New("mount not yet implemented on windows")
|
||||
}
|
@ -1,57 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
)
|
||||
|
||||
var cmdIpfsName = &commander.Command{
|
||||
UsageLine: "name [publish | resolve]",
|
||||
Short: "ipfs namespace (ipns) tool",
|
||||
Long: `ipfs name - Get/Set ipfs config values.
|
||||
|
||||
ipfs name publish [<name>] <ref> - Assign the <ref> to <name>
|
||||
ipfs name resolve [<name>] - Resolve the <ref> value of <name>
|
||||
|
||||
IPNS is a PKI namespace, where names are the hashes of public keys, and
|
||||
the private key enables publishing new (signed) values. In both publish
|
||||
and resolve, the default value of <name> is your own identity public key.
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
Publish a <ref> to your identity name:
|
||||
|
||||
> ipfs name publish QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
Publish a <ref> to another public key:
|
||||
|
||||
> ipfs name publish QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
Resolve the value of your identity:
|
||||
|
||||
> ipfs name resolve
|
||||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
Resolve te value of another name:
|
||||
|
||||
> ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
|
||||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
`,
|
||||
Run: nameCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-name", flag.ExitOnError),
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsPub,
|
||||
cmdIpfsResolve,
|
||||
},
|
||||
}
|
||||
|
||||
func nameCmd(c *commander.Command, args []string) error {
|
||||
fmt.Println(c.Long)
|
||||
return nil
|
||||
}
|
@ -1,112 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsObject = &commander.Command{
|
||||
UsageLine: "object",
|
||||
Short: "interact with ipfs objects",
|
||||
Long: `ipfs object - interact with ipfs objects
|
||||
|
||||
ipfs object data <key> - return the data for this key as raw bytes
|
||||
ipfs object links <key> - lists (the keys of ?) the links this key points to
|
||||
ipfs object get <key> - output dag object to stdout
|
||||
ipfs object put - add dag object from stdin
|
||||
|
||||
ipfs object is a plumbing command used to manipulate dag objects directly.
|
||||
- <key> is a base58 encoded multihash.
|
||||
- It reads from stdin or writes to stdout.
|
||||
- It accepts multiple encodings: --encoding=[ protobuf, json, ... ]`,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsObjectData,
|
||||
cmdIpfsObjectLinks,
|
||||
cmdIpfsObjectGet,
|
||||
cmdIpfsObjectPut,
|
||||
},
|
||||
Flag: *flag.NewFlagSet("ipfs-object", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsObjectData = &commander.Command{
|
||||
UsageLine: "data <key>",
|
||||
Short: "data outputs the raw bytes named by <key>",
|
||||
Long: `ipfs data <key> - data outputs the raw bytes named by <key>
|
||||
|
||||
ipfs data is a plumbing command for retreiving the raw bytes stored in a dag node.
|
||||
It outputs to stdout, and <key> is a base58 encoded multihash.`,
|
||||
Run: makeCommand(command{
|
||||
name: "objectData",
|
||||
args: 1,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.ObjectData,
|
||||
}),
|
||||
}
|
||||
|
||||
var cmdIpfsObjectLinks = &commander.Command{
|
||||
UsageLine: "links <key>",
|
||||
Short: "outputs the links pointed to by <key>",
|
||||
Long: `ipfs links <key> - outputs the links pointed to by <key>
|
||||
|
||||
ipfs block get is a plumbing command for retreiving raw ipfs blocks.
|
||||
It outputs to stdout, and <key> is a base58 encoded multihash.`,
|
||||
Run: makeCommand(command{
|
||||
name: "objectLinks",
|
||||
args: 1,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.ObjectLinks,
|
||||
}),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsObjectGet.Flag.String("encoding", "json", "the encoding to use..")
|
||||
cmdIpfsObjectPut.Flag.String("encoding", "json", "the encoding to use..")
|
||||
}
|
||||
|
||||
var cmdIpfsObjectGet = &commander.Command{
|
||||
UsageLine: "get <key>",
|
||||
Short: "get and serialize the dag node named by <key>",
|
||||
Long: `ipfs get <key> - get and output the dag node named by <key>
|
||||
|
||||
ipfs object get is a plumbing command for retreiving dag nodes.
|
||||
It serialize the dag node to the format specified by the format flag.
|
||||
It outputs to stdout, and <key> is a base58 encoded multihash.
|
||||
|
||||
Formats:
|
||||
|
||||
This command outputs and accepts data in a variety of encodings: protobuf, json, etc.
|
||||
Use the --encoding flag
|
||||
`,
|
||||
Run: makeCommand(command{
|
||||
name: "blockGet",
|
||||
args: 1,
|
||||
flags: []string{"encoding"},
|
||||
online: true,
|
||||
cmdFn: commands.ObjectGet,
|
||||
}),
|
||||
}
|
||||
|
||||
var cmdIpfsObjectPut = &commander.Command{
|
||||
UsageLine: "put",
|
||||
Short: "store stdin as a dag object, outputs <key>",
|
||||
Long: `ipfs put - store stdin as a dag object, outputs <key>
|
||||
|
||||
ipfs object put is a plumbing command for storing dag nodes.
|
||||
It serialize the dag node to the format specified by the format flag.
|
||||
It reads from stding, and <key> is a base58 encoded multihash.
|
||||
|
||||
Formats:
|
||||
|
||||
This command outputs and accepts data in a variety of encodings: protobuf, json, etc.
|
||||
Use the --encoding flag`,
|
||||
Run: makeCommand(command{
|
||||
name: "blockPut",
|
||||
args: 0,
|
||||
flags: []string{"encoding"},
|
||||
online: true,
|
||||
cmdFn: commands.ObjectPut,
|
||||
}),
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsPin = &commander.Command{
|
||||
UsageLine: "pin",
|
||||
Short: "",
|
||||
Long: `ipfs pin [add|rm] - object pinning commands
|
||||
`,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsSubPin,
|
||||
cmdIpfsSubUnpin,
|
||||
},
|
||||
}
|
||||
|
||||
var cmdIpfsSubPin = &commander.Command{
|
||||
UsageLine: "add",
|
||||
Short: "pin an ipfs object to local storage.",
|
||||
Long: `ipfs pin add <ipfs-path> - pin ipfs object to local storage.
|
||||
|
||||
Retrieves the object named by <ipfs-path> and stores it locally
|
||||
on disk.
|
||||
`,
|
||||
Run: pinSubCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-pin", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var pinSubCmd = makeCommand(command{
|
||||
name: "pin",
|
||||
args: 1,
|
||||
flags: []string{"r", "d"},
|
||||
cmdFn: commands.Pin,
|
||||
})
|
||||
|
||||
var cmdIpfsSubUnpin = &commander.Command{
|
||||
UsageLine: "rm",
|
||||
Short: "unpin an ipfs object from local storage.",
|
||||
Long: `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.
|
||||
`,
|
||||
Run: unpinSubCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-unpin", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var unpinSubCmd = makeCommand(command{
|
||||
name: "unpin",
|
||||
args: 1,
|
||||
flags: []string{"r"},
|
||||
cmdFn: commands.Unpin,
|
||||
})
|
||||
|
||||
func init() {
|
||||
cmdIpfsSubPin.Flag.Bool("r", false, "pin objects recursively")
|
||||
cmdIpfsSubPin.Flag.Int("d", 1, "recursive depth")
|
||||
cmdIpfsSubUnpin.Flag.Bool("r", false, "unpin objects recursively")
|
||||
}
|
@ -1,41 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsPub = &commander.Command{
|
||||
UsageLine: "publish",
|
||||
Short: "publish a <ref> to ipns.",
|
||||
Long: `ipfs publish [<name>] <ref> - publish a <ref> to ipns.
|
||||
|
||||
IPNS is a PKI namespace, where names are the hashes of public keys, and
|
||||
the private key enables publishing new (signed) values. In publish, the
|
||||
default value of <name> is your own identity public key.
|
||||
|
||||
Examples:
|
||||
|
||||
Publish a <ref> to your identity name:
|
||||
|
||||
> ipfs name publish QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
Publish a <ref> to another public key:
|
||||
|
||||
> ipfs name publish QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
published name QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n to QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
`,
|
||||
Run: pubCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-publish", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var pubCmd = makeCommand(command{
|
||||
name: "publish",
|
||||
args: 1,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.Publish,
|
||||
})
|
@ -1,36 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
commands "github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsRefs = &commander.Command{
|
||||
UsageLine: "refs",
|
||||
Short: "List link hashes from an object.",
|
||||
Long: `ipfs refs <ipfs-path> - List link hashes from an object..
|
||||
|
||||
Retrieves the object named by <ipfs-path> and displays the link
|
||||
hashes it contains, with the following format:
|
||||
|
||||
<link base58 hash>
|
||||
|
||||
Note: list all refs recursively with -r.
|
||||
|
||||
`,
|
||||
Run: refCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-refs", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsRefs.Flag.Bool("r", false, "recursive: list refs recursively")
|
||||
cmdIpfsRefs.Flag.Bool("u", false, "unique: list each ref only once")
|
||||
}
|
||||
|
||||
var refCmd = makeCommand(command{
|
||||
name: "refs",
|
||||
args: 1,
|
||||
flags: []string{"r", "u"},
|
||||
cmdFn: commands.Refs,
|
||||
})
|
@ -1,42 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
var cmdIpfsResolve = &commander.Command{
|
||||
UsageLine: "resolve",
|
||||
Short: "resolve an ipns name to a <ref>",
|
||||
Long: `ipfs resolve [<name>] - Resolve an ipns name to a <ref>.
|
||||
|
||||
IPNS is a PKI namespace, where names are the hashes of public keys, and
|
||||
the private key enables publishing new (signed) values. In resolve, the
|
||||
default value of <name> is your own identity public key.
|
||||
|
||||
|
||||
Examples:
|
||||
|
||||
Resolve the value of your identity:
|
||||
|
||||
> ipfs name resolve
|
||||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
Resolve te value of another name:
|
||||
|
||||
> ipfs name resolve QmbCMUZw6JFeZ7Wp9jkzbye3Fzp2GGcPgC3nmeUjfVF87n
|
||||
QmatmE9msSfkKxoffpHwNLNKgwZG8eT9Bud6YoPab52vpy
|
||||
|
||||
`,
|
||||
Run: resolveCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-resolve", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var resolveCmd = makeCommand(command{
|
||||
name: "resolve",
|
||||
args: 0,
|
||||
flags: nil,
|
||||
online: true,
|
||||
cmdFn: commands.Resolve,
|
||||
})
|
@ -1,36 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/signal"
|
||||
"syscall"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
)
|
||||
|
||||
var cmdIpfsRun = &commander.Command{
|
||||
UsageLine: "run",
|
||||
Short: "run local ifps node.",
|
||||
Long: `run a local ipfs node with no other interface.
|
||||
`,
|
||||
Run: runCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-run", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func runCmd(c *commander.Command, inp []string) error {
|
||||
cc, err := setupCmdContext(c, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
sigc := make(chan os.Signal, 1)
|
||||
signal.Notify(sigc, syscall.SIGHUP, syscall.SIGINT,
|
||||
syscall.SIGTERM, syscall.SIGQUIT)
|
||||
|
||||
// wait until we get a signal to exit.
|
||||
<-sigc
|
||||
|
||||
cc.daemon.Close()
|
||||
return nil
|
||||
}
|
@ -1,49 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
|
||||
h "github.com/jbenet/go-ipfs/server/http"
|
||||
)
|
||||
|
||||
var cmdIpfsServe = &commander.Command{
|
||||
UsageLine: "serve",
|
||||
Short: "Serve an interface to ipfs",
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsServeHTTP,
|
||||
},
|
||||
Flag: *flag.NewFlagSet("ipfs-serve", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsServeHTTP = &commander.Command{
|
||||
UsageLine: "http",
|
||||
Short: "Serve an HTTP API",
|
||||
Long: `ipfs serve http - Serve an http gateway into ipfs.`,
|
||||
Run: serveHTTPCmd,
|
||||
Flag: *flag.NewFlagSet("ipfs-serve-http", flag.ExitOnError),
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsServeHTTP.Flag.String("address", "/ip4/127.0.0.1/tcp/8080", "Listen Address")
|
||||
}
|
||||
|
||||
func serveHTTPCmd(c *commander.Command, _ []string) error {
|
||||
cc, err := setupCmdContext(c, true)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer cc.daemon.Close()
|
||||
|
||||
address := c.Flag.Lookup("address").Value.Get().(string)
|
||||
maddr, err := ma.NewMultiaddr(address)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("Serving on %s\n", address)
|
||||
return h.Serve(maddr, cc.node)
|
||||
}
|
134
cmd/ipfs/tour.go
134
cmd/ipfs/tour.go
@ -1,134 +0,0 @@
|
||||
// +build linux darwin freebsd
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
tour "github.com/jbenet/go-ipfs/tour"
|
||||
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
)
|
||||
|
||||
var cmdIpfsTour = &commander.Command{
|
||||
UsageLine: "tour [<number>]",
|
||||
Short: "Take the IPFS Tour.",
|
||||
Long: `ipfs tour - Take the IPFS Tour.
|
||||
|
||||
ipfs tour [<number>] - Show tour topic. Default to current.
|
||||
ipfs tour next - Show the next tour topic.
|
||||
ipfs tour list - Show a list of topics.
|
||||
ipfs tour restart - Restart the tour.
|
||||
|
||||
This is a tour that takes you through various IPFS concepts,
|
||||
features, and tools to make sure you get up to speed with
|
||||
IPFS very quickly. To start, run:
|
||||
|
||||
ipfs tour
|
||||
`,
|
||||
Run: tourCmd,
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsTourNext,
|
||||
cmdIpfsTourList,
|
||||
cmdIpfsTourRestart,
|
||||
},
|
||||
}
|
||||
|
||||
var cmdIpfsTourNext = &commander.Command{
|
||||
UsageLine: "next",
|
||||
Short: "Show the next IPFS Tour topic.",
|
||||
Run: tourNextCmd,
|
||||
}
|
||||
|
||||
var cmdIpfsTourList = &commander.Command{
|
||||
UsageLine: "list",
|
||||
Short: "Show a list of IPFS Tour topics.",
|
||||
Run: tourListCmd,
|
||||
}
|
||||
|
||||
var cmdIpfsTourRestart = &commander.Command{
|
||||
UsageLine: "restart",
|
||||
Short: "Restart the IPFS Tour.",
|
||||
Run: tourRestartCmd,
|
||||
}
|
||||
|
||||
func tourCmd(c *commander.Command, inp []string) error {
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
topic := tour.TopicID(cfg.Tour.Last)
|
||||
if len(inp) > 0 {
|
||||
topic = tour.TopicID(inp[0])
|
||||
}
|
||||
return tourShow(topic)
|
||||
}
|
||||
|
||||
func tourNextCmd(c *commander.Command, _ []string) error {
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
topic := tour.NextTopic(tour.TopicID(cfg.Tour.Last))
|
||||
if err := tourShow(topic); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// if topic didn't change (last) done
|
||||
if string(topic) == cfg.Tour.Last {
|
||||
return nil
|
||||
}
|
||||
|
||||
// topic changed, not last. write it out.
|
||||
cfg.Tour.Last = string(topic)
|
||||
return writeConfig(c, cfg)
|
||||
}
|
||||
|
||||
func tourListCmd(c *commander.Command, _ []string) error {
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
lastid := tour.TopicID(cfg.Tour.Last)
|
||||
|
||||
for _, id := range tour.IDs {
|
||||
c := ' '
|
||||
switch {
|
||||
case id == lastid:
|
||||
c = '*'
|
||||
case id.LessThan(lastid):
|
||||
c = '✓'
|
||||
}
|
||||
|
||||
t := tour.Topics[id]
|
||||
fmt.Printf("- %c %-5.5s %s\n", c, id, t.Title)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func tourRestartCmd(c *commander.Command, _ []string) error {
|
||||
cfg, err := getConfig(c)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg.Tour.Last = ""
|
||||
return writeConfig(c, cfg)
|
||||
}
|
||||
|
||||
func tourShow(id tour.ID) error {
|
||||
t, found := tour.Topics[id]
|
||||
if !found {
|
||||
return fmt.Errorf("no topic with id: %s", id)
|
||||
}
|
||||
|
||||
fmt.Printf("Tour %s - %s\n\n%s\n", t.ID, t.Title, t.Text)
|
||||
return nil
|
||||
}
|
||||
|
||||
func lastTour(cfg *config.Config) string {
|
||||
return ""
|
||||
}
|
@ -1,62 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
flag "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/gonuts/flag"
|
||||
commander "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
)
|
||||
|
||||
func init() {
|
||||
cmdIpfsUpdate.Flag.Bool("force", false, "force shutdown of daemon when updating")
|
||||
}
|
||||
|
||||
var cmdIpfsUpdate = &commander.Command{
|
||||
UsageLine: "update",
|
||||
Short: "check for updates and apply them",
|
||||
Long: `ipfs update - check for updates and apply them
|
||||
|
||||
ipfs update <version> - apply
|
||||
ipfs update check - just check
|
||||
ipfs update log - list the changelogs
|
||||
|
||||
ipfs update is a utility command used to check for updates and apply them.
|
||||
I wont even try, @jbenet. You do this much better :)`,
|
||||
Run: makeCommand(command{
|
||||
name: "updateApply",
|
||||
args: 0,
|
||||
flags: []string{"force"},
|
||||
online: true,
|
||||
cmdFn: commands.UpdateApply,
|
||||
}),
|
||||
Subcommands: []*commander.Command{
|
||||
cmdIpfsUpdateCheck,
|
||||
cmdIpfsUpdateLog,
|
||||
},
|
||||
Flag: *flag.NewFlagSet("ipfs-update", flag.ExitOnError),
|
||||
}
|
||||
|
||||
var cmdIpfsUpdateCheck = &commander.Command{
|
||||
UsageLine: "check",
|
||||
Short: "",
|
||||
Long: `ipfs update check <key>`,
|
||||
Run: makeCommand(command{
|
||||
name: "updateCheck",
|
||||
args: 0,
|
||||
flags: nil,
|
||||
online: false,
|
||||
cmdFn: commands.UpdateCheck,
|
||||
}),
|
||||
}
|
||||
|
||||
var cmdIpfsUpdateLog = &commander.Command{
|
||||
UsageLine: "log",
|
||||
Short: "list the last versions and their changelog",
|
||||
Long: `ipfs updage log - list the last versions and their changelog`,
|
||||
Run: makeCommand(command{
|
||||
name: "updateLog",
|
||||
args: 0,
|
||||
flags: nil,
|
||||
online: false,
|
||||
cmdFn: commands.UpdateCheck,
|
||||
}),
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/commander"
|
||||
)
|
||||
|
||||
var cmdIpfsVersion = &commander.Command{
|
||||
UsageLine: "version",
|
||||
Short: "Show ipfs version information.",
|
||||
Long: `ipfs version - Show ipfs version information.
|
||||
|
||||
Returns the current version of ipfs and exits.
|
||||
`,
|
||||
Run: versionCmd,
|
||||
}
|
||||
|
||||
func init() {
|
||||
cmdIpfsVersion.Flag.Bool("number", false, "show only the number")
|
||||
}
|
||||
|
||||
func versionCmd(c *commander.Command, _ []string) error {
|
||||
number := c.Flag.Lookup("number").Value.Get().(bool)
|
||||
if !number {
|
||||
u.POut("ipfs version ")
|
||||
}
|
||||
u.POut("%s\n", config.CurrentVersionNumber)
|
||||
return nil
|
||||
}
|
@ -1,136 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
"github.com/jbenet/go-ipfs/importer"
|
||||
dag "github.com/jbenet/go-ipfs/merkledag"
|
||||
"github.com/jbenet/go-ipfs/pin"
|
||||
ft "github.com/jbenet/go-ipfs/unixfs"
|
||||
)
|
||||
|
||||
// Error indicating the max depth has been exceded.
|
||||
var ErrDepthLimitExceeded = fmt.Errorf("depth limit exceeded")
|
||||
|
||||
// Add is a command that imports files and directories -- given as arguments -- into ipfs.
|
||||
func Add(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
depth := 1
|
||||
|
||||
// if recursive, set depth to reflect so
|
||||
if r, ok := opts["r"].(bool); r && ok {
|
||||
depth = -1
|
||||
}
|
||||
|
||||
// add every path in args
|
||||
for _, path := range args {
|
||||
|
||||
// Add the file
|
||||
_, err := AddPath(n, path, depth, out)
|
||||
if err != nil {
|
||||
if err == ErrDepthLimitExceeded && depth == 1 {
|
||||
err = errors.New("use -r to recursively add directories")
|
||||
}
|
||||
return fmt.Errorf("addFile error: %v", err)
|
||||
}
|
||||
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// AddPath adds a particular path to ipfs.
|
||||
func AddPath(n *core.IpfsNode, fpath string, depth int, out io.Writer) (*dag.Node, error) {
|
||||
if depth == 0 {
|
||||
return nil, ErrDepthLimitExceeded
|
||||
}
|
||||
|
||||
fi, err := os.Stat(fpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if fi.IsDir() {
|
||||
return addDir(n, fpath, depth, out)
|
||||
}
|
||||
|
||||
return addFile(n, fpath, depth, out)
|
||||
}
|
||||
|
||||
func addDir(n *core.IpfsNode, fpath string, depth int, out io.Writer) (*dag.Node, error) {
|
||||
tree := &dag.Node{Data: ft.FolderPBData()}
|
||||
|
||||
files, err := ioutil.ReadDir(fpath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// construct nodes for containing files.
|
||||
for _, f := range files {
|
||||
fp := filepath.Join(fpath, f.Name())
|
||||
nd, err := AddPath(n, fp, depth-1, out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err = tree.AddNodeLink(f.Name(), nd); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("adding dir: %s", fpath)
|
||||
|
||||
return tree, addNode(n, tree, fpath, out)
|
||||
}
|
||||
|
||||
func addFile(n *core.IpfsNode, fpath string, depth int, out io.Writer) (*dag.Node, error) {
|
||||
mp, ok := n.Pinning.(pin.ManualPinner)
|
||||
if !ok {
|
||||
return nil, errors.New("invalid pinner type! expected manual pinner")
|
||||
}
|
||||
|
||||
root, err := importer.BuildDagFromFile(fpath, n.DAG, mp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Infof("adding file: %s", fpath)
|
||||
|
||||
for _, l := range root.Links {
|
||||
log.Infof("adding subblock: '%s' %s", l.Name, l.Hash.B58String())
|
||||
}
|
||||
|
||||
k, err := root.Key()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// output that we've added this node
|
||||
fmt.Fprintf(out, "added %s %s\n", k, fpath)
|
||||
|
||||
return root, nil
|
||||
}
|
||||
|
||||
// addNode adds the node to the graph + local storage
|
||||
func addNode(n *core.IpfsNode, nd *dag.Node, fpath string, out io.Writer) error {
|
||||
// add the file to the graph + local storage
|
||||
err := n.DAG.AddRecursive(nd)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
k, err := nd.Key()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// output that we've added this node
|
||||
fmt.Fprintf(out, "added %s %s\n", k, fpath)
|
||||
|
||||
// ensure we keep it
|
||||
return n.Pinning.Pin(nd, true)
|
||||
}
|
@ -1,60 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"time"
|
||||
|
||||
"github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context"
|
||||
|
||||
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
||||
"github.com/jbenet/go-ipfs/blocks"
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// BlockGet retrives a raw ipfs block from the node's BlockService
|
||||
func BlockGet(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
|
||||
if !u.IsValidHash(args[0]) {
|
||||
return fmt.Errorf("block get: not a valid hash")
|
||||
}
|
||||
|
||||
h, err := mh.FromB58String(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("block get: %v", err)
|
||||
}
|
||||
|
||||
k := u.Key(h)
|
||||
log.Debugf("BlockGet key: '%q'", k)
|
||||
ctx, _ := context.WithTimeout(context.TODO(), time.Second*5)
|
||||
b, err := n.Blocks.GetBlock(ctx, k)
|
||||
if err != nil {
|
||||
return fmt.Errorf("block get: %v", err)
|
||||
}
|
||||
|
||||
_, err = out.Write(b.Data)
|
||||
return err
|
||||
}
|
||||
|
||||
// BlockPut reads everything from conn and saves the data to the nodes BlockService
|
||||
func BlockPut(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
// TODO: this should read from an io.Reader arg
|
||||
data, err := ioutil.ReadAll(os.Stdin)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
b := blocks.NewBlock(data)
|
||||
log.Debugf("BlockPut key: '%q'", b.Key())
|
||||
|
||||
k, err := n.Blocks.AddBlock(b)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(out, "added as '%s'\n", k)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
uio "github.com/jbenet/go-ipfs/unixfs/io"
|
||||
)
|
||||
|
||||
func Cat(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
for _, fn := range args {
|
||||
dagnode, err := n.Resolver.ResolvePath(fn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("catFile error: %v", err)
|
||||
}
|
||||
|
||||
read, err := uio.NewDagReader(dagnode, n.DAG)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cat error: %v", err)
|
||||
}
|
||||
|
||||
_, err = io.Copy(out, read)
|
||||
if err != nil {
|
||||
return fmt.Errorf("cat error: %v", err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
var log = u.Logger("commands")
|
||||
|
||||
type CmdFunc func(*core.IpfsNode, []string, map[string]interface{}, io.Writer) error
|
@ -1,49 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"time"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
diagn "github.com/jbenet/go-ipfs/diagnostics"
|
||||
)
|
||||
|
||||
func PrintDiagnostics(info []*diagn.DiagInfo, out io.Writer) {
|
||||
for _, i := range info {
|
||||
fmt.Fprintf(out, "Peer: %s\n", i.ID)
|
||||
fmt.Fprintf(out, "\tUp for: %s\n", i.LifeSpan.String())
|
||||
fmt.Fprintf(out, "\tConnected To:\n")
|
||||
for _, c := range i.Connections {
|
||||
fmt.Fprintf(out, "\t%s\n\t\tLatency = %s\n", c.ID, c.Latency.String())
|
||||
}
|
||||
fmt.Fprintln(out)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func Diag(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
if n.Diagnostics == nil {
|
||||
return errors.New("Cannot run diagnostic in offline mode!")
|
||||
}
|
||||
info, err := n.Diagnostics.GetDiagnostic(time.Second * 20)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
raw, ok := opts["raw"].(bool)
|
||||
if !ok {
|
||||
return errors.New("incorrect value to parameter 'raw'")
|
||||
}
|
||||
if raw {
|
||||
enc := json.NewEncoder(out)
|
||||
err = enc.Encode(info)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
PrintDiagnostics(info, out)
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,18 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// Log changes the log level of a subsystem
|
||||
func Log(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
if err := u.SetLogLevel(args[0], args[1]); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Info("Changed LogLevel of %q to %q", args[0], args[1])
|
||||
return nil
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
)
|
||||
|
||||
func Ls(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
for _, fn := range args {
|
||||
dagnode, err := n.Resolver.ResolvePath(fn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("ls error: %v", err)
|
||||
}
|
||||
|
||||
for _, link := range dagnode.Links {
|
||||
fmt.Fprintf(out, "%s %d %s\n", link.Hash.B58String(), link.Size, link.Name)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
@ -1,135 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
dag "github.com/jbenet/go-ipfs/merkledag"
|
||||
)
|
||||
|
||||
// ObjectData takes a key string from args and writes out the raw bytes of that node (if there is one)
|
||||
func ObjectData(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
dagnode, err := n.Resolver.ResolvePath(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("objectData error: %v", err)
|
||||
}
|
||||
log.Debugf("objectData: found dagnode %q (# of bytes: %d - # links: %d)", args[0], len(dagnode.Data), len(dagnode.Links))
|
||||
|
||||
_, err = io.Copy(out, bytes.NewReader(dagnode.Data))
|
||||
return err
|
||||
}
|
||||
|
||||
// ObjectLinks takes a key string from args and lists the links it points to
|
||||
func ObjectLinks(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
dagnode, err := n.Resolver.ResolvePath(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("objectLinks error: %v", err)
|
||||
}
|
||||
log.Debugf("ObjectLinks: found dagnode %q (# of bytes: %d - # links: %d)", args[0], len(dagnode.Data), len(dagnode.Links))
|
||||
|
||||
for _, link := range dagnode.Links {
|
||||
_, err = fmt.Fprintf(out, "%s %d %q\n", link.Hash.B58String(), link.Size, link.Name)
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// ErrUnknownObjectEnc is returned if a invalid encoding is supplied
|
||||
var ErrUnknownObjectEnc = errors.New("unknown object encoding")
|
||||
|
||||
type objectEncoding string
|
||||
|
||||
const (
|
||||
objectEncodingJSON objectEncoding = "json"
|
||||
objectEncodingProtobuf = "protobuf"
|
||||
)
|
||||
|
||||
func getObjectEnc(o interface{}) objectEncoding {
|
||||
v, ok := o.(string)
|
||||
if !ok {
|
||||
// chosen as default because it's human readable
|
||||
log.Warning("option is not a string - falling back to json")
|
||||
return objectEncodingJSON
|
||||
}
|
||||
|
||||
return objectEncoding(v)
|
||||
}
|
||||
|
||||
// ObjectGet takes a key string from args and a format option and serializes the dagnode to that format
|
||||
func ObjectGet(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
dagnode, err := n.Resolver.ResolvePath(args[0])
|
||||
if err != nil {
|
||||
return fmt.Errorf("ObjectGet error: %v", err)
|
||||
}
|
||||
log.Debugf("objectGet: found dagnode %q (# of bytes: %d - # links: %d)", args[0], len(dagnode.Data), len(dagnode.Links))
|
||||
|
||||
// sadly all encodings dont implement a common interface
|
||||
var data []byte
|
||||
switch getObjectEnc(opts["encoding"]) {
|
||||
case objectEncodingJSON:
|
||||
data, err = json.MarshalIndent(dagnode, "", " ")
|
||||
|
||||
case objectEncodingProtobuf:
|
||||
data, err = dagnode.Marshal()
|
||||
|
||||
default:
|
||||
return ErrUnknownObjectEnc
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("ObjectGet error: %v", err)
|
||||
}
|
||||
|
||||
_, err = io.Copy(out, bytes.NewReader(data))
|
||||
return err
|
||||
}
|
||||
|
||||
// ErrObjectTooLarge is returned when too much data was read from stdin. current limit 512k
|
||||
var ErrObjectTooLarge = errors.New("input object was too large. limit is 512kbytes")
|
||||
|
||||
const inputLimit = 512 * 1024
|
||||
|
||||
// ObjectPut takes a format option, serilizes bytes from stdin and updates the dag with that data
|
||||
func ObjectPut(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
var (
|
||||
dagnode *dag.Node
|
||||
data []byte
|
||||
err error
|
||||
)
|
||||
|
||||
data, err = ioutil.ReadAll(io.LimitReader(os.Stdin, inputLimit+10))
|
||||
if err != nil {
|
||||
return fmt.Errorf("ObjectPut error: %v", err)
|
||||
}
|
||||
|
||||
if len(data) >= inputLimit {
|
||||
return ErrObjectTooLarge
|
||||
}
|
||||
|
||||
switch getObjectEnc(opts["encoding"]) {
|
||||
case objectEncodingJSON:
|
||||
dagnode = new(dag.Node)
|
||||
err = json.Unmarshal(data, dagnode)
|
||||
|
||||
case objectEncodingProtobuf:
|
||||
dagnode, err = dag.Decoded(data)
|
||||
|
||||
default:
|
||||
return ErrUnknownObjectEnc
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return fmt.Errorf("ObjectPut error: %v", err)
|
||||
}
|
||||
|
||||
return addNode(n, dagnode, "stdin", out)
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
)
|
||||
|
||||
func Pin(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
|
||||
// set recursive flag
|
||||
recursive, _ := opts["r"].(bool) // false if cast fails.
|
||||
|
||||
// if recursive, set depth flag
|
||||
depth := 1 // default (non recursive)
|
||||
if d, ok := opts["d"].(int); recursive && ok {
|
||||
depth = d
|
||||
}
|
||||
if depth < -1 {
|
||||
return fmt.Errorf("ipfs pin: called with invalid depth: %v", depth)
|
||||
}
|
||||
|
||||
fmt.Printf("recursive, depth: %v, %v\n", recursive, depth)
|
||||
|
||||
for _, fn := range args {
|
||||
dagnode, err := n.Resolver.ResolvePath(fn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pin error: %v", err)
|
||||
}
|
||||
|
||||
err = n.Pinning.Pin(dagnode, recursive)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pin: %v", err)
|
||||
}
|
||||
}
|
||||
return n.Pinning.Flush()
|
||||
}
|
||||
|
||||
func Unpin(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
|
||||
// set recursive flag
|
||||
recursive, _ := opts["r"].(bool) // false if cast fails.
|
||||
|
||||
for _, fn := range args {
|
||||
dagnode, err := n.Resolver.ResolvePath(fn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pin error: %v", err)
|
||||
}
|
||||
|
||||
k, _ := dagnode.Key()
|
||||
err = n.Pinning.Unpin(k, recursive)
|
||||
if err != nil {
|
||||
return fmt.Errorf("pin: %v", err)
|
||||
}
|
||||
}
|
||||
return n.Pinning.Flush()
|
||||
}
|
@ -1,53 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
|
||||
nsys "github.com/jbenet/go-ipfs/namesys"
|
||||
)
|
||||
|
||||
func Publish(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
log.Debug("Begin Publish")
|
||||
|
||||
if n.Identity == nil {
|
||||
return errors.New("Identity not loaded!")
|
||||
}
|
||||
|
||||
// name := ""
|
||||
ref := ""
|
||||
|
||||
switch len(args) {
|
||||
case 2:
|
||||
// name = args[0]
|
||||
ref = args[1]
|
||||
return errors.New("keychains not yet implemented")
|
||||
case 1:
|
||||
// name = n.Identity.ID.String()
|
||||
ref = args[0]
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Publish expects 1 or 2 args; got %d.", len(args))
|
||||
}
|
||||
|
||||
// later, n.Keychain.Get(name).PrivKey
|
||||
k := n.Identity.PrivKey()
|
||||
|
||||
pub := nsys.NewRoutingPublisher(n.Routing)
|
||||
err := pub.Publish(k, ref)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
hash, err := k.GetPublic().Hash()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Fprintf(out, "published name %s to %s\n", u.Key(hash), ref)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"io"
|
||||
|
||||
mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash"
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
mdag "github.com/jbenet/go-ipfs/merkledag"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
func Refs(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
unique, ok := opts["u"].(bool)
|
||||
if !ok {
|
||||
unique = false
|
||||
}
|
||||
|
||||
recursive, ok := opts["r"].(bool)
|
||||
if !ok {
|
||||
recursive = false
|
||||
}
|
||||
|
||||
var refsSeen map[u.Key]bool
|
||||
if unique {
|
||||
refsSeen = make(map[u.Key]bool)
|
||||
}
|
||||
|
||||
for _, fn := range args {
|
||||
nd, err := n.Resolver.ResolvePath(fn)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
printRefs(n, nd, refsSeen, recursive)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func printRefs(n *core.IpfsNode, nd *mdag.Node, refSeen map[u.Key]bool, recursive bool) {
|
||||
for _, link := range nd.Links {
|
||||
printRef(link.Hash, refSeen)
|
||||
|
||||
if recursive {
|
||||
nd, err := n.DAG.Get(u.Key(link.Hash))
|
||||
if err != nil {
|
||||
log.Errorf("error: cannot retrieve %s (%s)", link.Hash.B58String(), err)
|
||||
return
|
||||
}
|
||||
|
||||
printRefs(n, nd, refSeen, recursive)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printRef(h mh.Multihash, refsSeen map[u.Key]bool) {
|
||||
if refsSeen != nil {
|
||||
_, found := refsSeen[u.Key(h)]
|
||||
if found {
|
||||
return
|
||||
}
|
||||
refsSeen[u.Key(h)] = true
|
||||
}
|
||||
|
||||
u.POut("%s\n", h.B58String())
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
)
|
||||
|
||||
func Resolve(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
|
||||
name := ""
|
||||
|
||||
switch len(args) {
|
||||
case 1:
|
||||
name = args[0]
|
||||
case 0:
|
||||
if n.Identity == nil {
|
||||
return errors.New("Identity not loaded!")
|
||||
}
|
||||
name = n.Identity.ID().String()
|
||||
|
||||
default:
|
||||
return fmt.Errorf("Publish expects 1 or 2 args; got %d.", len(args))
|
||||
}
|
||||
|
||||
res, err := n.Namesys.Resolve(name)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Fprintf(out, "%s\n", res)
|
||||
return nil
|
||||
}
|
@ -1,76 +0,0 @@
|
||||
package commands
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
"github.com/jbenet/go-ipfs/core"
|
||||
"github.com/jbenet/go-ipfs/updates"
|
||||
)
|
||||
|
||||
// UpdateApply applys an update of the ipfs binary and shuts down the node if successful
|
||||
func UpdateApply(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
fmt.Fprintln(out, "Current Version:", updates.Version)
|
||||
u, err := updates.CheckForUpdate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
fmt.Fprintln(out, "No update available")
|
||||
return nil
|
||||
}
|
||||
fmt.Fprintln(out, "New Version:", u.Version)
|
||||
|
||||
_, onDaemon := opts["onDaemon"]
|
||||
force := opts["force"].(bool)
|
||||
if onDaemon && !force {
|
||||
return fmt.Errorf(`Error: update must stop running ipfs service.
|
||||
You may want to abort the update, or shut the service down manually.
|
||||
To shut it down automatically, run:
|
||||
|
||||
ipfs update --force
|
||||
`)
|
||||
}
|
||||
|
||||
if err = updates.Apply(u); err != nil {
|
||||
fmt.Fprint(out, err.Error())
|
||||
return fmt.Errorf("Couldn't apply update: %v", err)
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, "Updated applied!")
|
||||
if onDaemon {
|
||||
if force {
|
||||
fmt.Fprintln(out, "Shutting down ipfs service.")
|
||||
os.Exit(1) // is there a cleaner shutdown routine?
|
||||
} else {
|
||||
fmt.Fprintln(out, "You can now restart the ipfs service.")
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateCheck checks wether there is an update available
|
||||
func UpdateCheck(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
fmt.Fprintln(out, "Current Version:", updates.Version)
|
||||
u, err := updates.CheckForUpdate()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if u == nil {
|
||||
fmt.Fprintln(out, "No update available")
|
||||
return nil
|
||||
}
|
||||
|
||||
fmt.Fprintln(out, "New Version:", u.Version)
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateLog lists the version available online
|
||||
func UpdateLog(n *core.IpfsNode, args []string, opts map[string]interface{}, out io.Writer) error {
|
||||
return errors.New("Not yet implemented")
|
||||
}
|
166
daemon/daemon.go
166
daemon/daemon.go
@ -1,166 +0,0 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path"
|
||||
"sync"
|
||||
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
"github.com/jbenet/go-ipfs/core/commands"
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
|
||||
lock "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/camlistore/lock"
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net"
|
||||
)
|
||||
|
||||
var log = u.Logger("daemon")
|
||||
|
||||
// LockFile is the filename of the daemon lock, relative to config dir
|
||||
const LockFile = "daemon.lock"
|
||||
|
||||
// DaemonListener listens to an initialized IPFS node and can send it commands instead of
|
||||
// starting up a new set of connections
|
||||
type DaemonListener struct {
|
||||
node *core.IpfsNode
|
||||
list manet.Listener
|
||||
closed bool
|
||||
wg sync.WaitGroup
|
||||
lk io.Closer
|
||||
}
|
||||
|
||||
//Command accepts user input and can be sent to the running IPFS node
|
||||
type Command struct {
|
||||
Command string
|
||||
Args []string
|
||||
Opts map[string]interface{}
|
||||
}
|
||||
|
||||
func NewDaemonListener(ipfsnode *core.IpfsNode, addr ma.Multiaddr, confdir string) (*DaemonListener, error) {
|
||||
var err error
|
||||
confdir, err = u.TildeExpansion(confdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
lk, err := daemonLock(confdir)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ofi, err := os.Create(confdir + "/rpcaddress")
|
||||
if err != nil {
|
||||
log.Warningf("Could not create rpcaddress file: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
_, err = ofi.Write([]byte(addr.String()))
|
||||
if err != nil {
|
||||
log.Warningf("Could not write to rpcaddress file: %s", err)
|
||||
return nil, err
|
||||
}
|
||||
ofi.Close()
|
||||
|
||||
list, err := manet.Listen(addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
log.Info("New daemon listener initialized.")
|
||||
|
||||
return &DaemonListener{
|
||||
node: ipfsnode,
|
||||
list: list,
|
||||
lk: lk,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func NewCommand() *Command {
|
||||
return &Command{
|
||||
Opts: make(map[string]interface{}),
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *DaemonListener) Listen() {
|
||||
if dl.closed {
|
||||
panic("attempting to listen on a closed daemon Listener")
|
||||
}
|
||||
|
||||
// add ourselves to workgroup. and remove ourselves when done.
|
||||
dl.wg.Add(1)
|
||||
defer dl.wg.Done()
|
||||
|
||||
log.Info("daemon listening")
|
||||
for {
|
||||
conn, err := dl.list.Accept()
|
||||
if err != nil {
|
||||
if !dl.closed {
|
||||
log.Warning("DaemonListener Accept: %v", err)
|
||||
}
|
||||
return
|
||||
}
|
||||
go dl.handleConnection(conn)
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *DaemonListener) handleConnection(conn manet.Conn) {
|
||||
defer conn.Close()
|
||||
|
||||
dec := json.NewDecoder(conn)
|
||||
|
||||
var command Command
|
||||
err := dec.Decode(&command)
|
||||
if err != nil {
|
||||
fmt.Fprintln(conn, err)
|
||||
return
|
||||
}
|
||||
|
||||
log.Debugf("Got command: %v", command)
|
||||
switch command.Command {
|
||||
case "add":
|
||||
err = commands.Add(dl.node, command.Args, command.Opts, conn)
|
||||
case "cat":
|
||||
err = commands.Cat(dl.node, command.Args, command.Opts, conn)
|
||||
case "ls":
|
||||
err = commands.Ls(dl.node, command.Args, command.Opts, conn)
|
||||
case "pin":
|
||||
err = commands.Pin(dl.node, command.Args, command.Opts, conn)
|
||||
case "publish":
|
||||
err = commands.Publish(dl.node, command.Args, command.Opts, conn)
|
||||
case "resolve":
|
||||
err = commands.Resolve(dl.node, command.Args, command.Opts, conn)
|
||||
case "diag":
|
||||
err = commands.Diag(dl.node, command.Args, command.Opts, conn)
|
||||
case "blockGet":
|
||||
err = commands.BlockGet(dl.node, command.Args, command.Opts, conn)
|
||||
case "blockPut":
|
||||
err = commands.BlockPut(dl.node, command.Args, command.Opts, conn)
|
||||
case "log":
|
||||
err = commands.Log(dl.node, command.Args, command.Opts, conn)
|
||||
case "unpin":
|
||||
err = commands.Unpin(dl.node, command.Args, command.Opts, conn)
|
||||
case "updateApply":
|
||||
command.Opts["onDaemon"] = true
|
||||
err = commands.UpdateApply(dl.node, command.Args, command.Opts, conn)
|
||||
default:
|
||||
err = fmt.Errorf("Invalid Command: '%s'", command.Command)
|
||||
}
|
||||
if err != nil {
|
||||
log.Errorf("%s: %s", command.Command, err)
|
||||
fmt.Fprintln(conn, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (dl *DaemonListener) Close() error {
|
||||
dl.closed = true
|
||||
err := dl.list.Close()
|
||||
dl.wg.Wait() // wait till done before releasing lock.
|
||||
dl.lk.Close()
|
||||
return err
|
||||
}
|
||||
|
||||
func daemonLock(confdir string) (io.Closer, error) {
|
||||
return lock.Lock(path.Join(confdir, LockFile))
|
||||
}
|
@ -1,107 +0,0 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"io"
|
||||
"os"
|
||||
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
manet "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr/net"
|
||||
|
||||
u "github.com/jbenet/go-ipfs/util"
|
||||
)
|
||||
|
||||
// ErrDaemonNotRunning is returned when attempting to retrieve the daemon's
|
||||
// address and the daemon is not actually running.
|
||||
var ErrDaemonNotRunning = errors.New("daemon not running")
|
||||
|
||||
func getDaemonAddr(confdir string) (string, error) {
|
||||
var err error
|
||||
confdir, err = u.TildeExpansion(confdir)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
fi, err := os.Open(confdir + "/rpcaddress")
|
||||
if err != nil {
|
||||
log.Debugf("getDaemonAddr failed: %s", err)
|
||||
if err == os.ErrNotExist {
|
||||
return "", ErrDaemonNotRunning
|
||||
}
|
||||
return "", err
|
||||
}
|
||||
|
||||
read := bufio.NewReader(fi)
|
||||
|
||||
// TODO: operating system agostic line delim
|
||||
line, err := read.ReadBytes('\n')
|
||||
if err != nil && err != io.EOF {
|
||||
return "", err
|
||||
}
|
||||
return string(line), nil
|
||||
}
|
||||
|
||||
// SendCommand attempts to run the command over a currently-running daemon.
|
||||
// If there is no running daemon, returns ErrDaemonNotRunning. This is done
|
||||
// over network RPC API. The address of the daemon is retrieved from the config
|
||||
// directory, where live daemons write their addresses to special files.
|
||||
func SendCommand(command *Command, confdir string) error {
|
||||
server := os.Getenv("IPFS_ADDRESS_RPC")
|
||||
|
||||
if server == "" {
|
||||
//check if daemon is running
|
||||
log.Info("Checking if daemon is running...")
|
||||
if !serverIsRunning(confdir) {
|
||||
return ErrDaemonNotRunning
|
||||
}
|
||||
|
||||
log.Info("Daemon is running!")
|
||||
|
||||
var err error
|
||||
server, err = getDaemonAddr(confdir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return serverComm(server, command)
|
||||
}
|
||||
|
||||
func serverIsRunning(confdir string) bool {
|
||||
var err error
|
||||
confdir, err = u.TildeExpansion(confdir)
|
||||
if err != nil {
|
||||
log.Errorf("Tilde Expansion Failed: %s", err)
|
||||
return false
|
||||
}
|
||||
lk, err := daemonLock(confdir)
|
||||
if err == nil {
|
||||
lk.Close()
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func serverComm(server string, command *Command) error {
|
||||
log.Info("Daemon address: %s", server)
|
||||
maddr, err := ma.NewMultiaddr(server)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
conn, err := manet.Dial(maddr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
enc := json.NewEncoder(conn)
|
||||
err = enc.Encode(command)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
io.Copy(os.Stdout, conn)
|
||||
|
||||
return nil
|
||||
}
|
@ -1,86 +0,0 @@
|
||||
package daemon
|
||||
|
||||
import (
|
||||
"encoding/base64"
|
||||
"os"
|
||||
"testing"
|
||||
|
||||
ma "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multiaddr"
|
||||
config "github.com/jbenet/go-ipfs/config"
|
||||
core "github.com/jbenet/go-ipfs/core"
|
||||
ci "github.com/jbenet/go-ipfs/crypto"
|
||||
peer "github.com/jbenet/go-ipfs/peer"
|
||||
)
|
||||
|
||||
func TestInitializeDaemonListener(t *testing.T) {
|
||||
|
||||
priv, pub, err := ci.GenerateKeyPair(ci.RSA, 512)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
prbytes, err := priv.Bytes()
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
ident, _ := peer.IDFromPubKey(pub)
|
||||
privKey := base64.StdEncoding.EncodeToString(prbytes)
|
||||
pID := ident.Pretty()
|
||||
|
||||
id := config.Identity{
|
||||
PeerID: pID,
|
||||
PrivKey: privKey,
|
||||
}
|
||||
|
||||
nodeConfigs := []*config.Config{
|
||||
&config.Config{
|
||||
Identity: id,
|
||||
Datastore: config.Datastore{
|
||||
Type: "memory",
|
||||
},
|
||||
Addresses: config.Addresses{
|
||||
Swarm: "/ip4/0.0.0.0/tcp/4001",
|
||||
API: "/ip4/127.0.0.1/tcp/8000",
|
||||
},
|
||||
},
|
||||
|
||||
&config.Config{
|
||||
Identity: id,
|
||||
Datastore: config.Datastore{
|
||||
Type: "leveldb",
|
||||
Path: ".test/datastore",
|
||||
},
|
||||
Addresses: config.Addresses{
|
||||
Swarm: "/ip4/0.0.0.0/tcp/4001",
|
||||
API: "/ip4/127.0.0.1/tcp/8000",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var tempConfigDir = ".test"
|
||||
err = os.MkdirAll(tempConfigDir, os.ModeDir|0777)
|
||||
if err != nil {
|
||||
t.Fatalf("error making temp config dir: %v", err)
|
||||
}
|
||||
|
||||
for _, c := range nodeConfigs {
|
||||
|
||||
node, _ := core.NewIpfsNode(c, false)
|
||||
addr, err := ma.NewMultiaddr("/ip4/127.0.0.1/tcp/1327")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dl, initErr := NewDaemonListener(node, addr, tempConfigDir)
|
||||
if initErr != nil {
|
||||
t.Fatal(initErr)
|
||||
}
|
||||
|
||||
closeErr := dl.Close()
|
||||
if closeErr != nil {
|
||||
t.Fatal(closeErr)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user