Merge pull request #5825 from ipfs/feat/coreapi/opts

CoreAPI: Global offline option
This commit is contained in:
Steven Allen 2018-12-20 08:24:28 -08:00 committed by GitHub
commit 28dabc7349
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
44 changed files with 455 additions and 244 deletions

View File

@ -40,7 +40,7 @@ const (
ipnsMountKwd = "mount-ipns"
migrateKwd = "migrate"
mountKwd = "mount"
offlineKwd = "offline"
offlineKwd = "offline" // global option
routingOptionKwd = "routing"
routingOptionSupernodeKwd = "supernode"
routingOptionDHTClientKwd = "dhtclient"
@ -161,7 +161,6 @@ Headers.
cmdkit.BoolOption(unencryptTransportKwd, "Disable transport encryption (for debugging protocols)"),
cmdkit.BoolOption(enableGCKwd, "Enable automatic periodic repo garbage collection"),
cmdkit.BoolOption(adjustFDLimitKwd, "Check and raise file descriptor limits if needed").WithDefault(true),
cmdkit.BoolOption(offlineKwd, "Run offline. Do not connect to the rest of the network but provide local API."),
cmdkit.BoolOption(migrateKwd, "If true, assume yes at the migrate prompt. If false, assume no."),
cmdkit.BoolOption(enablePubSubKwd, "Instantiate the ipfs daemon with the experimental pubsub feature enabled."),
cmdkit.BoolOption(enableIPNSPubSubKwd, "Enable IPNS record distribution through pubsub; enables pubsub."),

View File

@ -68,7 +68,10 @@ func (c *Context) GetAPI() (coreiface.CoreAPI, error) {
if err != nil {
return nil, err
}
c.api = coreapi.NewCoreAPI(n)
c.api, err = coreapi.NewCoreAPI(n)
if err != nil {
return nil, err
}
}
return c.api, nil
}

View File

