Commit 408fadc8 authored by Brian Tiger Chow's avatar Brian Tiger Chow

fix(2/main) don't check for updates when running init

@jbenet @mappum

Yeah, there's some duplicated work. But there's also a separation of
concerns. In one case, we check to determine where the command should
run. In the other case, we check to determine which hooks should run.
Having these actions separated reduces complexity in a nice way.

License: MIT
Signed-off-by: default avatarBrian Tiger Chow <brian@perfmode.com>
parent eb5bb1da
...@@ -55,6 +55,13 @@ type cmdDetails struct { ...@@ -55,6 +55,13 @@ type cmdDetails struct {
cannotRunOnClient bool cannotRunOnClient bool
cannotRunOnDaemon bool cannotRunOnDaemon bool
doesNotUseRepo bool doesNotUseRepo bool
// initializesConfig describes commands that initialize the config.
// pre-command hooks that require configs must not be run before this
// command
initializesConfig bool
preemptsUpdates bool
} }
func (d *cmdDetails) String() string { func (d *cmdDetails) String() string {
...@@ -71,14 +78,14 @@ func (d *cmdDetails) usesRepo() bool { return !d.doesNotUseRepo } ...@@ -71,14 +78,14 @@ func (d *cmdDetails) usesRepo() bool { return !d.doesNotUseRepo }
// properties so that other code can make decisions about whether to invoke a // properties so that other code can make decisions about whether to invoke a
// command or return an error to the user. // command or return an error to the user.
var cmdDetailsMap = map[*cmds.Command]cmdDetails{ var cmdDetailsMap = map[*cmds.Command]cmdDetails{
initCmd: cmdDetails{cannotRunOnDaemon: true, doesNotUseRepo: true}, initCmd: cmdDetails{initializesConfig: true, cannotRunOnDaemon: true, doesNotUseRepo: true},
daemonCmd: cmdDetails{cannotRunOnDaemon: true}, daemonCmd: cmdDetails{cannotRunOnDaemon: true},
commandsClientCmd: cmdDetails{doesNotUseRepo: true}, commandsClientCmd: cmdDetails{doesNotUseRepo: true},
commands.CommandsDaemonCmd: cmdDetails{doesNotUseRepo: true}, commands.CommandsDaemonCmd: cmdDetails{doesNotUseRepo: true},
commands.DiagCmd: cmdDetails{cannotRunOnClient: true}, commands.DiagCmd: cmdDetails{cannotRunOnClient: true},
commands.VersionCmd: cmdDetails{doesNotUseRepo: true}, commands.VersionCmd: cmdDetails{doesNotUseRepo: true},
commands.UpdateCmd: cmdDetails{cannotRunOnDaemon: true}, commands.UpdateCmd: cmdDetails{preemptsUpdates: true, cannotRunOnDaemon: true},
commands.UpdateCheckCmd: cmdDetails{}, commands.UpdateCheckCmd: cmdDetails{preemptsUpdates: true},
commands.UpdateLogCmd: cmdDetails{}, commands.UpdateLogCmd: cmdDetails{preemptsUpdates: true},
commands.LogCmd: cmdDetails{cannotRunOnClient: true}, commands.LogCmd: cmdDetails{cannotRunOnClient: true},
} }
...@@ -20,6 +20,7 @@ import ( ...@@ -20,6 +20,7 @@ import (
daemon "github.com/jbenet/go-ipfs/daemon2" daemon "github.com/jbenet/go-ipfs/daemon2"
updates "github.com/jbenet/go-ipfs/updates" updates "github.com/jbenet/go-ipfs/updates"
u "github.com/jbenet/go-ipfs/util" u "github.com/jbenet/go-ipfs/util"
"github.com/jbenet/go-ipfs/util/debugerror"
) )
// log is the command logger // log is the command logger
...@@ -201,21 +202,61 @@ func (i *cmdInvocation) requestedHelp() (short bool, long bool, err error) { ...@@ -201,21 +202,61 @@ func (i *cmdInvocation) requestedHelp() (short bool, long bool, err error) {
return longHelp, shortHelp, nil return longHelp, shortHelp, nil
} }
func callPreCommandHooks(details cmdDetails, req cmds.Request, root *cmds.Command) error {
log.Debug("Calling pre-command hooks...")
// some hooks only run when the command is executed locally
daemon, err := commandShouldRunOnDaemon(details, req, root)
if err != nil {
return err
}
// check for updates when 1) commands is going to be run locally, 2) the
// command does not initialize the config, and 3) the command does not
// pre-empt updates
if !daemon && !details.initializesConfig && !details.preemptsUpdates {
log.Debug("Calling hook: Check for updates")
cfg, err := req.Context().GetConfig()
if err != nil {
return err
}
// Check for updates and potentially install one.
if err := updates.CliCheckForUpdates(cfg, req.Context().ConfigRoot); err != nil {
return err
}
}
return nil
}
func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) { func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) {
var res cmds.Response var res cmds.Response
useDaemon, err := commandShouldRunOnDaemon(req, root) details, err := commandDetails(req.Path(), root)
if err != nil {
return nil, err
}
useDaemon, err := commandShouldRunOnDaemon(*details, req, root)
if err != nil { if err != nil {
return nil, err return nil, err
} }
cfg, err := req.Context().GetConfig() err = callPreCommandHooks(*details, req, root)
if err != nil { if err != nil {
return nil, err return nil, err
} }
if useDaemon { if useDaemon {
cfg, err := req.Context().GetConfig()
if err != nil {
return nil, err
}
addr, err := ma.NewMultiaddr(cfg.Addresses.API) addr, err := ma.NewMultiaddr(cfg.Addresses.API)
if err != nil { if err != nil {
return nil, err return nil, err
...@@ -237,11 +278,6 @@ func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) { ...@@ -237,11 +278,6 @@ func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) {
} else { } else {
log.Info("Executing command locally") log.Info("Executing command locally")
// Check for updates and potentially install one.
if err := updates.CliCheckForUpdates(cfg, req.Context().ConfigRoot); err != nil {
return nil, err
}
// this sets up the function that will initialize the node // this sets up the function that will initialize the node
// this is so that we can construct the node lazily. // this is so that we can construct the node lazily.
ctx := req.Context() ctx := req.Context()
...@@ -267,13 +303,11 @@ func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) { ...@@ -267,13 +303,11 @@ func callCommand(req cmds.Request, root *cmds.Command) (cmds.Response, error) {
return res, nil return res, nil
} }
func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error) { // commandDetails returns a command's details for the command given by |path|
path := req.Path() // within the |root| command tree.
// root command. //
if len(path) < 1 { // Returns an error if the command is not found in the Command tree.
return false, nil func commandDetails(path []string, root *cmds.Command) (*cmdDetails, error) {
}
var details cmdDetails var details cmdDetails
// find the last command in path that has a cmdDetailsMap entry // find the last command in path that has a cmdDetailsMap entry
cmd := root cmd := root
...@@ -281,7 +315,7 @@ func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error ...@@ -281,7 +315,7 @@ func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error
var found bool var found bool
cmd, found = cmd.Subcommands[cmp] cmd, found = cmd.Subcommands[cmp]
if !found { if !found {
return false, fmt.Errorf("subcommand %s should be in root", cmp) return nil, debugerror.Errorf("subcommand %s should be in root", cmp)
} }
if cmdDetails, found := cmdDetailsMap[cmd]; found { if cmdDetails, found := cmdDetailsMap[cmd]; found {
...@@ -289,6 +323,21 @@ func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error ...@@ -289,6 +323,21 @@ func commandShouldRunOnDaemon(req cmds.Request, root *cmds.Command) (bool, error
} }
} }
log.Debugf("cmd perms for +%v: %s", path, details.String()) log.Debugf("cmd perms for +%v: %s", path, details.String())
return &details, nil
}
// commandShouldRunOnDaemon determines, from commmand details, whether a
// command ought to be executed on an IPFS daemon.
//
// It returns true if the command should be executed on a daemon and false if
// it should be executed on a client. It returns an error if the command must
// NOT be executed on either.
func commandShouldRunOnDaemon(details cmdDetails, req cmds.Request, root *cmds.Command) (bool, error) {
path := req.Path()
// root command.
if len(path) < 1 {
return false, nil
}
if details.cannotRunOnClient && details.cannotRunOnDaemon { if details.cannotRunOnClient && details.cannotRunOnDaemon {
return false, fmt.Errorf("command disabled: %s", path[0]) return false, fmt.Errorf("command disabled: %s", path[0])
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment