diff --git a/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineComputerLauncher.java b/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineComputerLauncher.java index b0b0be1cd..3bd94c50b 100644 --- a/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineComputerLauncher.java +++ b/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineComputerLauncher.java @@ -154,14 +154,16 @@ public void launch(SlaveComputer slaveComputer, TaskListener listener) { } if (opError != null) { LOGGER.info(String.format( - "Launch failed while waiting for operation %s to complete. Operation error was %s", + "Launch failed while waiting for operation %s to complete. Operation error was %s. Terminating instance.", insertOperationId, opError.getErrors().get(0).getMessage())); + terminateNode(computer, listener); return; } } catch (InterruptedException e) { LOGGER.info(String.format( - "Launch failed while waiting for operation %s to complete. Operation error was %s", + "Launch failed while waiting for operation %s to complete. Operation error was %s. Terminating instance", insertOperationId, opError.getErrors().get(0).getMessage())); + terminateNode(computer, listener); return; } @@ -214,19 +216,23 @@ public void launch(SlaveComputer slaveComputer, TaskListener listener) { launch(computer, listener); } catch (IOException ioe) { ioe.printStackTrace(listener.error(ioe.getMessage())); - node = (ComputeEngineInstance) slaveComputer.getNode(); - if (node != null) { - try { - node.terminate(); - } catch (Exception e) { - listener.error(String.format("Failed to terminate node %s", node.getDisplayName())); - } - } + terminateNode(slaveComputer, listener); } catch (InterruptedException ie) { } } + private static void terminateNode(SlaveComputer slaveComputer, TaskListener listener) { + ComputeEngineInstance node = (ComputeEngineInstance) slaveComputer.getNode(); + if (node != null) { + try { + node.terminate(); + } catch (Exception e) { + listener.error(String.format("Failed to terminate node %s", node.getDisplayName())); + } + } + } + private boolean testCommand( ComputeEngineComputer computer, Connection conn, diff --git a/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineInstance.java b/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineInstance.java index ec0f92a24..6bf1bd8e8 100644 --- a/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineInstance.java +++ b/src/main/java/com/google/jenkins/plugins/computeengine/ComputeEngineInstance.java @@ -16,8 +16,11 @@ package com.google.jenkins.plugins.computeengine; +import static com.google.jenkins.plugins.computeengine.ComputeEngineCloud.CLOUD_ID_LABEL_KEY; + import com.google.cloud.graphite.platforms.plugin.client.ComputeClient.OperationException; import com.google.common.base.Strings; +import com.google.common.collect.ImmutableMap; import com.google.jenkins.plugins.computeengine.ssh.GoogleKeyCredential; import edu.umd.cs.findbugs.annotations.Nullable; import hudson.Extension; @@ -30,6 +33,7 @@ import hudson.slaves.RetentionStrategy; import java.io.IOException; import java.util.Collections; +import java.util.Map; import java.util.Optional; import java.util.logging.Level; import java.util.logging.Logger; @@ -130,9 +134,16 @@ protected void _terminate(TaskListener listener) throws IOException, Interrupted .createSnapshotSync(cloud.getProjectId(), this.zone, this.getNodeName(), createSnapshotTimeout); } - // If the instance is running, attempt to terminate it. This is an async call and we + Map filterLabel = ImmutableMap.of(CLOUD_ID_LABEL_KEY, cloud.getInstanceId()); + var instanceExistsInCloud = + cloud.getClient().listInstancesWithLabel(cloud.getProjectId(), filterLabel).stream() + .anyMatch(instance -> instance.getName().equals(name)); + + // If the instance exists in the cloud, attempt to terminate it. This is an async call and we // return immediately, hoping for the best. - cloud.getClient().terminateInstanceAsync(cloud.getProjectId(), zone, name); + if (instanceExistsInCloud) { + cloud.getClient().terminateInstanceAsync(cloud.getProjectId(), zone, name); + } } catch (CloudNotFoundException cnfe) { listener.error(cnfe.getMessage()); } catch (OperationException oe) {