aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2021-05-25 10:34:07 +0200
committerMartin Polden <mpolden@mpolden.no>2021-05-25 14:50:45 +0200
commit2d71988eb1241422d3b9830926cc6a03d9239bd5 (patch)
tree5522403d5735281ebdca3ceef8ae351d73fadb73 /node-repository
parent78ad2acf63c772c4926ac38977adba388b58b468 (diff)
Allow removing allocated nodes from parked and failed
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java17
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiTest.java2
2 files changed, 12 insertions, 7 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java
index cd96bdf1241..2ef68566a87 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java
@@ -520,17 +520,22 @@ public class Nodes {
/**
* Throws if the given node cannot be removed. Removal is allowed if:
- * - Tenant node: node is unallocated
+ * - Tenant node:
+ * - non-recursively: node is unallocated
+ * - recursively: node is unallocated or node is in failed|parked
* - Host node: iff in state provisioned|failed|parked
* - Child node:
- * If only removing the container node: node in state ready
- * If also removing the parent node: child is in state provisioned|failed|parked|dirty|ready
+ * - non-recursively: node in state ready
+ * - recursively: child is in state provisioned|failed|parked|dirty|ready
*/
private void requireRemovable(Node node, boolean removingRecursively, boolean force) {
if (force) return;
- if (node.type() == NodeType.tenant && node.allocation().isPresent())
- illegal(node + " is currently allocated and cannot be removed");
+ if (node.type() == NodeType.tenant && node.allocation().isPresent()) {
+ EnumSet<Node.State> removableStates = EnumSet.of(Node.State.failed, Node.State.parked);
+ if (!removingRecursively || !removableStates.contains(node.state()))
+ illegal(node + " is currently allocated and cannot be removed while in " + node.state());
+ }
final Set<Node.State> removableStates;
if (node.type().isHost()) {
@@ -542,7 +547,7 @@ public class Nodes {
: EnumSet.of(Node.State.ready);
}
if (!removableStates.contains(node.state()))
- illegal(node + " can not be removed as it is not in the states " + removableStates);
+ illegal(node + " can not be removed while in " + node.state());
}
/**
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiTest.java
index d152cbaf5db..a28c11d009f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/NodesV2ApiTest.java
@@ -500,7 +500,7 @@ public class NodesV2ApiTest {
// Attempt to DELETE allocated node
tester.assertResponse(new Request("http://localhost:8080/nodes/v2/node/host4.yahoo.com",
new byte[0], Request.Method.DELETE),
- 400, "{\"error-code\":\"BAD_REQUEST\",\"message\":\"active child node host4.yahoo.com allocated to tenant3.application3.instance3 as 'content/id3/0/0/stateful' is currently allocated and cannot be removed\"}");
+ 400, "{\"error-code\":\"BAD_REQUEST\",\"message\":\"active child node host4.yahoo.com allocated to tenant3.application3.instance3 as 'content/id3/0/0/stateful' is currently allocated and cannot be removed while in active\"}");
// PUT current restart generation with string instead of long
tester.assertResponse(new Request("http://localhost:8080/nodes/v2/node/host4.yahoo.com",