Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fsoc 24 #145

Merged
merged 16 commits into from
Jul 17, 2023
Merged

Fsoc 24 #145

merged 16 commits into from
Jul 17, 2023

Conversation

GDW1
Copy link
Contributor

@GDW1 GDW1 commented Jul 10, 2023

Description

Every 24 hours, FSOC will check if there is a update available. It will create a temp file that holds the most recent timestep

Type of Change

  • Bug Fix
  • New Feature
  • Breaking Change
  • Refactor
  • Documentation
  • Other (please describe)

Checklist

  • I have read the contributing guidelines
  • Existing issues have been referenced (where applicable)
  • I have verified this change is not present in other open pull requests
  • Functionality is documented
  • All code style checks pass
  • New code contribution is covered by automated tests
  • All new and existing tests pass

@GDW1 GDW1 requested a review from pnickolov as a code owner July 10, 2023 21:21
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Outdated Show resolved Hide resolved
cmd/root.go Show resolved Hide resolved
@codecov-commenter
Copy link

codecov-commenter commented Jul 12, 2023

Codecov Report

Merging #145 (29c082f) into main (62d908f) will decrease coverage by 0.65%.
The diff coverage is 0.00%.

❗ Your organization is not using the GitHub App Integration. As a result you may experience degraded service beginning May 15th. Please install the Github App Integration for your organization. Read more.

@@            Coverage Diff             @@
##             main     #145      +/-   ##
==========================================
- Coverage   32.34%   31.69%   -0.65%     
==========================================
  Files          27       28       +1     
  Lines        3568     3641      +73     
==========================================
  Hits         1154     1154              
- Misses       2323     2396      +73     
  Partials       91       91              
Impacted Files Coverage Δ
cmd/version/version_check.go 0.00% <0.00%> (ø)

... and 2 files with indirect coverage changes

cmd/root.go Outdated
@@ -93,6 +102,7 @@ func init() {
rootCmd.PersistentFlags().BoolP("verbose", "v", false, "Enable detailed output")
rootCmd.PersistentFlags().Bool("curl", false, "Log curl equivalent for platform API calls (implies --verbose)")
rootCmd.PersistentFlags().String("log", path.Join(os.TempDir(), "fsoc.log"), "determines the location of the fsoc log file")
rootCmd.PersistentFlags().Bool("no-update-warning", false, "Removes daily warning for updates")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
rootCmd.PersistentFlags().Bool("no-update-warning", false, "Removes daily warning for updates")
rootCmd.PersistentFlags().Bool("no-version-check", false, "Removes daily check for new versions of fsoc")

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that what we're skipping is the whole check, not just the warning. If this flag is set, none of the actions should be taken (no reading the timestamp file, no reading the latest version, no updating the timestamp file). This is useful in restricted environments (e.g., CI), where outgoing access is not possible or there is no need to perform the check; as well as in cases when the check is causing problems.

cmd/root.go Outdated
@@ -222,6 +232,35 @@ func preExecHook(cmd *cobra.Command, args []string) {
log.Fatalf("fsoc is not configured, please use \"fsoc config set\" to configure an initial context")
}
}

// Do version checking
noUpdateWarning, _ := cmd.Flags().GetBool("no-update-warning")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also please check if FSOC_NO_VERSION_CHECK (matches the flag name, prefixed with FSOC_ and uppercased) environment variable is set. For some cases, such as CI, it is more convenient to set the env var once rather than add the flag to every command.

cmd/root.go Outdated

// Do version checking
noUpdateWarning, _ := cmd.Flags().GetBool("no-update-warning")
updateChecked := int(time.Now().Unix())-getRecentTimestamp() > int(secondInDay) && !noUpdateWarning
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this code must be conditional on whether we're doing the check. If the --no-version-check flag is set (or env var), there is no need to check timestamps. You can leave the channel as nil, and then in the post hook, omit reading if it's nil

cmd/root.go Outdated
_ = os.Remove(os.TempDir() + "fsoc.timestamp")
_, err = os.Create(os.TempDir() + "fsoc.timestamp")
if err != nil {
log.Errorf(err.Error())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be a warning and there should be some context to the error, such as "failed to create version check timestamp file, check will be performed next time", and then the error info. This way a warning that says that, for example, a directory is not writeable, will be in context of what we were trying to do; otherwise, users will wonder why we are trying to write to a file when they are asking for a solution list, for example.
Also, when formatting an error, it's recommended to use "%w" format and the err value itself, rather than just the string err.Error(). This allows for unwrapping the error).

cmd/root.go Outdated
}
}

