diff options
author | HÃ¥kon Hallingstad <hakon@verizonmedia.com> | 2021-03-03 15:20:48 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-03 15:20:48 +0100 |
commit | f4ce7be8026913554f81737b059ddee90e4f8ab7 (patch) | |
tree | a354ae12d3491256601b50e4ba5335bdba5fe922 | |
parent | b9a60a5a2901cdd103ba904f50c7fee4a5adb588 (diff) | |
parent | 9490d21634b322a2f2842b3cd7400af537de998d (diff) |
Merge pull request #16765 from vespa-engine/mpolden/respect-exclusive
Respect exclusive request when allocating by type
6 files changed, 25 insertions, 10 deletions
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 f6e0ede4e7d..b5943cedb9c 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 @@ -436,9 +436,9 @@ class NodeAllocation { } private static Integer parseIndex(String hostname) { - // Node index is the first number appearing in the hostname, before the first dot + // Node index is the first number appearing in the hostname try { - return Integer.parseInt(hostname.replaceFirst("^\\D+(\\d+)\\..*", "$1")); + return Integer.parseInt(hostname.replaceFirst("^\\D+(\\d+).*", "$1")); } catch (NumberFormatException e) { throw new IllegalArgumentException("Could not parse index from hostname '" + hostname + "'", e); } 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 22242e526f9..ec5444bfc98 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 @@ -19,7 +19,6 @@ import com.yahoo.config.provision.Zone; import com.yahoo.transaction.Mutex; import com.yahoo.vespa.flags.FlagSource; import com.yahoo.vespa.hosted.provision.Node; -import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.applications.Application; import com.yahoo.vespa.hosted.provision.autoscale.AllocatableClusterResources; @@ -105,7 +104,7 @@ public class NodeRepositoryProvisioner implements Provisioner { else { groups = 1; // type request with multiple groups is not supported resources = requested.minResources().nodeResources(); - nodeSpec = NodeSpec.from(requested.type()); + nodeSpec = NodeSpec.from(requested.type(), cluster.isExclusive()); } return asSortedHosts(preparer.prepare(application, cluster, nodeSpec, groups), resources); } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java index c3cb805499c..9a111deeac3 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java @@ -77,8 +77,8 @@ public interface NodeSpec { return new CountNodeSpec(nodeCount, resources, exclusive, canFail); } - static NodeSpec from(NodeType type) { - return new TypeNodeSpec(type); + static NodeSpec from(NodeType type, boolean exclusive) { + return new TypeNodeSpec(type, exclusive); } /** A node spec specifying a node count and a flavor */ @@ -174,16 +174,18 @@ public interface NodeSpec { private static final Map<NodeType, Integer> WANTED_NODE_COUNT = Map.of(NodeType.config, 3); private final NodeType type; + private final boolean exclusive; - public TypeNodeSpec(NodeType type) { + public TypeNodeSpec(NodeType type, boolean exclusive) { this.type = type; + this.exclusive = exclusive; } @Override public NodeType type() { return type; } @Override - public boolean isExclusive() { return false; } + public boolean isExclusive() { return exclusive; } @Override public boolean isCompatible(Flavor flavor, NodeFlavors flavors) { return true; } 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 25e74df677b..a7a0848e1c1 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 @@ -58,6 +58,10 @@ public class MockHostProvisioner implements HostProvisioner { Flavor hostFlavor = this.hostFlavor.orElseGet(() -> flavors.stream().filter(f -> compatible(f, resources)) .findFirst() .orElseThrow(() -> new OutOfCapacityException("No host flavor matches " + resources))); + Optional<ApplicationId> exclusiveTo = Optional.empty(); + if (sharing == HostSharing.exclusive) { + exclusiveTo = Optional.of(applicationId); + } List<ProvisionedHost> hosts = new ArrayList<>(); for (int index : provisionIndices) { String hostHostname = hostType == NodeType.host ? "hostname" + index : hostType.name() + index; @@ -65,7 +69,7 @@ public class MockHostProvisioner implements HostProvisioner { hostHostname, hostFlavor, hostType, - Optional.empty(), + exclusiveTo, createAddressesForHost(hostType, hostFlavor, index), resources, osVersion)); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java index 4a1b3df0514..dea7e50d641 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java @@ -428,13 +428,18 @@ public class DynamicProvisioningMaintainerTest { // Initial config server hosts are provisioned manually ApplicationId hostApp = ApplicationId.from("hosted-vespa", "configserver-host", "default"); + ApplicationId configSrvApp = ApplicationId.from("hosted-vespa", "zone-config-servers", "default"); List<Node> provisionedHosts = tester.makeReadyNodes(3, "default", NodeType.confighost).stream() .sorted(Comparator.comparing(Node::hostname)) .collect(Collectors.toList()); tester.prepareAndActivateInfraApplication(hostApp, NodeType.confighost); + tester.patchNodes(provisionedHosts, (node) -> node.withExclusiveTo(configSrvApp)); + assertTrue("All hosts are exclusive", tester.nodeRepository().nodes().list() + .nodeType(NodeType.confighost) + .stream() + .allMatch(node -> node.allocation().get().membership().cluster().isExclusive())); // Provision config servers - ApplicationId configSrvApp = ApplicationId.from("hosted-vespa", "zone-config-servers", "default"); for (int i = 0; i < provisionedHosts.size(); i++) { tester.makeReadyChildren(1, i + 1, NodeResources.unspecified(), NodeType.config, provisionedHosts.get(i).hostname(), (nodeIndex) -> "cfg" + nodeIndex); @@ -498,6 +503,10 @@ public class DynamicProvisioningMaintainerTest { newNode = tester.nodeRepository().nodes().node(newNode.hostname()).get(); assertSame(Node.State.active, newNode.state()); assertEquals("Removed index is reused", removedIndex, newNode.allocation().get().membership().index()); + assertTrue("All nodes are exclusive", tester.nodeRepository().nodes().list() + .nodeType(NodeType.config) + .stream() + .allMatch(node -> node.allocation().get().membership().cluster().isExclusive())); // Next redeployment does nothing NodeList nodesBefore = tester.nodeRepository().nodes().list().nodeType(NodeType.config); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java index eefbd03ce4e..df348fc1c48 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java @@ -230,6 +230,7 @@ public class ProvisioningTester { ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from(nodeType.toString())) .vespaVersion(version) .stateful(nodeType == NodeType.config || nodeType == NodeType.controller) + .exclusive(nodeType != NodeType.tenant) .build(); Capacity capacity = Capacity.fromRequiredNodeType(nodeType); List<HostSpec> hostSpecs = prepare(application, cluster, capacity); |