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

Unable to create a pod using example YAML InputStream with client >=6.4 #4873

Closed
oreillymj opened this issue Feb 14, 2023 · 11 comments · Fixed by #4912
Closed

Unable to create a pod using example YAML InputStream with client >=6.4 #4873

oreillymj opened this issue Feb 14, 2023 · 11 comments · Fixed by #4912
Assignees
Milestone

Comments

@oreillymj
Copy link

Describe the bug

Using client 6.4.1

While trying to create a pod from an Inputstream, I get the error below.

2023-02-13 16:39:26 - createPodFromInputStream()-> got resource from Inputstream
Exception in thread "main" io.fabric8.kubernetes.client.KubernetesClientException: name not specified for an operation requiring one.
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.requireFromServer(BaseOperation.java:182)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.get(BaseOperation.java:142)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.get(BaseOperation.java:93)
at Main.createPodFromInputStream(Main.java:616)

The code is again based on the examples ( PodCreateYamlEquivalent ), down to the yaml file for the pod.

The "test" namespace exists and I have permission to create pods in it.

Fabric8 Kubernetes Client version

6.4.1

Steps to reproduce

InputStream pod_resource_inputstream = Main.class.getClassLoader().getResourceAsStream("json/test-pod.yaml");
if (pod_resource_inputstream!=null) {
   PodResource podresource = client.pods().load(pod_resource_inputstream);
    if (podresource != null) {
        System.out.println(dt() + "createPodFromInputStream()-> got resource from Inputstream");
        client.pods().inNamespace("test").create(podresource.get());  **<--- Exception triggered here**
        System.out.println(dt() + "createPodFromInputStream()-> created pod with deprecated method");
        client.pods().inNamespace("test").resource(podresource.get()).create();
    }
}

Expected behavior

I expect the nginx pod to be created in the test namespace.

Runtime

Kubernetes (vanilla)

Kubernetes API Server version

1.25.3@latest

Environment

Linux

Fabric8 Kubernetes Client Logs

Exception in thread "main" io.fabric8.kubernetes.client.KubernetesClientException: name not specified for an operation requiring one.
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.requireFromServer(BaseOperation.java:182)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.get(BaseOperation.java:142)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.get(BaseOperation.java:93)
at Main.createPodFromInputStream(Main.java:616)

Additional context

ClusterRole for test namespace

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
namespace: test
name: api-reader-role
rules:

  • apiGroups: [""] # "" indicates the core API group
    resources: ["services", "pods", "deployments", "namespaces"]
    verbs: ["get", "watch", "list", "create", "update", "patch", "delete"]
@rohanKanojia
Copy link
Member

rohanKanojia commented Feb 14, 2023

@oreillymj : Does it work if you modify your code like this?

if (pod_resource_inputstream!=null) {
   Pod pod = client.pods().load(pod_resource_inputstream).get();
    if (pod != null) {
        client.pods().inNamespace("test").resource(pod).create();
    }
}

So you're saying that client.pods().inNamespace("test").create(podresource.get()); is not working?

@oreillymj oreillymj changed the title Unable to create a pod using example YAML InputStream Unable to create a pod using example YAML InputStream with client >=6.40 Feb 14, 2023
@oreillymj
Copy link
Author

yes, I've gone back and tested.
6.31 works
6.40 broken
6.41 broken

I changed my code to test for the existence of the pod before trying to create it as with older (working) versions of the client I was getting exceptions trying to create a pod that already existed in the namespace.

@manusa manusa changed the title Unable to create a pod using example YAML InputStream with client >=6.40 Unable to create a pod using example YAML InputStream with client >=6.4 Feb 14, 2023
@sunix sunix added bug and removed bug labels Feb 14, 2023
@manusa
Copy link
Member

manusa commented Feb 14, 2023

Since last release.get() method will always retrieve the Object from the cluster, so if it doesn't exist, it will fail (which it's what happening in your example)

You can learn more about this in the release notes:

Fix #4574: fromServer has been deprecated - it no longer needs to be called. All get() operations will fetch the resource(s) from the api server. If you need the context item that was passed in from a resource, load, or resourceList methods, use the item or items method.

You should migrate to use this:

client.pods().inNamespace("test").create(podresource.item());
// Or better
client.load(pod_resource_inputstream).inNamespace("test").create()

@manusa manusa added the Waiting on feedback Issues that require feedback from User/Other community members label Feb 14, 2023
@oreillymj
Copy link
Author

Tested some suggestions above with 6.4.1

Using this code to check for an existing pod, as suggested above...

Pod myPod = client.pods().load(pod_resource_inputstream).get();

... results in.....
Exception in thread "main" io.fabric8.kubernetes.client.KubernetesClientException: An error has occurred.
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:129)
at io.fabric8.kubernetes.client.KubernetesClientException.launderThrowable(KubernetesClientException.java:122)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:269)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:387)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:353)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:337)
at io.fabric8.kubernetes.client.dsl.internal.OperationSupport.unmarshal(OperationSupport.java:753)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.load(BaseOperation.java:261)
at io.fabric8.kubernetes.client.dsl.internal.BaseOperation.load(BaseOperation.java:93)
at Main.createPodFromInputStream(Main.java:615)
at Main.main(Main.java:113)
Caused by: java.io.IOException: Stream closed
at java.base/java.util.zip.InflaterInputStream.ensureOpen(InflaterInputStream.java:67)
at java.base/java.util.zip.InflaterInputStream.read(InflaterInputStream.java:142)
at java.base/java.io.FilterInputStream.read(FilterInputStream.java:132)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:244)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:263)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:250)

