This repository has been archived by the owner on Feb 12, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Add config profile endpoint and CLI (#2165)
* feat: config profile * fix: increase command count * feat: ipfs init --profile option * chore: update dependencies License: MIT Signed-off-by: Alan Shaw <alan.shaw@protocol.ai> * fix: make sure default-config still works * chore: add http api tests * chore: address PR comments * chore: fix linting * test: let internals of config profiles be internal * chore: add test for listing profiles * chore: turn profile list into list outside of core * chore: expose profile list over http * fix: use chai exported from interface tests Workaround for chaijs/chai#1298 * chore: fix linting * chore: update deps and make keys agree with spec * chore: update interface tests * chore: udpate test skips/includes * chore: fix up interface tests
- Loading branch information
1 parent
8c01259
commit 7314f0d
Showing
20 changed files
with
467 additions
and
48 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
'use strict' | ||
|
||
module.exports = { | ||
command: 'profile <command>', | ||
|
||
description: 'Interact with config profiles.', | ||
|
||
builder (yargs) { | ||
return yargs | ||
.commandDir('profile') | ||
}, | ||
|
||
handler (argv) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
'use strict' | ||
|
||
const JSONDiff = require('jsondiffpatch') | ||
|
||
module.exports = { | ||
command: 'apply <profile>', | ||
|
||
describe: 'Apply profile to config', | ||
|
||
builder: { | ||
'dry-run': { | ||
type: 'boolean', | ||
describe: 'print difference between the current config and the config that would be generated.' | ||
} | ||
}, | ||
|
||
handler (argv) { | ||
argv.resolve((async () => { | ||
const ipfs = await argv.getIpfs() | ||
const diff = await ipfs.config.profiles.apply(argv.profile, { dryRun: argv.dryRun }) | ||
const delta = JSONDiff.diff(diff.original, diff.updated) | ||
const res = JSONDiff.formatters.console.format(delta, diff.original) | ||
|
||
if (res) { | ||
argv.print(res) | ||
|
||
if (ipfs.send) { | ||
argv.print('\nThe IPFS daemon is running in the background, you may need to restart it for changes to take effect.') | ||
} | ||
} else { | ||
argv.print(`IPFS config already contains the settings from the '${argv.profile}' profile`) | ||
} | ||
})()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
'use strict' | ||
|
||
module.exports = { | ||
command: 'ls', | ||
|
||
describe: 'List available config profiles', | ||
|
||
builder: {}, | ||
|
||
handler (argv) { | ||
argv.resolve( | ||
(async () => { | ||
const ipfs = await argv.getIpfs() | ||
|
||
for (const profile of await ipfs.config.profiles.list()) { | ||
argv.print(`${profile.name}:\n ${profile.description}`) | ||
} | ||
})() | ||
) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,129 @@ | ||
'use strict' | ||
|
||
const callbackify = require('callbackify') | ||
const getDefaultConfig = require('../runtime/config-nodejs.js') | ||
const log = require('debug')('ipfs:core:config') | ||
|
||
module.exports = function config (self) { | ||
return { | ||
get: callbackify.variadic(self._repo.config.get), | ||
set: callbackify(self._repo.config.set), | ||
replace: callbackify.variadic(self._repo.config.set) | ||
replace: callbackify.variadic(self._repo.config.set), | ||
profiles: { | ||
apply: callbackify.variadic(applyProfile), | ||
list: callbackify.variadic(listProfiles) | ||
} | ||
} | ||
|
||
async function applyProfile (profileName, opts) { | ||
opts = opts || {} | ||
const { dryRun } = opts | ||
|
||
const profile = profiles[profileName] | ||
|
||
if (!profile) { | ||
throw new Error(`No profile with name '${profileName}' exists`) | ||
} | ||
|
||
try { | ||
const oldCfg = await self.config.get() | ||
let newCfg = JSON.parse(JSON.stringify(oldCfg)) // clone | ||
newCfg = profile.transform(newCfg) | ||
|
||
if (!dryRun) { | ||
await self.config.replace(newCfg) | ||
} | ||
|
||
// Scrub private key from output | ||
delete oldCfg.Identity.PrivKey | ||
delete newCfg.Identity.PrivKey | ||
|
||
return { original: oldCfg, updated: newCfg } | ||
} catch (err) { | ||
log(err) | ||
|
||
throw new Error(`Could not apply profile '${profileName}' to config: ${err.message}`) | ||
} | ||
} | ||
} | ||
|
||
async function listProfiles (options) { // eslint-disable-line require-await | ||
return Object.keys(profiles).map(name => ({ | ||
name, | ||
description: profiles[name].description | ||
})) | ||
} | ||
|
||
const profiles = { | ||
server: { | ||
description: 'Disables local host discovery - recommended when running IPFS on machines with public IPv4 addresses.', | ||
transform: (config) => { | ||
config.Discovery.MDNS.Enabled = false | ||
config.Discovery.webRTCStar.Enabled = false | ||
|
||
return config | ||
} | ||
}, | ||
'local-discovery': { | ||
description: 'Enables local host discovery - inverse of "server" profile.', | ||
transform: (config) => { | ||
config.Discovery.MDNS.Enabled = true | ||
config.Discovery.webRTCStar.Enabled = true | ||
|
||
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.', | ||
transform: (config) => { | ||
const defaultConfig = getDefaultConfig() | ||
|
||
config.Addresses.API = defaultConfig.Addresses.API ? '/ip4/127.0.0.1/tcp/0' : '' | ||
config.Addresses.Gateway = defaultConfig.Addresses.Gateway ? '/ip4/127.0.0.1/tcp/0' : '' | ||
config.Addresses.Swarm = defaultConfig.Addresses.Swarm.length ? ['/ip4/127.0.0.1/tcp/0'] : [] | ||
config.Bootstrap = [] | ||
config.Discovery.MDNS.Enabled = false | ||
config.Discovery.webRTCStar.Enabled = false | ||
|
||
return config | ||
} | ||
}, | ||
'default-networking': { | ||
description: 'Restores default network settings - inverse of "test" profile.', | ||
transform: (config) => { | ||
const defaultConfig = getDefaultConfig() | ||
|
||
config.Addresses.API = defaultConfig.Addresses.API | ||
config.Addresses.Gateway = defaultConfig.Addresses.Gateway | ||
config.Addresses.Swarm = defaultConfig.Addresses.Swarm | ||
config.Bootstrap = defaultConfig.Bootstrap | ||
config.Discovery.MDNS.Enabled = defaultConfig.Discovery.MDNS.Enabled | ||
config.Discovery.webRTCStar.Enabled = defaultConfig.Discovery.webRTCStar.Enabled | ||
|
||
return config | ||
} | ||
} | ||
} | ||
|
||
module.exports.profiles = profiles |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.