diff --git a/cmd/ipfs/daemon.go b/cmd/ipfs/daemon.go index a1be01c6d..e4c891053 100644 --- a/cmd/ipfs/daemon.go +++ b/cmd/ipfs/daemon.go @@ -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."), diff --git a/commands/context.go b/commands/context.go index 41d6b05d0..29fe652f1 100644 --- a/commands/context.go +++ b/commands/context.go @@ -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 } diff --git a/core/commands/add.go b/core/commands/add.go index 148e3a76b..a992eaeb8 100644 --- a/core/commands/add.go +++ b/core/commands/add.go @@ -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), diff --git a/core/commands/block.go b/core/commands/block.go index a95f9d930..52d7a7b96 100644 --- a/core/commands/block.go +++ b/core/commands/block.go @@ -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 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 } diff --git a/core/commands/cat.go b/core/commands/cat.go index fe25d6dc7..663f75b3c 100644 --- a/core/commands/cat.go +++ b/core/commands/cat.go @@ -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 } diff --git a/core/commands/cmdenv/env.go b/core/commands/cmdenv/env.go index c30cd13f8..290239381 100644 --- a/core/commands/cmdenv/env.go +++ b/core/commands/cmdenv/env.go @@ -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. diff --git a/core/commands/files.go b/core/commands/files.go index 2f98fb083..5ca77a604 100644 --- a/core/commands/files.go +++ b/core/commands/files.go @@ -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 } diff --git a/core/commands/keystore.go b/core/commands/keystore.go index 2a8ecc81a..7c1517851 100644 --- a/core/commands/keystore.go +++ b/core/commands/keystore.go @@ -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 } diff --git a/core/commands/ls.go b/core/commands/ls.go index 09009eee2..5c65cfaed 100644 --- a/core/commands/ls.go +++ b/core/commands/ls.go @@ -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 } diff --git a/core/commands/name/ipns.go b/core/commands/name/ipns.go index 6187419df..4e18d2ade 100644 --- a/core/commands/name/ipns.go +++ b/core/commands/name/ipns.go @@ -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), } diff --git a/core/commands/name/publish.go b/core/commands/name/publish.go index 7d083b245..72f874ba2 100644 --- a/core/commands/name/publish.go +++ b/core/commands/name/publish.go @@ -83,7 +83,7 @@ Alternatively, publish an 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 } diff --git a/core/commands/object/diff.go b/core/commands/object/diff.go index b37b3375d..d1170ae3b 100644 --- a/core/commands/object/diff.go +++ b/core/commands/object/diff.go @@ -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 } diff --git a/core/commands/object/object.go b/core/commands/object/object.go index 0640a7d6d..bbe2ffb29 100644 --- a/core/commands/object/object.go +++ b/core/commands/object/object.go @@ -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 } diff --git a/core/commands/object/patch.go b/core/commands/object/patch.go index a7c598898..88eeb7a9f 100644 --- a/core/commands/object/patch.go +++ b/core/commands/object/patch.go @@ -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 } diff --git a/core/commands/pin.go b/core/commands/pin.go index c7be82a8e..7ad571d64 100644 --- a/core/commands/pin.go +++ b/core/commands/pin.go @@ -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 } diff --git a/core/commands/pubsub.go b/core/commands/pubsub.go index a69a6ec82..c9ae8bc17 100644 --- a/core/commands/pubsub.go +++ b/core/commands/pubsub.go @@ -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 } diff --git a/core/commands/resolve.go b/core/commands/resolve.go index 61b826941..32a5b47ca 100644 --- a/core/commands/resolve.go +++ b/core/commands/resolve.go @@ -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 } diff --git a/core/commands/root.go b/core/commands/root.go index ce9fdafa1..798fc1732 100644 --- a/core/commands/root.go +++ b/core/commands/root.go @@ -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 diff --git a/core/commands/swarm.go b/core/commands/swarm.go index 3c25855ef..75938c89b 100644 --- a/core/commands/swarm.go +++ b/core/commands/swarm.go @@ -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 } diff --git a/core/commands/unixfs/ls.go b/core/commands/unixfs/ls.go index b7090c688..0f8ab95ca 100644 --- a/core/commands/unixfs/ls.go +++ b/core/commands/unixfs/ls.go @@ -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 } diff --git a/core/core.go b/core/core.go index 6a146bb20..fe75ad5ea 100644 --- a/core/core.go +++ b/core/core.go @@ -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") diff --git a/core/coreapi/block.go b/core/coreapi/block.go index 933d5de72..fafd24755 100644 --- a/core/coreapi/block.go +++ b/core/coreapi/block.go @@ -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 } diff --git a/core/coreapi/coreapi.go b/core/coreapi/coreapi.go index b27a7cfed..b927cea59 100644 --- a/core/coreapi/coreapi.go +++ b/core/coreapi/coreapi.go @@ -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 } diff --git a/core/coreapi/dht.go b/core/coreapi/dht.go index ce94e8ca7..4b0616566 100644 --- a/core/coreapi/dht.go +++ b/core/coreapi/dht.go @@ -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 diff --git a/core/coreapi/interface/coreapi.go b/core/coreapi/interface/coreapi.go index bab4fc13b..226399967 100644 --- a/core/coreapi/interface/coreapi.go +++ b/core/coreapi/interface/coreapi.go @@ -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) } diff --git a/core/coreapi/interface/options/global.go b/core/coreapi/interface/options/global.go new file mode 100644 index 000000000..93d635e41 --- /dev/null +++ b/core/coreapi/interface/options/global.go @@ -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 + } +} diff --git a/core/coreapi/interface/options/name.go b/core/coreapi/interface/options/name.go index c614db3ab..e2a0fc164 100644 --- a/core/coreapi/interface/options/name.go +++ b/core/coreapi/interface/options/name.go @@ -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 { diff --git a/core/coreapi/interface/options/unixfs.go b/core/coreapi/interface/options/unixfs.go index b771896bc..fd748bb4a 100644 --- a/core/coreapi/interface/options/unixfs.go +++ b/core/coreapi/interface/options/unixfs.go @@ -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 { diff --git a/core/coreapi/key.go b/core/coreapi/key.go index 30c26ada9..cf0411046 100644 --- a/core/coreapi/key.go +++ b/core/coreapi/key.go @@ -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 } diff --git a/core/coreapi/name.go b/core/coreapi/name.go index e30801317..e986567b5 100644 --- a/core/coreapi/name.go +++ b/core/coreapi/name.go @@ -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 } diff --git a/core/coreapi/object.go b/core/coreapi/object.go index 9e18d479b..f343a8e00 100644 --- a/core/coreapi/object.go +++ b/core/coreapi/object.go @@ -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 } diff --git a/core/coreapi/path.go b/core/coreapi/path.go index 93d39cd1e..a5706fee1 100644 --- a/core/coreapi/path.go +++ b/core/coreapi/path.go @@ -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 { diff --git a/core/coreapi/pin.go b/core/coreapi/pin.go index d5222fdf7..9e8c15da9 100644 --- a/core/coreapi/pin.go +++ b/core/coreapi/pin.go @@ -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)) diff --git a/core/coreapi/pubsub.go b/core/coreapi/pubsub.go index 119134eea..6ec123a98 100644 --- a/core/coreapi/pubsub.go +++ b/core/coreapi/pubsub.go @@ -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 { diff --git a/core/coreapi/swarm.go b/core/coreapi/swarm.go index de4f36533..310b9ada1 100644 --- a/core/coreapi/swarm.go +++ b/core/coreapi/swarm.go @@ -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) { diff --git a/core/coreapi/unixfs.go b/core/coreapi/unixfs.go index 27341c927..847eea6e3 100644 --- a/core/coreapi/unixfs.go +++ b/core/coreapi/unixfs.go @@ -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 } diff --git a/core/coreapi/unixfs_test.go b/core/coreapi/unixfs_test.go index f6a1e48d6..4cdd5e4cf 100644 --- a/core/coreapi/unixfs_test.go +++ b/core/coreapi/unixfs_test.go @@ -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) } diff --git a/core/corehttp/gateway.go b/core/corehttp/gateway.go index 5fad3acf3..52560750a 100644 --- a/core/corehttp/gateway.go +++ b/core/corehttp/gateway.go @@ -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) diff --git a/core/corerepo/pinning.go b/core/corerepo/pinning.go index f39d39276..9c2a02781 100644 --- a/core/corerepo/pinning.go +++ b/core/corerepo/pinning.go @@ -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 } diff --git a/core/coreunix/add.go b/core/coreunix/add.go index e50adaa08..b4636a5ba 100644 --- a/core/coreunix/add.go +++ b/core/coreunix/add.go @@ -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 } diff --git a/fuse/readonly/ipfs_test.go b/fuse/readonly/ipfs_test.go index 8a02d68d1..34749db95 100644 --- a/fuse/readonly/ipfs_test.go +++ b/fuse/readonly/ipfs_test.go @@ -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 diff --git a/test/integration/addcat_test.go b/test/integration/addcat_test.go index 0d8a20073..099116445 100644 --- a/test/integration/addcat_test.go +++ b/test/integration/addcat_test.go @@ -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 { diff --git a/test/integration/bench_cat_test.go b/test/integration/bench_cat_test.go index d228e45a1..25264fd45 100644 --- a/test/integration/bench_cat_test.go +++ b/test/integration/bench_cat_test.go @@ -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 { diff --git a/test/integration/three_legged_cat_test.go b/test/integration/three_legged_cat_test.go index 200c584e3..b118c3579 100644 --- a/test/integration/three_legged_cat_test.go +++ b/test/integration/three_legged_cat_test.go @@ -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()