summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@yahooinc.com>2023-10-16 14:19:40 +0200
committerHåkon Hallingstad <hakon@yahooinc.com>2023-10-16 14:19:40 +0200
commit3d4ed6313d47b92b39d1d215a04c059eff06ffd2 (patch)
treec6888a992a7ea1c1b533397a831ac692315763fa
parent0ccfe8aab8c12ecd518f882a048f8a13fb2084f1 (diff)
Set provisioned-for if enabled and application has exclusive="true"
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ClusterSpec.java30
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java11
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java6
6 files changed, 43 insertions, 18 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 ed0f9aac884..04aced68d1b 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
@@ -2,8 +2,6 @@
package com.yahoo.config.provision;
import com.yahoo.component.Version;
-import com.yahoo.config.provision.ZoneEndpoint.AccessType;
-import com.yahoo.config.provision.ZoneEndpoint.AllowedUrn;
import java.util.Objects;
import java.util.Optional;
@@ -24,19 +22,21 @@ public final class ClusterSpec {
private final Version vespaVersion;
private final boolean exclusive;
+ private final boolean provisionForApplication;
private final Optional<Id> combinedId;
private final Optional<DockerImage> dockerImageRepo;
private final ZoneEndpoint zoneEndpoint;
private final boolean stateful;
private ClusterSpec(Type type, Id id, Optional<Group> groupId, Version vespaVersion, boolean exclusive,
- Optional<Id> combinedId, Optional<DockerImage> dockerImageRepo,
+ boolean provisionForApplication, Optional<Id> combinedId, Optional<DockerImage> dockerImageRepo,
ZoneEndpoint zoneEndpoint, boolean stateful) {
this.type = type;
this.id = id;
this.groupId = groupId;
this.vespaVersion = Objects.requireNonNull(vespaVersion, "vespaVersion cannot be null");
this.exclusive = exclusive;
+ this.provisionForApplication = provisionForApplication;
if (type == Type.combined) {
if (combinedId.isEmpty()) throw new IllegalArgumentException("combinedId must be set for cluster of type " + type);
} else {
@@ -85,21 +85,22 @@ public final class ClusterSpec {
*/
public boolean isExclusive() { return exclusive; }
+ /** Returns whether the physical hosts must be provisioned specifically for this application. */
+ public boolean provisionForApplication() { return provisionForApplication; }
+
/** Returns whether this cluster has state */
public boolean isStateful() { return stateful; }
public ClusterSpec with(Optional<Group> newGroup) {
- return new ClusterSpec(type, id, newGroup, vespaVersion, exclusive, combinedId, dockerImageRepo, zoneEndpoint, stateful);
+ return new ClusterSpec(type, id, newGroup, vespaVersion, exclusive, provisionForApplication, combinedId, dockerImageRepo, zoneEndpoint, stateful);
}
public ClusterSpec withExclusivity(boolean exclusive) {
- return new ClusterSpec(type, id, groupId, vespaVersion, exclusive, combinedId, dockerImageRepo, zoneEndpoint, stateful);
+ return new ClusterSpec(type, id, groupId, vespaVersion, exclusive, provisionForApplication, combinedId, dockerImageRepo, zoneEndpoint, stateful);
}
- // TODO: Remove after July 2023
- @Deprecated
- public ClusterSpec exclusive(boolean exclusive) {
- return new ClusterSpec(type, id, groupId, vespaVersion, exclusive, combinedId, dockerImageRepo, zoneEndpoint, stateful);
+ public ClusterSpec withProvisionForApplication(boolean provisionForApplication) {
+ return new ClusterSpec(type, id, groupId, vespaVersion, exclusive, provisionForApplication, combinedId, dockerImageRepo, zoneEndpoint, stateful);
}
/** Creates a ClusterSpec when requesting a cluster */
@@ -121,6 +122,7 @@ public final class ClusterSpec {
private Optional<DockerImage> dockerImageRepo = Optional.empty();
private Version vespaVersion;
private boolean exclusive = false;
+ private boolean provisionForApplication = false;
private Optional<Id> combinedId = Optional.empty();
private ZoneEndpoint zoneEndpoint = ZoneEndpoint.defaultEndpoint;
private boolean stateful;
@@ -132,7 +134,7 @@ public final class ClusterSpec {
}
public ClusterSpec build() {
- return new ClusterSpec(type, id, groupId, vespaVersion, exclusive, combinedId, dockerImageRepo, zoneEndpoint, stateful);
+ return new ClusterSpec(type, id, groupId, vespaVersion, exclusive, provisionForApplication, combinedId, dockerImageRepo, zoneEndpoint, stateful);
}
public Builder group(Group groupId) {
@@ -155,6 +157,11 @@ public final class ClusterSpec {
return this;
}
+ public Builder provisionForApplication(boolean provisionForApplication) {
+ this.provisionForApplication = provisionForApplication;
+ return this;
+ }
+
public Builder combinedId(Optional<Id> combinedId) {
this.combinedId = combinedId;
return this;
@@ -188,6 +195,7 @@ public final class ClusterSpec {
if (o == null || getClass() != o.getClass()) return false;
ClusterSpec that = (ClusterSpec) o;
return exclusive == that.exclusive &&
+ provisionForApplication == that.provisionForApplication &&
stateful == that.stateful &&
type == that.type &&
id.equals(that.id) &&
@@ -200,7 +208,7 @@ public final class ClusterSpec {
@Override
public int hashCode() {
- return Objects.hash(type, id, groupId, vespaVersion, exclusive, combinedId, dockerImageRepo, zoneEndpoint, stateful);
+ return Objects.hash(type, id, groupId, vespaVersion, exclusive, provisionForApplication, combinedId, dockerImageRepo, zoneEndpoint, stateful);
}
/**
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index 56cd06d3b35..a09c6ea00c6 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -340,6 +340,14 @@ public class Flags {
"Takes effect at redeployment",
INSTANCE_ID);
+ public static final UnboundBooleanFlag EXCLUSIVE_PROVISIONING = defineFeatureFlag(
+ "exclusive-provisioning", false,
+ List.of("hakonhall"), "2023-10-12", "2023-12-12",
+ "Whether to provision a host exclusively to an application ID only based on exclusive=\"true\" from services.xml. " +
+ "Enabling this will produce hosts with exclusiveTo[ApplicationId] without provisionedToApplicationId.",
+ "Takes immediate effect newly provisioned hosts new hosts",
+ HOSTNAME, CLOUD_ACCOUNT);
+
public static final UnboundBooleanFlag WRITE_CONFIG_SERVER_SESSION_DATA_AS_ONE_BLOB = defineFeatureFlag(
"write-config-server-session-data-as-blob", false,
List.of("hmusum"), "2023-07-19", "2023-11-01",
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
index f9ac7367778..b4fa3d549f8 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java
@@ -174,7 +174,7 @@ public class CapacityPolicies {
public ClusterSpec decideExclusivity(Capacity capacity, ClusterSpec requestedCluster) {
if (capacity.cloudAccount().isPresent()) return requestedCluster.withExclusivity(true); // Implicit exclusive
boolean exclusive = requestedCluster.isExclusive() && (capacity.isRequired() || zone.environment() == Environment.prod);
- return requestedCluster.withExclusivity(exclusive);
+ return requestedCluster.withExclusivity(exclusive).withProvisionForApplication(exclusive);
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
index 09d6f96d88e..a876999e80b 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java
@@ -22,14 +22,21 @@ public interface HostProvisioner {
enum HostSharing {
- /** The host must be provisioned exclusively for the applicationId */
+ /** The host must be provisioned exclusively for the application ID. */
+ provision,
+
+ /** The host must be exclusive to a single application ID */
exclusive,
/** The host must be provisioned to be shared with other applications. */
shared,
/** The client has no requirements on whether the host must be provisioned exclusively or shared. */
- any
+ any;
+
+ public boolean isExclusiveAllocation() {
+ return this == provision || this == exclusive;
+ }
}
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 0ffd42aedba..bd84ec9b05a 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
@@ -208,7 +208,9 @@ public class Preparer {
private HostSharing hostSharing(ClusterSpec cluster, NodeType hostType) {
if ( hostType.isSharable())
- return nodeRepository.exclusiveAllocation(cluster) ? HostSharing.exclusive : HostSharing.any;
+ return cluster.provisionForApplication() ? HostSharing.provision :
+ nodeRepository.exclusiveAllocation(cluster) ? HostSharing.exclusive :
+ HostSharing.any;
else
return HostSharing.any;
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
index def3e003ab3..57a5308288d 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockHostProvisioner.java
@@ -78,8 +78,8 @@ public class MockHostProvisioner implements HostProvisioner {
Flavor hostFlavor = hostFlavors.get(request.clusterType().orElse(ClusterSpec.Type.content));
if (hostFlavor == null)
hostFlavor = flavors.stream()
- .filter(f -> request.sharing() == HostSharing.exclusive ? compatible(f, request.resources())
- : satisfies(f, request.resources()))
+ .filter(f -> request.sharing().isExclusiveAllocation() ? compatible(f, request.resources())
+ : satisfies(f, request.resources()))
.filter(f -> realHostResourcesWithinLimits.test(f.resources()))
.findFirst()
.orElseThrow(() -> new NodeAllocationException("No host flavor matches " + request.resources(), true));
@@ -91,7 +91,7 @@ public class MockHostProvisioner implements HostProvisioner {
hostHostname,
hostFlavor,
request.type(),
- request.sharing() == HostSharing.exclusive ? Optional.of(request.owner()) : Optional.empty(),
+ request.sharing().isExclusiveAllocation() ? Optional.of(request.owner()) : Optional.empty(),
Optional.empty(),
createHostnames(request.type(), hostFlavor, index),
request.resources(),