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

kubeadm: refactor validateStableVersion() #72059

Merged

Conversation

rojkov
Copy link

@rojkov rojkov commented Dec 14, 2018

What type of PR is this?
/kind cleanup

What this PR does / why we need it:
Currently the function cmd/kubeadm/app/util.validateStableVersion() doesn't validate remote versions in the special case when the client version is empty. This makes the code more difficult to reason about, because the function may successfully return a string which isn't a valid version. And this conflicts with name of the function.

Move handling the special case outside of the function to the place where its meaning is more obvious.

Does this PR introduce a user-facing change?:

NONE

@k8s-ci-robot k8s-ci-robot added release-note-none Denotes a PR that doesn't merit a release note. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. size/S Denotes a PR that changes 10-29 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Dec 14, 2018
@k8s-ci-robot
Copy link
Contributor

Hi @rojkov. Thanks for your PR.

I'm waiting for a kubernetes member to verify that this patch is reasonable to test. If it is, they should reply with /ok-to-test on its own line. Until that is done, I will not automatically test new commits in this PR, but the usual testing commands by org members will still work. Regular contributors should join the org to skip this step.

Once the patch is verified, the new status will be reflected by the ok-to-test label.

I understand the commands that are listed here.

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.

@k8s-ci-robot k8s-ci-robot added the needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. label Dec 14, 2018
@k8s-ci-robot k8s-ci-robot added area/kubeadm sig/cluster-lifecycle Categorizes an issue or PR as relevant to SIG Cluster Lifecycle. and removed needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Dec 14, 2018
Copy link
Member

@neolit123 neolit123 left a comment

Choose a reason for hiding this comment

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

@rojkov

doesn't validate remote versions in the special case when the client version is empty

the client version should never be empty.
if that's the case then we can consider this a build environment problem.
i'd argue that we pretty much need to os.Exit(1) if pkgversion.Get().String() fails to obtain an actual version.

it means that you could be building kubectl, the kubelet and control plane with the same environment and that not a great idea.
we had bug reports where we could not figure out what is happening and eventually found out that the user was building k8s components without the version info that the linker passes from GIT.

make all WHAT=./cmd/kubeadm
should populate the version info for you and you don't need an internet connection for that.
this will will feed a valid client version into kubeadm.

/priority backlog
/assign kad

@k8s-ci-robot k8s-ci-robot added priority/backlog Higher priority than priority/awaiting-more-evidence. and removed needs-priority Indicates a PR lacks a `priority/foo` label and requires one. labels Dec 14, 2018
@neolit123
Copy link
Member

@kubernetes/sig-cluster-lifecycle-pr-reviews

@bart0sh
Copy link
Contributor

bart0sh commented Dec 14, 2018

/ok-to-test

@k8s-ci-robot k8s-ci-robot added ok-to-test Indicates a non-member PR verified by an org member that is safe to test. and removed needs-ok-to-test Indicates a PR that requires an org member to verify it is safe to test. labels Dec 14, 2018
@bart0sh
Copy link
Contributor

bart0sh commented Dec 14, 2018

@neolit123 can you elaborate a bit more on this? Existing code already checks if version is empty. This PR just moves it to another place where it is more understandable. Am I missing something here? Are you suggesting to add os.Exit(1) call on top of the proposed change?

@neolit123
Copy link
Member

@bart0sh
my point is that the fallback from client version to remote version should never happen.
yes, we have a check for that but this is a weird edge case.

@rojkov
please explain your problem again - pkgversion.Get().String() should not return an empty version.
if that's the case, this is a build system issue as explained here:
#72059 (review)
and should be resolved in the build system.

@rojkov
Copy link
Author

rojkov commented Dec 17, 2018

@neolit123 Thanks for review!

This PR doesn't solve any problem except clarifying the code. Just wanted to keep the PR as simple and clear as possible.

At least now it became more obvious that the empty string check is a weird edge case with missing explanation why it's needed. To illustrate why exactly this check is needed I submitted one more commit removing the check. Here's the result
https://gubernator.k8s.io/build/kubernetes-jenkins/pr-logs/pull/72059/pull-kubernetes-bazel-test/70250/

As you can see 7 bazel tests in CI start to fail and I can't say the reason is obvious. I've added one more commit which brings the fallback back and adds a TODO comment and an explicit error check.

Then I'd argue that it's a build system problem. By definition a unit test is supposed to test only its corresponding unit. If it depends on other units like build systems it's not unit test any more or it's a manifestation of an architectural issue. As clientVersion I'd prefer using a constant that Ed is going to introduce.

@rosti
Copy link
Contributor

rosti commented Dec 17, 2018

@rojkov @bart0sh @neolit123 the string returned by pkgversion.Get().String() is a GitVersion. I haven't checked the build system code, but it's entirely possible that in certain cases this won't get filled in. For example, when building from a release source tarball or in case the actual build environment does not have git.

