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

Fix test failures for various combinations of kubectl and Kubernetes versions #198

Merged
merged 11 commits into from
Nov 8, 2017

Conversation

skaes
Copy link
Contributor

@skaes skaes commented Oct 31, 2017

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.

…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.
@KnVerey KnVerey requested review from KnVerey and kirs October 31, 2017 20:31
@stefanmb
Copy link
Contributor

stefanmb commented Nov 3, 2017

I can confirm this PR fixes all known test failures on k8s 1.8.2 (and also passes on 1.7.6 and 1.7.9). Test run here: https://buildkite.com/shopify/kubernetes-deploy-gem/builds/206

@stefanmb
Copy link
Contributor

stefanmb commented Nov 3, 2017

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

Copy link
Contributor

@KnVerey KnVerey left a 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. 😄

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

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

Copy link
Contributor Author

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

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

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

Copy link
Contributor Author

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.

Copy link
Contributor

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.

end

def client_version
version_info["clientVersion"]["gitVersion"]
Copy link
Contributor

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.

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

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

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.

Copy link
Contributor Author

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

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.

@KnVerey
Copy link
Contributor

KnVerey commented Nov 6, 2017

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

@skaes
Copy link
Contributor Author

skaes commented Nov 7, 2017

@KnVerey I think I have addressed all your concerns with the latest commits. Would be great to see a new version soon!

BTW, any chance you might merge #140 soon? We do have StatefulSets too.

Copy link
Contributor

@KnVerey KnVerey left a 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.

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

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)

@KnVerey
Copy link
Contributor

KnVerey commented Nov 7, 2017

Actually, CI just finished and we have a problem on 1.6.4:


[2017-11-07T21:00:05Z] [WARN][2017-11-07 21:00:05 +0000]	The following command failed: kubectl version --output\=yaml --context\=minikube --request-timeout\=5s
--
  | [2017-11-07T21:00:05Z] [WARN][2017-11-07 21:00:05 +0000]	Error: unknown flag: --output
  | [2017-11-07T21:00:05Z]
  | [2017-11-07T21:00:05Z]
  | [2017-11-07T21:00:05Z] Examples:
  | [2017-11-07T21:00:05Z]   # Print the client and server versions for the current context
  | [2017-11-07T21:00:05Z]   kubectl version
  | [2017-11-07T21:00:05Z]
  | [2017-11-07T21:00:05Z] Options:
  | [2017-11-07T21:00:05Z]   -c, --client=false: Client version only (no server required).
  | [2017-11-07T21:00:05Z]       --short=false: Print just the version number.
  | [2017-11-07T21:00:05Z]
  | [2017-11-07T21:00:05Z] Usage:
  | [2017-11-07T21:00:05Z]   kubectl version [options]
  | [2017-11-07T21:00:05Z]
  | [2017-11-07T21:00:05Z] Use "kubectl options" for a list of global command-line options (applies to all commands).

@KnVerey
Copy link
Contributor

KnVerey commented Nov 7, 2017

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

@skaes
Copy link
Contributor Author

skaes commented Nov 8, 2017

Hopefully this is good to go now.

@KnVerey
Copy link
Contributor

KnVerey commented Nov 8, 2017

CI run was green: https://buildkite.com/shopify/kubernetes-deploy-gem/builds/225. Thanks again for the contribution!

@stefanmb
Copy link
Contributor

stefanmb commented Nov 8, 2017

@KnVerey That run did not include 1.8, but it was passing previously.

@KnVerey KnVerey merged commit 4ead9cc into Shopify:master Nov 8, 2017
@KnVerey
Copy link
Contributor

KnVerey commented Nov 10, 2017

@skaes FYI we released version 0.13.0 yesterday, which includes the StatefulSet support. 😄

@skaes skaes deleted the fix-test-failures-for-1.8 branch November 11, 2017 11:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants