diff --git a/cmd/ipfs/init.go b/cmd/ipfs/init.go index 1215d0481f0..6793d9843e4 100644 --- a/cmd/ipfs/init.go +++ b/cmd/ipfs/init.go @@ -33,11 +33,7 @@ Initializes ipfs configuration files and generates a new keypair. If you are going to run IPFS in server environment, you may want to initialize it using 'server' profile. -Available profiles: - 'server' - Disables local host discovery, recommended when - running IPFS on machines with public IPv4 addresses. - 'test' - Reduces external interference of IPFS daemon, this - is useful when using the daemon in test environments. +For the list of available profiles see 'ipfs config profile --help' ipfs uses a repository in the local file system. By default, the repo is located at ~/.ipfs. To change the repo location, set the $IPFS_PATH @@ -165,7 +161,7 @@ func doInit(out io.Writer, repoRoot string, empty bool, nBitsForKeypair int, con return fmt.Errorf("invalid configuration profile: %s", profile) } - if err := transformer(conf); err != nil { + if err := transformer.Transform(conf); err != nil { return err } } diff --git a/core/commands/config.go b/core/commands/config.go index 2ac87b4892d..29641b82bcd 100644 --- a/core/commands/config.go +++ b/core/commands/config.go @@ -296,6 +296,10 @@ can't be undone. var configProfileCmd = &cmds.Command{ Helptext: cmdkit.HelpText{ Tagline: "Apply profiles to config.", + ShortDescription: fmt.Sprintf(` +Available profiles: +%s +`, buildProfileHelp()), }, Subcommands: map[string]*cmds.Command{ @@ -317,7 +321,7 @@ var configProfileApplyCmd = &cmds.Command{ return } - err := transformConfig(req.InvocContext().ConfigRoot, req.Arguments()[0], profile) + err := transformConfig(req.InvocContext().ConfigRoot, req.Arguments()[0], profile.Transform) if err != nil { res.SetError(err, cmdkit.ErrNormal) return @@ -326,6 +330,21 @@ var configProfileApplyCmd = &cmds.Command{ }, } +func buildProfileHelp() string { + var out string + + for name, profile := range config.Profiles { + dlines := strings.Split(profile.Description, "\n") + for i := range dlines { + dlines[i] = " " + dlines[i] + } + + out = out + fmt.Sprintf(" '%s':\n%s\n", name, strings.Join(dlines, "\n")) + } + + return out +} + func transformConfig(configRoot string, configName string, transformer config.Transformer) error { r, err := fsrepo.Open(configRoot) if err != nil { diff --git a/repo/config/profile.go b/repo/config/profile.go index 74383cda63f..d51fed81842 100644 --- a/repo/config/profile.go +++ b/repo/config/profile.go @@ -3,6 +3,15 @@ package config // Transformer is a function which takes configuration and applies some filter to it type Transformer func(c *Config) error +// Profile contains the profile transformer the description of the profile +type Profile struct { + // Description briefly describes the functionality of the profile + Description string + + // Transform takes ipfs configuration and applies the profile to it + Transform Transformer +} + // defaultServerFilters has a list of non-routable IPv4 prefixes // according to http://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml var defaultServerFilters = []string{ @@ -24,54 +33,96 @@ var defaultServerFilters = []string{ } // Profiles is a map holding configuration transformers. Docs are in docs/config.md -var Profiles = map[string]Transformer{ - "server": func(c *Config) error { - c.Addresses.NoAnnounce = appendSingle(c.Addresses.NoAnnounce, defaultServerFilters) - c.Swarm.AddrFilters = appendSingle(c.Swarm.AddrFilters, defaultServerFilters) - c.Discovery.MDNS.Enabled = false - return nil +var Profiles = map[string]Profile{ + "server": { + Description: `Disables local host discovery, recommended when +running IPFS on machines with public IPv4 addresses.`, + + Transform: func(c *Config) error { + c.Addresses.NoAnnounce = appendSingle(c.Addresses.NoAnnounce, defaultServerFilters) + c.Swarm.AddrFilters = appendSingle(c.Swarm.AddrFilters, defaultServerFilters) + c.Discovery.MDNS.Enabled = false + return nil + }, }, - "local-discovery": func(c *Config) error { - c.Addresses.NoAnnounce = deleteEntries(c.Addresses.NoAnnounce, defaultServerFilters) - c.Swarm.AddrFilters = deleteEntries(c.Swarm.AddrFilters, defaultServerFilters) - c.Discovery.MDNS.Enabled = true - return nil + + "local-discovery": { + Description: `Sets default values to fields affected by the server +profile, enables discovery in local networks.`, + + Transform: func(c *Config) error { + c.Addresses.NoAnnounce = deleteEntries(c.Addresses.NoAnnounce, defaultServerFilters) + c.Swarm.AddrFilters = deleteEntries(c.Swarm.AddrFilters, defaultServerFilters) + c.Discovery.MDNS.Enabled = true + return nil + }, }, - "test": func(c *Config) error { - c.Addresses.API = "/ip4/127.0.0.1/tcp/0" - c.Addresses.Gateway = "/ip4/127.0.0.1/tcp/0" - c.Addresses.Swarm = []string{ - "/ip4/127.0.0.1/tcp/0", - } - - c.Swarm.DisableNatPortMap = true - - c.Bootstrap = []string{} - c.Discovery.MDNS.Enabled = false - return nil + "test": { + Description: `Reduces external interference of IPFS daemon, this +is useful when using the daemon in test environments.`, + + Transform: func(c *Config) error { + c.Addresses.API = "/ip4/127.0.0.1/tcp/0" + c.Addresses.Gateway = "/ip4/127.0.0.1/tcp/0" + c.Addresses.Swarm = []string{ + "/ip4/127.0.0.1/tcp/0", + } + + c.Swarm.DisableNatPortMap = true + + c.Bootstrap = []string{} + c.Discovery.MDNS.Enabled = false + return nil + }, }, - "default-networking": func(c *Config) error { - c.Addresses = addressesConfig() + "default-networking": { + Description: `Restores default network settings. +Inverse profile of the test profile.`, + + Transform: func(c *Config) error { + c.Addresses = addressesConfig() - c.Swarm.DisableNatPortMap = false - c.Discovery.MDNS.Enabled = true - return nil + c.Swarm.DisableNatPortMap = false + c.Discovery.MDNS.Enabled = true + return nil + }, }, - "badgerds": func(c *Config) error { - c.Datastore.Spec = map[string]interface{}{ - "type": "measure", - "prefix": "badger.datastore", - "child": map[string]interface{}{ - "type": "badgerds", - "path": "badgerds", - "syncWrites": true, - }, - } - return nil + "badgerds": { + Description: `Replaces default datastore configuration with experimental +badger datastore. + +If you apply this profile after ipfs init, you will need +to convert your datastore to the new configuration. +You can do this using ipfs-ds-convert. + +WARNING: badger datastore is experimental. +Make sure to backup your data frequently.`, + + Transform: func(c *Config) error { + c.Datastore.Spec = map[string]interface{}{ + "type": "measure", + "prefix": "badger.datastore", + "child": map[string]interface{}{ + "type": "badgerds", + "path": "badgerds", + "syncWrites": true, + }, + } + return nil + }, }, - "default-datastore": func(c *Config) error { - c.Datastore.Spec = DefaultDatastoreConfig().Spec - return nil + "default-datastore": { + Description: `Restores default datastore configuration. + +If you apply this profile after ipfs init, you will need +to convert your datastore to the new configuration. +You can do this using ipfs-ds-convert. +`, + + Transform: func(c *Config) error { + c.Datastore.Spec = DefaultDatastoreConfig().Spec + return nil + }, }, }