aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@yahooinc.com>2023-10-24 16:08:19 +0200
committerHåkon Hallingstad <hakon@yahooinc.com>2023-10-24 16:08:19 +0200
commitdf2aed8b80016984617bc4effe530d842b78a523 (patch)
treee8035aeda4ddab9fbab759a8c366e06e6fd9d3fc
parente9ffd971c241e91dd7718628210e0d6c24fbeb04 (diff)
Node must fit host (only) if allocation is exclusive
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java15
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java19
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java5
4 files changed, 30 insertions, 15 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java
index a5135ca0e1f..7155a49ef58 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/HostCapacityMaintainer.java
@@ -278,20 +278,21 @@ public class HostCapacityMaintainer extends NodeRepositoryMaintainer {
// We'll allocate each ClusterCapacity as a unique cluster in a dummy application
ApplicationId applicationId = ApplicationId.defaultId();
- ClusterSpec clusterSpec = asSpec(Optional.ofNullable(clusterCapacity.clusterType()), clusterIndex);
+ ClusterSpec cluster = asSpec(Optional.ofNullable(clusterCapacity.clusterType()), clusterIndex);
NodeSpec nodeSpec = NodeSpec.from(clusterCapacity.count(), 1, nodeResources, false, true,
nodeRepository().zone().cloud().account(), Duration.ZERO);
var allocationContext = IP.Allocation.Context.from(nodeRepository().zone().cloud().name(),
nodeSpec.cloudAccount().isExclave(nodeRepository().zone()),
nodeRepository().nameResolver());
- NodePrioritizer prioritizer = new NodePrioritizer(allNodes, applicationId, clusterSpec, nodeSpec,
- true, allocationContext, nodeRepository().nodes(), nodeRepository().resourcesCalculator(),
- nodeRepository().spareCount());
+ NodePrioritizer prioritizer = new NodePrioritizer(allNodes, applicationId, cluster, nodeSpec,
+ true, false, allocationContext, nodeRepository().nodes(),
+ nodeRepository().resourcesCalculator(), nodeRepository().spareCount(),
+ nodeRepository().exclusiveAllocation(cluster), makeExclusive);
List<NodeCandidate> nodeCandidates = prioritizer.collect()
.stream()
- .filter(node -> node.violatesExclusivity(clusterSpec,
+ .filter(node -> node.violatesExclusivity(cluster,
applicationId,
- nodeRepository().exclusiveAllocation(clusterSpec),
+ nodeRepository().exclusiveAllocation(cluster),
false,
nodeRepository().zone().cloud().allowHostSharing(),
allNodes,
@@ -304,7 +305,7 @@ public class HostCapacityMaintainer extends NodeRepositoryMaintainer {
.limit(clusterCapacity.count())
.map(candidate -> candidate.toNode()
.allocate(applicationId,
- ClusterMembership.from(clusterSpec, index.next()),
+ ClusterMembership.from(cluster, index.next()),
nodeResources,
nodeRepository().clock().instant()))
.toList();
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
index 0cb1eaa574c..e1be5b48e2d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java
@@ -141,7 +141,7 @@ class NodeAllocation {
++rejectedDueToClashingParentHost;
continue;
}
- switch (violatesExclusivity(candidate, makeExclusive)) {
+ switch (violatesExclusivity(candidate)) {
case PARENT_HOST_NOT_EXCLUSIVE -> candidate = candidate.withExclusiveParent(true);
case NONE -> {}
case YES -> {
@@ -175,7 +175,7 @@ class NodeAllocation {
if (candidate.parent.map(node -> node.status().wantToUpgradeFlavor()).orElse(false)) return Retirement.violatesHostFlavorGeneration;
if (candidate.wantToRetire()) return Retirement.hardRequest;
if (candidate.preferToRetire() && candidate.replaceableBy(candidates)) return Retirement.softRequest;
- if (violatesExclusivity(candidate, makeExclusive) != NodeCandidate.ExclusivityViolation.NONE) return Retirement.violatesExclusivity;
+ if (violatesExclusivity(candidate) != NodeCandidate.ExclusivityViolation.NONE) return Retirement.violatesExclusivity;
if (requiredHostFlavor.isPresent() && ! candidate.parent.map(node -> node.flavor().name()).equals(requiredHostFlavor)) return Retirement.violatesHostFlavor;
if (candidate.violatesSpares) return Retirement.violatesSpares;
return Retirement.none;
@@ -196,7 +196,7 @@ class NodeAllocation {
return nodes.values().stream().anyMatch(acceptedNode -> acceptedNode.parentHostname().equals(candidate.parentHostname()));
}
- private NodeCandidate.ExclusivityViolation violatesExclusivity(NodeCandidate candidate, boolean makeExclusive) {
+ private NodeCandidate.ExclusivityViolation violatesExclusivity(NodeCandidate candidate) {
return candidate.violatesExclusivity(cluster, application,
nodeRepository.exclusiveAllocation(cluster),
nodeRepository.exclusiveProvisioning(cluster),
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 d0b13bb7f6c..b92d6fb6d18 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
@@ -9,7 +9,6 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
import com.yahoo.vespa.hosted.provision.node.IP;
import com.yahoo.vespa.hosted.provision.node.Nodes;
-import com.yahoo.vespa.hosted.provision.persistence.NameResolver;
import java.util.ArrayList;
import java.util.Collections;
@@ -40,14 +39,17 @@ public class NodePrioritizer {
private final IP.Allocation.Context ipAllocationContext;
private final Nodes nodes;
private final boolean dynamicProvisioning;
+ private final boolean allowHostSharing;
+ private final boolean exclusiveAllocation;
+ private final boolean makeExclusive;
private final boolean canAllocateToSpareHosts;
private final boolean topologyChange;
private final int currentClusterSize;
private final Set<Node> spareHosts;
public NodePrioritizer(LockedNodeList allNodes, ApplicationId application, ClusterSpec clusterSpec, NodeSpec nodeSpec,
- boolean dynamicProvisioning, IP.Allocation.Context ipAllocationContext, Nodes nodes,
- HostResourcesCalculator hostResourcesCalculator, int spareCount) {
+ boolean dynamicProvisioning, boolean allowHostSharing, IP.Allocation.Context ipAllocationContext, Nodes nodes,
+ HostResourcesCalculator hostResourcesCalculator, int spareCount, boolean exclusiveAllocation, boolean makeExclusive) {
this.allNodes = allNodes;
this.calculator = hostResourcesCalculator;
this.capacity = new HostCapacity(this.allNodes, hostResourcesCalculator);
@@ -55,6 +57,9 @@ public class NodePrioritizer {
this.clusterSpec = clusterSpec;
this.application = application;
this.dynamicProvisioning = dynamicProvisioning;
+ this.allowHostSharing = allowHostSharing;
+ this.exclusiveAllocation = exclusiveAllocation;
+ this.makeExclusive = makeExclusive;
this.spareHosts = dynamicProvisioning ?
capacity.findSpareHostsInDynamicallyProvisionedZones(this.allNodes.asList()) :
capacity.findSpareHosts(this.allNodes.asList(), spareCount);
@@ -122,7 +127,13 @@ public class NodePrioritizer {
if (nodes.suspended(host)) continue; // Hosts that are suspended may be down for some time, e.g. for OS upgrade
if (host.reservedTo().isPresent() && !host.reservedTo().get().equals(application.tenant())) continue;
if (host.reservedTo().isPresent() && application.instance().isTester()) continue;
- if (host.exclusiveToApplicationId().isPresent() && ! fitsPerfectly(host)) continue;
+ if (makeExclusive) {
+ if ( ! allowHostSharing && exclusiveAllocation && ! fitsPerfectly(host)) continue;
+ } else {
+ if (host.exclusiveToApplicationId().isPresent() && ! fitsPerfectly(host)) continue;
+ }
+ if ( ! host.provisionedForApplicationId().map(application::equals).orElse(true)) continue;
+ if ( ! host.exclusiveToApplicationId().map(application::equals).orElse(true)) continue;
if ( ! host.exclusiveToClusterType().map(clusterSpec.type()::equals).orElse(true)) continue;
if (spareHosts.contains(host) && !canAllocateToSpareHosts) continue;
if ( ! capacity.hasCapacity(host, requested.resources().get())) continue;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java
index 9cbd3765cf8..9f5775ee8c3 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java
@@ -189,10 +189,13 @@ public class Preparer {
cluster,
requested,
nodeRepository.zone().cloud().dynamicProvisioning(),
+ nodeRepository.zone().cloud().allowHostSharing(),
allocationContext,
nodeRepository.nodes(),
nodeRepository.resourcesCalculator(),
- nodeRepository.spareCount());
+ nodeRepository.spareCount(),
+ nodeRepository.exclusiveAllocation(cluster),
+ makeExclusive);
allocation.offer(prioritizer.collect());
return allocation;
}