Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 26 additions & 4 deletions cmd/ipfs/kubo/daemon.go
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,26 @@ environment variable:

export IPFS_PATH=/path/to/ipfsrepo

CONFIGURATION FILE MANAGEMENT

The --init-config and --config-file flags serve different purposes:

--init-config <path>
Copies a configuration template to $IPFS_PATH/config during --init.
This is a one-time operation; subsequent changes to the template
have no effect.

--config-file <path>
Uses an external configuration file directly for all commands.
Takes precedence over $IPFS_PATH/config. The config is never copied;
Kubo always reads from this path. Useful for Kubernetes ConfigMaps
or container deployments where config should be managed separately
from the repo data.

Example using --config-file for Kubernetes:

ipfs daemon --init --repo-dir /data/ipfs --config-file /etc/ipfs/config

DEPRECATION NOTICE

Previously, Kubo used an environment variable as seen below:
Expand All @@ -169,7 +189,7 @@ Headers.

Options: []cmds.Option{
cmds.BoolOption(initOptionKwd, "Initialize Kubo with default settings if not already initialized"),
cmds.StringOption(initConfigOptionKwd, "Path to existing configuration file to be loaded during --init"),
cmds.StringOption(initConfigOptionKwd, "Path to configuration template to copy during --init (one-time). For persistent external config, use --config-file instead"),
cmds.StringOption(initProfileOptionKwd, "Configuration profiles to apply for --init. See ipfs init --help for more"),
cmds.StringOption(routingOptionKwd, "Overrides the routing option").WithDefault(routingOptionDefaultKwd),
cmds.BoolOption(mountKwd, "Mounts IPFS to the filesystem using FUSE (experimental)"),
Expand Down Expand Up @@ -266,6 +286,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
if initialize && !fsrepo.IsInitialized(cctx.ConfigRoot) {
cfgLocation, _ := req.Options[initConfigOptionKwd].(string)
profiles, _ := req.Options[initProfileOptionKwd].(string)
configFileOpt, _ := req.Options[commands.ConfigFileOption].(string)
var conf *config.Config

if cfgLocation != "" {
Expand All @@ -287,7 +308,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
}
}

if err = doInit(os.Stdout, cctx.ConfigRoot, false, profiles, conf); err != nil {
if err = doInit(os.Stdout, cctx.ConfigRoot, configFileOpt, false, profiles, conf); err != nil {
return err
}
}
Expand All @@ -297,7 +318,8 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment

// acquire the repo lock _before_ constructing a node. we need to make
// sure we are permitted to access the resources (datastore, etc.)
repo, err := fsrepo.Open(cctx.ConfigRoot)
configFileOpt, _ := req.Options[commands.ConfigFileOption].(string)
repo, err := fsrepo.OpenWithUserConfig(cctx.ConfigRoot, configFileOpt)
switch err {
default:
return err
Expand Down Expand Up @@ -347,7 +369,7 @@ func daemonFunc(req *cmds.Request, re cmds.ResponseEmitter, env cmds.Environment
// Note: Migration caching/pinning functionality has been deprecated
// The hybrid migration system handles legacy migrations more efficiently

repo, err = fsrepo.Open(cctx.ConfigRoot)
repo, err = fsrepo.OpenWithUserConfig(cctx.ConfigRoot, configFileOpt)
if err != nil {
return err
}
Expand Down
21 changes: 11 additions & 10 deletions cmd/ipfs/kubo/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ environment variable:
`,
},
Arguments: []cmds.Argument{
cmds.FileArg("default-config", false, false, "Initialize with the given configuration.").EnableStdin(),
cmds.FileArg("default-config", false, false, "Initialize using this configuration file as a template. Identity and all other values are preserved. The file is copied to --config-file location (or $IPFS_PATH/config if not set).").EnableStdin(),
},
Options: []cmds.Option{
cmds.StringOption(algorithmOptionName, "a", "Cryptographic algorithm to use for key generation.").WithDefault(algorithmDefault),
Expand Down Expand Up @@ -124,7 +124,8 @@ environment variable:
}

profiles, _ := req.Options[profileOptionName].(string)
return doInit(os.Stdout, cctx.ConfigRoot, empty, profiles, conf)
configFileOpt, _ := req.Options[commands.ConfigFileOption].(string)
return doInit(os.Stdout, cctx.ConfigRoot, configFileOpt, empty, profiles, conf)
},
}

Expand All @@ -146,7 +147,7 @@ func applyProfiles(conf *config.Config, profiles string) error {
return nil
}

func doInit(out io.Writer, repoRoot string, empty bool, confProfiles string, conf *config.Config) error {
func doInit(out io.Writer, repoRoot string, configFilePath string, empty bool, confProfiles string, conf *config.Config) error {
if _, err := fmt.Fprintf(out, "initializing IPFS node at %s\n", repoRoot); err != nil {
return err
}
Expand All @@ -163,17 +164,17 @@ func doInit(out io.Writer, repoRoot string, empty bool, confProfiles string, con
return err
}

if err := fsrepo.Init(repoRoot, conf); err != nil {
if err := fsrepo.InitWithUserConfig(repoRoot, configFilePath, conf); err != nil {
return err
}

if !empty {
if err := addDefaultAssets(out, repoRoot); err != nil {
if err := addDefaultAssets(out, repoRoot, configFilePath); err != nil {
return err
}
}

return initializeIpnsKeyspace(repoRoot)
return initializeIpnsKeyspace(repoRoot, configFilePath)
}

func checkWritable(dir string) error {
Expand Down Expand Up @@ -204,11 +205,11 @@ func checkWritable(dir string) error {
return err
}

func addDefaultAssets(out io.Writer, repoRoot string) error {
func addDefaultAssets(out io.Writer, repoRoot string, configFilePath string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

r, err := fsrepo.Open(repoRoot)
r, err := fsrepo.OpenWithUserConfig(repoRoot, configFilePath)
if err != nil { // NB: repo is owned by the node
return err
}
Expand All @@ -233,11 +234,11 @@ func addDefaultAssets(out io.Writer, repoRoot string) error {
return err
}

func initializeIpnsKeyspace(repoRoot string) error {
func initializeIpnsKeyspace(repoRoot string, configFilePath string) error {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()

r, err := fsrepo.Open(repoRoot)
r, err := fsrepo.OpenWithUserConfig(repoRoot, configFilePath)
if err != nil { // NB: repo is owned by the node
return err
}
Expand Down
10 changes: 6 additions & 4 deletions cmd/ipfs/kubo/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ const (

type PluginPreloader func(*loader.PluginLoader) error

func loadPlugins(repoPath string, preload PluginPreloader) (*loader.PluginLoader, error) {
plugins, err := loader.NewPluginLoader(repoPath)
func loadPlugins(repoPath string, configFilePath string, preload PluginPreloader) (*loader.PluginLoader, error) {
plugins, err := loader.NewPluginLoader(repoPath, configFilePath)
if err != nil {
return nil, fmt.Errorf("error loading plugins: %s", err)
}
Expand Down Expand Up @@ -116,7 +116,8 @@ func BuildEnv(pl PluginPreloader) func(ctx context.Context, req *cmds.Request) (
}
log.Debugf("config path is %s", repoPath)

plugins, err := loadPlugins(repoPath, pl)
configFileOpt, _ := req.Options[corecmds.ConfigFileOption].(string)
plugins, err := loadPlugins(repoPath, configFileOpt, pl)
if err != nil {
return nil, err
}
Expand All @@ -132,7 +133,8 @@ func BuildEnv(pl PluginPreloader) func(ctx context.Context, req *cmds.Request) (
return nil, errors.New("constructing node without a request")
}

r, err := fsrepo.Open(repoPath)
configFileOpt, _ := req.Options[corecmds.ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(repoPath, configFileOpt)
if err != nil { // repo is owned by the node
return nil, err
}
Expand Down
12 changes: 8 additions & 4 deletions core/commands/bootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,8 @@ the bootstrap list, which gets resolved using the AutoConf system.
return err
}

r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -139,7 +140,8 @@ var bootstrapRemoveCmd = &cmds.Command{
return err
}

r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -184,7 +186,8 @@ var bootstrapRemoveAllCmd = &cmds.Command{
return err
}

r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -224,7 +227,8 @@ var bootstrapListCmd = &cmds.Command{
return err
}

r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down
3 changes: 3 additions & 0 deletions core/commands/cmdutils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ const (
AllowBigBlockOptionName = "allow-big-block"
SoftBlockLimit = 1024 * 1024 // https://github.com/ipfs/kubo/issues/7421#issuecomment-910833499
MaxPinNameBytes = 255 // Maximum number of bytes allowed for a pin name

// ConfigFileOption is the name of the global --config-file option
ConfigFileOption = "config-file"
)

var AllowBigBlockOption cmds.Option
Expand Down
13 changes: 8 additions & 5 deletions core/commands/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,8 @@ Set multiple values in the 'Addresses.AppendAnnounce' array:
if err != nil {
return err
}
r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -362,7 +363,8 @@ can't be undone.
return err
}

r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -414,7 +416,8 @@ var configProfileApplyCmd = &cmds.Command{
return err
}

oldCfg, newCfg, err := transformConfig(cfgRoot, req.Arguments[0], profile.Transform, dryRun)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
oldCfg, newCfg, err := transformConfig(cfgRoot, configFileOpt, req.Arguments[0], profile.Transform, dryRun)
if err != nil {
return err
}
Expand Down Expand Up @@ -482,8 +485,8 @@ func scrubPrivKey(cfg *config.Config) (map[string]interface{}, error) {
// If dryRun is true, repo's config should not be updated and persisted
// to storage. Otherwise, repo's config should be updated and persisted
// to storage.
func transformConfig(configRoot string, configName string, transformer config.Transformer, dryRun bool) (*config.Config, *config.Config, error) {
r, err := fsrepo.Open(configRoot)
func transformConfig(configRoot string, configFilePath string, configName string, transformer config.Transformer, dryRun bool) (*config.Config, *config.Config, error) {
r, err := fsrepo.OpenWithUserConfig(configRoot, configFilePath)
if err != nil {
return nil, nil, err
}
Expand Down
10 changes: 6 additions & 4 deletions core/commands/keystore.go
Original file line number Diff line number Diff line change
Expand Up @@ -412,7 +412,8 @@ The PEM format allows for key generation outside of the IPFS node:
return err
}

r, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
r, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -621,13 +622,14 @@ environment variable:
if oldKey == "self" {
return fmt.Errorf("keystore name for back up cannot be named 'self'")
}
return doRotate(os.Stdout, cctx.ConfigRoot, oldKey, algorithm, nBitsForKeypair, nBitsGiven)
configFileOpt, _ := req.Options[ConfigFileOption].(string)
return doRotate(os.Stdout, cctx.ConfigRoot, configFileOpt, oldKey, algorithm, nBitsForKeypair, nBitsGiven)
},
}

func doRotate(out io.Writer, repoRoot string, oldKey string, algorithm string, nBitsForKeypair int, nBitsGiven bool) error {
func doRotate(out io.Writer, repoRoot string, configFilePath string, oldKey string, algorithm string, nBitsForKeypair int, nBitsGiven bool) error {
// Open repo
repo, err := fsrepo.Open(repoRoot)
repo, err := fsrepo.OpenWithUserConfig(repoRoot, configFilePath)
if err != nil {
return fmt.Errorf("opening repo (%v)", err)
}
Expand Down
27 changes: 15 additions & 12 deletions core/commands/pin/remotepin.go
Original file line number Diff line number Diff line change
Expand Up @@ -473,7 +473,8 @@ TIP:
if err != nil {
return err
}
repo, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[cmdutils.ConfigFileOption].(string)
repo, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -529,7 +530,8 @@ var rmRemotePinServiceCmd = &cmds.Command{
if err != nil {
return err
}
repo, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[cmdutils.ConfigFileOption].(string)
repo, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand Down Expand Up @@ -580,7 +582,8 @@ TIP: pass '--enc=json' for more useful JSON output.
if err != nil {
return err
}
repo, err := fsrepo.Open(cfgRoot)
configFileOpt, _ := req.Options[cmdutils.ConfigFileOption].(string)
repo, err := fsrepo.OpenWithUserConfig(cfgRoot, configFileOpt)
if err != nil {
return err
}
Expand All @@ -600,8 +603,8 @@ TIP: pass '--enc=json' for more useful JSON output.

// if --pin-count is passed, we try to fetch pin numbers from remote service
if req.Options[pinServiceStatOptionName].(bool) {
lsRemotePinCount := func(ctx context.Context, env cmds.Environment, svcName string) (*PinCount, error) {
c, err := getRemotePinService(env, svcName)
lsRemotePinCount := func(ctx context.Context, env cmds.Environment, configFileOpt string, svcName string) (*PinCount, error) {
c, err := getRemotePinService(env, configFileOpt, svcName)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -646,7 +649,7 @@ TIP: pass '--enc=json' for more useful JSON output.
return pc, nil
}

pinCount, err := lsRemotePinCount(ctx, env, svcName)
pinCount, err := lsRemotePinCount(ctx, env, configFileOpt, svcName)

// PinCount is present only if we were able to fetch counts.
// We don't want to break listing of services so this is best-effort.
Expand Down Expand Up @@ -731,32 +734,32 @@ func getRemotePinServiceFromRequest(req *cmds.Request, env cmds.Environment) (*p
}

serviceStr := service.(string)
var err error
c, err := getRemotePinService(env, serviceStr)
configFileOpt, _ := req.Options[cmdutils.ConfigFileOption].(string)
c, err := getRemotePinService(env, configFileOpt, serviceStr)
if err != nil {
return nil, err
}

return c, nil
}

func getRemotePinService(env cmds.Environment, name string) (*pinclient.Client, error) {
func getRemotePinService(env cmds.Environment, configFilePath string, name string) (*pinclient.Client, error) {
if name == "" {
return nil, fmt.Errorf("remote pinning service name not specified")
}
endpoint, key, err := getRemotePinServiceInfo(env, name)
endpoint, key, err := getRemotePinServiceInfo(env, configFilePath, name)
if err != nil {
return nil, err
}
return pinclient.NewClient(endpoint, key), nil
}

func getRemotePinServiceInfo(env cmds.Environment, name string) (endpoint, key string, err error) {
func getRemotePinServiceInfo(env cmds.Environment, configFilePath string, name string) (endpoint, key string, err error) {
cfgRoot, err := cmdenv.GetConfigRoot(env)
if err != nil {
return "", "", err
}
repo, err := fsrepo.Open(cfgRoot)
repo, err := fsrepo.OpenWithUserConfig(cfgRoot, configFilePath)
if err != nil {
return "", "", err
}
Expand Down
Loading
Loading