aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2020-05-11 23:08:04 +0200
committerGitHub <noreply@github.com>2020-05-11 23:08:04 +0200
commitdfbe98d77704e4c598c28b90e739634dd33d2127 (patch)
tree7edbcc739029801250b81b2b19e95a9d73cf94ff
parent4b7df75c499b44b9dd1693dd959105cf78589ea0 (diff)
parente030cc94a1151029355b3241c415d23dd1c608c4 (diff)
Merge pull request #13218 from vespa-engine/bratseth/exclusivity-on-app-level
Exclusivity on app level
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java26
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java2
3 files changed, 19 insertions, 14 deletions
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java
index 3a230c89732..f7030535573 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java
@@ -66,8 +66,7 @@ public final class ClusterSpec {
/**
* Returns whether the physical hosts running the nodes of this application can
- * also run nodes of other applications. Using exclusive nodes for containers increases security
- * and increases cost.
+ * also run nodes of other applications. Using exclusive nodes for containers increases security and cost.
*/
public boolean isExclusive() { return exclusive; }
@@ -84,7 +83,7 @@ public final class ClusterSpec {
return new Builder(type, id, false);
}
- /** Creates a ClusterSpec for an existing cluster, group id and vespa version needs to be set */
+ /** Creates a ClusterSpec for an existing cluster, group id and Vespa version needs to be set */
public static Builder specification(Type type, Id id) {
return new Builder(type, id, true);
}
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 a67a5b8e3fb..71e8259665b 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
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
@@ -116,7 +117,7 @@ class NodeAllocation {
if (violatesParentHostPolicy(this.nodes, offered)) wantToRetireNode = true;
if ( ! hasCompatibleFlavor(node)) wantToRetireNode = true;
if (offered.status().wantToRetire()) wantToRetireNode = true;
- if (requestedNodes.isExclusive() && ! hostsOnly(application.tenant(), offered.parentHostname()))
+ if (requestedNodes.isExclusive() && ! hostsOnly(application.tenant(), application.application(), offered.parentHostname()))
wantToRetireNode = true;
if ((! saturated() && hasCompatibleFlavor(node)) || acceptToRetire(node))
accepted.add(acceptNode(node, wantToRetireNode, node.isResizable));
@@ -130,11 +131,11 @@ class NodeAllocation {
++rejectedWithClashingParentHost;
continue;
}
- if ( ! exclusiveTo(application.tenant(), offered.parentHostname())) {
+ if ( ! exclusiveTo(application.tenant(), application.application(), offered.parentHostname())) {
++rejectedDueToExclusivity;
continue;
}
- if ( requestedNodes.isExclusive() && ! hostsOnly(application.tenant(), offered.parentHostname())) {
+ if ( requestedNodes.isExclusive() && ! hostsOnly(application.tenant(), application.application(), offered.parentHostname())) {
++rejectedDueToExclusivity;
continue;
}
@@ -172,32 +173,37 @@ class NodeAllocation {
}
/**
- * If a parent host is given, and it hosts another tenant with an application which requires exclusive access
+ * If a parent host is given, and it hosts another application which requires exclusive access
* to the physical host, then we cannot host this application on it.
*/
- private boolean exclusiveTo(TenantName tenant, Optional<String> parentHostname) {
+ private boolean exclusiveTo(TenantName tenant, ApplicationName application, Optional<String> parentHostname) {
if (parentHostname.isEmpty()) return true;
for (Node nodeOnHost : allNodes.childrenOf(parentHostname.get())) {
if (nodeOnHost.allocation().isEmpty()) continue;
-
if ( nodeOnHost.allocation().get().membership().cluster().isExclusive() &&
- ! nodeOnHost.allocation().get().owner().tenant().equals(tenant))
+ ! allocatedTo(tenant, application, nodeOnHost))
return false;
}
return true;
}
- private boolean hostsOnly(TenantName tenant, Optional<String> parentHostname) {
+ /** Returns true if this host only hosts the given applicaton (in any instance) */
+ private boolean hostsOnly(TenantName tenant, ApplicationName application, Optional<String> parentHostname) {
if (parentHostname.isEmpty()) return true; // yes, as host is exclusive
for (Node nodeOnHost : allNodes.childrenOf(parentHostname.get())) {
if (nodeOnHost.allocation().isEmpty()) continue;
- if ( ! nodeOnHost.allocation().get().owner().tenant().equals(tenant))
- return false;
+ if ( ! allocatedTo(tenant, application, nodeOnHost)) return false;
}
return true;
}
+ private boolean allocatedTo(TenantName tenant, ApplicationName application, Node node) {
+ if (node.allocation().isEmpty()) return false;
+ ApplicationId owner = node.allocation().get().owner();
+ return owner.tenant().equals(tenant) && owner.application().equals(application);
+ }
+
/**
* Returns whether this node should be accepted into the cluster even if it is not currently desired
* (already enough nodes, or wrong flavor).
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
index d6d6d76e182..df35cabab36 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java
@@ -101,9 +101,9 @@ public class NodeRepositoryProvisioner implements Provisioner {
if ( requested.type() == NodeType.tenant) {
ClusterResources target = decideTargetResources(application, cluster, requested);
int nodeCount = capacityPolicies.decideSize(target.nodes(), requested, cluster, application);
+ groups = Math.min(target.groups(), nodeCount); // cannot have more groups than nodes
resources = capacityPolicies.decideNodeResources(target.nodeResources(), requested, cluster);
boolean exclusive = capacityPolicies.decideExclusivity(cluster.isExclusive());
- groups = Math.min(target.groups(), nodeCount); // cannot have more groups than nodes
nodeSpec = NodeSpec.from(nodeCount, resources, exclusive, requested.canFail());
logIfDownscaled(target.nodes(), nodeCount, cluster, logger);
}