From 37073e642d19892eb3fce7ec16d7832e8e0d31e9 Mon Sep 17 00:00:00 2001 From: Hugo Dias Date: Thu, 17 Oct 2019 13:51:30 +0100 Subject: [PATCH] fix: add profiles docs, support in validation and tests (#2545) * fix: add profiles docs, support in validation and tests * feat: support ipfs daemon --init-config --- README.md | 1 + docs/config.md | 44 +++++++++++++++++++++++++++--- src/cli/commands/daemon.js | 10 ++++++- src/cli/daemon.js | 2 +- src/core/components/config.js | 51 ++++++++++++++++++----------------- src/core/config.js | 3 ++- test/cli/daemon.js | 9 +++++++ test/core/config.spec.js | 11 ++++++++ test/core/init.spec.js | 15 +++++++++++ 9 files changed, 115 insertions(+), 31 deletions(-) diff --git a/README.md b/README.md index bcb345c98c..f0aca22e4f 100644 --- a/README.md +++ b/README.md @@ -307,6 +307,7 @@ Instead of a boolean, you may provide an object with custom initialization optio }) ``` - `pass` (string) A passphrase to encrypt keys. You should generally use the [top-level `pass` option](#optionspass) instead of the `init.pass` option (this one will take its value from the top-level option if not set). +- `profiles` (Array) Apply profile settings to config. ##### `options.start` diff --git a/docs/config.md b/docs/config.md index 13d33c37d9..b4bf37c92d 100644 --- a/docs/config.md +++ b/docs/config.md @@ -2,6 +2,44 @@ The js-ipfs config file is a JSON document located in the root directory of the js-ipfs repository. +#### Profiles + +Configuration profiles allow to tweak configuration quickly. Profiles can be +applied with `--profile` flag to `ipfs init` or with the `ipfs config profile +apply` command. When a profile is applied a backup of the configuration file +will be created in `$IPFS_PATH`. + +Available profiles: + +- `server` + + Recommended for nodes with public IPv4 address (servers, VPSes, etc.), + disables host and content discovery in local networks. + +- `local-discovery` + + Sets default values to fields affected by `server` profile, enables + discovery in local networks. + +- `test` + + Reduces external interference, useful for running ipfs in test environments. + Note that with these settings node won't be able to talk to the rest of the + network without manual bootstrap. + +- `default-networking` + + Restores default network settings. Inverse profile of the `test` profile. + +- `lowpower` + + Reduces daemon overhead on the system. May affect node functionality, + performance of content discovery and data fetching may be degraded. + +- `default-power` + + Inverse of "lowpower" profile. + ## Table of Contents - [`Addresses`](#addresses) @@ -121,18 +159,18 @@ Options for Multicast DNS peer discovery: - `Enabled` A boolean value for whether or not MDNS should be active. - + Default: `true` - `Interval` A number of seconds to wait between discovery checks. - + Default: `10` ### `webRTCStar` -WebRTCStar is a discovery mechanism prvided by a signalling-star that allows peer-to-peer communications in the browser. +WebRTCStar is a discovery mechanism prvided by a signalling-star that allows peer-to-peer communications in the browser. Options for webRTCstar peer discovery: diff --git a/src/cli/commands/daemon.js b/src/cli/commands/daemon.js index 3c3bbec345..b1e8aef26a 100644 --- a/src/cli/commands/daemon.js +++ b/src/cli/commands/daemon.js @@ -19,6 +19,13 @@ module.exports = { type: 'string', desc: 'Path to existing configuration file to be loaded during --init.' }) + .option('init-profile', { + type: 'string', + desc: 'Configuration profiles to apply for --init. See ipfs init --help for more.', + coerce: (value) => { + return (value || '').split(',') + } + }) .option('enable-sharding-experiment', { type: 'boolean', default: false @@ -73,7 +80,8 @@ module.exports = { ipnsPubsub: argv.enableNamesysPubsub, dht: argv.enableDhtExperiment, sharding: argv.enableShardingExperiment - } + }, + init: argv.initProfile ? { profiles: argv.initProfile } : true }) try { diff --git a/src/cli/daemon.js b/src/cli/daemon.js index e1a75e4b41..6fe2083e36 100644 --- a/src/cli/daemon.js +++ b/src/cli/daemon.js @@ -54,7 +54,7 @@ class Daemon { } // start the daemon - const ipfsOpts = Object.assign({ }, this._options, { init: true, start: true, libp2p }) + const ipfsOpts = Object.assign({ }, { init: true, start: true, libp2p }, this._options) const ipfs = new IPFS(ipfsOpts) await new Promise((resolve, reject) => { diff --git a/src/core/components/config.js b/src/core/components/config.js index f36e684521..381a36ce61 100644 --- a/src/core/components/config.js +++ b/src/core/components/config.js @@ -56,7 +56,7 @@ async function listProfiles (options) { // eslint-disable-line require-await const profiles = { server: { - description: 'Disables local host discovery - recommended when running IPFS on machines with public IPv4 addresses.', + description: 'Recommended for nodes with public IPv4 address (servers, VPSes, etc.), disables host and content discovery in local networks.', transform: (config) => { config.Discovery.MDNS.Enabled = false config.Discovery.webRTCStar.Enabled = false @@ -65,7 +65,7 @@ const profiles = { } }, 'local-discovery': { - description: 'Enables local host discovery - inverse of "server" profile.', + description: 'Sets default values to fields affected by `server` profile, enables discovery in local networks.', transform: (config) => { config.Discovery.MDNS.Enabled = true config.Discovery.webRTCStar.Enabled = true @@ -73,29 +73,8 @@ const profiles = { return config } }, - lowpower: { - description: 'Reduces daemon overhead on the system - recommended for low power systems.', - transform: (config) => { - config.Swarm = config.Swarm || {} - config.Swarm.ConnMgr = config.Swarm.ConnMgr || {} - config.Swarm.ConnMgr.LowWater = 20 - config.Swarm.ConnMgr.HighWater = 40 - - return config - } - }, - 'default-power': { - description: 'Inverse of "lowpower" profile.', - transform: (config) => { - const defaultConfig = getDefaultConfig() - - config.Swarm = defaultConfig.Swarm - - return config - } - }, test: { - description: 'Reduces external interference of IPFS daemon - for running the daemon in test environments.', + description: 'Reduces external interference, useful for running ipfs in test environments. Note that with these settings node won\'t be able to talk to the rest of the network without manual bootstrap.', transform: (config) => { const defaultConfig = getDefaultConfig() @@ -110,7 +89,7 @@ const profiles = { } }, 'default-networking': { - description: 'Restores default network settings - inverse of "test" profile.', + description: 'Restores default network settings. Inverse profile of the `test` profile.', transform: (config) => { const defaultConfig = getDefaultConfig() @@ -121,9 +100,31 @@ const profiles = { config.Discovery.MDNS.Enabled = defaultConfig.Discovery.MDNS.Enabled config.Discovery.webRTCStar.Enabled = defaultConfig.Discovery.webRTCStar.Enabled + return config + } + }, + lowpower: { + description: 'Reduces daemon overhead on the system. May affect node functionality,performance of content discovery and data fetching may be degraded. Recommended for low power systems.', + transform: (config) => { + config.Swarm = config.Swarm || {} + config.Swarm.ConnMgr = config.Swarm.ConnMgr || {} + config.Swarm.ConnMgr.LowWater = 20 + config.Swarm.ConnMgr.HighWater = 40 + + return config + } + }, + 'default-power': { + description: 'Inverse of "lowpower" profile.', + transform: (config) => { + const defaultConfig = getDefaultConfig() + + config.Swarm = defaultConfig.Swarm + return config } } + } module.exports.profiles = profiles diff --git a/src/core/config.js b/src/core/config.js index beb1d149f8..d0070d1a32 100644 --- a/src/core/config.js +++ b/src/core/config.js @@ -37,7 +37,8 @@ const configSchema = s({ bits: 'number?', emptyRepo: 'boolean?', privateKey: optional(s('object|string')), // object should be a custom type for PeerId using 'kind-of' - pass: 'string?' + pass: 'string?', + profiles: 'array?' })])), start: 'boolean?', offline: 'boolean?', diff --git a/test/cli/daemon.js b/test/cli/daemon.js index 7dbe89f9d8..68fc981eb6 100644 --- a/test/cli/daemon.js +++ b/test/cli/daemon.js @@ -286,4 +286,13 @@ describe('daemon', () => { const out = await ipfs('config \'Addresses.API\'') expect(out).to.be.eq('/ip4/127.0.0.1/tcp/9999\n') }) + + it('should init with profiles', async function () { + this.timeout(100 * 1000) + const daemon = ipfs('daemon --init-profile test') + + await daemonReady(daemon) + const out = await ipfs('config Bootstrap') + expect(out).to.be.eq('[]\n') + }) }) diff --git a/test/core/config.spec.js b/test/core/config.spec.js index bd5fa43814..ee1fa4a00e 100644 --- a/test/core/config.spec.js +++ b/test/core/config.spec.js @@ -209,4 +209,15 @@ describe('config', () => { cfgs.forEach(cfg => expect(() => config.validate(cfg)).to.throw()) }) + + it('should validate valid profiles', () => { + expect( + () => config.validate({ init: { profiles: ['test'] } }) + ).to.not.throw() + }) + it('should validate invalid profiles', () => { + expect( + () => config.validate({ init: { profiles: 'test' } }) + ).to.throw() + }) }) diff --git a/test/core/init.spec.js b/test/core/init.spec.js index 182438cef7..3d8d094b09 100644 --- a/test/core/init.spec.js +++ b/test/core/init.spec.js @@ -85,4 +85,19 @@ describe('init', () => { }) }) }) + + it('profiles apply one', async () => { + await ipfs.init({ profiles: ['test'] }) + + const config = await repo.config.get() + expect(config.Bootstrap).to.be.empty() + }) + + it('profiles apply multiple', async () => { + await ipfs.init({ profiles: ['test', 'local-discovery'] }) + + const config = await repo.config.get() + expect(config.Bootstrap).to.be.empty() + expect(config.Discovery.MDNS.Enabled).to.be.true() + }) })