diff options
author | Jon Bratseth <bratseth@verizonmedia.com> | 2020-01-17 11:23:16 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@verizonmedia.com> | 2020-01-17 11:23:16 +0100 |
commit | c4341ca86ce65e7702d5358f41fbe0e678c9379d (patch) | |
tree | 9e7fffb5a6836d40a708a3e8ec6360c27377a092 /node-repository | |
parent | dcc114ba5cbdb622cdc8fb4226c4fcecd9e085e1 (diff) |
Refactor and hash
Diffstat (limited to 'node-repository')
4 files changed, 49 insertions, 12 deletions
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 99248848d1a..7c5ff35878b 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 @@ -30,10 +30,9 @@ public class CapacityPolicies { public int decideSize(Capacity capacity, ClusterSpec.Type clusterType, ApplicationId application) { int requestedNodes = capacity.nodeCount(); - ensureRedundancy(requestedNodes, clusterType, capacity.canFail()); + if (application.instance().isTester()) return 1; - if ( ! hasQuota(application, requestedNodes)) - throw new IllegalArgumentException(requestedNodes + " exceeds your quota. Please contact Vespa support"); + ensureRedundancy(requestedNodes, clusterType, capacity.canFail()); if (capacity.isRequired()) return requestedNodes; @@ -64,13 +63,6 @@ public class CapacityPolicies { return resources; } - private boolean hasQuota(ApplicationId application, int requestedNodes) { - if ( ! this.zone.system().isPublic()) return true; // no quota management - - if ("yj".equals(application.tenant().value())) return requestedNodes <= 60; - return requestedNodes <= 5; - } - private void ensureSufficientResources(NodeResources resources, ClusterSpec cluster) { double minMemoryGb = minMemoryGb(cluster.type()); if (resources.memoryGb() >= minMemoryGb) return; 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 a24de356244..0ee0e027ba9 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 @@ -89,7 +89,7 @@ public class NodeRepositoryProvisioner implements Provisioner { NodeSpec requestedNodes; Optional<NodeResources> resources = requestedCapacity.nodeResources(); if ( requestedCapacity.type() == NodeType.tenant) { - int nodeCount = application.instance().isTester() ? 1 : capacityPolicies.decideSize(requestedCapacity, cluster.type(), application); + int nodeCount = capacityPolicies.decideSize(requestedCapacity, cluster.type(), application); if (zone.environment().isManuallyDeployed() && nodeCount < requestedCapacity.nodeCount()) logger.log(Level.INFO, "Requested " + requestedCapacity.nodeCount() + " nodes for " + cluster + ", downscaling to " + nodeCount + " nodes in " + zone.environment()); @@ -97,6 +97,11 @@ public class NodeRepositoryProvisioner implements Provisioner { boolean exclusive = capacityPolicies.decideExclusivity(cluster.isExclusive()); effectiveGroups = Math.min(wantedGroups, nodeCount); // cannot have more groups than nodes requestedNodes = NodeSpec.from(nodeCount, resources.get(), exclusive, requestedCapacity.canFail()); + + if ( ! hasQuota(application, nodeCount)) + throw new IllegalArgumentException(requestedCapacity + " requested for " + cluster + + (requestedCapacity.nodeCount() != nodeCount ? " resolved to " + nodeCount + " nodes" : "") + + " exceeds your quota. Please contact Vespa support."); } else { requestedNodes = NodeSpec.from(requestedCapacity.type()); @@ -123,6 +128,13 @@ public class NodeRepositoryProvisioner implements Provisioner { loadBalancerProvisioner.ifPresent(lbProvisioner -> lbProvisioner.deactivate(application, transaction)); } + private boolean hasQuota(ApplicationId application, int requestedNodes) { + if ( ! this.zone.system().isPublic()) return true; // no quota management + + if (application.tenant().value().hashCode() == 3857) return requestedNodes <= 60; + return requestedNodes <= 5; + } + private List<HostSpec> asSortedHosts(List<Node> nodes, Optional<NodeResources> requestedResources) { nodes.sort(Comparator.comparingInt(node -> node.allocation().get().membership().index())); List<HostSpec> hosts = new ArrayList<>(nodes.size()); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerAllocationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerAllocationTest.java index 9bccfb74334..d1498507a7c 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerAllocationTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerAllocationTest.java @@ -403,7 +403,7 @@ public class DynamicDockerAllocationTest { ApplicationId application = tester.makeApplicationId(); ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Version.fromString("1"), false); - List<HostSpec> hosts1 = tester.prepare(application, cluster, Capacity.fromNodeCount(2, Optional.of("d-2-8-50"), false, true), 1); + List<HostSpec> hosts1 = tester.prepare(application, cluster, Capacity.fromCount(2, Optional.of(NodeResources.fromLegacyName("d-2-8-50")), false, true), 1); tester.activate(application, hosts1); NodeResources resources = new NodeResources(1.5, 8, 50, 0.3); 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 709db53d512..e6c626585d4 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 @@ -3,17 +3,20 @@ package com.yahoo.vespa.hosted.provision.provisioning; import com.yahoo.component.Version; import com.yahoo.config.provision.ApplicationId; +import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.Capacity; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.Environment; import com.yahoo.config.provision.HostFilter; import com.yahoo.config.provision.HostSpec; +import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.OutOfCapacityException; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.SystemName; +import com.yahoo.config.provision.TenantName; import com.yahoo.config.provision.Zone; import com.yahoo.transaction.NestedTransaction; import com.yahoo.vespa.hosted.provision.Node; @@ -30,6 +33,7 @@ import java.util.Iterator; import java.util.List; import java.util.Optional; import java.util.Set; +import java.util.UUID; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -437,6 +441,35 @@ public class ProvisioningTest { } @Test + public void out_of_quota() { + ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(SystemName.Public, + Environment.prod, + RegionName.from("us-east"))).build(); + + tester.makeReadyNodes(13, defaultResources); + ApplicationId application = tester.makeApplicationId(); + try { + prepare(application, 2, 2, 6, 3, defaultResources, tester); + fail("Expected exception"); + } + catch (IllegalArgumentException e) { + assertEquals("6 nodes [vcpu: 1.0, memory: 4.0 Gb, disk 10.0 Gb, bandwidth: 4.0 Gbps] requested for content cluster 'content0' 6.42 exceeds your quota. Please contact Vespa support.", + e.getMessage()); + } + } + + @Test + public void no_out_of_quota_outside_public() { + ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(SystemName.main, + Environment.prod, + RegionName.from("us-east"))).build(); + + tester.makeReadyNodes(13, defaultResources); + ApplicationId application = tester.makeApplicationId(); + prepare(application, 2, 2, 6, 3, defaultResources, tester); + } + + @Test public void out_of_capacity_but_cannot_fail() { ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build(); tester.makeReadyNodes(4, defaultResources); |