mirror of
https://github.com/ipfs/kubo.git
synced 2025-06-16 23:58:45 +08:00
194 lines
4.3 KiB
Go
194 lines
4.3 KiB
Go
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"
|
|
u "github.com/jbenet/go-ipfs/util"
|
|
)
|
|
|
|
// 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:
|
|
|
|
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.
|
|
serve Serve an interface to ipfs.
|
|
|
|
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,
|
|
},
|
|
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 {
|
|
config = ""
|
|
}
|
|
CmdIpfs.Flag.String("c", config, "specify config directory")
|
|
}
|
|
|
|
func ipfsCmd(c *commander.Command, args []string) error {
|
|
u.POut(c.Long)
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
u.Debug = false
|
|
|
|
// setup logging
|
|
u.SetupLogging()
|
|
|
|
// if debugging, setup profiling.
|
|
if u.Debug {
|
|
ofi, err := os.Create("cpu.prof")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
pprof.StartCPUProfile(ofi)
|
|
defer ofi.Close()
|
|
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)
|
|
}
|
|
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
|
|
}
|
|
|
|
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) {
|
|
root := c
|
|
for root.Parent != nil {
|
|
root = root.Parent
|
|
}
|
|
conf := root.Flag.Lookup("c").Value.Get()
|
|
if conf == nil {
|
|
return config.PathRoot()
|
|
}
|
|
confStr, ok := conf.(string)
|
|
if !ok {
|
|
return "", errors.New("failed to retrieve config flag value")
|
|
}
|
|
if len(confStr) == 0 {
|
|
return config.PathRoot()
|
|
}
|
|
|
|
return u.TildeExpansion(confStr)
|
|
}
|
|
|
|
// 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 = c.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
|
|
}
|