Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,21 @@
package io.seqera.tower.cli.commands.computeenvs;

import io.seqera.tower.ApiException;
import io.seqera.tower.cli.commands.enums.OutputType;
import io.seqera.tower.cli.commands.global.WorkspaceOptionalOptions;
import io.seqera.tower.cli.exceptions.ComputeEnvNotFoundException;
import io.seqera.tower.cli.responses.Response;
import io.seqera.tower.cli.responses.computeenvs.ComputeEnvDeleted;
import io.seqera.tower.model.ComputeEnvResponseDto;
import io.seqera.tower.model.ComputeEnvStatus;
import picocli.CommandLine;
import picocli.CommandLine.Command;

import java.util.Collections;
import java.util.concurrent.TimeUnit;

import static io.seqera.tower.cli.utils.ResponseHelper.waitStatus;

@Command(
name = "delete",
description = "Delete a compute environment."
Expand All @@ -37,6 +44,9 @@ public class DeleteCmd extends AbstractComputeEnvCmd {
@CommandLine.Mixin
public WorkspaceOptionalOptions workspace;

@CommandLine.Option(names = {"--wait"}, description = "Wait until the compute environment is fully deleted.")
public boolean wait;

@Override
protected Response exec() throws ApiException {
Long wspId = workspaceId(workspace.workspace);
Expand All @@ -51,7 +61,7 @@ protected Response exec() throws ApiException {

try {
computeEnvsApi().deleteComputeEnv(id, wspId, null);
return new ComputeEnvDeleted(id, workspaceRef(wspId));
return new ComputeEnvDeleted(id, workspaceRef(wspId), wspId);
} catch (ApiException e) {
if (e.getCode() == 403) {
// Customize the forbidden message
Expand All @@ -60,4 +70,36 @@ protected Response exec() throws ApiException {
throw e;
}
}
}

@Override
protected Integer onBeforeExit(int exitCode, Response response) {
if (exitCode != 0 || !wait || response == null) {
return exitCode;
}

ComputeEnvDeleted computeEnv = (ComputeEnvDeleted) response;
boolean showProgress = app().output != OutputType.json;

try {
return waitStatus(
app().getOut(),
showProgress,
ComputeEnvStatus.DELETED,
ComputeEnvStatus.values(),
() -> checkComputeEnvStatus(computeEnv.id, computeEnv.workspaceId),
ComputeEnvStatus.ERRORED, ComputeEnvStatus.INVALID
);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return exitCode;
}
}
Comment thread
stefanoboriero marked this conversation as resolved.

private ComputeEnvStatus checkComputeEnvStatus(String computeEnvId, Long workspaceId) {
try {
return computeEnvsApi().describeComputeEnv(computeEnvId, workspaceId, Collections.emptyList()).getComputeEnv().getStatus();
} catch (ApiException | NullPointerException e) {
return null;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@ public class ComputeEnvDeleted extends Response {

public final String id;
public final String workspaceRef;
public final Long workspaceId;

public ComputeEnvDeleted(String id, String workspaceRef) {
public ComputeEnvDeleted(String id, String workspaceRef, Long workspaceId) {
this.id = id;
this.workspaceId = workspaceId;
this.workspaceRef = workspaceRef;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ void testDelete(OutputType format, MockServerClient mock) {
);

ExecOut out = exec(format, mock, "compute-envs", "delete", "-i", "vYOK4vn7spw7bHHWBDXZ2");
assertOutput(format, out, new ComputeEnvDeleted("vYOK4vn7spw7bHHWBDXZ2", USER_WORKSPACE_NAME));
assertOutput(format, out, new ComputeEnvDeleted("vYOK4vn7spw7bHHWBDXZ2", USER_WORKSPACE_NAME, null));
}

@Test
Expand Down Expand Up @@ -712,4 +712,53 @@ void testUpdateInvalidName(OutputType format, MockServerClient mock) {
assertEquals("", out.stdOut);
assertEquals(1, out.exitCode);
}

@Test
void testDeleteWaitHappyPath(MockServerClient mock) {
// DELETE returns 204
mock.when(
request().withMethod("DELETE").withPath("/compute-envs/vYOK4vn7spw7bHHWBDXZ2"), exactly(1)
).respond(
response().withStatusCode(204)
);

// First DESCRIBE returns DELETING
mock.when(
request().withMethod("GET").withPath("/compute-envs/vYOK4vn7spw7bHHWBDXZ2"), exactly(1)
).respond(
response().withStatusCode(200).withBody("{\"computeEnv\":{\"id\":\"vYOK4vn7spw7bHHWBDXZ2\",\"name\":\"demo\",\"platform\":\"aws-batch\",\"status\":\"DELETING\"}}").withContentType(MediaType.APPLICATION_JSON)
);

// Second DESCRIBE returns 404 (CE has been deleted)
mock.when(
request().withMethod("GET").withPath("/compute-envs/vYOK4vn7spw7bHHWBDXZ2"), exactly(1)
).respond(
response().withStatusCode(200).withBody("{\"computeEnv\":{\"id\":\"vYOK4vn7spw7bHHWBDXZ2\",\"name\":\"demo\",\"platform\":\"aws-batch\",\"status\":\"DELETED\"}}").withContentType(MediaType.APPLICATION_JSON)
);

ExecOut out = exec(mock, "compute-envs", "delete", "-i", "vYOK4vn7spw7bHHWBDXZ2", "--wait");

assertEquals(0, out.exitCode);
}

@Test
void testDeleteWaitErrored(MockServerClient mock) {
// DELETE returns 204
mock.when(
request().withMethod("DELETE").withPath("/compute-envs/vYOK4vn7spw7bHHWBDXZ2"), exactly(1)
).respond(
response().withStatusCode(204)
);

// DESCRIBE returns ERRORED
mock.when(
request().withMethod("GET").withPath("/compute-envs/vYOK4vn7spw7bHHWBDXZ2"), exactly(1)
).respond(
response().withStatusCode(200).withBody("{\"computeEnv\":{\"id\":\"vYOK4vn7spw7bHHWBDXZ2\",\"name\":\"demo\",\"platform\":\"aws-batch\",\"status\":\"ERRORED\"}}").withContentType(MediaType.APPLICATION_JSON)
);

ExecOut out = exec(mock, "compute-envs", "delete", "-i", "vYOK4vn7spw7bHHWBDXZ2", "--wait");

assertEquals(1, out.exitCode);
}
}
Loading