kubectl icon indicating copy to clipboard operation
kubectl copied to clipboard

kubectl wait with `jsonpath` fails when field is not found

Open pierDipi opened this issue 2 years ago • 10 comments

What happened?

Waiting for a field to be set on a resource using --for=jsonpath= fails when the field is not found.

kubectl wait brokers -n knative-eventing  --timeout 300s --for=jsonpath='{.status.state}'=https://example.com
error: state is not found

What did you expect to happen?

The jsonpath syntax behaves differently when compared to --for=condition= since this:

kubectl wait deployment <deployment_name> --timeout 300s --for=condition=Nope=True

waits even when there is no condition called Nope.

In addition, waiting on status fields that are set asynchronously is really useful, so the usual flow of creating and waiting for a resource to have a specific field isn't reliably solvable with this error thrown.

How can we reproduce it (as minimally and precisely as possible)?

Run:

$ kubectl create deployment nginx --image=nginx; kubectl wait --for=jsonpath='{.status.readyReplicas}'=1 deploy/nginx
deployment.apps/nginx created
error: readyReplicas is not found

Anything else we need to know?

I see a test with this behavior [1], however, I think it's not consistent with the existing wait behavior.

[1] https://github.com/kubernetes/kubernetes/blob/10dcc6c5f44a0607881cd2f3bd5c4d80f61ad120/staging/src/k8s.io/kubectl/pkg/cmd/wait/wait_test.go#L1167-L1176

Kubernetes version

$ kubectl version
Client Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.5", GitCommit:"c285e781331a3785a7f436042c65c5641ce8a9e9", GitTreeState:"clean", BuildDate:"2022-03-16T15:58:47Z", GoVersion:"go1.17.8", Compiler:"gc", Platform:"linux/amd64"}

Server Version: version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.3", GitCommit:"816c97ab8cff8a1c72eccca1026f7820e93e0d25", GitTreeState:"clean", BuildDate:"2022-01-26T08:02:07Z", GoVersion:"go1.17.6", Compiler:"gc", Platform:"linux/amd64"}

Cloud provider

N/A

OS version

NAME="Fedora Linux"
VERSION="35 (Workstation Edition)"
ID=fedora
VERSION_ID=35
VERSION_CODENAME=""
PLATFORM_ID="platform:f35"
PRETTY_NAME="Fedora Linux 35 (Workstation Edition)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:35"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f35/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=35
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=35
PRIVACY_POLICY_URL="https://fedoraproject.org/wiki/Legal:PrivacyPolicy"
VARIANT="Workstation Edition"
VARIANT_ID=workstation

Install tools

N/A

Container runtime (CRI) and version (if applicable)

N/A

Related plugins (CNI, CSI, ...) and versions (if applicable)

N/A

pierDipi avatar Apr 14 '22 17:04 pierDipi

@pierDipi: This issue is currently awaiting triage.

If a SIG or subproject determines this is a relevant issue, they will accept it by applying the triage/accepted label and provide further guidance.

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/test-infra repository.

k8s-ci-robot avatar Apr 14 '22 17:04 k8s-ci-robot

/sig cli

pierDipi avatar Apr 14 '22 17:04 pierDipi

I think it's not consistent with the existing wait behavior.

Could u please explain this more? IMO, If the field is not exist, wait will return field is not found just like the test.

jonyhy96 avatar Apr 15 '22 11:04 jonyhy96

Currently, waiting on a condition with

kubectl wait deployment <deployment_name> --timeout 300s --for=condition=Nope=True

waits even when the condition Nope doesn't exist, while waiting on a custom field with jsonpath like:

kubectl wait <my_crd> <name> --timeout 300s --for=jsonpath='{.status.state}'=https://example.com

fails immediately when .status.state doesn't exist which defeats the purpose of waiting for a specific value that is set asynchronously.

pierDipi avatar Apr 15 '22 13:04 pierDipi

Example use case where the wait with jsonpath fails immediately:

$ kubectl create deployment nginx --image=nginx; kubectl wait --for=jsonpath='{.status.readyReplicas}'=1 deploy/nginx
deployment.apps/nginx created
error: readyReplicas is not found

instead with condition it waits even when the condition doesn't exist:

kubectl create deployment nginx --image=nginx; kubectl wait --for=condition=Available=True deploy/nginx
deployment.apps/nginx created
deployment.apps/nginx condition met

pierDipi avatar Apr 15 '22 13:04 pierDipi

I think this is more like a feature which keep the behavior of both logics consistent. I'm interest in implementing this. /assign

jonyhy96 avatar Apr 18 '22 03:04 jonyhy96

Already implement this and test locally.

kubectl create deployment nginx --image=nginx; kubectl wait --for=jsonpath=.status.readyReplicas=1 deploy/nginx
deployment.apps/nginx created
deployment.apps/nginx condition met

For fileds that not exist, will return timeout.

jonyhy96 avatar Apr 18 '22 07:04 jonyhy96

/transfer kubectl

lauchokyip avatar Jun 28 '22 23:06 lauchokyip

/triage accepted

lauchokyip avatar Jun 28 '22 23:06 lauchokyip

This might be a duplicate of #1204

zevisert avatar Sep 02 '22 23:09 zevisert