Getting beyond that error using a hard-coded name check for the pod......

client.load(pod_resource_inputstream).inNamespace("test").create()

Gives the following exception

2023-02-14 11:23:54 - createPodFromInputStream()-> no existing pod, so create one
Exception in thread "main" java.lang.RuntimeException: Could not read stream
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:226)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:202)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:170)
at io.fabric8.kubernetes.client.impl.KubernetesClientImpl.load(KubernetesClientImpl.java:302)
at Main.createPodFromInputStream(Main.java:624)

Testing the other create option is successful.
Both the deprecated create method and supported create method work if using item()

InputStream pod_resource_inputstream = Main.class.getClassLoader().getResourceAsStream("json/test-pod.yaml");
if (pod_resource_inputstream!=null) {
    PodResource podresource = client.pods().load(pod_resource_inputstream);

    client.pods().inNamespace("test").create(podresource.item()); // works
    client.pods().inNamespace("test").resource(podresource.item()).create(); //also works, but can only do 1 at a time to avoid pod exists error.

}

Any calls to .get() triggers an exception, even though the code is valid and compiles. Also the error message
"name not specified for an operation requiring one."
is very unclear what name is missing in valid scenarios. Maybe that is difficult to provide in an error involving generics.

@manusa
Copy link
Member

manusa commented Feb 14, 2023

The suggestions from Rohan are NOT OK, they are based on the same assumptions as yours. We changed the default behavior of .get() in 6.4.0, please read my comment:

#4873 (comment)

@manusa
Copy link
Member

manusa commented Feb 14, 2023

Just for clarification:

Getting beyond that error using a hard-coded name check for the pod......

client.load(pod_resource_inputstream).inNamespace("test").create()

This doesn't work?

It seems that there might be some problem while parsing your YAML. Could you share it so we can try and reproduce?

@oreillymj
Copy link
Author

oreillymj commented Feb 14, 2023

I am using the valid yaml from your repo here https://github.com/fabric8io/kubernetes-client/blob/master/kubernetes-examples/src/main/resources/test-pod.yaml

From your suggestions in #4873

This works, but is using a deprecated method
client.pods().inNamespace("test").create(podresource.item());
This also works using a supported method (so nothing wrong with the yaml)
client.pods().inNamespace("test").resource(podresource.item()).create();

To be clear, this does not work
// Or better
client.load(pod_resource_inputstream).inNamespace("test").create()

It triggers this error
Exception in thread "main" java.lang.RuntimeException: Could not read stream
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:226)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:202)
at io.fabric8.kubernetes.client.utils.Serialization.unmarshal(Serialization.java:170)
at io.fabric8.kubernetes.client.impl.KubernetesClientImpl.load(KubernetesClientImpl.java:302)
at Main.createPodFromInputStream(Main.java:625)
at Main.main(Main.java:113)

@manusa
Copy link
Member

manusa commented Feb 14, 2023

To be clear, this does not work
// Or better
client.load(pod_resource_inputstream).inNamespace("test").create()

We definitely need to check that one since it should work

@manusa manusa added bug and removed Waiting on feedback Issues that require feedback from User/Other community members labels Feb 14, 2023
@shawkins
Copy link
Contributor

We definitely need to check that one since it should work

I can confirm that it does work.

To be clear, this does not work

This is different from the exception you were initially encountering. You need ensure that the inputstream you are passing to load is valid - hasn't already been read from or closed.

@oreillymj
Copy link
Author

Ah okay, I found what i was doing wrong...

So my earlier (non-working) code was reading the stream, And even though I'd commented out non working code, I had read the Inputstream once into podresource.

PodResource podresource = client.pods().load(pod_resource_inputstream);
                if ((podresource != null){
                client.pods().inNamespace("test").create(podresource.get());

So even though I was no longer using podresource in my code

// client.pods().inNamespace("test").create(podresource.get());

I couldn't re-use/reload the Inputstream variable as follows.

client.load(pod_resource_inputstream).inNamespace("test").create();

The example here no longer works.

@manusa manusa added the doc label Feb 14, 2023
@shawkins
Copy link
Contributor

The example here no longer works.

Yes the get method needs to be changed to item. We can use this issue to address that.

@rohanKanojia rohanKanojia self-assigned this Feb 22, 2023
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Feb 23, 2023
…se up to date code (fabric8io#4873)

+ Replace deprecated method calls with updated method calls
+ Replace load(..).get() with load(..).item() calls

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Feb 23, 2023
…se up to date code (fabric8io#4873)

+ Replace deprecated method calls with updated method calls
+ Replace load(..).get() with load(..).item() calls

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Feb 23, 2023
…se up to date code (fabric8io#4873)

+ Replace deprecated method calls with updated method calls
+ Replace load(..).get() with load(..).item() calls

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
rohanKanojia added a commit to rohanKanojia/kubernetes-client that referenced this issue Feb 27, 2023
…se up to date code (fabric8io#4873)

+ Replace deprecated method calls with updated method calls
+ Replace load(..).get() with load(..).item() calls

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
@manusa manusa added this to the 6.5.0 milestone Mar 2, 2023
manusa pushed a commit that referenced this issue Mar 2, 2023
…se up to date code (#4873)

+ Replace deprecated method calls with updated method calls
+ Replace load(..).get() with load(..).item() calls

Signed-off-by: Rohan Kumar <rohaan@redhat.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
5 participants