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 #4516: adding a blocking delete operation #4578

Merged
merged 3 commits into from Dec 7, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -24,6 +24,7 @@
* Fix #4136: added support for fieldValidation as a dsl method for POST/PUT/PATCH operations
* Fix #3896: added dsl support for server side apply
* Fix #4582: updated [client.secrets] createOrReplace document
* Fix #4516: added support for blocking delete operations using the withTimeout methods: op.withTimeout(1, TimeUnit.MINUTE).delete() - will wait for up to 1 minute for the resources to be fully deleted. This makes for a more concise replacement of the deletingExisting method.

#### _**Note**_: Breaking changes
* Fix #4515: files located at the root of jars named model.properties, e.g. core.properties, have been removed
Expand Down
3 changes: 1 addition & 2 deletions doc/MIGRATION-v6.md
Expand Up @@ -164,8 +164,7 @@ Use:

```java
var resource = client.resource(deployment).inNamespace(session.getNamespace());
resource.delete();
resource.waitUntilCondition(Objects::isNull, 30, TimeUnit.SECONDS);
resource.withTimeout(30, TimeUnit.SECONDS).delete();
resource.create();
```

Expand Down
Expand Up @@ -19,7 +19,15 @@
import io.fabric8.kubernetes.client.GracePeriodConfigurable;
import io.fabric8.kubernetes.client.PropagationPolicyConfigurable;

import java.util.concurrent.TimeUnit;

