summaryrefslogtreecommitdiffstats
path: root/node-repository/src
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@verizonmedia.com>2020-10-29 16:21:31 +0100
committerValerij Fredriksen <valerijf@verizonmedia.com>2020-10-29 16:22:50 +0100
commit61eb803ca7cbd26652c0b956e715bad6299fb917 (patch)
tree18718ba56ab212f89abc7420389a551d07ebf79b /node-repository/src
parente32b268ab273699a912c095af280e6c1f45e40af (diff)
Allocate existing reserved application nodes for infra apps
Diffstat (limited to 'node-repository/src')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java8
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java37
2 files changed, 41 insertions, 4 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java
index 7ddb5fec3ed..4f5b2fd086e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java
@@ -132,7 +132,7 @@ public class NodePrioritizer {
if ( !canAllocateNew) return;
for (Node host : allNodes) {
- if (host.type() == NodeType.host && !nodeRepository.canAllocateTenantNodeTo(host)) continue;
+ if ( ! nodeRepository.canAllocateTenantNodeTo(host)) continue;
if (host.reservedTo().isPresent() && !host.reservedTo().get().equals(application.tenant())) continue;
if (host.exclusiveTo().isPresent()) continue; // Never allocate new nodes to exclusive hosts
if ( spareHosts.contains(host) && !canAllocateToSpareHosts) continue;
@@ -156,7 +156,7 @@ public class NodePrioritizer {
.filter(node -> node.allocation().isPresent())
.filter(node -> node.allocation().get().owner().equals(application))
.filter(node -> node.allocation().get().membership().cluster().id().equals(clusterSpec.id()))
- .filter(node -> node.state() == Node.State.active || canStillAllocateToParentOf(node))
+ .filter(node -> node.state() == Node.State.active || canStillAllocate(node))
.map(node -> candidateFrom(node, false))
.forEach(nodes::add);
}
@@ -204,8 +204,8 @@ public class NodePrioritizer {
*
* @return true if we still want to allocate the given node to its parent
*/
- private boolean canStillAllocateToParentOf(Node node) {
- if (node.parentHostname().isEmpty()) return true;
+ private boolean canStillAllocate(Node node) {
+ if (node.type() != NodeType.tenant || node.parentHostname().isEmpty()) return true;
Optional<Node> parent = allNodes.parentOf(node);
if (parent.isEmpty()) return false;
return nodeRepository.canAllocateTenantNodeTo(parent.get());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
index f22ddfb81c9..9c1ced856cc 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java
@@ -15,6 +15,7 @@ import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.OutOfCapacityException;
+import com.yahoo.config.provision.ParentHostUnavailableException;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
@@ -24,9 +25,14 @@ import com.yahoo.vespa.hosted.provision.maintenance.ReservationExpirer;
import com.yahoo.vespa.hosted.provision.maintenance.TestMetric;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.History;
+import com.yahoo.vespa.hosted.provision.node.IP;
+import com.yahoo.vespa.service.duper.ConfigServerApplication;
+import com.yahoo.vespa.service.duper.ConfigServerHostApplication;
+import com.yahoo.vespa.service.duper.InfraApplication;
import org.junit.Test;
import java.time.Duration;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
@@ -879,6 +885,37 @@ public class ProvisioningTest {
}
@Test
+ public void allocates_reserved_nodes_for_type_spec_deployment() {
+ ProvisioningTester tester = new ProvisioningTester.Builder().build();
+ Function<InfraApplication, Collection<HostSpec>> prepareAndActivate = app -> tester.activate(app.getApplicationId(),
+ tester.prepare(app.getApplicationId(), app.getClusterSpecWithVersion(Version.fromString("1.2.3")), app.getCapacity()));
+
+ // Add 2 config server hosts and 2 config servers
+ Flavor flavor = tester.nodeRepository().flavors().getFlavorOrThrow("default");
+ List<Node> nodes = List.of(
+ Node.create("cfghost1", new IP.Config(Set.of("::1:0"), Set.of("::1:1")), "cfghost1", flavor, NodeType.confighost).build(),
+ Node.create("cfghost2", new IP.Config(Set.of("::2:0"), Set.of("::2:1")), "cfghost2", flavor, NodeType.confighost).ipConfig(Set.of("::2:0"), Set.of("::2:1")).build(),
+ Node.create("cfg1", new IP.Config(Set.of("::1:1"), Set.of()), "cfg1", flavor, NodeType.config).parentHostname("cfghost1").build(),
+ Node.create("cfg2", new IP.Config(Set.of("::2:1"), Set.of()), "cfg2", flavor, NodeType.config).parentHostname("cfghost2").build());
+ tester.nodeRepository().setReady(tester.nodeRepository().addNodes(nodes, Agent.system), Agent.system, ProvisioningTest.class.getSimpleName());
+
+ InfraApplication cfgHostApp = new ConfigServerHostApplication();
+ InfraApplication cfgApp = new ConfigServerApplication();
+
+ // Attempt to prepare & activate cfg, this should fail as cfg hosts are not active
+ try {
+ prepareAndActivate.apply(cfgApp);
+ } catch (ParentHostUnavailableException ignored) { }
+ assertEquals(2, tester.nodeRepository().list(cfgApp.getApplicationId()).state(Node.State.reserved).size());
+
+ prepareAndActivate.apply(cfgHostApp);
+
+ // After activating cfg hosts, we can activate cfgs and all 4 should become active
+ prepareAndActivate.apply(cfgApp);
+ assertEquals(4, tester.nodeRepository().list().state(Node.State.active).size());
+ }
+
+ @Test
public void cluster_spec_update_for_already_reserved_nodes() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
ApplicationId application = ProvisioningTester.makeApplicationId();