-
Notifications
You must be signed in to change notification settings - Fork 66
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
Notify users if there is a new version of preflight #1103
Notify users if there is a new version of preflight #1103
Conversation
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: skattoju The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
fb91968
to
d28dec9
Compare
d28dec9
to
e65d008
Compare
dd746b7
to
67697ee
Compare
67697ee
to
dee20f5
Compare
dee20f5
to
4fbba38
Compare
cmd/preflight/cmd/check_container.go
Outdated
@@ -198,7 +204,7 @@ func checkContainerRunE(cmd *cobra.Command, args []string, runpreflight runPrefl | |||
|
|||
func checkContainerPositionalArgs(cmd *cobra.Command, args []string) error { | |||
if len(args) != 1 { | |||
return fmt.Errorf("a container image positional argument is required") | |||
return fmt.Errorf("a container image positional argument is required, found %v", args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this updated needed for this task? It seems like an enhancement that might need it's own PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i figured no harm in keeping it 🤷♂️
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @acornett21. This change doesn't appear necessary. Please revert this change.
cmd/preflight/cmd/check_container.go
Outdated
@@ -257,6 +270,38 @@ func validateCertificationProjectID(cmd *cobra.Command, args []string) error { | |||
return nil | |||
} | |||
|
|||
// checkForNewerReleaseVersion checks if there is a newer release available | |||
func checkForNewerReleaseVersion(cmd *cobra.Command) { | |||
logger, err := logr.FromContext(cmd.Context()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think using logr.FromContextOrDiscard
might be a better choice, that way we don't have to worry about errors. But I'll let other's chime in as well.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to ignore the error, you may as well use logr.FromContextOrDiscard
here. Not having a logger should not translate to not running this check.
ghToken, err := cmd.Flags().GetString("gh-auth-token") | ||
if err == nil && len(ghToken) > 0 { | ||
client = github.NewClient(&http.Client{ | ||
// Timeout in 1s in case Github is slow to respond | ||
Timeout: time.Second * 1, | ||
}).WithAuthToken(ghToken) | ||
} else { | ||
client = github.NewClient(&http.Client{ | ||
// timeout in 1s in case Github is slow to respond | ||
Timeout: time.Second * 1, | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this should be simplified, sudo code below
client := github.NewClient(nil) // this lets gh initialize a client we do this in other apps
if check for token {
client = client.WithAuthToken(ghToken)
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wanted to keep the time out short in order not to interfere with CI when github has issues
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't think we should add the entire GitHub client solely to use the token. Do we really foresee people running into the GitHub rate limit?
We should probably just be hitting it with net/http without bringing in the github client library. If we get reports that people are hitting it, we can address it then.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we said earlier that hitting the rate limit would happen quite often to people running the tool in CI behind a VPN and that was the reason to use GH client and have the option to pass a token.
version/version.go
Outdated
|
||
func (vc *VersionContext) LatestReleasedVersion(cmd *cobra.Command, svc VersionClient) (*github.RepositoryRelease, error) { | ||
ctx := cmd.Context() | ||
logger, err := logr.FromContext(ctx) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same logr.FromContextOrDiscard
here
version/version.go
Outdated
|
||
var ( | ||
projectName = "github.com/redhat-openshift-ecosystem/openshift-preflight" | ||
version = "unknown" | ||
version = "0.0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this just changed so that other tests became valid?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes this was for tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we add a comment next to this and anywhere else that changed to 0.0.1
so we know it has to stay that value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Its not implicit ? Ok will add a comment 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think it's implicit, since it's been unknown or 0.0.0
locally forever.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather this remain its original value "unknown". We inject this at build time, and we only truly care about whether someone is using an outdated version in cases where they've used our release binaries, which have this value populated.
Which test needs this to change?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have tests comparing semver style versions thats why I changed it from unknown to 0.0.1. May be 0.0.0 is better ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(The tests in version_test.go)
4fbba38
to
465434a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Couple of changes/questions.
Overall, I'm wondering if we might be better off updating a cookie file somewhere on each release than querying the GitHub releases page.
I don't particularly love having to pass a GitHub API token into the tool for behavior that isn't core to Preflight's execution. That seems distracting to the end user, and I'm fairly confident it would be hit frequently since the only real client information GitHub would have is IP space. I think.
At any rate, I would much prefer making like an HTTP call that's hard-code to pull a value. Maybe it's a gh-pages thing. Not sure what I would want to see.
Some food for thought. cc @acornett21 @bcrochet
cmd/preflight/cmd/check_container.go
Outdated
@@ -198,7 +204,7 @@ func checkContainerRunE(cmd *cobra.Command, args []string, runpreflight runPrefl | |||
|
|||
func checkContainerPositionalArgs(cmd *cobra.Command, args []string) error { | |||
if len(args) != 1 { | |||
return fmt.Errorf("a container image positional argument is required") | |||
return fmt.Errorf("a container image positional argument is required, found %v", args) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed with @acornett21. This change doesn't appear necessary. Please revert this change.
// validateConditions run all pre-run functions | ||
func validateConditions(cmd *cobra.Command, args []string) error { | ||
err := validateCertificationProjectID() | ||
checkForNewerReleaseVersion(cmd) | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of writing another function that we call, does it make sense to reuse cobra.MatchAll? Technically, it's to be used for the PositionalArgs struct key, but the signature looks the same to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I concur here. It seems odd here to call another function between setting err and returning it. Not sure about the use of MatchAll. But it wouldn't hurt to try it. Otherwise, at the very least I would suggest something like
// validateConditions run all pre-run functions | |
func validateConditions(cmd *cobra.Command, args []string) error { | |
err := validateCertificationProjectID() | |
checkForNewerReleaseVersion(cmd) | |
return err | |
} | |
// validateConditions run all pre-run functions | |
func validateConditions(cmd *cobra.Command, args []string) error { | |
checkForNewerReleaseVersion(cmd) | |
return validateCertificationProjectID() | |
} | |
cmd/preflight/cmd/check_container.go
Outdated
@@ -257,6 +270,38 @@ func validateCertificationProjectID(cmd *cobra.Command, args []string) error { | |||
return nil | |||
} | |||
|
|||
// checkForNewerReleaseVersion checks if there is a newer release available | |||
func checkForNewerReleaseVersion(cmd *cobra.Command) { | |||
logger, err := logr.FromContext(cmd.Context()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you're going to ignore the error, you may as well use logr.FromContextOrDiscard
here. Not having a logger should not translate to not running this check.
|
||
"github.com/redhat-openshift-ecosystem/openshift-preflight/artifacts" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/check" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/cli" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/formatters" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/lib" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/viper" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do know why these are changing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
looks like just the order is changing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's not correct. The project-local imports should be after stdlib, not last. Please figure out if it's your IDE doing that, and update its settings accordingly.
version/version.go
Outdated
|
||
"github.com/go-logr/logr" | ||
"github.com/google/go-github/v57/github" | ||
semvc "github.com/hashicorp/go-version" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any particular version why we're using this, and not https://pkg.go.dev/golang.org/x/mod/semver, or https://github.com/Masterminds/semver
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is one of these already used in a project we manage? If so I'd vote for picking that one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
changed to Masterminds 👍
@@ -25,3 +38,35 @@ type VersionContext struct { | |||
func (vc *VersionContext) String() string { | |||
return fmt.Sprintf("%s <commit: %s>", vc.Version, vc.Commit) | |||
} | |||
|
|||
func (vc *VersionContext) LatestReleasedVersion(cmd *cobra.Command, svc VersionClient) (*github.RepositoryRelease, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This shouldn't need *cobra.Command
to function. If you need a context, accept a context.
With that said, I would say we probably don't want this to log in any way. It likely makes more sense to emit an error here, and have the caller figure out what to do with it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, does this need to be a mod of the VersionContext struct for any reason? I think there's certainly value here in hard-coding some of the relevant values for our project ( e.g. the org/project values), but we're not accomplishing that by adding this as a method to the struct.
Make this an library function that accepts the parameters it needs to execute, then call it with the proper parameters provided at your call point(s).
If we make this just a generic library call that accepts the client you need to make to resolve the version, it may also simplify testing of this logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed on the context here. cobra.Command should not have made it out of cmd package.
version/version.go
Outdated
|
||
var ( | ||
projectName = "github.com/redhat-openshift-ecosystem/openshift-preflight" | ||
version = "unknown" | ||
version = "0.0.1" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would rather this remain its original value "unknown". We inject this at build time, and we only truly care about whether someone is using an outdated version in cases where they've used our release binaries, which have this value populated.
Which test needs this to change?
@komish The API key should be optional and not required. It would only be if a user experiences rate limiting from GH. Say they are using preflight in their CI system (which already calls GH a bunch). |
Understood, but if we made a web request to GitHub's public-facing HTTP endpoints instead of the API, we could avoid having to request an API from the caller altogether. We don't use the token for anything else - just the version check. That feels strange to me. [edit]: 100% believe it's necessary if we must make an API call to GitHub to get this information. There's no other way around it, we have to request it from the user so that they don't eventually complain they're getting rate limited and have no way of resolving. But having it be an input we need for something that doesn't impact core logic is what I prefer to avoid. |
465434a
to
aefbfe0
Compare
aefbfe0
to
c7babfb
Compare
from change #1103: |
c7babfb
to
229ef32
Compare
Signed-off-by: Sid Kattoju <[email protected]>
229ef32
to
831edc7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A few concurrences and some additional questions.
"os" | ||
"path/filepath" | ||
rt "runtime" | ||
"strings" | ||
"time" | ||
|
||
"github.com/go-logr/logr" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not move like it is. Is the IDE moving this block up? Or is the linter suggesting that this be moved ahead of "local" imports?
The order should be:
stdlib
project
3rd party
|
||
"github.com/redhat-openshift-ecosystem/openshift-preflight/artifacts" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/certification" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/check" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/cli" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/formatters" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/lib" | ||
"github.com/redhat-openshift-ecosystem/openshift-preflight/internal/viper" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well, it's not correct. The project-local imports should be after stdlib, not last. Please figure out if it's your IDE doing that, and update its settings accordingly.
@@ -25,3 +38,35 @@ type VersionContext struct { | |||
func (vc *VersionContext) String() string { | |||
return fmt.Sprintf("%s <commit: %s>", vc.Version, vc.Commit) | |||
} | |||
|
|||
func (vc *VersionContext) LatestReleasedVersion(cmd *cobra.Command, svc VersionClient) (*github.RepositoryRelease, error) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed on the context here. cobra.Command should not have made it out of cmd package.
// validateConditions run all pre-run functions | ||
func validateConditions(cmd *cobra.Command, args []string) error { | ||
err := validateCertificationProjectID() | ||
checkForNewerReleaseVersion(cmd) | ||
return err | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I concur here. It seems odd here to call another function between setting err and returning it. Not sure about the use of MatchAll. But it wouldn't hurt to try it. Otherwise, at the very least I would suggest something like
// validateConditions run all pre-run functions | |
func validateConditions(cmd *cobra.Command, args []string) error { | |
err := validateCertificationProjectID() | |
checkForNewerReleaseVersion(cmd) | |
return err | |
} | |
// validateConditions run all pre-run functions | |
func validateConditions(cmd *cobra.Command, args []string) error { | |
checkForNewerReleaseVersion(cmd) | |
return validateCertificationProjectID() | |
} | |
}) | ||
} | ||
// check if a newer release is available | ||
latestRelease, err := version.Version.LatestReleasedVersion(cmd, client.Repositories) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is awkward. LatestReleasedVersion, as @komish stated elsewhere, really doesn't need to be a part of Version.
latestRelease, err := version.Version.LatestReleasedVersion(cmd, client.Repositories) | |
latestRelease, err := version.LatestRelease(cmd.Context(), client.Repositories) |
ghToken, err := cmd.Flags().GetString("gh-auth-token") | ||
if err == nil && len(ghToken) > 0 { | ||
client = github.NewClient(&http.Client{ | ||
// Timeout in 1s in case Github is slow to respond | ||
Timeout: time.Second * 1, | ||
}).WithAuthToken(ghToken) | ||
} else { | ||
client = github.NewClient(&http.Client{ | ||
// timeout in 1s in case Github is slow to respond | ||
Timeout: time.Second * 1, | ||
}) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I really don't think we should add the entire GitHub client solely to use the token. Do we really foresee people running into the GitHub rate limit?
We should probably just be hitting it with net/http without bringing in the github client library. If we get reports that people are hitting it, we can address it then.
I don't think we'll need this PR anymore, since the business's new ask is to block on submission which will be handled by pyxis. And preflights high level responsibilities for that are now:
|
@skattoju: The following test failed, say
Full PR test history. Your PR dashboard. Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes/test-infra repository. I understand the commands that are listed here. |
Closing this since version enforcement will be implemented in the backend (pyxis) ref: CLOUDWF-10041 |
fixes #1043