@ -139,7 +139,7 @@ You can now check what blocks have been created by:
return nil
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -160,7 +160,6 @@ You can now check what blocks have been created by:
inline, _ := req.Options[inlineOptionName].(bool)
inlineLimit, _ := req.Options[inlineLimitOptionName].(int)
pathName, _ := req.Options[stdinPathName].(string)
local, _ := req.Options["local"].(bool)
hashFunCode, ok := mh.Names[strings.ToLower(hashFunStr)]
if !ok {
@ -179,7 +178,6 @@ You can now check what blocks have been created by:
options.Unixfs.Pin(dopin),
options.Unixfs.HashOnly(hash),
options.Unixfs.Local(local),
options.Unixfs.FsCache(fscache),
options.Unixfs.Nocopy(nocopy),

View File

@ -60,7 +60,7 @@ on raw IPFS blocks. It outputs the following to stdout:
cmdkit.StringArg("key", true, false, "The base58 multihash of an existing block to stat.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -102,7 +102,7 @@ It outputs to stdout, and <key> is a base58 encoded multihash.
cmdkit.StringArg("key", true, false, "The base58 multihash of an existing block to get.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -148,7 +148,7 @@ than 'sha2-256' or format to anything other than 'v0' will result in CIDv1.
cmdkit.IntOption(mhlenOptionName, "multihash hash length").WithDefault(-1),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -218,7 +218,7 @@ It takes a list of base58 encoded multihashes to remove.
cmdkit.BoolOption(blockQuietOptionName, "q", "Write minimal output."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -34,7 +34,7 @@ var CatCmd = &cmds.Command{
cmdkit.Int64Option(lengthOptionName, "l", "Maximum number of bytes to read."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -2,15 +2,20 @@ package cmdenv
import (
"fmt"
"strings"
"github.com/ipfs/go-ipfs/commands"
"github.com/ipfs/go-ipfs/core"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
options "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
config "gx/ipfs/QmYyzmMnhNTtoXx5ttgUaRdHHckYnQWjPL98hgLAR2QLDD/go-ipfs-config"
cmds "gx/ipfs/QmaAP56JAwdjwisPTu4yx17whcjTr6y5JCSCF77Y1rahWV/go-ipfs-cmds"
logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
)
var log = logging.Logger("core/commands/cmdenv")
// GetNode extracts the node from the environment.
func GetNode(env interface{}) (*core.IpfsNode, error) {
ctx, ok := env.(*commands.Context)
@ -22,13 +27,28 @@ func GetNode(env interface{}) (*core.IpfsNode, error) {
}
// GetApi extracts CoreAPI instance from the environment.
func GetApi(env cmds.Environment) (coreiface.CoreAPI, error) {
func GetApi(env cmds.Environment, req *cmds.Request) (coreiface.CoreAPI, error) {
ctx, ok := env.(*commands.Context)
if !ok {
return nil, fmt.Errorf("expected env to be of type %T, got %T", ctx, env)
}
return ctx.GetAPI()
offline, _ := req.Options["offline"].(bool)
if !offline {
offline, _ = req.Options["local"].(bool)
if offline {
log.Errorf("Command '%s', --local is deprecated, use --offline instead", strings.Join(req.Path, " "))
}
}
api, err := ctx.GetAPI()
if err != nil {
return nil, err
}
if offline {
return api.WithOptions(options.Api.Offline(offline))
}
return api, nil
}
// GetConfig extracts the config from the environment.

View File

@ -124,7 +124,7 @@ var filesStatCmd = &cmds.Command{
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -308,7 +308,7 @@ var filesCpCmd = &cmds.Command{
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -71,7 +71,7 @@ var keyGenCmd = &cmds.Command{
cmdkit.StringArg("name", true, false, "name of key to create"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -121,7 +121,7 @@ var keyListCmd = &cmds.Command{
cmdkit.BoolOption("l", "Show extra information about keys."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -161,7 +161,7 @@ var keyRenameCmd = &cmds.Command{
cmdkit.BoolOption(keyStoreForceOptionName, "f", "Allow to overwrite an existing key."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -206,7 +206,7 @@ var keyRmCmd = &cmds.Command{
cmdkit.BoolOption("l", "Show extra information about keys."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -74,7 +74,7 @@ The JSON output contains type information.
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -80,13 +80,12 @@ Resolve the value of a dnslink:
cmdkit.BoolOption(streamOptionName, "s", "Stream entries as they are found."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
nocache, _ := req.Options["nocache"].(bool)
local, _ := req.Options["local"].(bool)
var name string
if len(req.Arguments) == 0 {
@ -105,7 +104,6 @@ Resolve the value of a dnslink:
stream, _ := req.Options[streamOptionName].(bool)
opts := []options.NameResolveOption{
options.Name.Local(local),
options.Name.Cache(!nocache),
}

View File

@ -83,7 +83,7 @@ Alternatively, publish an <ipfs-path> using a valid PeerID (as listed by
cmdkit.BoolOption(quieterOptionName, "Q", "Write only final hash."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -55,7 +55,7 @@ Example:
cmdkit.BoolOption(verboseOptionName, "v", "Print extra information."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -77,7 +77,7 @@ is the raw data of the object.
cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -114,7 +114,7 @@ multihash.
cmdkit.BoolOption("headers", "v", "Print table headers (Hash, Size, Name)."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -204,7 +204,7 @@ Supported values are:
cmdkit.StringOption("data-encoding", "Encoding type of the data field, either \"text\" or \"base64\".").WithDefault("text"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -294,7 +294,7 @@ var ObjectStatCmd = &cmds.Command{
cmdkit.StringArg("key", true, false, "Key of the object to retrieve, in base58-encoded multihash format.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -386,7 +386,7 @@ And then run:
cmdkit.BoolOption("quiet", "q", "Write minimal output."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -459,7 +459,7 @@ Available templates:
cmdkit.StringArg("template", false, false, "Template to use. Optional."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -50,7 +50,7 @@ the limit will not be respected by the network.
cmdkit.FileArg("data", true, false, "Data to append.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -97,7 +97,7 @@ Example:
cmdkit.FileArg("data", true, false, "The data to set the object to.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -140,7 +140,7 @@ Remove a Merkle-link from the given object and return the hash of the result.
cmdkit.StringArg("name", true, false, "Name of the link to remove."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -192,7 +192,7 @@ to a file containing 'bar', and returns the hash of the new object.
cmdkit.BoolOption("create", "p", "Create intermediary nodes."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -72,7 +72,7 @@ var addPinCmd = &cmds.Command{
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -88,7 +88,7 @@ var addPinCmd = &cmds.Command{
}
if !showProgress {
added, err := corerepo.Pin(n, api, req.Context, req.Arguments, recursive)
added, err := corerepo.Pin(n.Pinning, api, req.Context, req.Arguments, recursive)
if err != nil {
return err
}
@ -105,7 +105,7 @@ var addPinCmd = &cmds.Command{
ch := make(chan pinResult, 1)
go func() {
added, err := corerepo.Pin(n, api, ctx, req.Arguments, recursive)
added, err := corerepo.Pin(n.Pinning, api, ctx, req.Arguments, recursive)
ch <- pinResult{pins: added, err: err}
}()
@ -203,7 +203,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -215,7 +215,7 @@ collected if needed. (By default, recursively. Use -r=false for direct pins.)
return err
}
removed, err := corerepo.Unpin(n, api, req.Context, req.Arguments, recursive)
removed, err := corerepo.Unpin(n.Pinning, api, req.Context, req.Arguments, recursive)
if err != nil {
return err
}
@ -294,7 +294,7 @@ Example:
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -366,7 +366,7 @@ new pin and removing the old one.
},
Type: PinOutput{},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -78,7 +78,7 @@ This command outputs data in the following encodings:
cmdkit.BoolOption(pubsubDiscoverOptionName, "try to discover other peers subscribed to the same topic"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -153,7 +153,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'.
cmdkit.StringArg("data", true, true, "Payload of message to publish.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -188,7 +188,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'.
`,
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -234,7 +234,7 @@ To use, the daemon must be run with '--enable-pubsub-experiment'.
cmdkit.StringArg("topic", false, false, "topic to list connected peers of"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -74,7 +74,7 @@ Resolve the value of an IPFS DAG path:
cmdkit.StringOption(resolveDhtTimeoutOptionName, "dhtt", "Max time to collect values during DHT resolution eg \"30s\". Pass 0 for no timeout."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -18,10 +18,11 @@ var log = logging.Logger("core/commands")
var ErrNotOnline = errors.New("this command must be run in online mode. Try running 'ipfs daemon' first")
const (
ConfigOption = "config"
DebugOption = "debug"
LocalOption = "local"
ApiOption = "api"
ConfigOption = "config"
DebugOption = "debug"
LocalOption = "local" // DEPRECATED: use OfflineOption
OfflineOption = "offline"
ApiOption = "api"
)
var Root = &cmds.Command{
@ -92,7 +93,8 @@ The CLI will exit with one of the following values:
cmdkit.BoolOption(DebugOption, "D", "Operate in debug mode."),
cmdkit.BoolOption(cmds.OptLongHelp, "Show the full command help text."),
cmdkit.BoolOption(cmds.OptShortHelp, "Show a short version of the command help text."),
cmdkit.BoolOption(LocalOption, "L", "Run the command locally, instead of using the daemon."),
cmdkit.BoolOption(LocalOption, "L", "Run the command locally, instead of using the daemon. DEPRECATED: use --offline."),
cmdkit.BoolOption(OfflineOption, "Run the command offline."),
cmdkit.StringOption(ApiOption, "Use a specific API instance (defaults to /ip4/127.0.0.1/tcp/5001)"),
// global options, added to every command

View File

@ -71,7 +71,7 @@ var swarmPeersCmd = &cmds.Command{
cmdkit.BoolOption(swarmDirectionOptionName, "Also list information about the direction of connection"),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -221,7 +221,7 @@ var swarmAddrsCmd = &cmds.Command{
"listen": swarmAddrsListenCmd,
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -275,7 +275,7 @@ var swarmAddrsLocalCmd = &cmds.Command{
cmdkit.BoolOption("id", "Show peer ID in addresses."),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -316,7 +316,7 @@ var swarmAddrsListenCmd = &cmds.Command{
`,
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -355,7 +355,7 @@ ipfs swarm connect /ip4/104.131.131.82/tcp/4001/ipfs/QmaCpDMGvV2BGHeYERUEnRQAwe3
cmdkit.StringArg("address", true, true, "Address of peer to connect to.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}
@ -403,7 +403,7 @@ it will reconnect.
cmdkit.StringArg("address", true, true, "Address of peer to disconnect from.").EnableStdin(),
},
Run: func(req *cmds.Request, res cmds.ResponseEmitter, env cmds.Environment) error {
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -77,7 +77,7 @@ possible, please use 'ipfs ls' instead.
return err
}
api, err := cmdenv.GetApi(env)
api, err := cmdenv.GetApi(env, req)
if err != nil {
return err
}

View File

@ -82,6 +82,7 @@ const IpnsValidatorTag = "ipns"
const kReprovideFrequency = time.Hour * 12
const discoveryConnTimeout = time.Second * 30
const DefaultIpnsCacheSize = 128
var log = logging.Logger("core")
@ -601,7 +602,7 @@ func (n *IpfsNode) getCacheSize() (int, error) {
cs := cfg.Ipns.ResolveCacheSize
if cs == 0 {
cs = 128
cs = DefaultIpnsCacheSize
}
if cs < 0 {
return 0, fmt.Errorf("cannot specify negative resolve cache size")

View File

@ -43,7 +43,7 @@ func (api *BlockAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Bloc
return nil, err
}
err = api.node.Blocks.AddBlock(b)
err = api.blocks.AddBlock(b)
if err != nil {
return nil, err
}
@ -57,7 +57,7 @@ func (api *BlockAPI) Get(ctx context.Context, p coreiface.Path) (io.Reader, erro
return nil, err
}
b, err := api.node.Blocks.GetBlock(ctx, rp.Cid())
b, err := api.blocks.GetBlock(ctx, rp.Cid())
if err != nil {
return nil, err
}
@ -78,7 +78,7 @@ func (api *BlockAPI) Rm(ctx context.Context, p coreiface.Path, opts ...caopts.Bl
cids := []cid.Cid{rp.Cid()}
o := util.RmBlocksOpts{Force: settings.Force}
out, err := util.RmBlocks(api.node.Blockstore, api.node.Pinning, cids, o)
out, err := util.RmBlocks(api.blockstore, api.pinning, cids, o)
if err != nil {
return err
}
@ -109,7 +109,7 @@ func (api *BlockAPI) Stat(ctx context.Context, p coreiface.Path) (coreiface.Bloc
return nil, err
}
b, err := api.node.Blocks.GetBlock(ctx, rp.Cid())
b, err := api.blocks.GetBlock(ctx, rp.Cid())
if err != nil {
return nil, err
}

View File

@ -15,26 +15,74 @@ package coreapi
import (
"context"
core "github.com/ipfs/go-ipfs/core"
"errors"
"fmt"
"github.com/ipfs/go-ipfs/core"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
"github.com/ipfs/go-ipfs/namesys"
"github.com/ipfs/go-ipfs/pin"
"github.com/ipfs/go-ipfs/repo"
ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto"
"gx/ipfs/QmP2g3VxmC7g7fyRJDj1VJ72KHZbJ9UW24YjSWEj1XTb4H/go-ipfs-exchange-interface"
bserv "gx/ipfs/QmPoh3SrQzFBWtdGK6qmHDV4EanKR6kYPj4DD3J2NLoEmZ/go-blockservice"
"gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing"
"gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore"
"gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer"
offlinexch "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline"
pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore"
pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub"
ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
logging "gx/ipfs/QmcuXC5cxs79ro2cUuHs4HQ2bkDLJUYokwL8aivcX6HW3C/go-log"
dag "gx/ipfs/QmdV35UHnL1FM52baPkeUo6u7Fxm2CRUkPTLRPxeF8a4Ap/go-merkledag"
offlineroute "gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline"
record "gx/ipfs/QmfARXVCzpwFXQdepAJZuqyNDgV9doEsMnVCo1ssmuSe1U/go-libp2p-record"
p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host"
)
var log = logging.Logger("core/coreapi")
type CoreAPI struct {
node *core.IpfsNode
dag ipld.DAGService
nctx context.Context
identity peer.ID
privateKey ci.PrivKey
repo repo.Repo
blockstore blockstore.GCBlockstore
baseBlocks blockstore.Blockstore
pinning pin.Pinner
blocks bserv.BlockService
dag ipld.DAGService
peerstore pstore.Peerstore
peerHost p2phost.Host
recordValidator record.Validator
exchange exchange.Interface
namesys namesys.NameSystem
routing routing.IpfsRouting
pubSub *pubsub.PubSub
checkPublishAllowed func() error
checkOnline func(allowOffline bool) error
// ONLY for re-applying options in WithOptions, DO NOT USE ANYWHERE ELSE
nd *core.IpfsNode
parentOpts options.ApiSettings
}
// NewCoreAPI creates new instance of IPFS CoreAPI backed by go-ipfs Node.
func NewCoreAPI(n *core.IpfsNode) coreiface.CoreAPI {
api := &CoreAPI{n, n.DAG}
return api
func NewCoreAPI(n *core.IpfsNode, opts ...options.ApiOption) (coreiface.CoreAPI, error) {
parentOpts, err := options.ApiOptions()
if err != nil {
return nil, err
}
return (&CoreAPI{nd: n, parentOpts: *parentOpts}).WithOptions(opts...)
}
// Unixfs returns the UnixfsAPI interface implementation backed by the go-ipfs node
@ -87,8 +135,99 @@ func (api *CoreAPI) PubSub() coreiface.PubSubAPI {
return (*PubSubAPI)(api)
}
// WithOptions returns api with global options applied
func (api *CoreAPI) WithOptions(opts ...options.ApiOption) (coreiface.CoreAPI, error) {
settings := api.parentOpts // make sure to copy
_, err := options.ApiOptionsTo(&settings, opts...)
if err != nil {
return nil, err
}
if api.nd == nil {
return nil, errors.New("cannot apply options to api without node")
}
n := api.nd
subApi := &CoreAPI{
nctx: n.Context(),
identity: n.Identity,
privateKey: n.PrivateKey,
repo: n.Repo,
blockstore: n.Blockstore,
baseBlocks: n.BaseBlocks,
pinning: n.Pinning,
blocks: n.Blocks,
dag: n.DAG,
peerstore: n.Peerstore,
peerHost: n.PeerHost,
namesys: n.Namesys,
recordValidator: n.RecordValidator,
exchange: n.Exchange,
routing: n.Routing,
pubSub: n.PubSub,
nd: n,
parentOpts: settings,
}
subApi.checkOnline = func(allowOffline bool) error {
if !n.OnlineMode() && !allowOffline {
return coreiface.ErrOffline
}
return nil
}
subApi.checkPublishAllowed = func() error {
if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
return errors.New("cannot manually publish while IPNS is mounted")
}
return nil
}
if settings.Offline {
cfg, err := n.Repo.Config()
if err != nil {
return nil, err
}
cs := cfg.Ipns.ResolveCacheSize
if cs == 0 {
cs = core.DefaultIpnsCacheSize
}
if cs < 0 {
return nil, fmt.Errorf("cannot specify negative resolve cache size")
}
subApi.routing = offlineroute.NewOfflineRouter(subApi.repo.Datastore(), subApi.recordValidator)
subApi.namesys = namesys.NewNameSystem(subApi.routing, subApi.repo.Datastore(), cs)
subApi.peerstore = nil
subApi.peerHost = nil
subApi.namesys = nil
subApi.recordValidator = nil
subApi.exchange = offlinexch.Exchange(subApi.blockstore)
subApi.blocks = bserv.New(api.blockstore, subApi.exchange)
subApi.dag = dag.NewDAGService(subApi.blocks)
}
return subApi, nil
}
// getSession returns new api backed by the same node with a read-only session DAG
func (api *CoreAPI) getSession(ctx context.Context) *CoreAPI {
ng := dag.NewReadOnlyDagService(dag.NewSession(ctx, api.dag))
return &CoreAPI{api.node, ng}
sesApi := *api
// TODO: We could also apply this to api.blocks, and compose into writable api,
// but this requires some changes in blockservice/merkledag
sesApi.dag = dag.NewReadOnlyDagService(dag.NewSession(ctx, api.dag))
return &sesApi
}

View File

@ -2,7 +2,6 @@ package coreapi
import (
"context"
"errors"
"fmt"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
@ -22,7 +21,12 @@ import (
type DhtAPI CoreAPI
func (api *DhtAPI) FindPeer(ctx context.Context, p peer.ID) (pstore.PeerInfo, error) {
pi, err := api.node.Routing.FindPeer(ctx, peer.ID(p))
err := api.checkOnline(false)
if err != nil {
return pstore.PeerInfo{}, err
}
pi, err := api.routing.FindPeer(ctx, peer.ID(p))
if err != nil {
return pstore.PeerInfo{}, err
}
@ -36,6 +40,11 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ...
return nil, err
}
err = api.checkOnline(false)
if err != nil {
return nil, err
}
rp, err := api.core().ResolvePath(ctx, p)
if err != nil {
return nil, err
@ -46,7 +55,7 @@ func (api *DhtAPI) FindProviders(ctx context.Context, p coreiface.Path, opts ...
return nil, fmt.Errorf("number of providers must be greater than 0")
}
pchan := api.node.Routing.FindProvidersAsync(ctx, rp.Cid(), numProviders)
pchan := api.routing.FindProvidersAsync(ctx, rp.Cid(), numProviders)
return pchan, nil
}
@ -56,8 +65,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao
return err
}
if api.node.Routing == nil {
return errors.New("cannot provide in offline mode")
err = api.checkOnline(false)
if err != nil {
return err
}
rp, err := api.core().ResolvePath(ctx, path)
@ -67,7 +77,7 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao
c := rp.Cid()
has, err := api.node.Blockstore.Has(c)
has, err := api.blockstore.Has(c)
if err != nil {
return err
}
@ -77,9 +87,9 @@ func (api *DhtAPI) Provide(ctx context.Context, path coreiface.Path, opts ...cao
}
if settings.Recursive {
err = provideKeysRec(ctx, api.node.Routing, api.node.Blockstore, []cid.Cid{c})
err = provideKeysRec(ctx, api.routing, api.blockstore, []cid.Cid{c})
} else {
err = provideKeys(ctx, api.node.Routing, []cid.Cid{c})
err = provideKeys(ctx, api.routing, []cid.Cid{c})
}
if err != nil {
return err

View File

@ -5,6 +5,8 @@ package iface
import (
"context"
"github.com/ipfs/go-ipfs/core/coreapi/interface/options"
ipld "gx/ipfs/QmcKKBwfz6FyQdHR2jsXrrF6XeSBXYL86anmWNewpFpoF5/go-ipld-format"
)
@ -46,4 +48,8 @@ type CoreAPI interface {
// ResolveNode resolves the path (if not resolved already) using Unixfs
// resolver, gets and returns the resolved Node
ResolveNode(context.Context, Path) (ipld.Node, error)
// WithOptions creates new instance of CoreAPI based on this instance with
// a set of options applied
WithOptions(...options.ApiOption) (CoreAPI, error)
}

View File

@ -0,0 +1,36 @@
package options
type ApiSettings struct {
Offline bool
}
type ApiOption func(*ApiSettings) error
func ApiOptions(opts ...ApiOption) (*ApiSettings, error) {
options := &ApiSettings{
Offline: false,
}
return ApiOptionsTo(options, opts...)
}
func ApiOptionsTo(options *ApiSettings, opts ...ApiOption) (*ApiSettings, error) {
for _, opt := range opts {
err := opt(options)
if err != nil {
return nil, err
}
}
return options, nil
}
type apiOpts struct{}
var Api apiOpts
func (apiOpts) Offline(offline bool) ApiOption {
return func(settings *ApiSettings) error {
settings.Offline = offline
return nil
}
}

View File

@ -20,7 +20,6 @@ type NamePublishSettings struct {
}
type NameResolveSettings struct {
Local bool
Cache bool
ResolveOpts []ropts.ResolveOpt
@ -49,7 +48,6 @@ func NamePublishOptions(opts ...NamePublishOption) (*NamePublishSettings, error)
func NameResolveOptions(opts ...NameResolveOption) (*NameResolveSettings, error) {
options := &NameResolveSettings{
Local: false,
Cache: true,
}
@ -106,15 +104,6 @@ func (nameOpts) TTL(ttl time.Duration) NamePublishOption {
}
}
// Local is an option for Name.Resolve which specifies if the lookup should be
// offline. Default value is false
func (nameOpts) Local(local bool) NameResolveOption {
return func(settings *NameResolveSettings) error {
settings.Local = local
return nil
}
}
// Cache is an option for Name.Resolve which specifies if cache should be used.
// Default value is true
func (nameOpts) Cache(cache bool) NameResolveOption {

View File

@ -30,7 +30,6 @@ type UnixfsAddSettings struct {
Pin bool
OnlyHash bool
Local bool
FsCache bool
NoCopy bool
@ -60,7 +59,6 @@ func UnixfsAddOptions(opts ...UnixfsAddOption) (*UnixfsAddSettings, cid.Prefix,
Pin: false,
OnlyHash: false,
Local: false,
FsCache: false,
NoCopy: false,
@ -220,16 +218,6 @@ func (unixfsOpts) HashOnly(hashOnly bool) UnixfsAddOption {
}
}
// Local will add the data to blockstore without announcing it to the network
//
// Note that this doesn't prevent other nodes from getting this data
func (unixfsOpts) Local(local bool) UnixfsAddOption {
return func(settings *UnixfsAddSettings) error {
settings.Local = local
return nil
}
}
// Wrap tells the adder to wrap the added file structure with an additional
// directory.
func (unixfsOpts) Wrap(wrap bool) UnixfsAddOption {

View File

@ -54,7 +54,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
return nil, fmt.Errorf("cannot create key with name 'self'")
}
_, err = api.node.Repo.Keystore().Get(name)
_, err = api.repo.Keystore().Get(name)
if err == nil {
return nil, fmt.Errorf("key with name '%s' already exists", name)
}
@ -87,7 +87,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
return nil, fmt.Errorf("unrecognized key type: %s", options.Algorithm)
}
err = api.node.Repo.Keystore().Put(name, sk)
err = api.repo.Keystore().Put(name, sk)
if err != nil {
return nil, err
}
@ -102,7 +102,7 @@ func (api *KeyAPI) Generate(ctx context.Context, name string, opts ...caopts.Key
// List returns a list keys stored in keystore.
func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
keys, err := api.node.Repo.Keystore().List()
keys, err := api.repo.Keystore().List()
if err != nil {
return nil, err
}
@ -110,10 +110,10 @@ func (api *KeyAPI) List(ctx context.Context) ([]coreiface.Key, error) {
sort.Strings(keys)
out := make([]coreiface.Key, len(keys)+1)
out[0] = &key{"self", api.node.Identity}
out[0] = &key{"self", api.identity}
for n, k := range keys {
privKey, err := api.node.Repo.Keystore().Get(k)
privKey, err := api.repo.Keystore().Get(k)
if err != nil {
return nil, err
}
@ -138,7 +138,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o
return nil, false, err
}
ks := api.node.Repo.Keystore()
ks := api.repo.Keystore()
if oldName == "self" {
return nil, false, fmt.Errorf("cannot rename key with name 'self'")
@ -192,7 +192,7 @@ func (api *KeyAPI) Rename(ctx context.Context, oldName string, newName string, o
// Remove removes keys from keystore. Returns ipns path of the removed key.
func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, error) {
ks := api.node.Repo.Keystore()
ks := api.repo.Keystore()
if name == "self" {
return nil, fmt.Errorf("cannot remove key with name 'self'")
@ -219,9 +219,9 @@ func (api *KeyAPI) Remove(ctx context.Context, name string) (coreiface.Key, erro
}
func (api *KeyAPI) Self(ctx context.Context) (coreiface.Key, error) {
if api.node.Identity == "" {
if api.identity == "" {
return nil, errors.New("identity not loaded")
}
return &key{"self", api.node.Identity}, nil
return &key{"self", api.identity}, nil
}

View File

@ -2,21 +2,19 @@ package coreapi
import (
"context"
"errors"
"fmt"
"strings"
"time"
"github.com/ipfs/go-ipfs/core"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
"github.com/ipfs/go-ipfs/keystore"
"github.com/ipfs/go-ipfs/namesys"
"gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto"
ci "gx/ipfs/QmNiJiXwWE3kRhZrC5ej3kSjWHm337pYfhjLGSCDNKJP2s/go-libp2p-crypto"
"gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer"
ipath "gx/ipfs/QmZErC2Ay6WuGi96CPg316PwitdwgLo6RxZRqVjJjRj2MR/go-path"
"gx/ipfs/QmdmWkx54g7VfVyxeG8ic84uf4G6Eq1GohuyKA3XDuJ8oC/go-ipfs-routing/offline"
)
type NameAPI CoreAPI
@ -38,20 +36,18 @@ func (e *ipnsEntry) Value() coreiface.Path {
// Publish announces new IPNS name and returns the new IPNS entry.
func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopts.NamePublishOption) (coreiface.IpnsEntry, error) {
if err := api.checkPublishAllowed(); err != nil {
return nil, err
}
options, err := caopts.NamePublishOptions(opts...)
if err != nil {
return nil, err
}
n := api.node
if !n.OnlineMode() {
if !options.AllowOffline {
return nil, coreiface.ErrOffline
}
}
if n.Mounts.Ipns != nil && n.Mounts.Ipns.IsActive() {
return nil, errors.New("cannot manually publish while IPNS is mounted")
err = api.checkOnline(options.AllowOffline)
if err != nil {
return nil, err
}
pth, err := ipath.ParsePath(p.String())
@ -59,7 +55,7 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt
return nil, err
}
k, err := keylookup(n, options.Key)
k, err := keylookup(api.privateKey, api.repo.Keystore(), options.Key)
if err != nil {
return nil, err
}
@ -69,7 +65,7 @@ func (api *NameAPI) Publish(ctx context.Context, p coreiface.Path, opts ...caopt
}
eol := time.Now().Add(options.ValidTime)
err = n.Namesys.PublishWithEOL(ctx, k, pth, eol)
err = api.namesys.PublishWithEOL(ctx, k, pth, eol)
if err != nil {
return nil, err
}
@ -91,21 +87,15 @@ func (api *NameAPI) Search(ctx context.Context, name string, opts ...caopts.Name
return nil, err
}
n := api.node
var resolver namesys.Resolver = n.Namesys
if options.Local && !options.Cache {
return nil, errors.New("cannot specify both local and nocache")
err = api.checkOnline(true)
if err != nil {
return nil, err
}
if options.Local {
offroute := offline.NewOfflineRouter(n.Repo.Datastore(), n.RecordValidator)
resolver = namesys.NewIpnsResolver(offroute)
}
var resolver namesys.Resolver = api.namesys
if !options.Cache {
resolver = namesys.NewNameSystem(n.Routing, n.Repo.Datastore(), 0)
resolver = namesys.NewNameSystem(api.routing, api.repo.Datastore(), 0)
}
if !strings.HasPrefix(name, "/ipns/") {
@ -150,8 +140,12 @@ func (api *NameAPI) Resolve(ctx context.Context, name string, opts ...caopts.Nam
return p, err
}
func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) {
res, err := n.GetKey(k)
func keylookup(self ci.PrivKey, kstore keystore.Keystore, k string) (crypto.PrivKey, error) {
if k == "self" {
return self, nil
}
res, err := kstore.Get(k)
if res != nil {
return res, nil
}
@ -160,13 +154,13 @@ func keylookup(n *core.IpfsNode, k string) (crypto.PrivKey, error) {
return nil, err
}
keys, err := n.Repo.Keystore().List()
keys, err := kstore.List()
if err != nil {
return nil, err
}
for _, key := range keys {
privKey, err := n.Repo.Keystore().Get(key)
privKey, err := kstore.Get(key)
if err != nil {
return nil, err
}

View File

@ -118,7 +118,7 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj
}
if options.Pin {
defer api.node.Blockstore.PinLock().Unlock()
defer api.blockstore.PinLock().Unlock()
}
err = api.dag.Add(ctx, dagnode)
@ -127,8 +127,8 @@ func (api *ObjectAPI) Put(ctx context.Context, src io.Reader, opts ...caopts.Obj
}
if options.Pin {
api.node.Pinning.PinWithMode(dagnode.Cid(), pin.Recursive)
err = api.node.Pinning.Flush()
api.pinning.PinWithMode(dagnode.Cid(), pin.Recursive)
err = api.pinning.Flush()
if err != nil {
return nil, err
}

View File

@ -38,7 +38,7 @@ func (api *CoreAPI) ResolvePath(ctx context.Context, p coreiface.Path) (coreifac
}
ipath := ipfspath.Path(p.String())
ipath, err := core.ResolveIPNS(ctx, api.node.Namesys, ipath)
ipath, err := core.ResolveIPNS(ctx, api.namesys, ipath)
if err == core.ErrNoNamesys {
return nil, coreiface.ErrOffline
} else if err != nil {

View File

@ -27,14 +27,14 @@ func (api *PinAPI) Add(ctx context.Context, p coreiface.Path, opts ...caopts.Pin
return err
}
defer api.node.Blockstore.PinLock().Unlock()
defer api.blockstore.PinLock().Unlock()
_, err = corerepo.Pin(api.node, api.core(), ctx, []string{rp.Cid().String()}, settings.Recursive)
_, err = corerepo.Pin(api.pinning, api.core(), ctx, []string{rp.Cid().String()}, settings.Recursive)
if err != nil {
return err
}
return api.node.Pinning.Flush()
return api.pinning.Flush()
}
func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreiface.Pin, error) {
@ -53,12 +53,12 @@ func (api *PinAPI) Ls(ctx context.Context, opts ...caopts.PinLsOption) ([]coreif
}
func (api *PinAPI) Rm(ctx context.Context, p coreiface.Path) error {
_, err := corerepo.Unpin(api.node, api.core(), ctx, []string{p.String()}, true)
_, err := corerepo.Unpin(api.pinning, api.core(), ctx, []string{p.String()}, true)
if err != nil {
return err
}
return api.node.Pinning.Flush()
return api.pinning.Flush()
}
func (api *PinAPI) Update(ctx context.Context, from coreiface.Path, to coreiface.Path, opts ...caopts.PinUpdateOption) error {
@ -77,14 +77,14 @@ func (api *PinAPI) Update(ctx context.Context, from coreiface.Path, to coreiface
return err
}
defer api.node.Blockstore.PinLock().Unlock()
defer api.blockstore.PinLock().Unlock()
err = api.node.Pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin)
err = api.pinning.Update(ctx, fp.Cid(), tp.Cid(), settings.Unpin)
if err != nil {
return err
}
return api.node.Pinning.Flush()
return api.pinning.Flush()
}
type pinStatus struct {
@ -117,10 +117,10 @@ func (n *badNode) Err() error {
func (api *PinAPI) Verify(ctx context.Context) (<-chan coreiface.PinStatus, error) {
visited := make(map[cid.Cid]*pinStatus)
bs := api.node.Blocks.Blockstore()
bs := api.blockstore
DAG := merkledag.NewDAGService(bserv.New(bs, offline.Exchange(bs)))
getLinks := merkledag.GetLinksWithDAG(DAG)
recPins := api.node.Pinning.RecursiveKeys()
recPins := api.pinning.RecursiveKeys()
var checkPin func(root cid.Cid) *pinStatus
checkPin = func(root cid.Cid) *pinStatus {
@ -187,11 +187,11 @@ func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pi
}
if typeStr == "direct" || typeStr == "all" {
AddToResultKeys(api.node.Pinning.DirectKeys(), "direct")
AddToResultKeys(api.pinning.DirectKeys(), "direct")
}
if typeStr == "indirect" || typeStr == "all" {
set := cid.NewSet()
for _, k := range api.node.Pinning.RecursiveKeys() {
for _, k := range api.pinning.RecursiveKeys() {
err := merkledag.EnumerateChildren(ctx, merkledag.GetLinksWithDAG(api.dag), k, set.Visit)
if err != nil {
return nil, err
@ -200,7 +200,7 @@ func (api *PinAPI) pinLsAll(typeStr string, ctx context.Context) ([]coreiface.Pi
AddToResultKeys(set.Keys(), "indirect")
}
if typeStr == "recursive" || typeStr == "all" {
AddToResultKeys(api.node.Pinning.RecursiveKeys(), "recursive")
AddToResultKeys(api.pinning.RecursiveKeys(), "recursive")
}
out := make([]coreiface.Pin, 0, len(keys))

View File

@ -7,14 +7,15 @@ import (
"sync"
"time"
core "github.com/ipfs/go-ipfs/core"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
caopts "github.com/ipfs/go-ipfs/core/coreapi/interface/options"
cid "gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
routing "gx/ipfs/QmRASJXJUFygM5qU4YrH7k7jD6S4Hg8nJmgqJ4bYJvLatd/go-libp2p-routing"
peer "gx/ipfs/QmY5Grm8pJdiSSVsYxx4uNRgweY72EmYwuSDbRnbFok3iY/go-libp2p-peer"
pstore "gx/ipfs/QmZ9zH2FnLcxv1xyzFeUpDUeo55xEhZQHgveZijcxr7TLj/go-libp2p-peerstore"
pubsub "gx/ipfs/QmaqGyUhWLsJbVo1QAujSu13mxNjFJ98Kt2VWGSnShGE1Q/go-libp2p-pubsub"
p2phost "gx/ipfs/QmfD51tKgJiTMnW9JEiDiPwsCY4mqUoxkhKhBfyW12spTC/go-libp2p-host"
)
type PubSubAPI CoreAPI
@ -29,15 +30,17 @@ type pubSubMessage struct {
}
func (api *PubSubAPI) Ls(ctx context.Context) ([]string, error) {
if err := api.checkNode(); err != nil {
_, err := api.checkNode()
if err != nil {
return nil, err
}
return api.node.PubSub.GetTopics(), nil
return api.pubSub.GetTopics(), nil
}
func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOption) ([]peer.ID, error) {
if err := api.checkNode(); err != nil {
_, err := api.checkNode()
if err != nil {
return nil, err
}
@ -46,7 +49,7 @@ func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio
return nil, err
}
peers := api.node.PubSub.ListPeers(settings.Topic)
peers := api.pubSub.ListPeers(settings.Topic)
out := make([]peer.ID, len(peers))
for i, peer := range peers {
@ -57,26 +60,28 @@ func (api *PubSubAPI) Peers(ctx context.Context, opts ...caopts.PubSubPeersOptio
}
func (api *PubSubAPI) Publish(ctx context.Context, topic string, data []byte) error {
if err := api.checkNode(); err != nil {
_, err := api.checkNode()
if err != nil {
return err
}
return api.node.PubSub.Publish(topic, data)
return api.pubSub.Publish(topic, data)
}
func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopts.PubSubSubscribeOption) (coreiface.PubSubSubscription, error) {
options, err := caopts.PubSubSubscribeOptions(opts...)
if err := api.checkNode(); err != nil {
return nil, err
}
sub, err := api.node.PubSub.Subscribe(topic)
r, err := api.checkNode()
if err != nil {
return nil, err
}
pubctx, cancel := context.WithCancel(api.node.Context())
sub, err := api.pubSub.Subscribe(topic)
if err != nil {
return nil, err
}
pubctx, cancel := context.WithCancel(api.nctx)
if options.Discover {
go func() {
@ -86,18 +91,18 @@ func (api *PubSubAPI) Subscribe(ctx context.Context, topic string, opts ...caopt
return
}
connectToPubSubPeers(pubctx, api.node, blk.Path().Cid())
connectToPubSubPeers(pubctx, r, api.peerHost, blk.Path().Cid())
}()
}
return &pubSubSubscription{cancel, sub}, nil
}
func connectToPubSubPeers(ctx context.Context, n *core.IpfsNode, cid cid.Cid) {
func connectToPubSubPeers(ctx context.Context, r routing.IpfsRouting, ph p2phost.Host, cid cid.Cid) {
ctx, cancel := context.WithCancel(ctx)
defer cancel()
provs := n.Routing.FindProvidersAsync(ctx, cid, 10)
provs := r.FindProvidersAsync(ctx, cid, 10)
var wg sync.WaitGroup
for p := range provs {
wg.Add(1)
@ -105,7 +110,7 @@ func connectToPubSubPeers(ctx context.Context, n *core.IpfsNode, cid cid.Cid) {
defer wg.Done()
ctx, cancel := context.WithTimeout(ctx, time.Second*10)
defer cancel()
err := n.PeerHost.Connect(ctx, pi)
err := ph.Connect(ctx, pi)
if err != nil {
log.Info("pubsub discover: ", err)
return
@ -117,16 +122,17 @@ func connectToPubSubPeers(ctx context.Context, n *core.IpfsNode, cid cid.Cid) {
wg.Wait()
}
func (api *PubSubAPI) checkNode() error {
if !api.node.OnlineMode() {
return coreiface.ErrOffline
func (api *PubSubAPI) checkNode() (routing.IpfsRouting, error) {
if api.pubSub == nil {
return nil, errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.")
}
if api.node.PubSub == nil {
return errors.New("experimental pubsub feature not enabled. Run daemon with --enable-pubsub-experiment to use.")
err := api.checkOnline(false)
if err != nil {
return nil, err
}
return nil
return api.routing, nil
}
func (sub *pubSubSubscription) Close() error {

View File

@ -5,7 +5,6 @@ import (
"sort"
"time"
core "github.com/ipfs/go-ipfs/core"
coreiface "github.com/ipfs/go-ipfs/core/coreapi/interface"
inet "gx/ipfs/QmPtFaR7BWHLAjSwLh9kXcyrgTzDpuhcWLkx8ioa9RMYnx/go-libp2p-net"
@ -21,9 +20,9 @@ import (
type SwarmAPI CoreAPI
type connInfo struct {
node *core.IpfsNode
conn net.Conn
dir net.Direction
peerstore pstore.Peerstore
conn net.Conn
dir net.Direction
addr ma.Multiaddr
peer peer.ID
@ -31,19 +30,19 @@ type connInfo struct {
}
func (api *SwarmAPI) Connect(ctx context.Context, pi pstore.PeerInfo) error {
if api.node.PeerHost == nil {
if api.peerHost == nil {
return coreiface.ErrOffline
}
if swrm, ok := api.node.PeerHost.Network().(*swarm.Swarm); ok {
if swrm, ok := api.peerHost.Network().(*swarm.Swarm); ok {
swrm.Backoff().Clear(pi.ID)
}
return api.node.PeerHost.Connect(ctx, pi)
return api.peerHost.Connect(ctx, pi)
}
func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error {
if api.node.PeerHost == nil {
if api.peerHost == nil {
return coreiface.ErrOffline
}
@ -54,7 +53,7 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error {
taddr := ia.Transport()
id := ia.ID()
net := api.node.PeerHost.Network()
net := api.peerHost.Network()
if taddr == nil {
if net.Connectedness(id) != inet.Connected {
@ -78,12 +77,12 @@ func (api *SwarmAPI) Disconnect(ctx context.Context, addr ma.Multiaddr) error {
}
func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, error) {
if api.node.PeerHost == nil {
if api.peerHost == nil {
return nil, coreiface.ErrOffline
}
addrs := make(map[peer.ID][]ma.Multiaddr)
ps := api.node.PeerHost.Network().Peerstore()
ps := api.peerHost.Network().Peerstore()
for _, p := range ps.Peers() {
for _, a := range ps.Addrs(p) {
addrs[p] = append(addrs[p], a)
@ -97,27 +96,27 @@ func (api *SwarmAPI) KnownAddrs(context.Context) (map[peer.ID][]ma.Multiaddr, er
}
func (api *SwarmAPI) LocalAddrs(context.Context) ([]ma.Multiaddr, error) {
if api.node.PeerHost == nil {
if api.peerHost == nil {
return nil, coreiface.ErrOffline
}
return api.node.PeerHost.Addrs(), nil
return api.peerHost.Addrs(), nil
}
func (api *SwarmAPI) ListenAddrs(context.Context) ([]ma.Multiaddr, error) {
if api.node.PeerHost == nil {
if api.peerHost == nil {
return nil, coreiface.ErrOffline
}
return api.node.PeerHost.Network().InterfaceListenAddresses()
return api.peerHost.Network().InterfaceListenAddresses()
}
func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error) {
if api.node.PeerHost == nil {
if api.peerHost == nil {
return nil, coreiface.ErrOffline
}
conns := api.node.PeerHost.Network().Conns()
conns := api.peerHost.Network().Conns()
var out []coreiface.ConnectionInfo
for _, c := range conns {
@ -125,9 +124,9 @@ func (api *SwarmAPI) Peers(context.Context) ([]coreiface.ConnectionInfo, error)
addr := c.RemoteMultiaddr()
ci := &connInfo{
node: api.node,
conn: c,
dir: c.Stat().Direction,
peerstore: api.peerstore,
conn: c,
dir: c.Stat().Direction,
addr: addr,
peer: pid,
@ -160,7 +159,7 @@ func (ci *connInfo) Direction() net.Direction {
}
func (ci *connInfo) Latency() (time.Duration, error) {
return ci.node.Peerstore.LatencyEWMA(peer.ID(ci.ID())), nil
return ci.peerstore.LatencyEWMA(peer.ID(ci.ID())), nil
}
func (ci *connInfo) Streams() ([]protocol.ID, error) {

View File

@ -15,7 +15,6 @@ import (
bstore "gx/ipfs/QmS2aqUZLJp8kF1ihE5rvDGE5LvmKDPnx32w9Z1BW9xLV5/go-ipfs-blockstore"
mfs "gx/ipfs/QmU3iDRUrxyTYdV2j5MuWLFvP1k7w98vD66PLnNChgvUmZ/go-mfs"
files "gx/ipfs/QmXWZCd8jfaHmt4UDSnjKmGcrQMw95bDGWqEeVLVJjoANX/go-ipfs-files"
offline "gx/ipfs/QmYZwey1thDTynSrvd6qQkX24UpTka6TFhQ2v569UpoqxD/go-ipfs-exchange-offline"
cidutil "gx/ipfs/QmbfKu17LbMWyGUxHEUns9Wf5Dkm8PT6be4uPhTkk4YvaV/go-cidutil"
ft "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs"
uio "gx/ipfs/Qmbvw7kpSM2p6rbQ57WGRhhqNfCiNGW6EKH4xgHLw4bsnB/go-unixfs/io"
@ -34,9 +33,7 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options
return nil, err
}
n := api.node
cfg, err := n.Repo.Config()
cfg, err := api.repo.Config()
if err != nil {
return nil, err
}
@ -53,6 +50,13 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options
return nil, filestore.ErrFilestoreNotEnabled
}
addblockstore := api.blockstore
if !(settings.FsCache || settings.NoCopy) {
addblockstore = bstore.NewGCBlockstore(api.baseBlocks, api.blockstore)
}
exch := api.exchange
pinning := api.pinning
if settings.OnlyHash {
nilnode, err := core.NewNode(ctx, &core.BuildCfg{
//TODO: need this to be true or all files
@ -62,23 +66,15 @@ func (api *UnixfsAPI) Add(ctx context.Context, files files.Node, opts ...options
if err != nil {
return nil, err
}
n = nilnode
}
addblockstore := n.Blockstore
if !(settings.FsCache || settings.NoCopy) {
addblockstore = bstore.NewGCBlockstore(n.BaseBlocks, n.GCLocker)
}
exch := n.Exchange
if settings.Local {
exch = offline.Exchange(addblockstore)
addblockstore = nilnode.Blockstore
exch = nilnode.Exchange
pinning = nilnode.Pinning
}
bserv := blockservice.New(addblockstore, exch) // hash security 001
dserv := dag.NewDAGService(bserv)
fileAdder, err := coreunix.NewAdder(ctx, n.Pinning, n.Blockstore, dserv)
fileAdder, err := coreunix.NewAdder(ctx, pinning, addblockstore, dserv)
if err != nil {
return nil, err
}

View File

@ -102,7 +102,10 @@ func makeAPISwarm(ctx context.Context, fullIdentity bool, n int) ([]*core.IpfsNo
return nil, nil, err
}
nodes[i] = node
apis[i] = coreapi.NewCoreAPI(node)
apis[i], err = coreapi.NewCoreAPI(node)
if err != nil {
return nil, nil, err
}
}
err := mn.LinkAll()
@ -180,6 +183,8 @@ func TestAdd(t *testing.T) {
data func() files.Node
expect func(files.Node) files.Node
apiOpts []options.ApiOption
path string
err string
@ -267,10 +272,10 @@ func TestAdd(t *testing.T) {
},
// Local
{
name: "addLocal", // better cases in sharness
data: strFile(helloStr),
path: hello,
opts: []options.UnixfsAddOption{options.Unixfs.Local(true)},
name: "addLocal", // better cases in sharness
data: strFile(helloStr),
path: hello,
apiOpts: []options.ApiOption{options.Api.Offline(true)},
},
{
name: "hashOnly", // test (non)fetchability
@ -508,9 +513,14 @@ func TestAdd(t *testing.T) {
}()
}
tapi, err := api.WithOptions(testCase.apiOpts...)
if err != nil {
t.Fatal(err)
}
// Add!
p, err := api.Unixfs().Add(ctx, data, opts...)
p, err := tapi.Unixfs().Add(ctx, data, opts...)
close(eventOut)
evtWg.Wait()
if testCase.err != "" {
@ -591,7 +601,7 @@ func TestAdd(t *testing.T) {
}
}
f, err := api.Unixfs().Get(ctx, p)
f, err := tapi.Unixfs().Get(ctx, p)
if err != nil {
t.Fatal(err)
}

View File

@ -25,11 +25,16 @@ func GatewayOption(writable bool, paths ...string) ServeOption {
return nil, err
}
api, err := coreapi.NewCoreAPI(n)
if err != nil {
return nil, err
}
gateway := newGatewayHandler(n, GatewayConfig{
Headers: cfg.Gateway.HTTPHeaders,
Writable: writable,
PathPrefixes: cfg.Gateway.PathPrefixes,
}, coreapi.NewCoreAPI(n))
}, api)
for _, p := range paths {
mux.Handle(p+"/", gateway)

View File

@ -16,14 +16,14 @@ package corerepo
import (
"context"
"fmt"
"github.com/ipfs/go-ipfs/pin"
"github.com/ipfs/go-ipfs/core"
"github.com/ipfs/go-ipfs/core/coreapi/interface"
"gx/ipfs/QmR8BauakNcBa3RbE4nbQu76PDiJgoQgz8AJdhJuiU4TAw/go-cid"
)
func Pin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
func Pin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
out := make([]cid.Cid, len(paths))
for i, fpath := range paths {
@ -36,14 +36,14 @@ func Pin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []strin
if err != nil {
return nil, fmt.Errorf("pin: %s", err)
}
err = n.Pinning.Pin(ctx, dagnode, recursive)
err = pinning.Pin(ctx, dagnode, recursive)
if err != nil {
return nil, fmt.Errorf("pin: %s", err)
}
out[i] = dagnode.Cid()
}
err := n.Pinning.Flush()
err := pinning.Flush()
if err != nil {
return nil, err
}
@ -51,7 +51,7 @@ func Pin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []strin
return out, nil
}
func Unpin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
func Unpin(pinning pin.Pinner, api iface.CoreAPI, ctx context.Context, paths []string, recursive bool) ([]cid.Cid, error) {
unpinned := make([]cid.Cid, len(paths))
for i, p := range paths {
@ -65,14 +65,14 @@ func Unpin(n *core.IpfsNode, api iface.CoreAPI, ctx context.Context, paths []str
return nil, err
}
err = n.Pinning.Unpin(ctx, k.Cid(), recursive)
err = pinning.Unpin(ctx, k.Cid(), recursive)
if err != nil {
return nil, err
}
unpinned[i] = k.Cid()
}
err := n.Pinning.Flush()
err := pinning.Flush()
if err != nil {
return nil, err
}

View File

@ -48,13 +48,13 @@ type Object struct {
}
// NewAdder Returns a new Adder used for a file add operation.
func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds ipld.DAGService) (*Adder, error) {
func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCLocker, ds ipld.DAGService) (*Adder, error) {
bufferedDS := ipld.NewBufferedDAG(ctx, ds)
return &Adder{
ctx: ctx,
pinning: p,
blockstore: bs,
gcLocker: bs,
dagService: ds,
bufferedDS: bufferedDS,
Progress: false,
@ -70,7 +70,7 @@ func NewAdder(ctx context.Context, p pin.Pinner, bs bstore.GCBlockstore, ds ipld
type Adder struct {
ctx context.Context
pinning pin.Pinner
blockstore bstore.GCBlockstore
gcLocker bstore.GCLocker
dagService ipld.DAGService
bufferedDS *ipld.BufferedDAG
Out chan<- interface{}
@ -401,7 +401,7 @@ func (adder *Adder) addNode(node ipld.Node, path string) error {
// AddAllAndPin adds the given request's files and pin them.
func (adder *Adder) AddAllAndPin(file files.Node) (ipld.Node, error) {
if adder.Pin {
adder.unlocker = adder.blockstore.PinLock()
adder.unlocker = adder.gcLocker.PinLock()
}
defer func() {
if adder.unlocker != nil {
@ -556,14 +556,14 @@ func (adder *Adder) addDir(path string, dir files.Directory) error {
}
func (adder *Adder) maybePauseForGC() error {
if adder.unlocker != nil && adder.blockstore.GCRequested() {
if adder.unlocker != nil && adder.gcLocker.GCRequested() {
err := adder.PinRoot()
if err != nil {
return err
}
adder.unlocker.Unlock()
adder.unlocker = adder.blockstore.PinLock()
adder.unlocker = adder.gcLocker.PinLock()
}
return nil
}

View File

@ -118,7 +118,10 @@ func TestIpfsStressRead(t *testing.T) {
nd, mnt := setupIpfsTest(t, nil)
defer mnt.Close()
api := coreapi.NewCoreAPI(nd)
api, err := coreapi.NewCoreAPI(nd)
if err != nil {
t.Fatal(err)
}
var nodes []ipld.Node
var paths []string

View File

@ -120,7 +120,10 @@ func DirectAddCat(data []byte, conf testutil.LatencyConfig) error {
}
defer catter.Close()
catterApi := coreapi.NewCoreAPI(catter)
catterApi, err := coreapi.NewCoreAPI(catter)
if err != nil {
return err
}
err = mn.LinkAll()
if err != nil {

View File

@ -66,7 +66,10 @@ func benchCat(b *testing.B, data []byte, conf testutil.LatencyConfig) error {
}
defer catter.Close()
catterApi := coreapi.NewCoreAPI(catter)
catterApi, err := coreapi.NewCoreAPI(catter)
if err != nil {
return err
}
err = mn.LinkAll()
if err != nil {

View File

@ -103,7 +103,10 @@ func RunThreeLeggedCat(data []byte, conf testutil.LatencyConfig) error {
}
defer catter.Close()
catterApi := coreapi.NewCoreAPI(catter)
catterApi, err := coreapi.NewCoreAPI(catter)
if err != nil {
return err
}
mn.LinkAll()