diff --git a/cmd/ipfs/ipfs.go b/cmd/ipfs/ipfs.go index be63170b4..29ec17835 100644 --- a/cmd/ipfs/ipfs.go +++ b/cmd/ipfs/ipfs.go @@ -120,13 +120,16 @@ func localNode(confdir string, online bool) (*core.IpfsNode, error) { return nil, err } - if cfg.Version.Check != config.CheckIgnore { + if cfg.Version.EligibleForUpdateCheck() { obsolete := updates.CheckForUpdates() if obsolete != nil { if cfg.Version.Check == config.CheckError { return nil, obsolete } log.Warning(fmt.Sprintf("%v", obsolete)) // when "warn" version.check mode we just show warning message + } else { + // update most recent check timestamp in config + cfg.RecordCurrentUpdateCheck(filename) } } diff --git a/config/config.go b/config/config.go index 63367a053..410fa0119 100644 --- a/config/config.go +++ b/config/config.go @@ -45,18 +45,6 @@ func (bp *BootstrapPeer) String() string { return bp.Address + "/" + bp.PeerID } -// Version regulates checking if the most recent version is run -type Version struct { - Check string // "ignore" for do not check, "warn" and "error" for reacting when obsolete - Current string // ipfs version for which config was generated -} - -const ( - CheckError = "error" // value for Version.Check to raise error and exit if version is obsolete - CheckWarn = "warn" // value for Version.Check to show warning message if version is obsolete - CheckIgnore = "ignore" // value for Version.Check to not perform update check -) - // Config is used to load IPFS config files. type Config struct { Identity Identity // local node's peer identity diff --git a/config/version.go b/config/version.go new file mode 100644 index 000000000..5cc469485 --- /dev/null +++ b/config/version.go @@ -0,0 +1,39 @@ +package config + +import "time" + +// Version regulates checking if the most recent version is run +type Version struct { + Check string // "ignore" for do not check, "warn" and "error" for reacting when obsolete + Current string // ipfs version for which config was generated + UpdateCheckedTime time.Time // timestamp for the last time API endpoint was checked for updates + UpdateCheckPeriod time.Duration // time duration over which the update check will not be performed +} + +// supported Version.Check values +const ( + CheckError = "error" // value for Version.Check to raise error and exit if version is obsolete + CheckWarn = "warn" // value for Version.Check to show warning message if version is obsolete + CheckIgnore = "ignore" // value for Version.Check to not perform update check +) + +var defaultUpdateCheckPeriod = time.Hour * 48 + +// EligibleForUpdateCheck returns if update check API endpoint is needed for this specific runtime +func (v *Version) EligibleForUpdateCheck() bool { + if v.Check == CheckIgnore || v.UpdateCheckedTime.Add(v.UpdateCheckPeriod).After(time.Now()) { + return false + } + return true +} + +// RecordCurrentUpdateCheck is called to record that update check was performed and showed that the running version is the most recent one +func (cfg *Config) RecordCurrentUpdateCheck(filename string) { + cfg.Version.UpdateCheckedTime = time.Now() + if cfg.Version.UpdateCheckPeriod == time.Duration(0) { + // UpdateCheckPeriod was not initialized for some reason (e.g. config file used is broken) + cfg.Version.UpdateCheckPeriod = defaultUpdateCheckPeriod + } + + WriteConfigFile(filename, cfg) +}