@bart0sh
Copy link
Contributor

bart0sh commented Dec 17, 2018

@neolit123, @rosti guys, I'd propose to look at this PR as a simple refactoring. First commit is quite obvious. Second commit improves readability. That's it. Let's not go to build system issues just yet, ok? Do you agree that as a simple refactoring PR it does make sense and worth merging?

@rosti
Copy link
Contributor

rosti commented Dec 17, 2018

Yes, we may have gone a bit stray from the original intent here. Sorry about that.
As long as this version is more readable than the original, which it is, then I am fine with it.
@rojkov could you squash your commits?

Copy link
Member

@neolit123 neolit123 left a comment

Choose a reason for hiding this comment

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

As you can see 7 bazel tests in CI start to fail and I can't say the reason is obvious. I've added one more commit which brings the fallback back and adds a TODO comment and an explicit error check.

i forgot about this.
it happens because when doing unit tests on individual packages, there is nothing to populate the version.

@@ -95,6 +94,13 @@ func KubernetesReleaseVersion(version string) (string, error) {
klog.Infof("falling back to the local client version: %s", clientVersion)
return KubernetesReleaseVersion(clientVersion)
}

if clientVersionErr != nil {
// TODO: theoretically clinetVersion is always accessible, but only if build system is tweaked correctly
Copy link
Member

Choose a reason for hiding this comment

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

i'd move the comment above:
pkgversion.Get().String()
and make it say:

pkgversion.Get().String() should always return a correct version added by the golang linker and the build system. The version can still be missing when doing unit tests on individual packages.


if clientVersionErr != nil {
// TODO: theoretically clinetVersion is always accessible, but only if build system is tweaked correctly
klog.Warningf("could not obtain client version; using remote version: %s", body)
Copy link
Member

Choose a reason for hiding this comment

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

at this point kubeadmVersion() can fail because of not being able to parse a remoteVersion too.
this case makes this error message invalid.

Copy link
Author

Choose a reason for hiding this comment

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

Very true! I guess if both versions are unavailable we can do nothing, but os.Exit(1) with some explanation. I'll squash these 3 commits and submit one more PR.

Copy link
Member

Choose a reason for hiding this comment

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

@rojkov FYI, @bart0sh is currently working on a PR (?) that may add a constant that refers to the actual current version of the client (even if not obtained from a build system).

this could be our final fallback.
let's decide if we want to do that.

Copy link
Author

Choose a reason for hiding this comment

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

Yeap, I'll discuss with Ed what would be the best option.

@neolit123
Copy link
Member

neolit123 commented Dec 17, 2018

@bart0sh

Do you agree that as a simple refactoring PR it does make sense and worth merging?

we can agree on that, sure.
just FYI this is not the only place where we are using pkgversion.Get().String(), upgrades are another area.

so if your production binary is lacking a GIT version and this is air gapped scenario, upgrades might be broken too.

Currently the function `cmd/kubeadm/app/util.validateStableVersion()`
doesn't validate remote versions in the special case when the client
version is empty. This makes the code more difficult to reason about,
because the function may successfully return a string which isn't a valid version.

Move handling the special case outside of the function to the place
where its meaning is more obvious.
@rojkov rojkov force-pushed the kubeadm-check-remote-version-v2 branch from 04aaad8 to b9c2139 Compare December 17, 2018 15:06
@rojkov
Copy link
Author

rojkov commented Dec 17, 2018

/test pull-kubernetes-e2e-kops-aws

Copy link
Member

@fabriziopandini fabriziopandini left a comment

Choose a reason for hiding this comment

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

@rojkov thanks! for this pr!
I'm ok with the proposed changes.
Ping me when all the feedback addressed for lgtm/approval

@fabriziopandini
Copy link
Member

/approve
/lgtm

@k8s-ci-robot k8s-ci-robot added the lgtm "Looks good to me", indicates that a PR is ready to be merged. label Dec 20, 2018
@k8s-ci-robot
Copy link
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: fabriziopandini, rojkov

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

@k8s-ci-robot k8s-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Dec 20, 2018
@k8s-ci-robot k8s-ci-robot merged commit 4a21a77 into kubernetes:master Dec 20, 2018
@rojkov rojkov deleted the kubeadm-check-remote-version-v2 branch February 18, 2019 07:55
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. area/kubeadm cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/cleanup Categorizes issue or PR as related to cleaning up code, process, or technical debt. lgtm "Looks good to me", indicates that a PR is ready to be merged. ok-to-test Indicates a non-member PR verified by an org member that is safe to test. priority/backlog Higher priority than priority/awaiting-more-evidence. release-note-none Denotes a PR that doesn't merit a release note. sig/cluster-lifecycle Categorizes an issue or PR as relevant to SIG Cluster Lifecycle. size/S Denotes a PR that changes 10-29 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

8 participants