public interface DeletableWithOptions extends GracePeriodConfigurable<PropagationPolicyConfigurable<? extends Deletable>>,
PropagationPolicyConfigurable<GracePeriodConfigurable<? extends Deletable>> {
PropagationPolicyConfigurable<GracePeriodConfigurable<? extends Deletable>>, Timeoutable {

@Override
DeletableWithOptions withTimeout(long timeout, TimeUnit unit);

@Override
DeletableWithOptions withTimeoutInMillis(long timeoutInMillis);

}
Expand Up @@ -16,7 +16,14 @@

package io.fabric8.kubernetes.client.dsl;

import java.util.concurrent.TimeUnit;

public interface TimeoutImageEditReplacePatchable<T> extends
Timeoutable<ImageEditReplacePatchable<T>>,
ImageEditReplacePatchable<T> {
Timeoutable, ImageEditReplacePatchable<T> {

@Override
ImageEditReplacePatchable<T> withTimeout(long timeout, TimeUnit unit);

@Override
ImageEditReplacePatchable<T> withTimeoutInMillis(long timeoutInMillis);
}
Expand Up @@ -18,9 +18,21 @@

import java.util.concurrent.TimeUnit;

public interface Timeoutable<T> {
public interface Timeoutable {

T withTimeout(long timeout, TimeUnit unit);
/**
* Wait for the given operation timeout.
*
* @param timeout 0 indicates no wait
* @param unit
*/
Object withTimeout(long timeout, TimeUnit unit);

/**
* Wait for the given operation timeout in milliseconds.
*
* @param timeoutInMillis 0 indicates no wait
*/
Object withTimeoutInMillis(long timeoutInMillis);

T withTimeoutInMillis(long timeoutInMillis);
}
Expand Up @@ -20,9 +20,11 @@
import io.fabric8.kubernetes.client.Client;
import io.fabric8.kubernetes.client.dsl.Nameable;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.client.dsl.WritableOperation;

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -84,4 +86,12 @@ public interface ExtensibleResource<T> extends Resource<T> {
@Override
ExtensibleResource<T> forceConflicts();

@Override
ExtensibleResource<T> withTimeout(long timeout, TimeUnit unit);

@Override
default WritableOperation<T> withTimeoutInMillis(long timeoutInMillis) {
return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS);
}

}
Expand Up @@ -21,6 +21,7 @@

import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;

/**
Expand Down Expand Up @@ -116,4 +117,14 @@ public ExtensibleResource<T> forceConflicts() {
return newInstance().init(resource.forceConflicts(), client);
}

@Override
public ExtensibleResource<T> withTimeout(long timeout, TimeUnit unit) {
return newInstance().init(resource.withTimeout(timeout, unit), client);
}

@Override
public ExtensibleResource<T> withTimeoutInMillis(long timeoutInMillis) {
return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS);
}

}
Expand Up @@ -26,6 +26,7 @@
import io.fabric8.kubernetes.client.Watch;
import io.fabric8.kubernetes.client.Watcher;
import io.fabric8.kubernetes.client.dsl.Deletable;
import io.fabric8.kubernetes.client.dsl.DeletableWithOptions;
import io.fabric8.kubernetes.client.dsl.Gettable;
import io.fabric8.kubernetes.client.dsl.Informable;
import io.fabric8.kubernetes.client.dsl.NonDeletingOperation;
Expand Down Expand Up @@ -324,4 +325,14 @@ public T serverSideApply() {
return resource.serverSideApply();
}

@Override
public DeletableWithOptions withTimeout(long timeout, TimeUnit unit) {
return resource.withTimeout(timeout, unit);
}

@Override
public DeletableWithOptions withTimeoutInMillis(long timeoutInMillis) {
return withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS);
}

}
Expand Up @@ -43,6 +43,7 @@
import io.fabric8.kubernetes.client.dsl.FilterWatchListDeletable;
import io.fabric8.kubernetes.client.dsl.MixedOperation;
import io.fabric8.kubernetes.client.dsl.Resource;
import io.fabric8.kubernetes.client.dsl.Waitable;
import io.fabric8.kubernetes.client.dsl.base.PatchContext;
import io.fabric8.kubernetes.client.dsl.base.PatchType;
import io.fabric8.kubernetes.client.extension.ExtensibleResource;
Expand Down Expand Up @@ -451,6 +452,21 @@ static void toStatusDetails(KubernetesResource obj, List<StatusDetails> details)

@Override
public List<StatusDetails> delete() {
List<StatusDetails> deleted = deleteAll();
waitForDelete(deleted, this.context, this);
return deleted;
}

static void waitForDelete(List<StatusDetails> deleted, OperationContext context,
Waitable<?, ? extends HasMetadata> waitable) {
if (context.getTimeout() > 0) {
Set<String> uids = deleted.stream().map(StatusDetails::getUid).collect(Collectors.toSet());
waitable.waitUntilCondition(h -> h == null || !uids.contains(h.getMetadata().getUid()), context.getTimeout(),
context.getTimeoutUnit());
}
}

protected List<StatusDetails> deleteAll() {
if (Utils.isNotNullOrEmpty(name) || Utils.isNotNullOrEmpty(namespace) || !isResourceNamespaced()) {
try {
URL resourceURLForWriteOperation = getResourceURLForWriteOperation(getResourceUrl());
Expand Down Expand Up @@ -1103,4 +1119,9 @@ public T serverSideApply() {
return this.patch(PatchContext.of(PatchType.SERVER_SIDE_APPLY));
}

@Override
public ExtensibleResource<T> withTimeout(long timeout, TimeUnit unit) {
return newInstance(context.withTimeout(timeout, unit));
}

}
Expand Up @@ -27,6 +27,7 @@
import io.fabric8.kubernetes.client.KubernetesClient;
import io.fabric8.kubernetes.client.KubernetesClientException;
import io.fabric8.kubernetes.client.KubernetesClientTimeoutException;
import io.fabric8.kubernetes.client.dsl.DeletableWithOptions;
import io.fabric8.kubernetes.client.dsl.Gettable;
import io.fabric8.kubernetes.client.dsl.ListVisitFromServerGetDeleteRecreateWaitApplicable;
import io.fabric8.kubernetes.client.dsl.ListVisitFromServerWritable;
Expand Down Expand Up @@ -202,7 +203,9 @@ public List<HasMetadata> createOrReplace() {

@Override
public List<StatusDetails> delete() {
return resources().flatMap(r -> r.delete().stream()).collect(Collectors.toList());
List<StatusDetails> deleted = resources().flatMap(r -> r.delete().stream()).collect(Collectors.toList());
BaseOperation.waitForDelete(deleted, this.context, this);
return deleted;
}

@Override
Expand Down Expand Up @@ -314,4 +317,14 @@ public List<HasMetadata> replaceStatus() {
return performOperation(Resource::replaceStatus);
}

@Override
public DeletableWithOptions withTimeout(long timeout, TimeUnit unit) {
return newInstance(context.withTimeout(timeout, unit));
}

@Override
public DeletableWithOptions withTimeoutInMillis(long timeoutInMillis) {
return this.withTimeout(timeoutInMillis, TimeUnit.MILLISECONDS);
}

}
Expand Up @@ -33,6 +33,7 @@
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.function.BiFunction;
import java.util.stream.Collectors;

Expand Down Expand Up @@ -68,6 +69,9 @@ public class OperationContext {

protected Client client;

private long timeout;
private TimeUnit timeoutUnit = TimeUnit.MILLISECONDS;

public OperationContext() {
}

Expand All @@ -76,7 +80,7 @@ public OperationContext(OperationContext other) {
other.item, other.labels, other.labelsNot, other.labelsIn, other.labelsNotIn, other.fields,
other.fieldsNot, other.resourceVersion, other.reloadingFromServer, other.gracePeriodSeconds, other.propagationPolicy,
other.dryRun, other.selectorAsString, other.defaultNamespace, other.fieldValidation, other.fieldManager,
other.forceConflicts);
other.forceConflicts, other.timeout, other.timeoutUnit);
}

public OperationContext(Client client, String plural, String namespace, String name,
Expand All @@ -85,7 +89,7 @@ public OperationContext(Client client, String plural, String namespace, String n
Map<String, String> fields, Map<String, String[]> fieldsNot, String resourceVersion, boolean reloadingFromServer,
long gracePeriodSeconds, DeletionPropagation propagationPolicy,
boolean dryRun, String selectorAsString, boolean defaultNamespace, FieldValidateable.Validation fieldValidation,
String fieldManager, Boolean forceConflicts) {
String fieldManager, Boolean forceConflicts, long timeout, TimeUnit timeoutUnit) {
this.client = client;
this.item = item;
this.plural = plural;
Expand All @@ -108,6 +112,8 @@ public OperationContext(Client client, String plural, String namespace, String n
this.fieldValidation = fieldValidation;
this.fieldManager = fieldManager;
this.forceConflicts = forceConflicts;
this.timeout = timeout;
this.timeoutUnit = timeoutUnit;
}

private void setFieldsNot(Map<String, String[]> fieldsNot) {
Expand Down Expand Up @@ -243,6 +249,14 @@ public boolean getDryRun() {
return dryRun;
}

public long getTimeout() {
return timeout;
}

public TimeUnit getTimeoutUnit() {
return timeoutUnit;
}

public String getLabelQueryParam() {
if (Utils.isNotNullOrEmpty(selectorAsString)) {
return selectorAsString;
Expand Down Expand Up @@ -527,4 +541,11 @@ public OperationContext withForceConflicts() {
return context;
}

public OperationContext withTimeout(long timeout, TimeUnit timeUnit) {
final OperationContext context = new OperationContext(this);
context.timeout = timeout;
context.timeoutUnit = timeUnit == null ? TimeUnit.MILLISECONDS : timeUnit;
return context;
}

}
Expand Up @@ -67,6 +67,8 @@ public StreamContext() {
private String dir;
private boolean terminateOnError;

private boolean rolling;

public PodOperationContext withContainerId(String containerId) {
return this.toBuilder().containerId(containerId).build();
}
Expand Down