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

Notify users if there is a new version of preflight #1103

Conversation

skattoju
Copy link
Contributor

@skattoju skattoju commented Dec 7, 2023

fixes #1043

  • Currently this is only done when running check container.
  • There is an option for specifying a Github auth token in case rate limiting becomes an issue. As of now its 60 request per hour unauthenticated which goes up to 5000 when using an auth token. In any case remaining requests are printed in the logs
  • The timeout for requests from the Github client to Github is set to one second to avoid waiting too long in case Github is slow to respond.

@openshift-ci openshift-ci bot requested review from jomkz and tonytcampbell December 7, 2023 16:14
@skattoju skattoju marked this pull request as draft December 7, 2023 16:14
Copy link

openshift-ci bot commented Dec 7, 2023

[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 /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci openshift-ci bot added do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. approved Indicates a PR has been approved by an approver from all required OWNERS files. labels Dec 7, 2023
@skattoju skattoju force-pushed the latest_available_version branch 2 times, most recently from fb91968 to d28dec9 Compare December 7, 2023 17:19
@skattoju skattoju force-pushed the latest_available_version branch from d28dec9 to e65d008 Compare December 17, 2023 18:13
@skattoju skattoju force-pushed the latest_available_version branch 3 times, most recently from dd746b7 to 67697ee Compare December 18, 2023 15:38
@skattoju skattoju marked this pull request as ready for review December 18, 2023 15:57
@openshift-ci openshift-ci bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Dec 18, 2023
@openshift-ci openshift-ci bot requested review from acornett21 and komish December 18, 2023 15:57
@skattoju skattoju requested review from bcrochet and removed request for acornett21 December 18, 2023 15:57
@skattoju skattoju force-pushed the latest_available_version branch from 67697ee to dee20f5 Compare December 19, 2023 16:23
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 5, 2024
@skattoju skattoju force-pushed the latest_available_version branch from dee20f5 to 4fbba38 Compare January 9, 2024 17:59
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 9, 2024
@@ -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)
Copy link
Contributor

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.

Copy link
Contributor Author

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 🤷‍♂️

Copy link
Contributor

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.

@@ -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())
Copy link
Contributor

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.

Copy link
Contributor

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.

Comment on lines +283 to +290
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,
})
}
Copy link
Contributor

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)
}

Copy link
Contributor Author

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

Copy link
Contributor

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.

Copy link
Contributor Author

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.


func (vc *VersionContext) LatestReleasedVersion(cmd *cobra.Command, svc VersionClient) (*github.RepositoryRelease, error) {
ctx := cmd.Context()
logger, err := logr.FromContext(ctx)
Copy link
Contributor

Choose a reason for hiding this comment

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

same logr.FromContextOrDiscard here


var (
projectName = "github.com/redhat-openshift-ecosystem/openshift-preflight"
version = "unknown"
version = "0.0.1"
Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Contributor

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?

Copy link
Contributor Author

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 👍

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 it's implicit, since it's been unknown or 0.0.0 locally forever.

Copy link
Contributor

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?

Copy link
Contributor Author

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 ?

Copy link
Contributor Author

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)

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 12, 2024
@skattoju skattoju force-pushed the latest_available_version branch from 4fbba38 to 465434a Compare January 17, 2024 20:45
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 17, 2024
Copy link
Contributor

@komish komish left a 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

@@ -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)
Copy link
Contributor

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.

Comment on lines +246 to +252
// validateConditions run all pre-run functions
func validateConditions(cmd *cobra.Command, args []string) error {
err := validateCertificationProjectID()
checkForNewerReleaseVersion(cmd)
return err
}

Copy link
Contributor

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.

cc @acornett21 @bcrochet

Copy link
Contributor

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

Suggested change
// 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()
}

@@ -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())
Copy link
Contributor

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.

Comment on lines +28 to +35

"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"
Copy link
Contributor

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?

Copy link
Contributor Author

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

Copy link
Contributor

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.


"github.com/go-logr/logr"
"github.com/google/go-github/v57/github"
semvc "github.com/hashicorp/go-version"
Copy link
Contributor

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

Copy link
Contributor

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.

Copy link
Contributor Author

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) {
Copy link
Contributor

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.

Copy link
Contributor

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.

Copy link
Contributor

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.


var (
projectName = "github.com/redhat-openshift-ecosystem/openshift-preflight"
version = "unknown"
version = "0.0.1"
Copy link
Contributor

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?

@acornett21
Copy link
Contributor

acornett21 commented Jan 17, 2024

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.

@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).

@komish
Copy link
Contributor

komish commented Jan 17, 2024

@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.

@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Jan 23, 2024
@skattoju skattoju force-pushed the latest_available_version branch from 465434a to aefbfe0 Compare February 19, 2024 15:01
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 19, 2024
@skattoju skattoju force-pushed the latest_available_version branch from aefbfe0 to c7babfb Compare February 19, 2024 15:16
@coveralls
Copy link

Coverage Status

coverage: 81.768% (+0.03%) from 81.735%
when pulling c7babfb on skattoju:latest_available_version
into 068aa75 on redhat-openshift-ecosystem:main.

@dcibot
Copy link

dcibot commented Feb 19, 2024

@skattoju skattoju force-pushed the latest_available_version branch from c7babfb to 229ef32 Compare February 21, 2024 19:40
@openshift-merge-robot openshift-merge-robot added the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 21, 2024
@skattoju skattoju force-pushed the latest_available_version branch from 229ef32 to 831edc7 Compare February 21, 2024 19:47
@openshift-merge-robot openshift-merge-robot removed the needs-rebase Indicates a PR cannot be merged because it has merge conflicts with HEAD. label Feb 21, 2024
Copy link
Contributor

@bcrochet bcrochet left a 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"
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 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

Comment on lines +28 to +35

"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"
Copy link
Contributor

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) {
Copy link
Contributor

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.

Comment on lines +246 to +252
// validateConditions run all pre-run functions
func validateConditions(cmd *cobra.Command, args []string) error {
err := validateCertificationProjectID()
checkForNewerReleaseVersion(cmd)
return err
}

Copy link
Contributor

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

Suggested change
// 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)
Copy link
Contributor

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.

Suggested change
latestRelease, err := version.Version.LatestReleasedVersion(cmd, client.Repositories)
latestRelease, err := version.LatestRelease(cmd.Context(), client.Repositories)

Comment on lines +283 to +290
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,
})
}
Copy link
Contributor

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.

@acornett21
Copy link
Contributor

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:

  • Handle and display the response.
  • Add/Update our GitHub Release Action to post to pyxis the version that was released.

Copy link

openshift-ci bot commented Feb 21, 2024

@skattoju: The following test failed, say /retest to rerun all failed tests or /retest-required to rerun all mandatory failed tests:

Test name Commit Details Required Rerun command
ci/prow/4.11-e2e 831edc7 link true /test 4.11-e2e

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.

@skattoju
Copy link
Contributor Author

Closing this since version enforcement will be implemented in the backend (pyxis) ref: CLOUDWF-10041

@skattoju skattoju closed this Feb 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Add Version Lookup to Notify Users of latest Release
7 participants