Skip to content
This repository has been archived by the owner on Jul 28, 2023. It is now read-only.

Blocking defect: api.deleteStack does not seem to work #2

Open
davco01a opened this issue Feb 15, 2020 · 8 comments
Open

Blocking defect: api.deleteStack does not seem to work #2

davco01a opened this issue Feb 15, 2020 · 8 comments

Comments

@davco01a
Copy link

davco01a commented Feb 15, 2020

api.deleteStack does not seem to work

trying to delete a stack that only has one version and this call fails and does not return any response object to debug what went wrong:

`
V1DeleteOptions deleteOptions = new V1DeleteOptions();
deleteOptions.setGracePeriodSeconds((long)3);
deleteOptions.setOrphanDependents(true);
deleteOptions.setKind("stacks");
deleteOptions.setApiVersion(apiVersion);
v1status=api.deleteStack(namespace, kabStack.getSpec().getName(), deleteOptions, 0, true, "");

@davco01a davco01a changed the title api.deleteStack does not seem to work Blocking defect:api.deleteStack does not seem to work Feb 15, 2020
@davco01a davco01a changed the title Blocking defect:api.deleteStack does not seem to work Blocking defect: api.deleteStack does not seem to work Feb 15, 2020
@davco01a
Copy link
Author

cli_1.log

@davco01a
Copy link
Author

davco01a commented Feb 15, 2020

see around line 761 in cli_1.log above

@davco01a
Copy link
Author

davco01a commented Feb 15, 2020

FYI:

I have also tried the old delete method as a work around, but it no longer works (gets a 404), I suspect because of version arrays in Spec now:

int rc = KubeUtils.deleteKubeResource(apiClient, namespace, name, group, version, "stacks");

@kaczyns
Copy link
Member

kaczyns commented Feb 18, 2020

@davco01a ok a couple of things here... I have a test program:

	public static void main(String[] parms) {
		try {
			ApiClient client = Config.defaultClient();
			Configuration.setDefaultApiClient(client);
			
			V1DeleteOptions deleteOptions = new V1DeleteOptions();
			deleteOptions.setGracePeriodSeconds((long)3);
			deleteOptions.setOrphanDependents(true);
			deleteOptions.setKind("Stacks");
			deleteOptions.setApiVersion("kabanero.io/v1alpha2");
			
			StackApi stackApi = new StackApi();
			System.out.println("Attempting to delete java-microprofile stack");
			V1Status status = stackApi.deleteStack("kabanero", "java-microprofile", deleteOptions, 0, true, "");
			System.out.println("Return status: " + status.toString());
		} catch (Throwable t) {
			System.out.println("Caught an exception: " + t.toString());
			t.printStackTrace(System.out);
			if (t instanceof ApiException) {
				ApiException ae = (ApiException) t;
				System.out.println("Message: " + ae.getMessage());
				System.out.println("Code: " + ae.getCode());
				System.out.println("Body: " + ae.getResponseBody());
			}
		}
	}

and I am able to reproduce the 500 internal server error.

  1. If I don't pass a V1DeleteOptions object then the delete works, but....
  2. then I get a JSON parsing exception because the kube server is not returning a Status object, but is returning the Stack object that I deleted instead.

For 1) I think that there is some conflict between the V1DeleteOptions you're passing, and the rest of the parameters. For 2) I need to research why the Kube API server is returning the deleted object instance instead of a Status object. In the end I guess I'll just change the code to read what it's sending back, but it makes no sense to me why it would return the object instance when every other delete operation says it returns status.

If you look at the StackApi it's really just a pass-thru, and I actually based it on what the CLI service was doing before. You should be able to continue doing what you were doing before. I don't know why you're getting a 404 when you do it the old way, but it has nothing to do with how the Stack object is structured. From the Kubernetes perspective, it doesn't care what's in the stack, it's just trying to delete it.

@kaczyns
Copy link
Member

kaczyns commented Feb 18, 2020

I've tried deleting Kabanero and Stack using the REST API and in both cases it returns the object instance that we're deleting, not the V1Status as the kube REST documentation suggests. So I'll update the return types on those.

For the V1DeleteOptions I would suggest just not setting any of these if you don't need to (just pass null). There is no need to set a delete policy or grace period or anything unless you really need these (and understand what they do).

@davco01a
Copy link
Author

returning a stack object is consistent with stack=api.updateStack(

so it would be good to leave it as such

@kaczyns
Copy link
Member

kaczyns commented Feb 18, 2020

I wish I got to pick what the kube API server handed us back, we just have to go with what we get (which happens to be what you want, a Stack).

I'm closing this as fixed in release 0.6.1.

@kaczyns kaczyns closed this as completed Feb 18, 2020
@kaczyns
Copy link
Member

kaczyns commented Feb 19, 2020

OK - so there may be more going on here. See this issue in the kube java client:
kubernetes-client/java#86

I'm not sure I followed all of the conversation here, but, what may be happening is:

  1. If the deletion completes immediately, or if there's some other problem, you'll get a V1Status back
  2. If something is taking a long time (ie if there's a finalizer we're waiting for) then you'll get the object instance back (in this case, Stack) so that you can see that the deletion timestamp is set.

I have been writing unit tests for the operator bindings, and the kubernetes cluster where I'm testing does not have any part of Kabanero installed, just the CRDs. So, there are no finalizers. When I call deleteStack() I get a V1Status object back, which of course now fails with a JSON parse exception because it's expecting a Stack.

The discussion in the java client issue seem to say that OpenAPI needs to support being able to return one or the other type. Java obviously allows only a single return type. The suggested workarounds included catching the exception, retry the delete, and see if the object is still there. That's hard to encapsulate in a client wrapper that shouldn't block. I suspect that where we'll end up is that we'll have to invent some return object type, that wraps both a V1Status and a Stack, and only one or the other will actually get populated. Perhaps there'll be a boolean on there too which indicates whether the delete was actually successful (the Status was successful, or the returned Stack object has the deletion timestamp set).

@kaczyns kaczyns reopened this Feb 19, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants