-
Notifications
You must be signed in to change notification settings - Fork 116
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
Fix test failures for various combinations of kubectl and Kubernetes versions #198
Conversation
…versions This patch fixes two different problems: 1. Kubernetes 1.8 has changed the behavior when secrets cannot be found. Instead of aborting a deployment quickly, Kubernetes retries quite a few times before it gives up. Removed the test case which checks for a quick exit. 2. kubectl 1.8 produces slighty different log output for some of the test cases. Made the matches version dependent. Another option would be to only check the parts which are identical in both versions.
I can confirm this PR fixes all known test failures on k8s |
@skaes Could I ask you to fix the trivial style issues reported here? https://policial.shopify.io/Shopify/kubernetes-deploy/builds/357126 It'll make merging this easier. Thank you! |
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.
Thanks for the PR! I just have a few requests. 😄
lib/kubernetes-deploy/kubectl.rb
Outdated
@version_info ||= | ||
begin | ||
response, _, status = run("version", "--output=yaml", use_namespace: false, log_failure: true) | ||
raise "Could not retrieve kubectl client info" unless status.success? |
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.
Please raise KubectlError
Nit: kubectl client info
-> Kubernetes version info
(we get both the kubectl client and the server versions, as you clearly know from the methods below 😄 )
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.
Sure thing. Did not know about KubectlError
lib/kubernetes-deploy/kubectl.rb
Outdated
response, _, status = run("version", "--output=yaml", use_namespace: false, log_failure: true) | ||
raise "Could not retrieve kubectl client info" unless status.success? | ||
YAML.load(response) | ||
rescue => e |
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.
why rescue and re-raise? If run
itself raised something, I'd generally consider that unexpected and let it raise up
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.
Fine with me. But the user might be confused if he sees for example an error from YAML.load.
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.
Ah, I wasn't noticing the YAML.load (even though it's right there 😄 ). I'm fine either way on this one.
lib/kubernetes-deploy/kubectl.rb
Outdated
end | ||
|
||
def client_version | ||
version_info["clientVersion"]["gitVersion"] |
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.
Let's make this return something that facilitates accurate comparison. For example, we could return instances of Gem::Version
. Currently, comparisons like "v1.7.9" < "v1.7.10"
will give the wrong result.
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 that I'll never need an exact comparison. Only comparisons of the form x < 1.8 or x > 1.7. But I can change it, of course.
lib/kubernetes-deploy/runner.rb
Outdated
with_retries(2) do | ||
_, _, st = kubectl.run("version", use_namespace: false, log_failure: true) | ||
response, _, st = kubectl.run("version", "--output=yaml", use_namespace: false, log_failure: true) |
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.
As it stands, we don't actually need kubectl_version_info
for anything in this class. We're using version
here as an arbitrary command that actually hits the server, to confirm that the master IP we got from the kubeconfig was valid. By explicitly doing this early on, we can fail with a relevant error instead of an error about whichever step (e.g. namespace validation) happened to hit the server first.
In other words, we can switch this line to use your new kubectl.version_info
, but let's leave the rest alone. Anything that does need the version in the future can use your new method directly.
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.
OK.
end | ||
assert_deploy_failure(result) | ||
if KUBE_SERVER_VERSION < "v1.8.0" | ||
# behavior in 1.8 has changed: kubernetes now times out instead of failing quickly |
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.
Hm, maybe this is something we can address in the gem. I've opened an issue to investigate: #203.
@skaes any chance you'd be able to update this PR in the next day? We've got our v1.8 CI ready to go now, so we're eager to have this in. 😄 |
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.
Changes look good, thanks! I'd appreciate it if you could fix the rubocop exceptions as @stefanmb mentioned, particularly the Avoid using rescue in its modifier form.
(commented in line as well): https://policial.shopify.io/Shopify/kubernetes-deploy/builds/364227. I know it can be annoying, but we're trying to keep this project green. If you don't have time, LMK and I'll do it after merging.
lib/kubernetes-deploy/runner.rb
Outdated
@@ -411,10 +411,8 @@ def confirm_context_exists | |||
def confirm_cluster_reachable | |||
success = false | |||
with_retries(2) do | |||
_, _, st = kubectl.run("version", use_namespace: false, log_failure: true) | |||
success = st.success? | |||
success = kubectl.version_info rescue false |
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.
Please rescue specific exceptions (Psych::SyntaxError
/ KubectlError
)
Actually, CI just finished and we have a problem on 1.6.4:
|
As for the StatefulSet PR, it is almost ready to ship, but we actually need your PR to merge first so that we can exclude rollingUpdate tests on < v1.7. 🙏 |
I sincerely hop this will make the code style checker happy.
kubectl before version 1.7 don't support the --output parameter.
Hopefully this is good to go now. |
CI run was green: https://buildkite.com/shopify/kubernetes-deploy-gem/builds/225. Thanks again for the contribution! |
@KnVerey That run did not include 1.8, but it was passing previously. |
@skaes FYI we released version 0.13.0 yesterday, which includes the StatefulSet support. 😄 |
This patch fixes two different problems:
Kubernetes 1.8 has changed the behavior when secrets cannot be found.
Instead of aborting a deployment quickly, Kubernetes retries quite a
few times before it gives up. Removed the test case which checks for
a quick exit.
kubectl 1.8 produces slighty different log output for some of the test
cases. Made the matches version dependent. Another option would be to
only check the parts which are identical in both versions.