func getRecentTimestamp() int {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
func getRecentTimestamp() int {
func getLastVersionCheckTime() int {

currentVersion := GetVersion()
currentVersionSemVer := ConvertVerToSemVar(currentVersion)
newerVersionAvailable := currentVersionSemVer.Compare(newestVersionSemVar) == -1
var debugFields = log.Fields{"newerVersionAvailable": newerVersionAvailable, "oldVersion": currentVersionSemVer.String(), "newVersion": newestVersionSemVar.String()}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we should include the newerVersionAvailable field. This should be--and is--part of the message: a newer version is available.
Also, instead of "old" and "new" version field names, it will be more helpful to call them "current" (i.e., this is what your current fsoc that is running is) and "latest" (i.e., this is what is available / you should run)

if newerVersionAvailable {
log.WithFields(debugFields).Warnf("There is a newer version of FSOC available, please upgrade from version %s to version %s", currentVersionSemVer.String(), newestVersionSemVar.String())
} else {
log.WithFields(debugFields)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we need to log this; but it we do, I propose we just log the version values

var debugFields = log.Fields{"newerVersionAvailable": newerVersionAvailable, "oldVersion": currentVersionSemVer.String(), "newVersion": newestVersionSemVar.String()}

if newerVersionAvailable {
log.WithFields(debugFields).Warnf("There is a newer version of FSOC available, please upgrade from version %s to version %s", currentVersionSemVer.String(), newestVersionSemVar.String())
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we already include the versions in the fields, I don't think we need to include them in the message as well. Just say "There is a newer version of fsoc available, please upgrade soon"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

consider moving this to a versioncheck.go. Even though the file is short, it is quite dense and I think it will be better to separate the code related to the latest-version check.

cmd/root.go Outdated
if updateChecked {
go version.CheckForUpdate(updateChannel)
} else {
go func() { updateChannel <- version.ConvertVerToSemVar(version.GetVersion()) }()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If the purpose of this is just to not do (skip) the check, isn't there a better way?

@pavel-georgiev
Copy link
Contributor

pavel-georgiev commented Jul 15, 2023

@pnickolov it is great to have the ability to check for available updates. Can we make this to not be the default behavior. This kind of hidden work raises some questions, in most cases would be undesirable and AFAIK it is somewhat unorthodox for an OSS CLI tool. On top of being a bad practice (IMO), I have a few practical cases where it would be undesirable:

  1. I do a local operation (like fsoc solution bump), but now I have to wait for a network call for something that I did not ask for
  2. Version check fails (or release location changed) - is the exit status going to reflect the status of my operation or the version check?

Here are some suggestions on how to make it less intrusive, ordered by my preference:

  • Make this run only as part of fsoc version so it can show you your version and latest available version, keep the flag for disabling the remote check
  • Make this a "best effort" operation - if it is done by the time the command is done, then tell me about the new version (and/or store the result so you can keep warning me even without making the network call), if it is not done, try next time. In short - never make fsoc run longer because of the version check
  • Have a config option to disable this (I suspect it will be a popular option, especially for CI operations and internal)

@pnickolov pnickolov merged commit b177e7f into cisco-open:main Jul 17, 2023
7 checks passed
@pnickolov
Copy link
Contributor

pnickolov commented Jul 17, 2023

In reply to @pavel-georgiev : I agree with some of the issues but we still expect significant changes and making sure the latest version is in use is important. We're trying to follow the pip approach (except warn no more than once a day).

I think @GDW1 has addressed most of the issues:

  • the check is best effort; if it fails, it will be warned but the operation and its exit code are never affected
  • the version check is done in parallel with the main operation
  • while very fast operations will still wait for the version check to complete at exit, the check is performed no more often than once a day, so it will not affect most operations (only one per day, less than login)
  • there is a global command-line option AND an environment variable to disable the version check (for CI or in environments that don't have access to github or writeable temp dir)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants