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

"kubectl get" does not behave like its help description says it will. #1596

Open
jmazzitelli opened this issue May 3, 2024 · 4 comments
Open
Labels
kind/bug Categorizes issue or PR as related to a bug. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one.

Comments

@jmazzitelli
Copy link

What happened:

kubectl get exit code does not match what the --help description says will happen.

kubectl get -h
...
    --ignore-not-found=false:
	If the requested object does not exist the command will return exit code 0.
$ kubectl get pod --ignore-not-found=true ; echo "==>exit code=$?"
==>exit code=0

$ kubectl get pod --ignore-not-found=false ; echo "==>exit code=$?"
No resources found in default namespace.
==>exit code=0

$ kubectl get pod -l foo=bar --ignore-not-found=true ; echo "==>exit code=$?"
==>exit code=0

$ kubectl get pod -l foo=bar --ignore-not-found=false ; echo "==>exit code=$?"
No resources found in default namespace.
==>exit code=0

$ kubectl get pod foo --ignore-not-found=true ; echo "==>exit code=$?"
==>exit code=0

$ kubectl get pod foo --ignore-not-found=false ; echo "==>exit code=$?"
Error from server (NotFound): pods "foo" not found
==>exit code=1

What you expected to happen:

The requested object does not exist (there are no pods). And yet, --ignore-not-found=false still results in an exit code of 0. Although --ignore-not-found does change the stdout behavior (error messages are printed out or not), the exit code doesn't match expectations of the documentation regarding the exit code.

How to reproduce it (as minimally and precisely as possible):

See above. Just don't have any pods in the default namespace.

Environment:

kubectl version v1.29.1

@jmazzitelli jmazzitelli added the kind/bug Categorizes issue or PR as related to a bug. label May 3, 2024
@k8s-ci-robot k8s-ci-robot added the needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. label May 3, 2024
@k8s-ci-robot
Copy link
Contributor

This issue is currently awaiting triage.

SIG CLI takes a lead on issue triage for this repo, but any Kubernetes member can accept issues by applying the triage/accepted label.

The triage/accepted label can be added by org members by writing /triage accepted in a comment.

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-sigs/prow repository.

@brianpursley
Copy link
Member

brianpursley commented May 3, 2024

To clarify, you are saying these two cases have the wrong exit code?

$ kubectl get pod --ignore-not-found=false ; echo "==>exit code=$?"
No resources found in default namespace.
==>exit code=0
$ kubectl get pod -l foo=bar --ignore-not-found=false ; echo "==>exit code=$?"
No resources found in default namespace.
==>exit code=0

And that they should have exit code 1 like this one?

$ kubectl get pod foo --ignore-not-found=false ; echo "==>exit code=$?"
Error from server (NotFound): pods "foo" not found
==>exit code=1

I think what is happening, is in case 1 and 2, you are not requesting a specific pod, so there is no NotFound error that occurs.

You can see what I mean if you use -v7 to look at the logs. Here you can see the HTTP response is 200 OK:

$ kubectl get pod -v7
I0503 16:34:23.156766   50407 loader.go:395] Config loaded from file:  /home/brian/.kube/config
I0503 16:34:23.162638   50407 round_trippers.go:463] GET https://k8s-master:6443/api/v1/namespaces/default/pods?limit=500
I0503 16:34:23.162662   50407 round_trippers.go:469] Request Headers:
I0503 16:34:23.162678   50407 round_trippers.go:473]     User-Agent: kubectl/v1.28.0 (linux/amd64) kubernetes/10a1216
I0503 16:34:23.162690   50407 round_trippers.go:473]     Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0503 16:34:23.213080   50407 round_trippers.go:574] Response Status: 200 OK in 50 milliseconds
No resources found in default namespace.

vs requesting a specific pod, where you can see the HTTP response is 404 NotFound:

$ kubectl get pod foo -v7
I0503 16:35:05.554206   50521 loader.go:395] Config loaded from file:  /home/brian/.kube/config
I0503 16:35:05.558568   50521 round_trippers.go:463] GET https://k8s-master:6443/api/v1/namespaces/default/pods/foo
I0503 16:35:05.558588   50521 round_trippers.go:469] Request Headers:
I0503 16:35:05.558603   50521 round_trippers.go:473]     User-Agent: kubectl/v1.28.0 (linux/amd64) kubernetes/10a1216
I0503 16:35:05.558614   50521 round_trippers.go:473]     Accept: application/json;as=Table;v=v1;g=meta.k8s.io,application/json;as=Table;v=v1beta1;g=meta.k8s.io,application/json
I0503 16:35:05.607220   50521 round_trippers.go:574] Response Status: 404 Not Found in 48 milliseconds
I0503 16:35:05.607768   50521 helpers.go:246] server response object: [{
  "kind": "Status",
  "apiVersion": "v1",
  "metadata": {},
  "status": "Failure",
  "message": "pods \"foo\" not found",
  "reason": "NotFound",
  "details": {
    "name": "foo",
    "kind": "pods"
  },
  "code": 404
}]
Error from server (NotFound): pods "foo" not found

So in case 1 and 2, the command is successfully returning an empty result, and in example 3, the command is failing because it could not find the specific pod you have specified.

I think that explains the behavior you are seeing. Whether it is the correct behavior I suppose is open for discussion.

The help text from the flag does imply that it only applies when you request a specific object, but maybe it isn't clear enough.

   --ignore-not-found=false:
	If the requested object does not exist the command will return exit code 0.

I guess kubectl could print a warning if you use --ignore-not-found without requesting a specific object, saying that it has no effect.


Incidentally, I do think there is a related bug, when you use --ignore-not-found with --watch:

$ kubectl get pod foo --watch --ignore-not-found
Error from server (NotFound): pods "foo" not found
$ echo $?
1

In this case, I think the exit code should be 0.

@jmazzitelli
Copy link
Author

Right. When reading that help text where it says "the requested object" - I assume "the requested object" means whatever I'm asking to get. And I am requesting an object when I use --selector or just a empty get (now, granted, I could be requesting multiple objects (plural) - but I really don't know what I have - that's why I'm getting them :)

The help text from the flag does imply that it only applies when you request a specific object, but maybe it isn't clear enough.

Yes. I think at minimum this is a problem that can easily be corrected - just make the help text more clear. It seems to me reading that help text that the exit code should be non-zero if the requested object (or objects, again I don't know how many there are) does not exist.

I guess kubectl could print a warning if you use --ignore-not-found without requesting a specific object, saying that it has no effect.

If that is the correct expected behavior, that would help also.

But, frankly, I think the behavior should change, too. If I ask to get resources, and I get nothing back, exit code should be 0 if --ignore-not-found=true and exit code should be 1 if --ignore-not-found=false. Saying "false" implies "do NOT ignore this if nothing is found - tell me with exit code 1".

@ardaguclu
Copy link
Member

I think, this KEP kubernetes/enhancements#2551 will propose a standartization with respect to exit code and will fix this.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Categorizes issue or PR as related to a bug. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one.
Projects
None yet
Development

No branches or pull requests

4 participants