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

✨ Clusterctl version check #3484

Merged

Conversation

wfernandes
Copy link
Contributor

@wfernandes wfernandes commented Aug 13, 2020

What this PR does / why we need it:
This PR allows clusterctl to prompt the user if it detects that the version being used is different from the latest available release. If the clusterctl version being used is either older or a dev release compared to the latest available release, it will print out a message to the terminal via os.Stderr. The version check happens on any sub-command of clusterctl.

An example of the output printed is:

$ clusterctl version
clusterctl version: &version.Info{Major:"0", Minor:"3", GitVersion:"v0.3.8-50-352a3a9d8b5430-dirty", GitCommit:"352a3a9d8b543078d194d80a34a2268652b314a0", GitTreeState:"dirty", BuildDate:"2020-08-13T20:01:57Z", GoVersion:"go1.13.14", Compiler:"gc", Platform:"darwin/amd64"}
Using configuration File="/Users/wfernandes/.cluster-api/clusterctl.yaml"


New clusterctl version available: v0.3.8-50-352a3a9d8b5430-dirty -> v0.3.8
https://github.com/kubernetes-sigs/cluster-api/releases/tag/v0.3.8

Which issue(s) this PR fixes (optional, in fixes #<issue number>(, fixes #<issue_number>, ...) format, will close the issue(s) when PR gets merged):
Fixes #3466

@k8s-ci-robot k8s-ci-robot added cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. labels Aug 13, 2020
@wfernandes wfernandes force-pushed the clusterctl-version-check branch from 2dbf915 to a52ec67 Compare August 13, 2020 20:23
@wfernandes
Copy link
Contributor Author

/test pull-cluster-api-e2e

@vincepri
Copy link
Member

@wfernandes From your example New clusterctl version available: v0.3.8-50-352a3a9d8b5430-dirty -> v0.3.8, the local built one is actually newer than the released version

@wfernandes
Copy link
Contributor Author

@vincepri Yeah...I realized that actually. I'm still looking into parsing the GitVersion (git describe --tags) into a proper semver.
I found an option: https://github.com/mdomke/git-semver but I'm not sure if I want to add another dependency just for this.
I thought I'd submit another PR for that specifically but if you'd prefer I can work on adding it in this PR.

@vincepri
Copy link
Member

We should be able to just use semver to compare IIRC

@wfernandes
Copy link
Contributor Author

Yeah so for the example above:
For the version v0.3.8-50-352a3a9d8b5430-dirty,
-50-352a3a9d8b5430-dirty is treated as a pre-release for v0.3.8. And the blang/semver library we are using marks a version v0.3.8 is greater than v0.3.8-50-352a3a9d8b5430-dirty which makes sense IMO.

TBH IMO, it feels that -50-352a3a9d8b5430-dirty should be considered as build metadata and the GitVersion should technically be v0.3.8+50.352a3a9d8b5430.dirty but I'm making sure if my understanding is correct before I make any changes.

@vincepri
Copy link
Member

Maybe when using pre-release version we should say something like "you're using a pre-release version" or if it's "-dirty" we should say "locally built version"?

Comment on lines +127 to +140
name: "returns message if cli version is a pre-release of the latest available release",
cliVersion: func() version.Info {
return version.Info{
GitVersion: "v0.3.9-alpha.0",
}
},
githubResponse: `{"tag_name": "v0.3.9", "html_url": "https://github.com/foo/bar/releases/v0.3.9"}`,
expectErr: false,
expectedOutput: `
New clusterctl version available: v0.3.9-alpha.0 -> v0.3.9
https://github.com/foo/bar/releases/v0.3.9
`,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we ever had our own official pre-releases, I wanted clusterctl to be able to notify the user via the output.

Comment on lines +141 to +154
name: "returns message if cli version is a pre-release and latest available release is the next pre-release",
cliVersion: func() version.Info {
return version.Info{
GitVersion: "v0.3.8-alpha.0",
}
},
githubResponse: `{"tag_name": "v0.3.8-alpha.1", "html_url": "https://github.com/foo/bar/releases/v0.3.8-alpha.1"}`,
expectErr: false,
expectedOutput: `
New clusterctl version available: v0.3.8-alpha.0 -> v0.3.8-alpha.1
https://github.com/foo/bar/releases/v0.3.8-alpha.1
`,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Same here. I wanted clusterctl to inform users if there were valid pre-releases available.
As long as we don't name our pre-releases in the same format as GitVersion we should be good.

@wfernandes wfernandes force-pushed the clusterctl-version-check branch from 4dcb857 to e7c1b31 Compare August 18, 2020 22:46
Comment on lines 108 to 122
// if we are using a dirty dev build, just log it out
if strings.HasSuffix(cliVer.String(), "-dirty") {
log.V(1).Info("Using a dirty dev build of clusterctl.", "CLIVersion", cliVer.String(), "LatestGithubRelease", release.Version)
return "", nil
}

// if the cli version is a dev build off of the latest available release,
// the just log it out as informational.
if strings.HasPrefix(cliVer.String(), latestVersion.String()) && gitVersionRegEx.MatchString(cliVer.String()) {
log.V(1).Info("Using a dev build of latest clusterctl release.", "CLIVersion", cliVer.String(), "LatestGithubRelease", release.Version)
return "", nil
}
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 chose to log out here because these are cases specifically for the "developer" users.
"developer" users being folks who have manually built clusterctl.
And I didn't want to bother the developers by printing out the a warning message after every command. TBH, I feel for the majority of users, these use cases will be minimal.
I felt that this was a good balance of notifying a "developer" instead of annoying them with a constant warning message.

cmd/clusterctl/cmd/version_checker.go Outdated Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker.go Outdated Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker.go Outdated Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker.go Outdated Show resolved Hide resolved
return "", nil
}

func (v *versionChecker) getLatestRelease() (*ReleaseInfo, error) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
func (v *versionChecker) getLatestRelease() (*ReleaseInfo, error) {
func (v *versionChecker) getLatestRelease() (ReleaseInfo, error) {

cmd/clusterctl/cmd/version_checker.go Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker_test.go Outdated Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker.go Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker.go Outdated Show resolved Hide resolved
cmd/clusterctl/cmd/version_checker.go Outdated Show resolved Hide resolved
@vincepri
Copy link
Member

@wfernandes Squash?

@wfernandes wfernandes force-pushed the clusterctl-version-check branch from 06f7723 to 7114511 Compare August 25, 2020 20:12
@wfernandes
Copy link
Contributor Author

@CecileRobertMichon @vincepri From the CAPI meeting, I can implement the strictly blocking feature separately as part of a different issue. Unless y'all wanted that to go in with this work. LMK your thoughts. Thanks.

@CecileRobertMichon
Copy link
Contributor

I vote on a separate issue, this is a good incremental change as-is.

@wfernandes
Copy link
Contributor Author

I can create a separate issue for that then and work on it. Thanks for the input.

Copy link
Member

@vincepri vincepri left a comment

Choose a reason for hiding this comment

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

/approve
/milestone v0.3.9
/assign @CecileRobertMichon @fabriziopandini
for final lgtm

@k8s-ci-robot k8s-ci-robot added this to the v0.3.9 milestone Aug 26, 2020
@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Aug 26, 2020
if vs == nil {
release, _, err := v.githubClient.Repositories.GetLatestRelease(context.TODO(), "kubernetes-sigs", "cluster-api")
if err != nil {
log.V(1).Info("⚠️ Unable to get latest github release for clusterctl")
Copy link
Contributor

Choose a reason for hiding this comment

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

Are we avoiding v(0) to avoid printing logs in the middle of yaml output? otherwise I think it makes sense to print this as a warning on all runs

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This was in regards to a previous feedback comment about failing silently. So I thought putting it at a log level that's informative only when asked for. As per the logging guidelines laid out here.

Also since this check is being run after every command, I didn't want the user to be peppered with the log line all the time.

Copy link
Contributor

@CecileRobertMichon CecileRobertMichon left a comment

Choose a reason for hiding this comment

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

overall lgtm, a couple of minor comments on formatting and log level

- Store release info in state file
Cache the release info in the state file in order to avoid excessive
github requests.
- Use GITHUB_TOKEN for github client if available
- Handle special cases of GitVersions
We want to treat pre-releases as valid.
We log out if the cli version is a dev build of any kind
- Do not return error if unable to get github release
This can be the case for air-gapped environments. So we just log the error instead.
- Prompt upgrade only within minor versions of cli
@wfernandes wfernandes force-pushed the clusterctl-version-check branch from 7114511 to ef3d157 Compare August 27, 2020 15:57
Copy link
Contributor

@CecileRobertMichon CecileRobertMichon left a comment

Choose a reason for hiding this comment

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

/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Aug 27, 2020
Copy link
Member

@vincepri vincepri left a comment

Choose a reason for hiding this comment

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

/approve

@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: vincepri

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

@vincepri
Copy link
Member

/test pull-cluster-api-test

@k8s-ci-robot k8s-ci-robot merged commit b7546f7 into kubernetes-sigs:master Aug 27, 2020
@wfernandes wfernandes deleted the clusterctl-version-check branch August 27, 2020 17:23
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. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. lgtm "Looks good to me", indicates that a PR is ready to be merged. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

clusterctl version check
6 participants