From 2595fc4b490d88ea3137262ee5eecb31c0bb4c36 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Thu, 15 Feb 2018 19:36:24 -0600 Subject: [PATCH 01/15] feat: add keysize through env or as an option to spawn --- .aegir.js | 1 - README.md | 3 ++- src/factory-daemon.js | 3 ++- src/factory-in-proc.js | 3 ++- src/ipfsd-daemon.js | 18 +++++++++++++++++- src/ipfsd-in-proc.js | 17 ++++++++++++++++- 6 files changed, 39 insertions(+), 6 deletions(-) diff --git a/.aegir.js b/.aegir.js index c9ede37d..36e730a6 100644 --- a/.aegir.js +++ b/.aegir.js @@ -3,7 +3,6 @@ const createServer = require('./src').createServer const server = createServer() // using defaults - module.exports = { karma: { files: [{ diff --git a/README.md b/README.md index b909f4a4..5cd6ad3a 100644 --- a/README.md +++ b/README.md @@ -115,7 +115,8 @@ Install one or both of the following modules: Spawn the daemon - `options` is an optional object the following properties: - - `init` bool (default true) - should the node be initialized + - `init` bool (default true) or Object - should the node be initialized + - if `init` is an Object, it is expected to be of the form `{keySize: }`, this will set the `keysize` to initialize the daemon with - `start` bool (default true) - should the node be started - `repoPath` string - the repository path to use for this node, ignored if node is disposable - `disposable` bool (default true) - a new repo is created and initialized for each invocation, as well as cleaned up automatically once the process exits diff --git a/src/factory-daemon.js b/src/factory-daemon.js index 4af08c40..08b87123 100644 --- a/src/factory-daemon.js +++ b/src/factory-daemon.js @@ -74,7 +74,8 @@ class FactoryDaemon { * Spawn an IPFS node, either js-ipfs or go-ipfs * * Options are: - * - `init` bool - should the node be initialized + * - `init` {bool|Object} - should the node be initialized + * - if `init` is an Object, it is expected to be of the form `{keySize: }` * - `start` bool - should the node be started * - `repoPath` string - the repository path to use for this node, ignored if node is disposable * - `disposable` bool - a new repo is created and initialized for each invocation diff --git a/src/factory-in-proc.js b/src/factory-in-proc.js index a3eeb773..8a0cae40 100644 --- a/src/factory-in-proc.js +++ b/src/factory-in-proc.js @@ -76,7 +76,8 @@ class FactoryInProc { * Spawn JSIPFS instances * * Options are: - * - `init` bool - should the node be initialized + * - `init` {bool|Object} - should the node be initialized + * - if `init` is an Object, it is expected to be of the form `{keySize: }` * - `start` bool - should the node be started * - `repoPath` string - the repository path to use for this node, ignored if node is disposable * - `disposable` bool - a new repo is created and initialized for each invocation diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index 1a903900..15430a7d 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -57,6 +57,14 @@ class Daemon { this._gatewayAddr = null this._started = false this.api = null + this.keySize = null + + this.keySize = process.env.IPFS_KEYSIZE + + // option takes precedence over env variable + if (typeof this.opts.init === 'Object') { + this.keySize = this.opts.init.keySize + } if (this.opts.env) { Object.assign(this.env, this.opts.env) @@ -128,11 +136,19 @@ class Daemon { this.path = initOpts.directory } - const args = ['init', '-b', initOpts.keysize || 2048] + const keySize = initOpts.keysize ? initOpts.keysize : this.keySize + const args = ['init'] + // do not just set a default keysize, + // in case we decide to change it at + // the daemon level in the future + if (keySize) { + args.concat(['-b', keySize]) + } if (initOpts.pass) { args.push('--pass') args.push('"' + initOpts.pass + '"') } + log(`initializing with keysize: ${keySize}`) run(this, args, { env: this.env }, (err, result) => { if (err) { return callback(err) diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index 3775a222..9a405a84 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -32,6 +32,7 @@ class Node { this._started = false this.initialized = false this.api = null + this.keySize = null this.opts.EXPERIMENTAL = defaults({}, opts.EXPERIMENTAL, { pubsub: false, @@ -55,6 +56,14 @@ class Node { throw new Error('Unkown argument ' + arg) } }) + + // option takes precedence over env variable + if (typeof this.opts.init === 'Object') { + this.keySize = this.opts.init.keySize + } else if (process.env.IPFS_KEYSIZE) { + this.keySize = process.env.IPFS_KEYSIZE + } + this.exec = new IPFS({ repo: this.repo, init: false, @@ -126,7 +135,13 @@ class Node { initOpts = {} } - initOpts.bits = initOpts.keysize || 2048 + const keySize = initOpts.keysize ? initOpts.keysize : this.keySize + // do not just set a default keysize, + // in case we decide to change it at + // the daemon level in the future + if (keySize) { + initOpts.bits = keySize + } this.exec.init(initOpts, (err) => { if (err) { return callback(err) From 718e0ce180a452559a737168a72f262c3ca08b52 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Thu, 15 Feb 2018 19:45:10 -0600 Subject: [PATCH 02/15] fix: lint --- src/ipfsd-daemon.js | 2 +- src/ipfsd-in-proc.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index 15430a7d..6262eb3f 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -62,7 +62,7 @@ class Daemon { this.keySize = process.env.IPFS_KEYSIZE // option takes precedence over env variable - if (typeof this.opts.init === 'Object') { + if (typeof this.opts.init === 'object') { this.keySize = this.opts.init.keySize } diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index 9a405a84..6310ea58 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -58,7 +58,7 @@ class Node { }) // option takes precedence over env variable - if (typeof this.opts.init === 'Object') { + if (typeof this.opts.init === 'object') { this.keySize = this.opts.init.keySize } else if (process.env.IPFS_KEYSIZE) { this.keySize = process.env.IPFS_KEYSIZE From c9c25da874df13945b181ba569f33b1937223c95 Mon Sep 17 00:00:00 2001 From: Volker Mische Date: Fri, 16 Feb 2018 16:21:35 +0100 Subject: [PATCH 03/15] fix: don't pass on arguments from node executable When running a script that involves `ipfsd-ctl` and you pass on additional parameters it used to pass on those parameters to the subprocesses it spaws. This lead to issues especially with `--inspect-brk` as it would spawn another inspector which then would fail because there is already one running on the same port. Fixes #202. --- src/utils/run.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/utils/run.js b/src/utils/run.js index 93dd32ac..9dd00894 100644 --- a/src/utils/run.js +++ b/src/utils/run.js @@ -13,5 +13,8 @@ module.exports = (node, args, opts, callback) => { executable = process.execPath } + // Don't pass on arguments that were passed into the node executable + opts.execArgv = [] + return exec(executable, args, opts, callback) } From c3fca62fd6f200e8cf995d5fafe7afc1eb40d8d9 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Fri, 16 Feb 2018 12:24:08 -0600 Subject: [PATCH 04/15] use initOpts istead of reusing init --- package.json | 8 ++++---- src/factory-daemon.js | 4 ++-- src/factory-in-proc.js | 2 +- src/ipfsd-daemon.js | 19 +++++++------------ src/ipfsd-in-proc.js | 17 ++++++----------- test/spawn-options.spec.js | 2 +- 6 files changed, 21 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index c46915ad..ac551792 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,13 @@ "lint": "aegir lint", "docs": "aegir docs", "build": "aegir build", - "test": "aegir test -t node -t browser --no-cors", - "test:node": "aegir test -t node", - "test:browser": "aegir test -t browser --no-cors", + "test": "IPFS_KEYSIZE=1024 aegir test -t node -t browser --no-cors", + "test:node": "IPFS_KEYSIZE=1024 aegir test -t node", + "test:browser": "IPFS_KEYSIZE=1024 aegir test -t browser --no-cors", "release": "aegir release", "release-minor": "aegir release --type minor", "release-major": "aegir release --type major", - "coverage": "COVERAGE=true aegir coverage --timeout 50000", + "coverage": "IPFS_KEYSIZE=1024 COVERAGE=true aegir coverage --timeout 50000", "coverage-publish": "aegir coverage -u" }, "browser": { diff --git a/src/factory-daemon.js b/src/factory-daemon.js index 08b87123..976a0b37 100644 --- a/src/factory-daemon.js +++ b/src/factory-daemon.js @@ -74,8 +74,8 @@ class FactoryDaemon { * Spawn an IPFS node, either js-ipfs or go-ipfs * * Options are: - * - `init` {bool|Object} - should the node be initialized - * - if `init` is an Object, it is expected to be of the form `{keySize: }` + * - `init` bool - should the node be initialized + * - `initOpts` Object, it is expected to be of the form `{bits: }`, which sets the desired key size * - `start` bool - should the node be started * - `repoPath` string - the repository path to use for this node, ignored if node is disposable * - `disposable` bool - a new repo is created and initialized for each invocation diff --git a/src/factory-in-proc.js b/src/factory-in-proc.js index 8a0cae40..551759c9 100644 --- a/src/factory-in-proc.js +++ b/src/factory-in-proc.js @@ -77,7 +77,7 @@ class FactoryInProc { * * Options are: * - `init` {bool|Object} - should the node be initialized - * - if `init` is an Object, it is expected to be of the form `{keySize: }` + * - `initOpts` Object, it is expected to be of the form `{bits: }`, which sets the desired key size * - `start` bool - should the node be started * - `repoPath` string - the repository path to use for this node, ignored if node is disposable * - `disposable` bool - a new repo is created and initialized for each invocation diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index 6262eb3f..8711befb 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -57,14 +57,9 @@ class Daemon { this._gatewayAddr = null this._started = false this.api = null - this.keySize = null + this.bits = null - this.keySize = process.env.IPFS_KEYSIZE - - // option takes precedence over env variable - if (typeof this.opts.init === 'object') { - this.keySize = this.opts.init.keySize - } + this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE if (this.opts.env) { Object.assign(this.env, this.opts.env) @@ -120,7 +115,7 @@ class Daemon { * Initialize a repo. * * @param {Object} [initOpts={}] - * @param {number} [initOpts.keysize=2048] - The bit size of the identiy key. + * @param {number} [initOpts.bits=2048] - The bit size of the identiy key. * @param {string} [initOpts.directory=IPFS_PATH] - The location of the repo. * @param {string} [initOpts.pass] - The passphrase of the keychain. * @param {function (Error, Node)} callback @@ -136,19 +131,19 @@ class Daemon { this.path = initOpts.directory } - const keySize = initOpts.keysize ? initOpts.keysize : this.keySize + const bits = initOpts.bits ? initOpts.bits : this.bits const args = ['init'] // do not just set a default keysize, // in case we decide to change it at // the daemon level in the future - if (keySize) { - args.concat(['-b', keySize]) + if (bits) { + args.concat(['-b', bits]) } if (initOpts.pass) { args.push('--pass') args.push('"' + initOpts.pass + '"') } - log(`initializing with keysize: ${keySize}`) + log(`initializing with keysize: ${bits}`) run(this, args, { env: this.env }, (err, result) => { if (err) { return callback(err) diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index 6310ea58..19101cd8 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -32,7 +32,7 @@ class Node { this._started = false this.initialized = false this.api = null - this.keySize = null + this.bits = null this.opts.EXPERIMENTAL = defaults({}, opts.EXPERIMENTAL, { pubsub: false, @@ -57,12 +57,7 @@ class Node { } }) - // option takes precedence over env variable - if (typeof this.opts.init === 'object') { - this.keySize = this.opts.init.keySize - } else if (process.env.IPFS_KEYSIZE) { - this.keySize = process.env.IPFS_KEYSIZE - } + this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE this.exec = new IPFS({ repo: this.repo, @@ -123,7 +118,7 @@ class Node { * Initialize a repo. * * @param {Object} [initOpts={}] - * @param {number} [initOpts.keysize=2048] - The bit size of the identiy key. + * @param {number} [initOpts.bits=2048] - The bit size of the identiy key. * @param {string} [initOpts.directory=IPFS_PATH] - The location of the repo. * @param {string} [initOpts.pass] - The passphrase of the keychain. * @param {function (Error, Node)} callback @@ -135,12 +130,12 @@ class Node { initOpts = {} } - const keySize = initOpts.keysize ? initOpts.keysize : this.keySize + const bits = initOpts.keysize ? initOpts.bits : this.bits // do not just set a default keysize, // in case we decide to change it at // the daemon level in the future - if (keySize) { - initOpts.bits = keySize + if (bits) { + initOpts.bits = bits } this.exec.init(initOpts, (err) => { if (err) { diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index cfb22a8b..cfa6a3cd 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -183,7 +183,7 @@ describe('Spawn options', () => { }) }) - describe('custom init options', () => { + describe('custom config options', () => { it('custom config', function (done) { this.timeout(40 * 1000) From 55142c51353436a15075409c7d54ee54e1218a74 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Sat, 17 Feb 2018 12:20:30 -0600 Subject: [PATCH 05/15] feat: replace config on init instead of setting it once for each option --- package.json | 4 ++- src/ipfsd-daemon.js | 51 ++++++++++++++++++++++++++++---------- src/ipfsd-in-proc.js | 39 ++++++++++++++++------------- test/spawn-options.spec.js | 4 ++- test/start-stop.node.js | 44 +++++++++++++++++--------------- 5 files changed, 90 insertions(+), 52 deletions(-) diff --git a/package.json b/package.json index ac551792..c063057d 100644 --- a/package.json +++ b/package.json @@ -78,17 +78,19 @@ "detect-node": "^2.0.3", "hapi": "^16.6.2", "hat": "0.0.3", + "ipfs-api": "^17.3.0", "ipfs-repo": "^0.18.5", "joi": "^13.0.2", "lodash.clone": "^4.5.0", + "lodash.defaults": "^4.2.0", "lodash.defaultsdeep": "^4.6.0", "multiaddr": "^3.0.2", "once": "^1.4.0", "readable-stream": "^2.3.3", "rimraf": "^2.6.2", "safe-json-parse": "^4.0.0", + "safe-json-stringify": "^1.0.4", "shutdown": "^0.3.0", - "ipfs-api": "^17.3.0", "stream-http": "^2.7.2", "subcomandante": "^1.0.5", "superagent": "^3.8.2", diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index 8711befb..ef5f9695 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -2,23 +2,26 @@ const fs = require('fs') const waterfall = require('async/waterfall') +const series = require('async/series') const ipfs = require('ipfs-api') const multiaddr = require('multiaddr') const rimraf = require('rimraf') const path = require('path') const once = require('once') const truthy = require('truthy') -const flatten = require('./utils/flatten') +const defaults = require('lodash.defaults') const debug = require('debug') +const os = require('os') +const hat = require('hat') const log = debug('ipfsd-ctl:daemon') const safeParse = require('safe-json-parse/callback') +const safeStringify = require('safe-json-stringify') const parseConfig = require('./utils/parse-config') const tmpDir = require('./utils/tmp-dir') const findIpfsExecutable = require('./utils/find-ipfs-executable') const setConfigValue = require('./utils/set-config-value') -const configureNode = require('./utils/configure-node') const run = require('./utils/run') const GRACE_PERIOD = 10500 // amount of ms to wait before sigkill @@ -42,8 +45,6 @@ class Daemon { const type = truthy(process.env.IPFS_TYPE) this.opts = opts || { type: type || 'go' } - this.opts.config = flatten(this.opts.config) - const td = tmpDir(opts.type === 'js') this.path = this.opts.disposable ? td @@ -57,8 +58,6 @@ class Daemon { this._gatewayAddr = null this._started = false this.api = null - this.bits = null - this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE if (this.opts.env) { @@ -149,14 +148,14 @@ class Daemon { return callback(err) } - configureNode(this, this.opts.config, (err) => { - if (err) { - return callback(err) - } - + waterfall([ + (cb) => this.getConfig(cb), + (conf, cb) => this.replaceConfig(defaults({}, this.opts.config, conf), cb) + ], (err) => { + if (err) { return callback } this.clean = false this.initialized = true - callback(null, this) + return callback(null, this) }) }) } @@ -339,7 +338,7 @@ class Daemon { cb ), (config, cb) => { - if (!key) { + if (key === 'show') { return safeParse(config, cb) } cb(null, config.trim()) @@ -359,6 +358,32 @@ class Daemon { setConfigValue(this, key, value, callback) } + /** + * Replace the current config with the provided one + * + * @param config + * @param callback + */ + replaceConfig (config, callback) { + const tmpFile = path.join(os.tmpdir(), hat()) + // I wanted to use streams here, but js-ipfs doesn't + // read from stdin when providing '-' (or piping) like + // go-ipfs, and adding it right now seems like a fair + // bit of work, so we're using tmp file for now - not ideal... + series([ + (cb) => fs.writeFile(tmpFile, safeStringify(config), cb), + (cb) => run( + this, + ['config', 'replace', `${tmpFile}`], + { env: this.env }, + cb + ) + ], (err) => { + if (err) { return callback(err) } + fs.unlink(tmpFile, callback) + }) + } + /** * Get the version of ipfs * diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index 19101cd8..b7d452fa 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -1,10 +1,10 @@ 'use strict' -const eachOf = require('async/eachOf') const multiaddr = require('multiaddr') -const defaults = require('lodash.defaultsdeep') +const defaultsDeep = require('lodash.defaultsdeep') const createRepo = require('./utils/repo/create-nodejs') -const flatten = require('./utils/flatten') +const defaults = require('lodash.defaults') +const waterfall = require('async/waterfall') /** * ipfsd for a js-ipfs instance (aka in-process IPFS node) @@ -32,9 +32,9 @@ class Node { this._started = false this.initialized = false this.api = null - this.bits = null + this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE - this.opts.EXPERIMENTAL = defaults({}, opts.EXPERIMENTAL, { + this.opts.EXPERIMENTAL = defaultsDeep({}, opts.EXPERIMENTAL, { pubsub: false, sharding: false, relay: { @@ -57,8 +57,6 @@ class Node { } }) - this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE - this.exec = new IPFS({ repo: this.repo, init: false, @@ -142,17 +140,14 @@ class Node { return callback(err) } - const conf = flatten(this.opts.config) - eachOf(conf, (val, key, cb) => { - this.setConfig(key, val, cb) - }, (err) => { - if (err) { - return callback(err) - } - - this.initialized = true + waterfall([ + (cb) => this.getConfig(cb), + (conf, cb) => this.replaceConfig(defaults({}, this.opts.config, conf), cb) + ], (err) => { + if (err) { return callback } this.clean = false - callback(null, this) + this.initialized = true + return callback(null, this) }) }) } @@ -288,6 +283,16 @@ class Node { this.exec.config.set(key, value, callback) } + /** + * Replace the current config with the provided one + * + * @param config + * @param callback + */ + replaceConfig (config, callback) { + this.exec.config.replace(config, callback) + } + /** * Get the version of ipfs * diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index cfa6a3cd..ceeee378 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -215,6 +215,7 @@ describe('Spawn options', () => { config = JSON.parse(config) } expect(config).to.eql([swarmAddr1]) + // expect(config).to.include(swarmAddr1) cb(null, ipfsd) }) ], (err, ipfsd) => { @@ -344,7 +345,8 @@ describe('Spawn options', () => { }) }) - after((done) => { + after(function (done) { + this.timeout(50 * 1000) ipfsd.stop(done) }) diff --git a/test/start-stop.node.js b/test/start-stop.node.js index de09c4f9..c7c48eb3 100644 --- a/test/start-stop.node.js +++ b/test/start-stop.node.js @@ -12,6 +12,7 @@ const fs = require('fs') const path = require('path') const os = require('os') const isrunning = require('is-running') +const JSIPFS = require('ipfs') const isWindows = os.platform() === 'win32' const findIpfsExecutable = require('../src/utils/find-ipfs-executable') @@ -180,29 +181,32 @@ types.forEach((type) => { it('ipfsd.exec should match exec', () => { expect(ipfsd.exec).to.equal(exec) }) + }) - describe('should fail on invalid exec path', function () { - this.timeout(20 * 1000) + describe('should fail on invalid exec path', function () { + this.timeout(20 * 1000) - before((done) => { - const df = IPFSFactory.create(dfConfig) - const exec = path.join('invalid', 'exec', 'ipfs') + let ipfsd + before((done) => { + const df = IPFSFactory.create(dfConfig) + const exec = path.join('invalid', 'exec', 'ipfs') - df.spawn({ init: false, start: false, exec: exec }, (err, daemon) => { - expect(err).to.not.exist() - expect(daemon).to.exist() + df.spawn({ init: false, start: false, exec: exec }, (err, daemon) => { + expect(err).to.not.exist() + expect(daemon).to.exist() - ipfsd = daemon - done() - }) + ipfsd = daemon + done() }) + }) - it('should fail on init', (done) => { - ipfsd.init((err, node) => { - expect(err).to.exist() - expect(node).to.not.exist() - done() - }) + after((done) => ipfsd.stop(done)) + + it('should fail on init', (done) => { + ipfsd.init((err, node) => { + expect(err).to.exist() + expect(node).to.not.exist() + done() }) }) }) @@ -217,8 +221,8 @@ types.forEach((type) => { async.series([ (cb) => f.spawn({ - init: true, - start: true, + init: false, + start: false, disposable: false, repoPath: tempDir(type), config: { @@ -244,7 +248,7 @@ types.forEach((type) => { expect(ipfsd).to.exist() }) - it('daemon should not be running', (done) => { + it('daemon should be running', (done) => { ipfsd.pid((pid) => { expect(pid).to.exist() done() From 17d578eb76c09c5d4f9b8fdd45b6bc8a10b3b427 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Sat, 17 Feb 2018 12:48:48 -0600 Subject: [PATCH 06/15] use cross-env to set env vars and not break windows --- package.json | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index c063057d..303f162c 100644 --- a/package.json +++ b/package.json @@ -7,9 +7,9 @@ "lint": "aegir lint", "docs": "aegir docs", "build": "aegir build", - "test": "IPFS_KEYSIZE=1024 aegir test -t node -t browser --no-cors", - "test:node": "IPFS_KEYSIZE=1024 aegir test -t node", - "test:browser": "IPFS_KEYSIZE=1024 aegir test -t browser --no-cors", + "test": "cross-env IPFS_KEYSIZE=1024 aegir test -t node -t browser --no-cors", + "test:node": "cross-env IPFS_KEYSIZE=1024 aegir test -t node", + "test:browser": "cross-env IPFS_KEYSIZE=1024 aegir test -t browser --no-cors", "release": "aegir release", "release-minor": "aegir release --type minor", "release-major": "aegir release --type major", @@ -99,6 +99,7 @@ "devDependencies": { "aegir": "^12.4.0", "chai": "^4.1.2", + "cross-env": "^5.1.3", "detect-port": "^1.2.2", "dirty-chai": "^2.0.1", "go-ipfs-dep": "0.4.13", From f5f400e88f12b40c59c6f5dfb67380026ada2135 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Sat, 17 Feb 2018 13:06:56 -0600 Subject: [PATCH 07/15] test: skip multiple start on windows --- src/ipfsd-daemon.js | 5 +++-- src/ipfsd-in-proc.js | 5 +++-- test/start-stop.node.js | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index ef5f9695..a80584d6 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -361,8 +361,9 @@ class Daemon { /** * Replace the current config with the provided one * - * @param config - * @param callback + * @param {object} config + * @param {function(Error)} callback + * @return {undefined} */ replaceConfig (config, callback) { const tmpFile = path.join(os.tmpdir(), hat()) diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index b7d452fa..b62cbede 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -286,8 +286,9 @@ class Node { /** * Replace the current config with the provided one * - * @param config - * @param callback + * @param {object} config + * @param {function(Error)} callback + * @return {undefined} */ replaceConfig (config, callback) { this.exec.config.replace(config, callback) diff --git a/test/start-stop.node.js b/test/start-stop.node.js index c7c48eb3..e08214fe 100644 --- a/test/start-stop.node.js +++ b/test/start-stop.node.js @@ -12,7 +12,6 @@ const fs = require('fs') const path = require('path') const os = require('os') const isrunning = require('is-running') -const JSIPFS = require('ipfs') const isWindows = os.platform() === 'win32' const findIpfsExecutable = require('../src/utils/find-ipfs-executable') @@ -212,6 +211,9 @@ types.forEach((type) => { }) describe('start and stop multiple times', () => { + // TODO: wont work on windows until we get /shutdown implemented in js-ipfs + if (isWindows) { return } + let ipfsd before(function (done) { From ee744278feb5446bd85a15384abe0d60ceefe2df Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Sat, 17 Feb 2018 13:16:51 -0600 Subject: [PATCH 08/15] test: skip spawn from a initialized repo on windows --- test/spawn-options.spec.js | 6 ++++++ test/start-stop.node.js | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index ceeee378..746c148b 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -13,6 +13,9 @@ const isNode = require('detect-node') const hat = require('hat') const IPFSFactory = require('../src') const JSIPFS = require('ipfs') +const os = require('os') + +const isWindows = os.platform() === 'win32' const tests = [ { type: 'go' }, @@ -112,6 +115,9 @@ describe('Spawn options', () => { }) describe('spawn from a initialized repo', () => { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { return } + // TODO: figure out why `proc` IPFS refuses // to start with a provided repo // `Error: Not able to start from state: uninitalized` diff --git a/test/start-stop.node.js b/test/start-stop.node.js index e08214fe..93160527 100644 --- a/test/start-stop.node.js +++ b/test/start-stop.node.js @@ -211,7 +211,7 @@ types.forEach((type) => { }) describe('start and stop multiple times', () => { - // TODO: wont work on windows until we get /shutdown implemented in js-ipfs + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs if (isWindows) { return } let ipfsd From b167a3ccb9e216f77115218ab88bf1e02fdab2b6 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Tue, 20 Feb 2018 12:30:49 -0600 Subject: [PATCH 09/15] feat: small changes from review --- README.md | 2 +- src/endpoint/routes.js | 4 ++-- src/factory-daemon.js | 8 ++++---- src/factory-in-proc.js | 2 +- src/ipfsd-client.js | 2 +- src/ipfsd-daemon.js | 35 ++++++++++++++++++----------------- src/ipfsd-in-proc.js | 29 +++++++++++++++-------------- test/endpoint/client.js | 5 ++--- 8 files changed, 44 insertions(+), 43 deletions(-) diff --git a/README.md b/README.md index 5cd6ad3a..97c84854 100644 --- a/README.md +++ b/README.md @@ -116,7 +116,7 @@ Spawn the daemon - `options` is an optional object the following properties: - `init` bool (default true) or Object - should the node be initialized - - if `init` is an Object, it is expected to be of the form `{keySize: }`, this will set the `keysize` to initialize the daemon with + - `initOptions` object - should be of the form `{bits: }`, which sets the desired key size - `start` bool (default true) - should the node be started - `repoPath` string - the repository path to use for this node, ignored if node is disposable - `disposable` bool (default true) - a new repo is created and initialized for each invocation, as well as cleaned up automatically once the process exits diff --git a/src/endpoint/routes.js b/src/endpoint/routes.js index 83f8c712..66e5d5ce 100644 --- a/src/endpoint/routes.js +++ b/src/endpoint/routes.js @@ -96,12 +96,12 @@ module.exports = (server) => { const payload = request.payload || {} - nodes[id].init(payload.initOpts, (err, node) => { + nodes[id].init(payload.initOpts, (err) => { if (err) { return reply(boom.badRequest(err)) } - reply({ initialized: node.initialized }) + reply({ initialized: true }) }) }, config: routeConfig diff --git a/src/factory-daemon.js b/src/factory-daemon.js index 976a0b37..53391421 100644 --- a/src/factory-daemon.js +++ b/src/factory-daemon.js @@ -2,7 +2,7 @@ const defaultsDeep = require('lodash.defaultsdeep') const clone = require('lodash.clone') -const waterfall = require('async/waterfall') +const series = require('async/series') const path = require('path') const tmpDir = require('./utils/tmp-dir') @@ -75,7 +75,7 @@ class FactoryDaemon { * * Options are: * - `init` bool - should the node be initialized - * - `initOpts` Object, it is expected to be of the form `{bits: }`, which sets the desired key size + * - `initOptions` Object, it is expected to be of the form `{bits: }`, which sets the desired key size * - `start` bool - should the node be started * - `repoPath` string - the repository path to use for this node, ignored if node is disposable * - `disposable` bool - a new repo is created and initialized for each invocation @@ -129,11 +129,11 @@ class FactoryDaemon { const node = new Daemon(options) - waterfall([ + series([ (cb) => options.init ? node.init(cb) : cb(null, node), - (node, cb) => options.start + (cb) => options.start ? node.start(options.args, cb) : cb() ], (err) => { diff --git a/src/factory-in-proc.js b/src/factory-in-proc.js index 551759c9..c9ad38ab 100644 --- a/src/factory-in-proc.js +++ b/src/factory-in-proc.js @@ -77,7 +77,7 @@ class FactoryInProc { * * Options are: * - `init` {bool|Object} - should the node be initialized - * - `initOpts` Object, it is expected to be of the form `{bits: }`, which sets the desired key size + * - `initOptions` Object, it is expected to be of the form `{bits: }`, which sets the desired key size * - `start` bool - should the node be started * - `repoPath` string - the repository path to use for this node, ignored if node is disposable * - `disposable` bool - a new repo is created and initialized for each invocation diff --git a/src/ipfsd-client.js b/src/ipfsd-client.js index 86d93119..b58c835d 100644 --- a/src/ipfsd-client.js +++ b/src/ipfsd-client.js @@ -94,7 +94,7 @@ class DaemonClient { } this.initialized = res.body.initialized - cb(null, res.body) + cb() }) } diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index a80584d6..211d67db 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -58,7 +58,7 @@ class Daemon { this._gatewayAddr = null this._started = false this.api = null - this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE + this.bits = this.opts.initOptions ? this.opts.initOptions.bits : process.env.IPFS_KEYSIZE if (this.opts.env) { Object.assign(this.env, this.opts.env) @@ -113,24 +113,24 @@ class Daemon { /** * Initialize a repo. * - * @param {Object} [initOpts={}] - * @param {number} [initOpts.bits=2048] - The bit size of the identiy key. - * @param {string} [initOpts.directory=IPFS_PATH] - The location of the repo. - * @param {string} [initOpts.pass] - The passphrase of the keychain. + * @param {Object} [initOptions={}] + * @param {number} [initOptions.bits=2048] - The bit size of the identiy key. + * @param {string} [initOptions.directory=IPFS_PATH] - The location of the repo. + * @param {string} [initOptions.pass] - The passphrase of the keychain. * @param {function (Error, Node)} callback * @returns {undefined} */ - init (initOpts, callback) { + init (initOptions, callback) { if (!callback) { - callback = initOpts - initOpts = {} + callback = initOptions + initOptions = {} } - if (initOpts.directory && initOpts.directory !== this.path) { - this.path = initOpts.directory + if (initOptions.directory && initOptions.directory !== this.path) { + this.path = initOptions.directory } - const bits = initOpts.bits ? initOpts.bits : this.bits + const bits = initOptions.bits || this.bits const args = ['init'] // do not just set a default keysize, // in case we decide to change it at @@ -138,9 +138,9 @@ class Daemon { if (bits) { args.concat(['-b', bits]) } - if (initOpts.pass) { + if (initOptions.pass) { args.push('--pass') - args.push('"' + initOpts.pass + '"') + args.push('"' + initOptions.pass + '"') } log(`initializing with keysize: ${bits}`) run(this, args, { env: this.env }, (err, result) => { @@ -148,14 +148,15 @@ class Daemon { return callback(err) } + const self = this waterfall([ (cb) => this.getConfig(cb), (conf, cb) => this.replaceConfig(defaults({}, this.opts.config, conf), cb) ], (err) => { - if (err) { return callback } - this.clean = false - this.initialized = true - return callback(null, this) + if (err) { return callback(err) } + self.clean = false + self.initialized = true + return callback() }) }) } diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index b62cbede..d05896a4 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -32,7 +32,7 @@ class Node { this._started = false this.initialized = false this.api = null - this.bits = this.opts.initOpts ? this.opts.initOpts.bits : process.env.IPFS_KEYSIZE + this.bits = this.opts.initOptions ? this.opts.initOptions.bits : process.env.IPFS_KEYSIZE this.opts.EXPERIMENTAL = defaultsDeep({}, opts.EXPERIMENTAL, { pubsub: false, @@ -115,39 +115,40 @@ class Node { /** * Initialize a repo. * - * @param {Object} [initOpts={}] - * @param {number} [initOpts.bits=2048] - The bit size of the identiy key. - * @param {string} [initOpts.directory=IPFS_PATH] - The location of the repo. - * @param {string} [initOpts.pass] - The passphrase of the keychain. + * @param {Object} [initOptions={}] + * @param {number} [initOptions.bits=2048] - The bit size of the identiy key. + * @param {string} [initOptions.directory=IPFS_PATH] - The location of the repo. + * @param {string} [initOptions.pass] - The passphrase of the keychain. * @param {function (Error, Node)} callback * @returns {undefined} */ - init (initOpts, callback) { + init (initOptions, callback) { if (!callback) { - callback = initOpts - initOpts = {} + callback = initOptions + initOptions = {} } - const bits = initOpts.keysize ? initOpts.bits : this.bits + const bits = initOptions.keysize ? initOptions.bits : this.bits // do not just set a default keysize, // in case we decide to change it at // the daemon level in the future if (bits) { - initOpts.bits = bits + initOptions.bits = bits } - this.exec.init(initOpts, (err) => { + this.exec.init(initOptions, (err) => { if (err) { return callback(err) } + const self = this waterfall([ (cb) => this.getConfig(cb), (conf, cb) => this.replaceConfig(defaults({}, this.opts.config, conf), cb) ], (err) => { if (err) { return callback } - this.clean = false - this.initialized = true - return callback(null, this) + self.clean = false + self.initialized = true + return callback() }) }) } diff --git a/test/endpoint/client.js b/test/endpoint/client.js index 1a305909..23944342 100644 --- a/test/endpoint/client.js +++ b/test/endpoint/client.js @@ -89,7 +89,6 @@ describe('client', () => { it('should handle valid request', (done) => { mock.post('http://localhost:9999/init', (req) => { expect(req.query.id).to.exist() - expect(req.body.initOpts.initOpt1).to.equal('hello!') return { body: { @@ -98,9 +97,9 @@ describe('client', () => { } }) - node.init({ initOpt1: 'hello!' }, (err, res) => { + node.init({ initOptions: { bits: 512 } }, (err) => { expect(err).to.not.exist() - expect(res.initialized).to.be.ok() + expect(node.initialized).to.be.ok() done() }) }) From ac70cda53279aed284ca6671230b238d4742d247 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Tue, 20 Feb 2018 17:34:56 -0600 Subject: [PATCH 10/15] fix: setting keysize on each tests --- package.json | 8 ++++---- src/ipfsd-daemon.js | 4 ++-- src/ipfsd-in-proc.js | 6 +++++- test/add-retrieve.spec.js | 4 +++- test/api.spec.js | 11 +++++++++-- test/endpoint/client.js | 2 +- test/spawn-options.spec.js | 26 ++++++++++++++++---------- test/start-stop.node.js | 34 ++++++++++++++++++++++++---------- 8 files changed, 64 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 303f162c..796efc54 100644 --- a/package.json +++ b/package.json @@ -7,13 +7,13 @@ "lint": "aegir lint", "docs": "aegir docs", "build": "aegir build", - "test": "cross-env IPFS_KEYSIZE=1024 aegir test -t node -t browser --no-cors", - "test:node": "cross-env IPFS_KEYSIZE=1024 aegir test -t node", - "test:browser": "cross-env IPFS_KEYSIZE=1024 aegir test -t browser --no-cors", + "test": "aegir test -t node -t browser --no-cors", + "test:node": "aegir test -t node", + "test:browser": "aegir test -t browser --no-cors", "release": "aegir release", "release-minor": "aegir release --type minor", "release-major": "aegir release --type major", - "coverage": "IPFS_KEYSIZE=1024 COVERAGE=true aegir coverage --timeout 50000", + "coverage": "COVERAGE=true aegir coverage --timeout 50000", "coverage-publish": "aegir coverage -u" }, "browser": { diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index 211d67db..4be5c479 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -58,7 +58,7 @@ class Daemon { this._gatewayAddr = null this._started = false this.api = null - this.bits = this.opts.initOptions ? this.opts.initOptions.bits : process.env.IPFS_KEYSIZE + this.bits = process.env.IPFS_KEYSIZE || (this.opts.initOptions ? this.opts.initOptions.bits : null) if (this.opts.env) { Object.assign(this.env, this.opts.env) @@ -137,12 +137,12 @@ class Daemon { // the daemon level in the future if (bits) { args.concat(['-b', bits]) + log(`initializing with keysize: ${bits}`) } if (initOptions.pass) { args.push('--pass') args.push('"' + initOptions.pass + '"') } - log(`initializing with keysize: ${bits}`) run(this, args, { env: this.env }, (err, result) => { if (err) { return callback(err) diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index d05896a4..cd59992e 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -5,6 +5,9 @@ const defaultsDeep = require('lodash.defaultsdeep') const createRepo = require('./utils/repo/create-nodejs') const defaults = require('lodash.defaults') const waterfall = require('async/waterfall') +const debug = require('debug') + +const log = debug('ipfsd-ctl:in-proc') /** * ipfsd for a js-ipfs instance (aka in-process IPFS node) @@ -32,7 +35,7 @@ class Node { this._started = false this.initialized = false this.api = null - this.bits = this.opts.initOptions ? this.opts.initOptions.bits : process.env.IPFS_KEYSIZE + this.bits = process.env.IPFS_KEYSIZE || (this.opts.initOptions ? this.opts.initOptions.bits : null) this.opts.EXPERIMENTAL = defaultsDeep({}, opts.EXPERIMENTAL, { pubsub: false, @@ -134,6 +137,7 @@ class Node { // the daemon level in the future if (bits) { initOptions.bits = bits + log(`initializing with keysize: ${bits}`) } this.exec.init(initOptions, (err) => { if (err) { diff --git a/test/add-retrieve.spec.js b/test/add-retrieve.spec.js index 2ba0d830..11006971 100644 --- a/test/add-retrieve.spec.js +++ b/test/add-retrieve.spec.js @@ -25,7 +25,9 @@ describe('data can be put and fetched', () => { const f = IPFSFactory.create(dfOpts) - f.spawn((err, _ipfsd) => { + f.spawn({ + initOptions: { bits: 1024 } + }, (err, _ipfsd) => { expect(err).to.not.exist() expect(_ipfsd).to.exist() expect(_ipfsd.api).to.exist() diff --git a/test/api.spec.js b/test/api.spec.js index d4ad07b7..084ab5c6 100644 --- a/test/api.spec.js +++ b/test/api.spec.js @@ -55,7 +55,11 @@ describe('ipfsd.api for Daemons', () => { series([ (cb) => { - df.spawn({ start: false, config: config }, (err, _ipfsd) => { + df.spawn({ + start: false, + config: config, + initOptions: { bits: 1024 } + }, (err, _ipfsd) => { expect(err).to.not.exist() ipfsd = _ipfsd ipfsd.start((err, _api) => { @@ -110,7 +114,10 @@ describe('ipfsd.api for Daemons', () => { it('check if API and Gateway addrs are correct', function (done) { this.timeout(30 * 1000) - df.spawn({ config: config }, (err, _ipfsd) => { + df.spawn({ + config: config, + initOptions: { bits: 1024 } + }, (err, _ipfsd) => { expect(err).to.not.exist() const ipfsd = _ipfsd diff --git a/test/endpoint/client.js b/test/endpoint/client.js index 23944342..646460e7 100644 --- a/test/endpoint/client.js +++ b/test/endpoint/client.js @@ -97,7 +97,7 @@ describe('client', () => { } }) - node.init({ initOptions: { bits: 512 } }, (err) => { + node.init({ bits: 512 }, (err) => { expect(err).to.not.exist() expect(node.initialized).to.be.ok() done() diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index 746c148b..84287cba 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -89,11 +89,12 @@ describe('Spawn options', () => { it('ipfsd.init', function (done) { this.timeout(20 * 1000) - ipfsd.init((err) => { - expect(err).to.not.exist() - expect(ipfsd.initialized).to.be.ok() - done() - }) + ipfsd.init({ bits: 1024 }, + (err) => { + expect(err).to.not.exist() + expect(ipfsd.initialized).to.be.ok() + done() + }) }) it('ipfsd.start', function (done) { @@ -171,7 +172,9 @@ describe('Spawn options', () => { it('create init and start node', function (done) { this.timeout(30 * 1000) - f.spawn((err, _ipfsd) => { + f.spawn({ + initOptions: { bits: 1024 } + }, (err, _ipfsd) => { expect(err).to.not.exist() expect(_ipfsd).to.exist() expect(_ipfsd.api).to.exist() @@ -204,7 +207,7 @@ describe('Spawn options', () => { } } - const options = { config: config } + const options = { config: config, initOptions: { bits: 1024 } } waterfall([ (cb) => f.spawn(options, cb), @@ -276,7 +279,7 @@ describe('Spawn options', () => { cb() }), (cb) => { - ipfsd.init(cb) + ipfsd.init({ bits: 1024 }, cb) }, (cb) => { ipfsd.start(cb) @@ -305,7 +308,8 @@ describe('Spawn options', () => { this.timeout(30 * 1000) const options = { - args: ['--enable-pubsub-experiment'] + args: ['--enable-pubsub-experiment'], + initOptions: { bits: 1024 } } f.spawn(options, (err, _ipfsd) => { @@ -344,7 +348,9 @@ describe('Spawn options', () => { before(function (done) { this.timeout(50 * 1000) - f.spawn((err, _ipfsd) => { + f.spawn({ + initOptions: { bits: 1024 } + }, (err, _ipfsd) => { expect(err).to.not.exist() ipfsd = _ipfsd done() diff --git a/test/start-stop.node.js b/test/start-stop.node.js index 93160527..cff88d5f 100644 --- a/test/start-stop.node.js +++ b/test/start-stop.node.js @@ -48,7 +48,8 @@ types.forEach((type) => { f.spawn({ init: true, start: false, - disposable: true + disposable: true, + initOptions: { bits: 1024 } }, (err, _ipfsd) => { expect(err).to.not.exist() expect(_ipfsd).to.exist() @@ -139,7 +140,10 @@ types.forEach((type) => { const df = IPFSFactory.create(dfConfig) - df.spawn({ start: false }, (err, ipfsd) => { + df.spawn({ + start: false, + initOptions: { bits: 1024 } + }, (err, ipfsd) => { expect(err).to.not.exist() ipfsd.start(['--should-not-exist'], (err) => { expect(err).to.exist() @@ -162,7 +166,10 @@ types.forEach((type) => { const df = IPFSFactory.create(dfConfig) exec = findIpfsExecutable(type) - df.spawn({ exec }, (err, daemon) => { + df.spawn({ + exec, + initOptions: { bits: 1024 } + }, (err, daemon) => { expect(err).to.not.exist() expect(daemon).to.exist() @@ -190,7 +197,11 @@ types.forEach((type) => { const df = IPFSFactory.create(dfConfig) const exec = path.join('invalid', 'exec', 'ipfs') - df.spawn({ init: false, start: false, exec: exec }, (err, daemon) => { + df.spawn({ + init: false, + start: false, + exec: exec + }, (err, daemon) => { expect(err).to.not.exist() expect(daemon).to.exist() @@ -202,11 +213,12 @@ types.forEach((type) => { after((done) => ipfsd.stop(done)) it('should fail on init', (done) => { - ipfsd.init((err, node) => { - expect(err).to.exist() - expect(node).to.not.exist() - done() - }) + ipfsd.init({ bits: 1024 }, + (err, node) => { + expect(err).to.exist() + expect(node).to.not.exist() + done() + }) }) }) @@ -241,7 +253,9 @@ types.forEach((type) => { ipfsd = daemon cb() }), - (cb) => ipfsd.init(cb), + (cb) => ipfsd.init({ + initOptions: { bits: 1024 } + }, cb), (cb) => ipfsd.start(cb) ], done) }) From 6c7a0280eb93e50755b18f2ec1a8efc8e3cb558d Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Wed, 21 Feb 2018 04:11:35 -0600 Subject: [PATCH 11/15] fix: several changes from review --- src/endpoint/routes.js | 2 +- src/ipfsd-daemon.js | 11 +++-- src/ipfsd-in-proc.js | 4 +- test/add-retrieve.spec.js | 14 +++---- test/api.spec.js | 4 +- test/spawn-options.spec.js | 83 ++++++++++++++++++++------------------ test/start-stop.node.js | 72 ++++++++++++++++++++------------- 7 files changed, 103 insertions(+), 87 deletions(-) diff --git a/src/endpoint/routes.js b/src/endpoint/routes.js index 66e5d5ce..9e851c7b 100644 --- a/src/endpoint/routes.js +++ b/src/endpoint/routes.js @@ -101,7 +101,7 @@ module.exports = (server) => { return reply(boom.badRequest(err)) } - reply({ initialized: true }) + reply({ initialized: nodes[id].initialized }) }) }, config: routeConfig diff --git a/src/ipfsd-daemon.js b/src/ipfsd-daemon.js index 4be5c479..e19895a2 100644 --- a/src/ipfsd-daemon.js +++ b/src/ipfsd-daemon.js @@ -58,7 +58,7 @@ class Daemon { this._gatewayAddr = null this._started = false this.api = null - this.bits = process.env.IPFS_KEYSIZE || (this.opts.initOptions ? this.opts.initOptions.bits : null) + this.bits = this.opts.initOptions ? this.opts.initOptions.bits : null if (this.opts.env) { Object.assign(this.env, this.opts.env) @@ -121,7 +121,7 @@ class Daemon { * @returns {undefined} */ init (initOptions, callback) { - if (!callback) { + if (typeof initOptions === 'function') { callback = initOptions initOptions = {} } @@ -368,10 +368,9 @@ class Daemon { */ replaceConfig (config, callback) { const tmpFile = path.join(os.tmpdir(), hat()) - // I wanted to use streams here, but js-ipfs doesn't - // read from stdin when providing '-' (or piping) like - // go-ipfs, and adding it right now seems like a fair - // bit of work, so we're using tmp file for now - not ideal... + // TODO: we're using tmp file here until + // https://github.com/ipfs/js-ipfs/pull/785 + // is ready series([ (cb) => fs.writeFile(tmpFile, safeStringify(config), cb), (cb) => run( diff --git a/src/ipfsd-in-proc.js b/src/ipfsd-in-proc.js index cd59992e..2866212a 100644 --- a/src/ipfsd-in-proc.js +++ b/src/ipfsd-in-proc.js @@ -35,7 +35,7 @@ class Node { this._started = false this.initialized = false this.api = null - this.bits = process.env.IPFS_KEYSIZE || (this.opts.initOptions ? this.opts.initOptions.bits : null) + this.bits = this.opts.initOptions ? this.opts.initOptions.bits : null this.opts.EXPERIMENTAL = defaultsDeep({}, opts.EXPERIMENTAL, { pubsub: false, @@ -126,7 +126,7 @@ class Node { * @returns {undefined} */ init (initOptions, callback) { - if (!callback) { + if (typeof initOptions === 'function') { callback = initOptions initOptions = {} } diff --git a/test/add-retrieve.spec.js b/test/add-retrieve.spec.js index 11006971..b47f900f 100644 --- a/test/add-retrieve.spec.js +++ b/test/add-retrieve.spec.js @@ -11,8 +11,8 @@ const IPFSFactory = require('../src') const JSIPFS = require('ipfs') const tests = [ - { type: 'go' }, - { type: 'js' }, + { type: 'go', bits: 1024 }, + { type: 'js', bits: 512 }, { type: 'proc', exec: JSIPFS } ] @@ -21,13 +21,11 @@ describe('data can be put and fetched', () => { let ipfsd before(function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) const f = IPFSFactory.create(dfOpts) - f.spawn({ - initOptions: { bits: 1024 } - }, (err, _ipfsd) => { + f.spawn({ initOptions: { bits: dfOpts.bits } }, (err, _ipfsd) => { expect(err).to.not.exist() expect(_ipfsd).to.exist() expect(_ipfsd.api).to.exist() @@ -39,12 +37,12 @@ describe('data can be put and fetched', () => { }) after(function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) ipfsd.stop(done) }) it('put and fetch a block', function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) const data = Buffer.from('blorb') diff --git a/test/api.spec.js b/test/api.spec.js index 084ab5c6..249c159d 100644 --- a/test/api.spec.js +++ b/test/api.spec.js @@ -40,7 +40,7 @@ describe('ipfsd.api for Daemons', () => { }) it('test the ipfsd.api', function (done) { - this.timeout(40 * 1000) + this.timeout(20 * 1000) // TODO skip in browser - can we avoid using file system operations here? if (!isNode) { this.skip() } @@ -112,7 +112,7 @@ describe('ipfsd.api for Daemons', () => { }) it('check if API and Gateway addrs are correct', function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) df.spawn({ config: config, diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index 84287cba..4a259f7a 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -18,8 +18,8 @@ const os = require('os') const isWindows = os.platform() === 'win32' const tests = [ - { type: 'go' }, - { type: 'js' }, + { type: 'go', bits: 1024 }, + { type: 'js', bits: 512 }, { type: 'proc', exec: JSIPFS } ] @@ -72,7 +72,8 @@ describe('Spawn options', () => { repoPath: repoPath, init: false, start: false, - disposable: false + disposable: false, + initOptions: { bits: fOpts.bits } } f.spawn(options, (err, _ipfsd) => { @@ -89,12 +90,11 @@ describe('Spawn options', () => { it('ipfsd.init', function (done) { this.timeout(20 * 1000) - ipfsd.init({ bits: 1024 }, - (err) => { - expect(err).to.not.exist() - expect(ipfsd.initialized).to.be.ok() - done() - }) + ipfsd.init((err) => { + expect(err).to.not.exist() + expect(ipfsd.initialized).to.be.ok() + done() + }) }) it('ipfsd.start', function (done) { @@ -116,9 +116,6 @@ describe('Spawn options', () => { }) describe('spawn from a initialized repo', () => { - // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs - if (isWindows) { return } - // TODO: figure out why `proc` IPFS refuses // to start with a provided repo // `Error: Not able to start from state: uninitalized` @@ -127,6 +124,9 @@ describe('Spawn options', () => { let ipfsd it('f.spawn', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { return } + this.timeout(20 * 1000) const options = { @@ -147,6 +147,9 @@ describe('Spawn options', () => { }) it('ipfsd.start', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { return } + this.timeout(20 * 1000) ipfsd.start((err, api) => { @@ -158,6 +161,9 @@ describe('Spawn options', () => { }) it('ipfsd.stop', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { return } + this.timeout(20 * 1000) ipfsd.stop(done) @@ -170,23 +176,22 @@ describe('Spawn options', () => { let ipfsd it('create init and start node', function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) - f.spawn({ - initOptions: { bits: 1024 } - }, (err, _ipfsd) => { - expect(err).to.not.exist() - expect(_ipfsd).to.exist() - expect(_ipfsd.api).to.exist() - expect(_ipfsd.api.id).to.exist() + f.spawn({ initOptions: { bits: fOpts.bits } }, + (err, _ipfsd) => { + expect(err).to.not.exist() + expect(_ipfsd).to.exist() + expect(_ipfsd.api).to.exist() + expect(_ipfsd.api.id).to.exist() - ipfsd = _ipfsd - done() - }) + ipfsd = _ipfsd + done() + }) }) it('ipfsd.stop', function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) ipfsd.stop(done) }) @@ -194,7 +199,7 @@ describe('Spawn options', () => { describe('custom config options', () => { it('custom config', function (done) { - this.timeout(40 * 1000) + this.timeout(20 * 1000) const addr = '/ip4/127.0.0.1/tcp/5678' const swarmAddr1 = '/ip4/127.0.0.1/tcp/35666' @@ -207,7 +212,7 @@ describe('Spawn options', () => { } } - const options = { config: config, initOptions: { bits: 1024 } } + const options = { config: config, initOptions: { bits: fOpts.bits } } waterfall([ (cb) => f.spawn(options, cb), @@ -251,7 +256,7 @@ describe('Spawn options', () => { }) it('allows passing custom repo path to spawn', function (done) { - this.timeout(50 * 1000) + this.timeout(20 * 1000) const config = { Addresses: { @@ -269,7 +274,8 @@ describe('Spawn options', () => { init: false, start: false, repoPath: repoPath, - config: config + config: config, + initOptions: { bits: fOpts.bits } } series([ @@ -279,7 +285,7 @@ describe('Spawn options', () => { cb() }), (cb) => { - ipfsd.init({ bits: 1024 }, cb) + ipfsd.init(cb) }, (cb) => { ipfsd.start(cb) @@ -309,7 +315,7 @@ describe('Spawn options', () => { const options = { args: ['--enable-pubsub-experiment'], - initOptions: { bits: 1024 } + initOptions: { bits: fOpts.bits } } f.spawn(options, (err, _ipfsd) => { @@ -347,18 +353,17 @@ describe('Spawn options', () => { let ipfsd before(function (done) { - this.timeout(50 * 1000) - f.spawn({ - initOptions: { bits: 1024 } - }, (err, _ipfsd) => { - expect(err).to.not.exist() - ipfsd = _ipfsd - done() - }) + this.timeout(20 * 1000) + f.spawn({ initOptions: { bits: fOpts.bits } }, + (err, _ipfsd) => { + expect(err).to.not.exist() + ipfsd = _ipfsd + done() + }) }) after(function (done) { - this.timeout(50 * 1000) + this.timeout(20 * 1000) ipfsd.stop(done) }) diff --git a/test/start-stop.node.js b/test/start-stop.node.js index cff88d5f..7ce59707 100644 --- a/test/start-stop.node.js +++ b/test/start-stop.node.js @@ -20,16 +20,19 @@ const IPFSFactory = require('../src') const dfBaseConfig = require('./utils/df-config-nodejs') -const types = ['js', 'go'] +const tests = [ + { type: 'go', bits: 1024 }, + { type: 'js', bits: 512 } +] const exec = { js: 'ipfs/src/cli/bin.js', go: 'go-ipfs-dep/go-ipfs/ipfs' } -types.forEach((type) => { - describe(`${type} daemon`, () => { - const dfConfig = Object.assign({}, dfBaseConfig, { type: type }) +tests.forEach((fOpts) => { + describe(`${fOpts.type} daemon`, () => { + const dfConfig = Object.assign({}, dfBaseConfig, { type: fOpts.type }) describe('start and stop', () => { if (isWindows) { return } @@ -49,7 +52,7 @@ types.forEach((type) => { init: true, start: false, disposable: true, - initOptions: { bits: 1024 } + initOptions: { bits: fOpts.bits } }, (err, _ipfsd) => { expect(err).to.not.exist() expect(_ipfsd).to.exist() @@ -65,7 +68,7 @@ types.forEach((type) => { }) it('daemon exec path should match type', () => { - let execPath = exec[type] + let execPath = exec[fOpts.type] expect(ipfsd.exec).to.include.string(execPath) }) @@ -118,7 +121,7 @@ types.forEach((type) => { it('is stopped', function (done) { // shutdown grace period is already 10500 - this.timeout(30 * 1000) + this.timeout(20 * 1000) ipfsd.pid((pid) => { expect(pid).to.not.exist() @@ -136,13 +139,13 @@ types.forEach((type) => { it('fail on start with non supported flags', function (done) { // TODO js-ipfs doesn't fail on unrecognized args. // Decided what should be the desired behaviour - if (type === 'js') { return this.skip() } + if (fOpts.type === 'js') { return this.skip() } const df = IPFSFactory.create(dfConfig) df.spawn({ start: false, - initOptions: { bits: 1024 } + initOptions: { bits: fOpts.bits } }, (err, ipfsd) => { expect(err).to.not.exist() ipfsd.start(['--should-not-exist'], (err) => { @@ -161,14 +164,14 @@ types.forEach((type) => { let exec before(function (done) { - this.timeout(30 * 1000) + this.timeout(20 * 1000) const df = IPFSFactory.create(dfConfig) - exec = findIpfsExecutable(type) + exec = findIpfsExecutable(fOpts.type) df.spawn({ exec, - initOptions: { bits: 1024 } + initOptions: { bits: fOpts.bits } }, (err, daemon) => { expect(err).to.not.exist() expect(daemon).to.exist() @@ -200,7 +203,8 @@ types.forEach((type) => { df.spawn({ init: false, start: false, - exec: exec + exec: exec, + initOptions: { bits: fOpts.bits } }, (err, daemon) => { expect(err).to.not.exist() expect(daemon).to.exist() @@ -213,23 +217,19 @@ types.forEach((type) => { after((done) => ipfsd.stop(done)) it('should fail on init', (done) => { - ipfsd.init({ bits: 1024 }, - (err, node) => { - expect(err).to.exist() - expect(node).to.not.exist() - done() - }) + ipfsd.init((err, node) => { + expect(err).to.exist() + expect(node).to.not.exist() + done() + }) }) }) describe('start and stop multiple times', () => { - // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs - if (isWindows) { return } - let ipfsd before(function (done) { - this.timeout(40 * 1000) + this.timeout(20 * 1000) const f = IPFSFactory.create(dfConfig) @@ -238,7 +238,8 @@ types.forEach((type) => { init: false, start: false, disposable: false, - repoPath: tempDir(type), + repoPath: tempDir(fOpts.type), + initOptions: { bits: fOpts.bits }, config: { Addresses: { Swarm: [`/ip4/127.0.0.1/tcp/0`], @@ -253,18 +254,22 @@ types.forEach((type) => { ipfsd = daemon cb() }), - (cb) => ipfsd.init({ - initOptions: { bits: 1024 } - }, cb), + (cb) => ipfsd.init(cb), (cb) => ipfsd.start(cb) ], done) }) - it('should return a node', () => { + it('should return a node', function () { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { this.skip() } + expect(ipfsd).to.exist() }) - it('daemon should be running', (done) => { + it('daemon should be running', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { this.skip() } + ipfsd.pid((pid) => { expect(pid).to.exist() done() @@ -272,6 +277,9 @@ types.forEach((type) => { }) it('.stop', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { this.skip() } + this.timeout(20 * 1000) ipfsd.stop((err) => { @@ -284,6 +292,9 @@ types.forEach((type) => { }) it('.start', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { this.skip() } + this.timeout(20 * 1000) ipfsd.start((err) => { @@ -296,6 +307,9 @@ types.forEach((type) => { }) it('.stop and cleanup', function (done) { + // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs + if (isWindows) { this.skip() } + this.timeout(20 * 1000) ipfsd.stop((err) => { From 2ca9aa1e0dcabd523b1b57dbc7739444378ea3dc Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Wed, 21 Feb 2018 04:27:45 -0600 Subject: [PATCH 12/15] feat: proc nodes should run whit bits --- test/spawn-options.spec.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index 4a259f7a..8ccb3563 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -20,7 +20,7 @@ const isWindows = os.platform() === 'win32' const tests = [ { type: 'go', bits: 1024 }, { type: 'js', bits: 512 }, - { type: 'proc', exec: JSIPFS } + { type: 'proc', exec: JSIPFS, bits: 512 } ] const jsVersion = require('ipfs/package.json').version @@ -125,7 +125,7 @@ describe('Spawn options', () => { it('f.spawn', function (done) { // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs - if (isWindows) { return } + if (isWindows) { this.skip() } this.timeout(20 * 1000) @@ -148,7 +148,7 @@ describe('Spawn options', () => { it('ipfsd.start', function (done) { // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs - if (isWindows) { return } + if (isWindows) { this.skip() } this.timeout(20 * 1000) @@ -162,7 +162,7 @@ describe('Spawn options', () => { it('ipfsd.stop', function (done) { // TODO: wont work on windows until we get `/shutdown` implemented in js-ipfs - if (isWindows) { return } + if (isWindows) { this.skip() } this.timeout(20 * 1000) From 1351ddef7f14a405593b25c565c25f2752b3a792 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Wed, 21 Feb 2018 04:42:38 -0600 Subject: [PATCH 13/15] fix: dont forget about bits in add retrieve --- test/add-retrieve.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/add-retrieve.spec.js b/test/add-retrieve.spec.js index b47f900f..439efb35 100644 --- a/test/add-retrieve.spec.js +++ b/test/add-retrieve.spec.js @@ -13,7 +13,7 @@ const JSIPFS = require('ipfs') const tests = [ { type: 'go', bits: 1024 }, { type: 'js', bits: 512 }, - { type: 'proc', exec: JSIPFS } + { type: 'proc', exec: JSIPFS, bits: 512 } ] describe('data can be put and fetched', () => { From fb30e0ee3f16ad5fe66ea9c4fabd1e76d200a0a1 Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Wed, 21 Feb 2018 04:43:29 -0600 Subject: [PATCH 14/15] chore: update ipfs-api --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 796efc54..1ec702c9 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "detect-node": "^2.0.3", "hapi": "^16.6.2", "hat": "0.0.3", - "ipfs-api": "^17.3.0", + "ipfs-api": "^18.1.1", "ipfs-repo": "^0.18.5", "joi": "^13.0.2", "lodash.clone": "^4.5.0", From 174e9dceb670b1e92fa528f23a557d9667f324dc Mon Sep 17 00:00:00 2001 From: Dmitriy Ryajov Date: Wed, 21 Feb 2018 05:37:56 -0600 Subject: [PATCH 15/15] timeouts --- test/spawn-options.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/spawn-options.spec.js b/test/spawn-options.spec.js index 8ccb3563..3b3e4721 100644 --- a/test/spawn-options.spec.js +++ b/test/spawn-options.spec.js @@ -199,7 +199,7 @@ describe('Spawn options', () => { describe('custom config options', () => { it('custom config', function (done) { - this.timeout(20 * 1000) + this.timeout(30 * 1000) const addr = '/ip4/127.0.0.1/tcp/5678' const swarmAddr1 = '/ip4/127.0.0.1/tcp/35666'