summaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorValerij Fredriksen <valerijf@verizonmedia.com>2019-05-07 09:06:21 +0200
committerValerij Fredriksen <valerijf@verizonmedia.com>2019-05-07 09:06:21 +0200
commit316f1e4a66d6e29e91f24a8e6a79a810f4aad430 (patch)
treec3775892085a3749e95f541bb3dc26743ab7af75 /node-repository
parentf6cf93af903ad78f505714a307ab11068616d3ab (diff)
parent231477602105f19e232fdb7fce3f7d0912028b64 (diff)
Merge branch 'master' into freva/move-job-controller-to-node-repo
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java7
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirer.java30
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java34
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java34
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacity.java30
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/FlavorConfigBuilder.java13
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/HostProvisioner.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java21
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java41
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java67
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/PrioritizableNode.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java27
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacity.java71
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityComparator.java36
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java67
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java35
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java5
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java10
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java7
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java30
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AllocationSimulator.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java12
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java15
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerAllocationTest.java38
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java19
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java5
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizerTest.java15
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java212
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java30
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityTest.java27
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java24
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/NodeIdentifierTest.java12
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-container1.json11
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node11.json11
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json11
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5-after-changes.json11
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5.json11
43 files changed, 614 insertions, 468 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
index bfccfdf4224..196aea3e4a5 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java
@@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableSet;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.hosted.provision.node.Agent;
import com.yahoo.vespa.hosted.provision.node.Allocation;
@@ -48,9 +49,9 @@ public final class Node {
private final Optional<Allocation> allocation;
/** Temporary method until we can merge it with the other create method */
- public static Node createDockerNode(Set<String> ipAddresses, Set<String> ipAddressPool, String hostname, Optional<String> parentHostname, Flavor flavor, NodeType type) {
- return new Node("fake-" + hostname, ipAddresses, ipAddressPool, hostname, parentHostname, flavor, Status.initial(), State.reserved,
- Optional.empty(), History.empty(), type, new Reports(), Optional.empty());
+ public static Node createDockerNode(Set<String> ipAddresses, Set<String> ipAddressPool, String hostname, Optional<String> parentHostname, NodeResources resources, NodeType type) {
+ return new Node("fake-" + hostname, ipAddresses, ipAddressPool, hostname, parentHostname, new Flavor(resources), Status.initial(), State.reserved,
+ Optional.empty(), History.empty(), type, new Reports(), Optional.empty());
}
/** Creates a node in the initial state (provisioned) */
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java
index bfb7bfe9dae..7058917d351 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.provision;
import com.google.common.collect.ImmutableList;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import java.util.Collection;
@@ -44,6 +45,9 @@ public class NodeList implements Iterable<Node> {
return filter(node -> ! node.allocation().get().membership().retired());
}
+ /** Returns the subset of nodes having exactly the given resources */
+ public NodeList resources(NodeResources resources) { return filter(node -> node.flavor().resources().equals(resources)); }
+
/** Returns the subset of nodes of the given flavor */
public NodeList flavor(String flavor) {
return filter(node -> node.flavor().name().equals(flavor));
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirer.java
index 2f1cadf5964..3d8639a43be 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirer.java
@@ -6,6 +6,7 @@ import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
+import com.yahoo.document.datatypes.Array;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepository;
import com.yahoo.vespa.hosted.provision.node.Agent;
@@ -16,6 +17,7 @@ import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.function.Predicate;
import java.util.logging.Logger;
import java.util.stream.Collectors;
@@ -75,23 +77,21 @@ public class FailedExpirer extends Maintainer {
@Override
protected void maintain() {
- List<Node> containerNodes = getExpiredNodes(containerExpiry)
- .stream()
- .filter(node -> node.allocation().isPresent() &&
- node.allocation().get().membership().cluster().type() == ClusterSpec.Type.container)
- .collect(Collectors.toList());
- List<Node> remainingNodes = getExpiredNodes(defaultExpiry);
- remainingNodes.removeAll(containerNodes);
- recycle(containerNodes);
- recycle(remainingNodes);
+ List<Node> remainingNodes = new ArrayList<>(nodeRepository.getNodes(Node.State.failed));
+
+ recycleIf(remainingNodes, node -> node.allocation().isEmpty());
+ recycleIf(remainingNodes, node ->
+ node.allocation().get().membership().cluster().type() == ClusterSpec.Type.container &&
+ node.history().hasEventBefore(History.Event.Type.failed, clock.instant().minus(containerExpiry)));
+ recycleIf(remainingNodes, node ->
+ node.history().hasEventBefore(History.Event.Type.failed, clock.instant().minus(defaultExpiry)));
}
- /** Get failed nodes that have expired according to given expiry */
- private List<Node> getExpiredNodes(Duration expiry) {
- return nodeRepository.getNodes(Node.State.failed).stream()
- .filter(node -> node.history()
- .hasEventBefore(History.Event.Type.failed, clock.instant().minus(expiry)))
- .collect(Collectors.toList());
+ /** Recycle the nodes matching condition, and remove those nodes from the nodes list. */
+ private void recycleIf(List<Node> nodes, Predicate<Node> recycleCondition) {
+ List<Node> nodesToRecycle = nodes.stream().filter(recycleCondition).collect(Collectors.toList());
+ nodes.removeAll(nodesToRecycle);
+ recycle(nodesToRecycle);
}
/** Move eligible nodes to dirty. This may be a subset of the given nodes */
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java
index 69e5ae32817..87c69d6a124 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java
@@ -215,12 +215,12 @@ public class MetricsReporter extends Maintainer {
private void updateDockerMetrics(List<Node> nodes) {
// Capacity flavors for docker
DockerHostCapacity capacity = new DockerHostCapacity(nodes);
- metric.set("hostedVespa.docker.totalCapacityCpu", capacity.getCapacityTotal().getCpu(), null);
- metric.set("hostedVespa.docker.totalCapacityMem", capacity.getCapacityTotal().getMemory(), null);
- metric.set("hostedVespa.docker.totalCapacityDisk", capacity.getCapacityTotal().getDisk(), null);
- metric.set("hostedVespa.docker.freeCapacityCpu", capacity.getFreeCapacityTotal().getCpu(), null);
- metric.set("hostedVespa.docker.freeCapacityMem", capacity.getFreeCapacityTotal().getMemory(), null);
- metric.set("hostedVespa.docker.freeCapacityDisk", capacity.getFreeCapacityTotal().getDisk(), null);
+ metric.set("hostedVespa.docker.totalCapacityCpu", capacity.getCapacityTotal().vcpu(), null);
+ metric.set("hostedVespa.docker.totalCapacityMem", capacity.getCapacityTotal().memoryGb(), null);
+ metric.set("hostedVespa.docker.totalCapacityDisk", capacity.getCapacityTotal().diskGb(), null);
+ metric.set("hostedVespa.docker.freeCapacityCpu", capacity.getFreeCapacityTotal().vcpu(), null);
+ metric.set("hostedVespa.docker.freeCapacityMem", capacity.getFreeCapacityTotal().memoryGb(), null);
+ metric.set("hostedVespa.docker.freeCapacityDisk", capacity.getFreeCapacityTotal().diskGb(), null);
List<Flavor> dockerFlavors = nodeRepository().getAvailableFlavors().getFlavors().stream()
.filter(f -> f.getType().equals(Flavor.Type.DOCKER_CONTAINER))
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
index 5ba56dfa8ed..bd2ce3a5f5e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java
@@ -11,6 +11,7 @@ import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NetworkPortsSerializer;
import com.yahoo.config.provision.NodeFlavors;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.TenantName;
import com.yahoo.slime.ArrayTraverser;
@@ -69,8 +70,14 @@ public class NodeSerializer {
private static final String reportsKey = "reports";
private static final String modelNameKey = "modelName";
- // Configuration fields
+ // Node resource fields
+ // ...for hosts and nodes allocated by legacy flavor specs
private static final String flavorKey = "flavor";
+ // ...for nodes allocated by resources
+ private static final String resourcesKey = "resources";
+ private static final String vcpuKey = "vcpu";
+ private static final String memoryKey = "memory";
+ private static final String diskKey = "disk";
// Allocation fields
private static final String tenantIdKey = "tenantId";
@@ -114,7 +121,7 @@ public class NodeSerializer {
toSlime(node.ipAddressPool().asSet(), object.setArray(ipAddressPoolKey), IP::requireAddressPool);
object.setString(idKey, node.id());
node.parentHostname().ifPresent(hostname -> object.setString(parentHostnameKey, hostname));
- object.setString(flavorKey, node.flavor().name());
+ toSlime(node.flavor(), object);
object.setLong(rebootGenerationKey, node.status().reboot().wanted());
object.setLong(currentRebootGenerationKey, node.status().reboot().current());
node.status().vespaVersion().ifPresent(version -> object.setString(vespaVersionKey, version.toString()));
@@ -134,6 +141,19 @@ public class NodeSerializer {
node.modelName().ifPresent(modelName -> object.setString(modelNameKey, modelName));
}
+ private void toSlime(Flavor flavor, Cursor object) {
+ if (flavor.isConfigured()) {
+ object.setString(flavorKey, flavor.name());
+ }
+ else {
+ NodeResources resources = flavor.resources();
+ Cursor resourcesObject = object.setObject(resourcesKey);
+ resourcesObject.setDouble(vcpuKey, resources.vcpu());
+ resourcesObject.setDouble(memoryKey, resources.memoryGb());
+ resourcesObject.setDouble(diskKey, resources.diskGb());
+ }
+ }
+
private void toSlime(Allocation allocation, Cursor object) {
object.setString(tenantIdKey, allocation.owner().tenant().value());
object.setString(applicationIdKey, allocation.owner().application().value());
@@ -198,7 +218,15 @@ public class NodeSerializer {
}
private Flavor flavorFromSlime(Inspector object) {
- return flavors.getFlavorOrThrow(object.field(flavorKey).asString());
+ if (object.field(flavorKey).valid()) {
+ return flavors.getFlavorOrThrow(object.field(flavorKey).asString());
+ }
+ else {
+ Inspector resources = object.field(resourcesKey);
+ return new Flavor(new NodeResources(resources.field(vcpuKey).asDouble(),
+ resources.field(memoryKey).asDouble(),
+ resources.field(diskKey).asDouble()));
+ }
}
private Optional<Allocation> allocationFromSlime(Inspector object) {
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 e437badf0dc..dbeed0c3e76 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
@@ -4,10 +4,10 @@ package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
-import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.NodeFlavors;
import java.util.Arrays;
@@ -41,19 +41,29 @@ public class CapacityPolicies {
}
}
- public Flavor decideFlavor(Capacity requestedCapacity, ClusterSpec cluster) {
- // for now, always use the requested flavor if a docker flavor is requested
- Optional<String> requestedFlavor = requestedCapacity.flavor();
- if (requestedFlavor.isPresent() &&
- flavors.getFlavorOrThrow(requestedFlavor.get()).getType() == Flavor.Type.DOCKER_CONTAINER)
- return flavors.getFlavorOrThrow(requestedFlavor.get());
+ public NodeResources decideFlavor(Capacity requestedCapacity, ClusterSpec cluster) {
+ Optional<NodeResources> requestedFlavor = requestedCapacity.nodeResources();
+ if (requestedFlavor.isPresent() && ! requestedFlavor.get().allocateByLegacyName())
+ return requestedFlavor.get();
- String defaultFlavorName = zone.defaultFlavor(cluster.type());
+ NodeResources defaultFlavor = NodeResources.fromLegacyName(zone.defaultFlavor(cluster.type()));
+ if (requestedFlavor.isEmpty())
+ return defaultFlavor;
+
+ // Flavor is specified and is allocateByLegacyName: Handle legacy flavor specs
if (zone.system() == SystemName.cd)
- return flavors.getFlavorOrThrow(requestedFlavor.orElse(defaultFlavorName));
- switch(zone.environment()) {
- case dev : case test : case staging : return flavors.getFlavorOrThrow(defaultFlavorName);
- default : return flavors.getFlavorOrThrow(requestedFlavor.orElse(defaultFlavorName));
+ return flavors.exists(requestedFlavor.get().legacyName().get()) ? requestedFlavor.get() : defaultFlavor;
+ else {
+ switch (zone.environment()) {
+ case dev: case test: case staging: return defaultFlavor;
+ default:
+ // Check existence of the legacy specified flavor
+ flavors.getFlavorOrThrow(requestedFlavor.get().legacyName().get());
+ // Return this spec containing the legacy flavor name, not the flavor's capacity object
+ // which describes the flavors capacity, as the point of legacy allocation is to match
+ // by name, not by resources
+ return requestedFlavor.get();
+ }
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacity.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacity.java
index 95b8bd24ba5..4c557c60802 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacity.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacity.java
@@ -33,13 +33,14 @@ public class DockerHostCapacity {
/**
* Compare hosts on free capacity.
- * <p>
* Used in prioritizing hosts for allocation in <b>descending</b> order.
*/
int compare(Node hostA, Node hostB) {
- int comp = freeCapacityOf(hostB, false).compare(freeCapacityOf(hostA, false));
+ int comp = compare(freeCapacityOf(hostB, false),
+ freeCapacityOf(hostA, false));
if (comp == 0) {
- comp = freeCapacityOf(hostB, false).compare(freeCapacityOf(hostA, false));
+ comp = compare(freeCapacityOf(hostB, false),
+ freeCapacityOf(hostA, false));
if (comp == 0) {
// If resources are equal - we want to assign to the one with the most IPaddresses free
comp = freeIPs(hostB) - freeIPs(hostA);
@@ -49,9 +50,11 @@ public class DockerHostCapacity {
}
int compareWithoutInactive(Node hostA, Node hostB) {
- int comp = freeCapacityOf(hostB, true).compare(freeCapacityOf(hostA, true));
+ int comp = compare(freeCapacityOf(hostB, true),
+ freeCapacityOf(hostA, true));
if (comp == 0) {
- comp = freeCapacityOf(hostB, true).compare(freeCapacityOf(hostA, true));
+ comp = compare(freeCapacityOf(hostB, true),
+ freeCapacityOf(hostA, true));
if (comp == 0) {
// If resources are equal - we want to assign to the one with the most IPaddresses free
comp = freeIPs(hostB) - freeIPs(hostA);
@@ -60,6 +63,10 @@ public class DockerHostCapacity {
return comp;
}
+ private int compare(ResourceCapacity a, ResourceCapacity b) {
+ return ResourceCapacityComparator.defaultOrder().compare(a, b);
+ }
+
/**
* Checks the node capacity and free ip addresses to see
* if we could allocate a flavor on the docker host.
@@ -105,11 +112,22 @@ public class DockerHostCapacity {
}
private int canFitNumberOf(Node node, Flavor flavor) {
- int capacityFactor = freeCapacityOf(node, false).freeCapacityInFlavorEquivalence(flavor);
+ ResourceCapacity freeCapacity = freeCapacityOf(node, false);
+ int capacityFactor = freeCapacityInFlavorEquivalence(freeCapacity, flavor);
int ips = freeIPs(node);
return Math.min(capacityFactor, ips);
}
+ int freeCapacityInFlavorEquivalence(ResourceCapacity freeCapacity, Flavor flavor) {
+ if ( ! freeCapacity.hasCapacityFor(ResourceCapacity.of(flavor))) return 0;
+
+ double cpuFactor = Math.floor(freeCapacity.vcpu() / flavor.getMinCpuCores());
+ double memoryFactor = Math.floor(freeCapacity.memoryGb() / flavor.getMinMainMemoryAvailableGb());
+ double diskFactor = Math.floor(freeCapacity.diskGb() / flavor.getMinDiskAvailableGb());
+
+ return (int) Math.min(Math.min(memoryFactor, cpuFactor), diskFactor);
+ }
+
/**
* Calculate the remaining capacity for the dockerHost.
* @param dockerHost The host to find free capacity of.
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/FlavorConfigBuilder.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/FlavorConfigBuilder.java
index cff62508ec6..77872fc1435 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/FlavorConfigBuilder.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/FlavorConfigBuilder.java
@@ -31,19 +31,6 @@ public class FlavorConfigBuilder {
return flavor;
}
- public FlavorsConfig.Flavor.Builder addNonStockFlavor(String flavorName, double cpu, double mem, double disk, Flavor.Type type) {
- FlavorsConfig.Flavor.Builder flavor = new FlavorsConfig.Flavor.Builder();
- flavor.name(flavorName);
- flavor.description("Flavor-name-is-" + flavorName);
- flavor.minDiskAvailableGb(disk);
- flavor.minCpuCores(cpu);
- flavor.minMainMemoryAvailableGb(mem);
- flavor.stock(false);
- flavor.environment(type.name());
- builder.flavor(flavor);
- return flavor;
- }
-
public void addReplaces(String replaces, FlavorsConfig.Flavor.Builder flavor) {
FlavorsConfig.Flavor.Replaces.Builder flavorReplaces = new FlavorsConfig.Flavor.Replaces.Builder();
flavorReplaces.name(replaces);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
index a8b48751d23..5db9eaf3d08 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/GroupPreparer.java
@@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.OutOfCapacityException;
import com.yahoo.lang.MutableInteger;
import com.yahoo.transaction.Mutex;
@@ -64,7 +65,8 @@ public class GroupPreparer {
// Create a prioritized set of nodes
NodeList nodeList = nodeRepository.list();
NodePrioritizer prioritizer = new NodePrioritizer(
- nodeList, application, cluster, requestedNodes, spareCount, nodeRepository.nameResolver());
+ nodeList, application, cluster, requestedNodes, spareCount, nodeRepository.nameResolver(),
+ nodeRepository.getAvailableFlavors());
prioritizer.addApplicationNodes();
prioritizer.addSurplusNodes(surplusActiveNodes);
@@ -73,14 +75,14 @@ public class GroupPreparer {
// Allocate from the prioritized list
NodeAllocation allocation = new NodeAllocation(nodeList, application, cluster, requestedNodes,
- highestIndex, nodeRepository.zone(), nodeRepository.clock());
+ highestIndex, nodeRepository.getAvailableFlavors(),
+ nodeRepository.zone(), nodeRepository.clock());
allocation.offer(prioritizer.prioritize());
if (dynamicProvisioningEnabled) {
List<ProvisionedHost> provisionedHosts = allocation.getFulfilledDockerDeficit()
- .map(deficit -> hostProvisioner.get().provisionHosts(
- nodeRepository.database().getProvisionIndexes(deficit.getCount()),
- deficit.getFlavor()))
+ .map(deficit -> hostProvisioner.get().provisionHosts(nodeRepository.database().getProvisionIndexes(deficit.getCount()),
+ deficit.getFlavor()))
.orElseGet(List::of);
// At this point we have started provisioning of the hosts, the first priority is to make sure that
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 79296e58045..af933d0a8f0 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
@@ -1,7 +1,7 @@
// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.provisioning;
-import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.vespa.hosted.provision.Node;
import java.util.List;
@@ -17,13 +17,12 @@ public interface HostProvisioner {
/**
* Schedule provisioning of a given number of hosts.
*
- * @param provisionIndexes List of unique provision indexes which will be used to generate the host hostnames
+ * @param provisionIndexes List of unique provision indexes which will be used to generate the node hostnames
* on the form of <code>[prefix][index].[domain]</code>
- * @param nodeFlavor Vespa flavor of the node that will run on this host. The resulting provisioned host
- * will be of a flavor that is at least as big or bigger than this.
- * @return list of {@link ProvisionedHost} describing the provisioned hosts and nodes on them.
+ * @param resources the resources needed per node
+ * @return list of {@link ProvisionedHost} describing the provisioned nodes
*/
- List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, Flavor nodeFlavor);
+ List<ProvisionedHost> provisionHosts(List<Integer> provisionIndexes, NodeResources resources);
/**
* Continue provisioning of given list of Nodes.
@@ -47,4 +46,5 @@ public interface HostProvisioner {
* @param host host to deprovision.
*/
void deprovision(Node host);
+
}
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 dcc3c4a0ef8..d4527452e9c 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
@@ -4,7 +4,8 @@ package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
-import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.TenantName;
import com.yahoo.config.provision.Zone;
@@ -67,17 +68,18 @@ class NodeAllocation {
/** The next membership index to assign to a new node */
private final MutableInteger highestIndex;
+ private final NodeFlavors flavors;
private final Zone zone;
-
private final Clock clock;
NodeAllocation(NodeList allNodes, ApplicationId application, ClusterSpec cluster, NodeSpec requestedNodes,
- MutableInteger highestIndex, Zone zone, Clock clock) {
+ MutableInteger highestIndex, NodeFlavors flavors, Zone zone, Clock clock) {
this.allNodes = allNodes;
this.application = application;
this.cluster = cluster;
this.requestedNodes = requestedNodes;
this.highestIndex = highestIndex;
+ this.flavors = flavors;
this.zone = zone;
this.clock = clock;
}
@@ -217,7 +219,7 @@ class NodeAllocation {
}
private boolean hasCompatibleFlavor(Node node) {
- return requestedNodes.isCompatible(node.flavor());
+ return requestedNodes.isCompatible(node.flavor(), flavors);
}
private Node acceptNode(PrioritizableNode prioritizableNode, boolean wantToRetire) {
@@ -284,8 +286,8 @@ class NodeAllocation {
return Optional.of(requestedNodes)
.filter(NodeSpec.CountNodeSpec.class::isInstance)
.map(NodeSpec.CountNodeSpec.class::cast)
- .map(spec -> new FlavorCount(spec.getFlavor(), spec.fulfilledDeficitCount(acceptedOfRequestedFlavor)))
- .filter(flavorCount -> flavorCount.getFlavor().getType() == Flavor.Type.DOCKER_CONTAINER)
+ .map(spec -> new FlavorCount(spec.resources(), spec.fulfilledDeficitCount(acceptedOfRequestedFlavor)))
+ .filter(flavorCount -> ! flavorCount.getFlavor().allocateByLegacyName())
.filter(flavorCount -> flavorCount.getCount() > 0);
}
@@ -364,15 +366,16 @@ class NodeAllocation {
}
static class FlavorCount {
- private final Flavor flavor;
+
+ private final NodeResources flavor;
private final int count;
- private FlavorCount(Flavor flavor, int count) {
+ private FlavorCount(NodeResources flavor, int count) {
this.flavor = flavor;
this.count = count;
}
- Flavor getFlavor() {
+ NodeResources getFlavor() {
return flavor;
}
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 5a3f0380fa2..288a24a0d89 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
@@ -4,6 +4,8 @@ package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.NodeType;
import com.yahoo.log.LogLevel;
import com.yahoo.transaction.Mutex;
@@ -44,21 +46,22 @@ class NodePrioritizer {
private final ApplicationId appId;
private final ClusterSpec clusterSpec;
private final NameResolver nameResolver;
+ private final NodeFlavors flavors;
private final boolean isDocker;
private final boolean isAllocatingForReplacement;
private final Set<Node> spareHosts;
NodePrioritizer(NodeList allNodes, ApplicationId appId, ClusterSpec clusterSpec, NodeSpec nodeSpec,
- int spares, NameResolver nameResolver) {
+ int spares, NameResolver nameResolver, NodeFlavors flavors) {
this.allNodes = allNodes;
this.capacity = new DockerHostCapacity(allNodes);
this.requestedNodes = nodeSpec;
this.clusterSpec = clusterSpec;
this.appId = appId;
this.nameResolver = nameResolver;
+ this.flavors = flavors;
this.spareHosts = findSpareHosts(allNodes, capacity, spares);
-
int nofFailedNodes = (int) allNodes.asList().stream()
.filter(node -> node.state().equals(Node.State.failed))
.filter(node -> node.allocation().isPresent())
@@ -143,8 +146,8 @@ class NodePrioritizer {
}
void addNewDockerNodesOn(Mutex allocationLock, NodeList candidates) {
- if (!isDocker) return;
- ResourceCapacity wantedResourceCapacity = ResourceCapacity.of(getFlavor(requestedNodes));
+ if ( ! isDocker) return;
+ ResourceCapacity wantedResourceCapacity = ResourceCapacity.of(resources(requestedNodes));
for (Node node : candidates) {
if (node.type() != NodeType.host) continue;
@@ -171,10 +174,10 @@ class NodePrioritizer {
Collections.emptySet(),
allocation.get().hostname(),
Optional.of(node.hostname()),
- getFlavor(requestedNodes),
+ resources(requestedNodes),
NodeType.tenant);
PrioritizableNode nodePri = toNodePriority(newNode, false, true);
- if (!nodePri.violatesSpares || isAllocatingForReplacement) {
+ if ( ! nodePri.violatesSpares || isAllocatingForReplacement) {
log.log(LogLevel.DEBUG, "Adding new Docker node " + newNode);
nodes.put(newNode, nodePri);
}
@@ -215,8 +218,7 @@ class NodePrioritizer {
PrioritizableNode.Builder builder = new PrioritizableNode.Builder(node)
.withSurplusNode(isSurplusNode)
.withNewNode(isNewNode)
- .withPreferredOnFlavor(
- requestedNodes.specifiesNonStockFlavor() && node.flavor().equals(getFlavor(requestedNodes)));
+ .withPreferredOnFlavor(preferredOnLegacyFlavor(node));
allNodes.parentOf(node).ifPresent(parent -> {
builder.withParent(parent).withFreeParentCapacity(capacity.freeCapacityOf(parent, false));
@@ -229,6 +231,18 @@ class NodePrioritizer {
return builder.build();
}
+ /** Needed to handle requests for legacy non-docker nodes only */
+ private boolean preferredOnLegacyFlavor(Node node) {
+ if (requestedNodes instanceof NodeSpec.CountNodeSpec) {
+ NodeResources requestedNodeResources = ((NodeSpec.CountNodeSpec)requestedNodes).resources();
+ if (requestedNodeResources.allocateByLegacyName()) {
+ Flavor requestedFlavor = flavors.getFlavorOrThrow(requestedNodeResources.legacyName().get());
+ return ! requestedFlavor.isStock() && node.flavor().equals(requestedFlavor);
+ }
+ }
+ return false;
+ }
+
static boolean isPreferredNodeToBeRelocated(List<Node> nodes, Node node, Node parent) {
NodeList list = new NodeList(nodes);
return list.childrenOf(parent).asList().stream()
@@ -243,22 +257,23 @@ class NodePrioritizer {
return requestedNodes.fulfilledBy(nofNodesInCluster - nodeFailedNodes);
}
- private static Flavor getFlavor(NodeSpec requestedNodes) {
+ private static NodeResources resources(NodeSpec requestedNodes) {
if (requestedNodes instanceof NodeSpec.CountNodeSpec) {
NodeSpec.CountNodeSpec countSpec = (NodeSpec.CountNodeSpec) requestedNodes;
- return countSpec.getFlavor();
+ return countSpec.resources();
}
return null;
}
private boolean isDocker() {
- Flavor flavor = getFlavor(requestedNodes);
- return (flavor != null) && flavor.getType().equals(Flavor.Type.DOCKER_CONTAINER);
+ NodeResources flavor = resources(requestedNodes);
+ return (flavor != null) && ! flavor.allocateByLegacyName();
}
private static int compareForRelocation(Node a, Node b) {
// Choose smallest node
- int capacity = ResourceCapacity.of(a).compare(ResourceCapacity.of(b));
+ int capacity = ResourceCapacityComparator.defaultOrder().compare(ResourceCapacity.of(a),
+ ResourceCapacity.of(b));
if (capacity != 0) return capacity;
// Choose unallocated over allocated (this case is when we have ready docker nodes)
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 8faabd268d4..f9d712e767e 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
@@ -6,7 +6,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
-import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeFlavors;
@@ -86,7 +86,7 @@ public class NodeRepositoryProvisioner implements Provisioner {
log.log(zone.system() == SystemName.cd ? Level.INFO : LogLevel.DEBUG,
() -> "Received deploy prepare request for " + requestedCapacity + " in " +
- wantedGroups + " groups for application " + application + ", cluster " + cluster);
+ wantedGroups + " groups for application " + application + ", cluster " + cluster);
int effectiveGroups;
NodeSpec requestedNodes;
@@ -96,7 +96,7 @@ public class NodeRepositoryProvisioner implements Provisioner {
if (zone.environment().isManuallyDeployed() && nodeCount < requestedCapacity.nodeCount())
logger.log(Level.INFO, "Requested " + requestedCapacity.nodeCount() + " nodes for " + cluster +
", downscaling to " + nodeCount + " nodes in " + zone.environment());
- Flavor flavor = capacityPolicies.decideFlavor(requestedCapacity, cluster);
+ NodeResources flavor = capacityPolicies.decideFlavor(requestedCapacity, cluster);
log.log(LogLevel.DEBUG, () -> "Decided flavor for requested tenant nodes: " + flavor);
boolean exclusive = capacityPolicies.decideExclusivity(cluster.isExclusive());
effectiveGroups = wantedGroups > nodeCount ? nodeCount : wantedGroups; // cannot have more groups than nodes
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 e033d994f24..ab48e82fbed 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
@@ -1,6 +1,8 @@
// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.hosted.provision.provisioning;
+import com.yahoo.config.provision.NodeResources;
+import com.yahoo.config.provision.NodeFlavors;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.Flavor;
import com.yahoo.vespa.hosted.provision.Node;
@@ -26,13 +28,7 @@ public interface NodeSpec {
boolean isExclusive();
/** Returns whether the given flavor is compatible with this spec */
- boolean isCompatible(Flavor flavor);
-
- /** Returns whether the given flavor is exactly specified by this node spec */
- boolean matchesExactly(Flavor flavor);
-
- /** Returns whether this requests a non-stock flavor */
- boolean specifiesNonStockFlavor();
+ boolean isCompatible(Flavor flavor, NodeFlavors flavors);
/** Returns whether the given node count is sufficient to consider this spec fulfilled to the maximum amount */
boolean saturatedBy(int count);
@@ -61,7 +57,7 @@ public interface NodeSpec {
*/
Node assignRequestedFlavor(Node node);
- static NodeSpec from(int nodeCount, Flavor flavor, boolean exclusive, boolean canFail) {
+ static NodeSpec from(int nodeCount, NodeResources flavor, boolean exclusive, boolean canFail) {
return new CountNodeSpec(nodeCount, flavor, exclusive, canFail);
}
@@ -73,20 +69,19 @@ public interface NodeSpec {
class CountNodeSpec implements NodeSpec {
private final int count;
- private final Flavor requestedFlavor;
+ private final NodeResources requestedNodeResources;
private final boolean exclusive;
private final boolean canFail;
- CountNodeSpec(int count, Flavor flavor, boolean exclusive, boolean canFail) {
+ CountNodeSpec(int count, NodeResources flavor, boolean exclusive, boolean canFail) {
this.count = count;
- this.requestedFlavor = Objects.requireNonNull(flavor, "A flavor must be specified");
+ this.requestedNodeResources = Objects.requireNonNull(flavor, "A flavor must be specified");
this.exclusive = exclusive;
this.canFail = canFail;
}
- // TODO: Remove usage of this
- public Flavor getFlavor() {
- return requestedFlavor;
+ public NodeResources resources() {
+ return requestedNodeResources;
}
@Override
@@ -96,18 +91,19 @@ public interface NodeSpec {
public NodeType type() { return NodeType.tenant; }
@Override
- public boolean isCompatible(Flavor flavor) {
- if (flavor.satisfies(requestedFlavor)) return true;
+ public boolean isCompatible(Flavor flavor, NodeFlavors flavors) {
+ if (requestedNodeResources.allocateByLegacyName() && flavor.isConfigured()) {
+ if (flavor.satisfies(flavors.getFlavorOrThrow(requestedNodeResources.legacyName().get())))
+ return true;
+ }
+ else {
+ if (requestedNodeResources.equals(flavor.resources()))
+ return true;
+ }
return requestedFlavorCanBeAchievedByResizing(flavor);
}
@Override
- public boolean matchesExactly(Flavor flavor) { return flavor.equals(this.requestedFlavor); }
-
- @Override
- public boolean specifiesNonStockFlavor() { return ! requestedFlavor.isStock(); }
-
- @Override
public boolean saturatedBy(int count) { return fulfilledBy(count); } // min=max for count specs
@Override
@@ -123,20 +119,19 @@ public interface NodeSpec {
@Override
public NodeSpec fraction(int divisor) {
- return new CountNodeSpec(count/divisor, requestedFlavor, exclusive, canFail);
+ return new CountNodeSpec(count/divisor, requestedNodeResources, exclusive, canFail);
}
@Override
public Node assignRequestedFlavor(Node node) {
- // Docker nodes can change flavor in place
- if (requestedFlavorCanBeAchievedByResizing(node.flavor()))
- return node.with(requestedFlavor);
-
+ // Docker nodes can change flavor in place - disabled - see below
+ // if (requestedFlavorCanBeAchievedByResizing(node.flavor()))
+ // return node.with(requestedFlavor);
return node;
}
@Override
- public String toString() { return "request for " + count + " nodes of " + requestedFlavor; }
+ public String toString() { return "request for " + count + " nodes with " + requestedNodeResources; }
/** Docker nodes can be downsized in place */
private boolean requestedFlavorCanBeAchievedByResizing(Flavor flavor) {
@@ -164,13 +159,7 @@ public interface NodeSpec {
public boolean isExclusive() { return false; }
@Override
- public boolean isCompatible(Flavor flavor) { return true; }
-
- @Override
- public boolean matchesExactly(Flavor flavor) { return false; }
-
- @Override
- public boolean specifiesNonStockFlavor() { return false; }
+ public boolean isCompatible(Flavor flavor, NodeFlavors flavors) { return true; }
@Override
public boolean saturatedBy(int count) { return false; }
@@ -180,11 +169,9 @@ public interface NodeSpec {
@Override
public int idealRetiredCount(int acceptedCount, int currentRetiredCount) {
- /*
- * All nodes marked with wantToRetire get marked as retired just before this function is called,
- * the job of this function is to throttle the retired count. If no nodes are marked as retired
- * then continue this way, otherwise allow only 1 node to be retired
- */
+ // All nodes marked with wantToRetire get marked as retired just before this function is called,
+ // the job of this function is to throttle the retired count. If no nodes are marked as retired
+ // then continue this way, otherwise allow only 1 node to be retired
return Math.min(1, currentRetiredCount);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/PrioritizableNode.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/PrioritizableNode.java
index f98de7ac579..7abb43374bf 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/PrioritizableNode.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/PrioritizableNode.java
@@ -90,7 +90,7 @@ class PrioritizableNode implements Comparable<PrioritizableNode> {
if (other.parent.isPresent() && !this.parent.isPresent()) return 1;
// Choose the node with parent node with the least capacity (TODO parameterize this as this is pretty much the core of the algorithm)
- int freeCapacity = this.freeParentCapacity.compare(other.freeParentCapacity);
+ int freeCapacity = ResourceCapacityComparator.defaultOrder().compare(this.freeParentCapacity, other.freeParentCapacity);
if (freeCapacity != 0) return freeCapacity;
// Choose cheapest node
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java
index e0cf882fffa..c2b56c757fa 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisionedHost.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.hosted.provision.Node;
@@ -15,18 +16,19 @@ import java.util.Set;
* @author freva
*/
public class ProvisionedHost {
+
private final String id;
private final String hostHostname;
private final Flavor hostFlavor;
private final String nodeHostname;
- private final Flavor nodeFlavor;
+ private final NodeResources nodeResources;
- public ProvisionedHost(String id, String hostHostname, Flavor hostFlavor, String nodeHostname, Flavor nodeFlavor) {
+ public ProvisionedHost(String id, String hostHostname, Flavor hostFlavor, String nodeHostname, NodeResources nodeResources) {
this.id = Objects.requireNonNull(id, "Host id must be set");
this.hostHostname = Objects.requireNonNull(hostHostname, "Host hostname must be set");
this.hostFlavor = Objects.requireNonNull(hostFlavor, "Host flavor must be set");
this.nodeHostname = Objects.requireNonNull(nodeHostname, "Node hostname must be set");
- this.nodeFlavor = Objects.requireNonNull(nodeFlavor, "Node flavor must be set");
+ this.nodeResources = Objects.requireNonNull(nodeResources, "Node resources must be set");
}
/** Generate {@link Node} instance representing the provisioned physical host */
@@ -36,28 +38,26 @@ public class ProvisionedHost {
/** Generate {@link Node} instance representing the node running on this physical host */
public Node generateNode() {
- return Node.createDockerNode(Set.of(), Set.of(), nodeHostname, Optional.of(hostHostname), nodeFlavor, NodeType.tenant);
+ return Node.createDockerNode(Set.of(), Set.of(), nodeHostname, Optional.of(hostHostname), nodeResources, NodeType.tenant);
}
public String getId() {
return id;
}
- public String getHostHostname() {
+ public String hostHostname() {
return hostHostname;
}
- public Flavor getHostFlavor() {
+ public Flavor hostFlavor() {
return hostFlavor;
}
- public String getNodeHostname() {
+ public String nodeHostname() {
return nodeHostname;
}
- public Flavor getNodeFlavor() {
- return nodeFlavor;
- }
+ public NodeResources nodeResources() { return nodeResources; }
@Override
public boolean equals(Object o) {
@@ -68,12 +68,12 @@ public class ProvisionedHost {
hostHostname.equals(that.hostHostname) &&
hostFlavor.equals(that.hostFlavor) &&
nodeHostname.equals(that.nodeHostname) &&
- nodeFlavor.equals(that.nodeFlavor);
+ nodeResources.equals(that.nodeResources);
}
@Override
public int hashCode() {
- return Objects.hash(id, hostHostname, hostFlavor, nodeHostname, nodeFlavor);
+ return Objects.hash(id, hostHostname, hostFlavor, nodeHostname, nodeResources);
}
@Override
@@ -83,7 +83,8 @@ public class ProvisionedHost {
", hostHostname='" + hostHostname + '\'' +
", hostFlavor=" + hostFlavor +
", nodeHostname='" + nodeHostname + '\'' +
- ", nodeFlavor=" + nodeFlavor +
+ ", nodeResources=" + nodeResources +
'}';
}
+
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacity.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacity.java
index 903951ef93b..3839d66c8de 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacity.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacity.java
@@ -2,6 +2,7 @@
package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.vespa.hosted.provision.Node;
/**
@@ -16,14 +17,14 @@ public class ResourceCapacity {
public static final ResourceCapacity NONE = new ResourceCapacity(0, 0, 0);
- private final double memory;
- private final double cpu;
- private final double disk;
+ private final double memoryGb;
+ private final double vcpu;
+ private final double diskGb;
- private ResourceCapacity(double memory, double cpu, double disk) {
- this.memory = memory;
- this.cpu = cpu;
- this.disk = disk;
+ private ResourceCapacity(double memoryGb, double vcpu, double diskGb) {
+ this.memoryGb = memoryGb;
+ this.vcpu = vcpu;
+ this.diskGb = diskGb;
}
static ResourceCapacity of(Flavor flavor) {
@@ -31,64 +32,46 @@ public class ResourceCapacity {
flavor.getMinMainMemoryAvailableGb(), flavor.getMinCpuCores(), flavor.getMinDiskAvailableGb());
}
+ static ResourceCapacity of(NodeResources resources) {
+ return new ResourceCapacity(resources.memoryGb(), resources.vcpu(), resources.diskGb());
+ }
+
static ResourceCapacity of(Node node) {
return ResourceCapacity.of(node.flavor());
}
- public double getMemory() {
- return memory;
+ public double memoryGb() {
+ return memoryGb;
}
- public double getCpu() {
- return cpu;
+ public double vcpu() {
+ return vcpu;
}
- public double getDisk() {
- return disk;
+ public double diskGb() {
+ return diskGb;
}
public ResourceCapacity subtract(ResourceCapacity other) {
- return new ResourceCapacity(memory - other.memory,
- cpu - other.cpu,
- disk - other.disk);
+ return new ResourceCapacity(memoryGb - other.memoryGb,
+ vcpu - other.vcpu,
+ diskGb - other.diskGb);
}
public ResourceCapacity add(ResourceCapacity other) {
- return new ResourceCapacity(memory + other.memory,
- cpu + other.cpu,
- disk + other.disk);
+ return new ResourceCapacity(memoryGb + other.memoryGb,
+ vcpu + other.vcpu,
+ diskGb + other.diskGb);
}
boolean hasCapacityFor(ResourceCapacity capacity) {
- return memory >= capacity.memory &&
- cpu >= capacity.cpu &&
- disk >= capacity.disk;
+ return memoryGb >= capacity.memoryGb &&
+ vcpu >= capacity.vcpu &&
+ diskGb >= capacity.diskGb;
}
boolean hasCapacityFor(Flavor flavor) {
return hasCapacityFor(ResourceCapacity.of(flavor));
}
- int freeCapacityInFlavorEquivalence(Flavor flavor) {
- if (!hasCapacityFor(ResourceCapacity.of(flavor))) return 0;
-
- double memoryFactor = Math.floor(memory/flavor.getMinMainMemoryAvailableGb());
- double cpuFactor = Math.floor(cpu/flavor.getMinCpuCores());
- double diskFactor = Math.floor(disk/flavor.getMinDiskAvailableGb());
-
- return (int) Math.min(Math.min(memoryFactor, cpuFactor), diskFactor);
- }
-
- /**
- * Normal compare implementation where -1 if this is less than that.
- */
- int compare(ResourceCapacity that) {
- if (memory > that.memory) return 1;
- if (memory < that.memory) return -1;
- if (disk > that.disk) return 1;
- if (disk < that.disk) return -1;
- if (cpu > that.cpu) return 1;
- if (cpu < that.cpu) return -1;
- return 0;
- }
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityComparator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityComparator.java
new file mode 100644
index 00000000000..c4f605bb9fc
--- /dev/null
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityComparator.java
@@ -0,0 +1,36 @@
+// Copyright 2019 Oath Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.hosted.provision.provisioning;
+
+import java.util.Comparator;
+
+/**
+ * Resource comparator
+ *
+ * @author bratseth
+ */
+public class ResourceCapacityComparator {
+
+ private static final MemoryDiskCpu memoryDiskCpuComparator = new MemoryDiskCpu();
+
+ /** Returns the default ordering */
+ public static Comparator<ResourceCapacity> defaultOrder() { return memoryDiskCpuOrder(); }
+
+ /** Returns a comparator comparing by memory, disk, vcpu */
+ public static Comparator<ResourceCapacity> memoryDiskCpuOrder() { return memoryDiskCpuComparator; }
+
+ private static class MemoryDiskCpu implements Comparator<ResourceCapacity> {
+
+ @Override
+ public int compare(ResourceCapacity a, ResourceCapacity b) {
+ if (a.memoryGb() > b.memoryGb()) return 1;
+ if (a.memoryGb() < b.memoryGb()) return -1;
+ if (a.diskGb() > b.diskGb()) return 1;
+ if (a.diskGb() < b.diskGb()) return -1;
+ if (a.vcpu() > b.vcpu()) return 1;
+ if (a.vcpu() < b.vcpu()) return -1;
+ return 0;
+ }
+
+ }
+
+}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
index b9fb88e900e..9fccdfda9fe 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/testutils/MockNodeRepository.java
@@ -8,6 +8,8 @@ import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.DockerImage;
+import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeFlavors;
@@ -35,7 +37,7 @@ import java.util.Set;
/**
* A mock repository prepopulated with some applications.
- * Instantiated by DI from application package above.
+ * Instantiated by DI.
*/
public class MockNodeRepository extends NodeRepository {
@@ -59,36 +61,47 @@ public class MockNodeRepository extends NodeRepository {
}
private void populate() {
- NodeRepositoryProvisioner provisioner = new NodeRepositoryProvisioner(this, flavors, Zone.defaultZone(),
- new MockProvisionServiceProvider(), new InMemoryFlagSource());
+ NodeRepositoryProvisioner provisioner = new NodeRepositoryProvisioner(this,
+ flavors,
+ Zone.defaultZone(),
+ new MockProvisionServiceProvider(),
+ new InMemoryFlagSource());
List<Node> nodes = new ArrayList<>();
// Regular nodes
Set<String> ipAddresses = ImmutableSet.of("::1", "127.0.0.1");
Set<String> ipAddressPool = ImmutableSet.of("::2", "::3", "::4");
- nodes.add(createNode("node1", "host1.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.tenant));
- nodes.add(createNode("node2", "host2.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.tenant));
- nodes.add(createNode("node3", "host3.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("expensive"), NodeType.tenant));
+ nodes.add(createNode("node1", "host1.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.tenant));
+ nodes.add(createNode("node2", "host2.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.tenant));
+ nodes.add(createNode("node3", "host3.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("expensive"), NodeType.tenant));
- Node node4 = createNode("node4", "host4.yahoo.com", ipAddresses, Optional.of("dockerhost1.yahoo.com"), flavors.getFlavorOrThrow("docker"), NodeType.tenant);
+ Node node4 = createNode("node4", "host4.yahoo.com", ipAddresses, Optional.of("dockerhost1.yahoo.com"),
+ new Flavor(new NodeResources(1, 1, 100)), NodeType.tenant);
node4 = node4.with(node4.status()
.withVespaVersion(new Version("6.41.0"))
.withDockerImage(DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa:6.41.0")));
nodes.add(node4);
- Node node5 = createNode("node5", "host5.yahoo.com", ipAddresses, Optional.of("dockerhost2.yahoo.com"), flavors.getFlavorOrThrow("docker"), NodeType.tenant);
+ Node node5 = createNode("node5", "host5.yahoo.com", ipAddresses, Optional.of("dockerhost2.yahoo.com"),
+ new Flavor(new NodeResources(1, 1, 100)), NodeType.tenant);
nodes.add(node5.with(node5.status()
.withVespaVersion(new Version("1.2.3"))
.withDockerImage(DockerImage.fromString("docker-registry.domain.tld:8080/dist/vespa:1.2.3"))));
- nodes.add(createNode("node6", "host6.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.tenant));
- Node node7 = createNode("node7", "host7.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.tenant);
+ nodes.add(createNode("node6", "host6.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.tenant));
+ Node node7 = createNode("node7", "host7.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.tenant);
nodes.add(node7);
// 8, 9, 11 and 12 are added by web service calls
- Node node10 = createNode("node10", "host10.yahoo.com", ipAddresses, Optional.of("parent1.yahoo.com"), flavors.getFlavorOrThrow("default"), NodeType.tenant);
+ Node node10 = createNode("node10", "host10.yahoo.com", ipAddresses, Optional.of("parent1.yahoo.com"),
+ flavors.getFlavorOrThrow("default"), NodeType.tenant);
Status node10newStatus = node10.status();
node10newStatus = node10newStatus
.withVespaVersion(Version.fromString("5.104.142"))
@@ -96,24 +109,34 @@ public class MockNodeRepository extends NodeRepository {
node10 = node10.with(node10newStatus);
nodes.add(node10);
- Node node13 = createNode("node13", "host13.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.tenant);
- Node node14 = createNode("node14", "host14.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.tenant);
+ Node node13 = createNode("node13", "host13.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.tenant);
+ Node node14 = createNode("node14", "host14.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.tenant);
nodes.add(node13);
nodes.add(node14);
- Node node55 = createNode("node55", "host55.yahoo.com", ipAddresses, Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.tenant);
+ Node node55 = createNode("node55", "host55.yahoo.com", ipAddresses, Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.tenant);
nodes.add(node55.with(node55.status().withWantToRetire(true).withWantToDeprovision(true)));
/* Setup docker hosts (two of these will be reserved for spares */
- nodes.add(createNode("dockerhost1", "dockerhost1.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.host));
- nodes.add(createNode("dockerhost2", "dockerhost2.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.host));
- nodes.add(createNode("dockerhost3", "dockerhost3.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.host));
- nodes.add(createNode("dockerhost4", "dockerhost4.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.host));
- nodes.add(createNode("dockerhost5", "dockerhost5.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(), flavors.getFlavorOrThrow("large"), NodeType.host));
+ nodes.add(createNode("dockerhost1", "dockerhost1.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.host));
+ nodes.add(createNode("dockerhost2", "dockerhost2.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.host));
+ nodes.add(createNode("dockerhost3", "dockerhost3.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.host));
+ nodes.add(createNode("dockerhost4", "dockerhost4.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.host));
+ nodes.add(createNode("dockerhost5", "dockerhost5.yahoo.com", ipAddresses, ipAddressPool, Optional.empty(), Optional.empty(),
+ flavors.getFlavorOrThrow("large"), NodeType.host));
// Config servers
- nodes.add(createNode("cfg1", "cfg1.yahoo.com", Collections.singleton("127.0.1.1"), Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.config));
- nodes.add(createNode("cfg2", "cfg2.yahoo.com", Collections.singleton("127.0.1.2"), Optional.empty(), flavors.getFlavorOrThrow("default"), NodeType.config));
+ nodes.add(createNode("cfg1", "cfg1.yahoo.com", Collections.singleton("127.0.1.1"), Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.config));
+ nodes.add(createNode("cfg2", "cfg2.yahoo.com", Collections.singleton("127.0.1.2"), Optional.empty(),
+ flavors.getFlavorOrThrow("default"), NodeType.config));
// Ready all nodes, except 7 and 55
nodes = addNodes(nodes);
@@ -152,7 +175,7 @@ public class MockNodeRepository extends NodeRepository {
ClusterSpec.Id.from("id3"),
Version.fromString("6.42"),
false, Collections.emptySet());
- activate(provisioner.prepare(app3, cluster3, Capacity.fromNodeCount(2, Optional.of("docker"), false, true), 1, null), app3, provisioner);
+ activate(provisioner.prepare(app3, cluster3, Capacity.fromCount(2, new NodeResources(1, 1, 100), false, true), 1, null), app3, provisioner);
ApplicationId app4 = ApplicationId.from(TenantName.from("tenant4"), ApplicationName.from("application4"), InstanceName.from("instance4"));
ClusterSpec cluster4 = ClusterSpec.request(ClusterSpec.Type.container,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
index c5c1e9dae16..23b71cc8b6e 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/FailedExpirerTest.java
@@ -9,6 +9,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeFlavors;
@@ -89,7 +90,7 @@ public class FailedExpirerTest {
scenario.clock().advance(Duration.ofDays(2));
scenario.expirer().run();
- scenario.assertNodesIn(Node.State.failed, "node1");
+ scenario.assertNodesIn(Node.State.dirty, "node1");
scenario.assertNodesIn(Node.State.parked, "node2", "node3");
}
@@ -125,7 +126,7 @@ public class FailedExpirerTest {
scenario.clock().advance(Duration.ofHours(2));
scenario.expirer().run();
- scenario.assertNodesIn(Node.State.failed, "node1");
+ scenario.assertNodesIn(Node.State.dirty, "node1");
scenario.assertNodesIn(Node.State.parked, "node2", "node3");
}
@@ -186,20 +187,24 @@ public class FailedExpirerTest {
.withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node1", "parent1")
.withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node2", "parent2")
.withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node3", "parent3")
- .withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node4", "parent1")
- .withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node5", "parent1")
+ .withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node4", "parent3")
+ .withNode(NodeType.tenant, FailureScenario.dockerFlavor, "node5", "parent3")
.setReady("node1", "node2", "node3")
.allocate(ClusterSpec.Type.content, FailureScenario.dockerFlavor, "node1", "node2", "node3")
- .failWithHardwareFailure("parent1");
+ .failNode(1, "node3")
+ .setReady("node4")
+ .allocate(ClusterSpec.Type.content, FailureScenario.dockerFlavor, "node1", "node2", "node4")
+ .failNode(1, "node4")
+ .setReady("node5")
+ .allocate(ClusterSpec.Type.content, FailureScenario.dockerFlavor, "node1", "node2", "node5")
+ .failWithHardwareFailure("parent3");
- scenario.clock().advance(Duration.ofDays(2));
- scenario.failNode(1, "node4", "node5");
scenario.clock().advance(Duration.ofDays(3));
scenario.expirer().run(); // Run twice because parent can only be parked after the child
scenario.expirer().run();
- scenario.assertNodesIn(Node.State.failed, "parent1", "node4", "node5");
+ scenario.assertNodesIn(Node.State.failed, "parent3", "node3", "node4");
}
@Test
@@ -232,8 +237,8 @@ public class FailedExpirerTest {
private static class FailureScenario {
private static final NodeFlavors nodeFlavors = FlavorConfigBuilder.createDummies("default", "docker");
- public static final Flavor defaultFlavor = nodeFlavors.getFlavorOrThrow("default");
- public static final Flavor dockerFlavor = nodeFlavors.getFlavorOrThrow("docker");
+ public static final NodeResources defaultFlavor = new NodeResources(2, 2, 2);
+ public static final NodeResources dockerFlavor = new NodeResources(1, 1, 1);
private final MockCurator curator = new MockCurator();
private final ManualClock clock = new ManualClock();
@@ -268,15 +273,15 @@ public class FailedExpirerTest {
.orElseThrow(() -> new IllegalArgumentException("No such node: " + hostname));
}
- public FailureScenario withNode(NodeType type, Flavor flavor, String hostname, String parentHostname) {
+ public FailureScenario withNode(NodeType type, NodeResources flavor, String hostname, String parentHostname) {
nodeRepository.addNodes(Collections.singletonList(
nodeRepository.createNode(UUID.randomUUID().toString(), hostname,
- Optional.ofNullable(parentHostname), flavor, type)
+ Optional.ofNullable(parentHostname), new Flavor(flavor), type)
));
return this;
}
- public FailureScenario withNode(NodeType type, Flavor flavor, String hostname) {
+ public FailureScenario withNode(NodeType type, NodeResources flavor, String hostname) {
return withNode(type, flavor, hostname, null);
}
@@ -316,13 +321,13 @@ public class FailedExpirerTest {
return allocate(clusterType, defaultFlavor, hostname);
}
- public FailureScenario allocate(ClusterSpec.Type clusterType, Flavor flavor, String... hostname) {
+ public FailureScenario allocate(ClusterSpec.Type clusterType, NodeResources flavor, String... hostname) {
ClusterSpec clusterSpec = ClusterSpec.request(clusterType,
ClusterSpec.Id.from("test"),
Version.fromString("6.42"),
false,
Collections.emptySet());
- Capacity capacity = Capacity.fromNodeCount(hostname.length, Optional.of(flavor.name()), false, true);
+ Capacity capacity = Capacity.fromCount(hostname.length, Optional.of(flavor), false, true);
return allocate(applicationId, clusterSpec, capacity);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java
index 9f251eea9bf..d7942cdb6e7 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/LoadBalancerExpirerTest.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.provision.maintenance;
import com.yahoo.component.Vtag;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.lb.LoadBalancer;
@@ -76,11 +77,11 @@ public class LoadBalancerExpirerTest {
}
private void deployApplication(ApplicationId application, ClusterSpec.Id cluster) {
- tester.makeReadyNodes(10, "default");
+ tester.makeReadyNodes(10, "d-1-1-1");
List<HostSpec> hosts = tester.prepare(application, ClusterSpec.request(ClusterSpec.Type.container, cluster,
Vtag.currentVersion, false, Collections.emptySet()),
2, 1,
- "default");
+ new NodeResources(1, 1, 1));
tester.activate(application, hosts);
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java
index 883da687d8d..1b109d5b080 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.NodeFlavors;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.Zone;
import com.yahoo.jdisc.Metric;
@@ -118,16 +119,19 @@ public class MetricsReporterTest {
// Allow 4 containers
Set<String> ipAddressPool = ImmutableSet.of("::2", "::3", "::4", "::5");
- Node dockerHost = Node.create("openStackId1", Collections.singleton("::1"), ipAddressPool, "dockerHost", Optional.empty(), Optional.empty(), nodeFlavors.getFlavorOrThrow("host"), NodeType.host);
+ Node dockerHost = Node.create("openStackId1", Collections.singleton("::1"), ipAddressPool, "dockerHost",
+ Optional.empty(), Optional.empty(), nodeFlavors.getFlavorOrThrow("host"), NodeType.host);
nodeRepository.addNodes(Collections.singletonList(dockerHost));
nodeRepository.dirtyRecursively("dockerHost", Agent.system, getClass().getSimpleName());
nodeRepository.setReady("dockerHost", Agent.system, getClass().getSimpleName());
- Node container1 = Node.createDockerNode(Collections.singleton("::2"), Collections.emptySet(), "container1", Optional.of("dockerHost"), nodeFlavors.getFlavorOrThrow("docker"), NodeType.tenant);
+ Node container1 = Node.createDockerNode(Collections.singleton("::2"), Collections.emptySet(), "container1",
+ Optional.of("dockerHost"), new NodeResources(1, 3, 2), NodeType.tenant);
container1 = container1.with(allocation(Optional.of("app1")).get());
nodeRepository.addDockerNodes(Collections.singletonList(container1), nodeRepository.lockAllocation());
- Node container2 = Node.createDockerNode(Collections.singleton("::3"), Collections.emptySet(), "container2", Optional.of("dockerHost"), nodeFlavors.getFlavorOrThrow("docker2"), NodeType.tenant);
+ Node container2 = Node.createDockerNode(Collections.singleton("::3"), Collections.emptySet(), "container2",
+ Optional.of("dockerHost"), new NodeResources(2, 4, 4), NodeType.tenant);
container2 = container2.with(allocation(Optional.of("app2")).get());
nodeRepository.addDockerNodes(Collections.singletonList(container2), nodeRepository.lockAllocation());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
index 0ead179e0ea..5e76ebff9b2 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/NodeFailTester.java
@@ -10,6 +10,7 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeFlavors;
@@ -128,7 +129,7 @@ public class NodeFailTester {
List<Node> hosts = tester.createHostNodes(numberOfHosts);
for (int i = 0; i < hosts.size(); i++) {
tester.createReadyNodes(nodesPerHost, i * nodesPerHost, Optional.of("parent" + i),
- nodeFlavors.getFlavorOrThrow("docker"), NodeType.tenant);
+ nodeFlavors.getFlavorOrThrow("d-1-1-1"), NodeType.tenant);
}
// Create applications
@@ -136,8 +137,8 @@ public class NodeFailTester {
ClusterSpec clusterApp1 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("test"), Version.fromString("6.75.0"), false, Collections.emptySet());
ClusterSpec clusterApp2 = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("test"), Version.fromString("6.75.0"), false, Collections.emptySet());
Capacity allHosts = Capacity.fromRequiredNodeType(NodeType.host);
- Capacity capacity1 = Capacity.fromNodeCount(3, Optional.of("docker"), false, true);
- Capacity capacity2 = Capacity.fromNodeCount(5, Optional.of("docker"), false, true);
+ Capacity capacity1 = Capacity.fromCount(3, new NodeResources(1, 1, 1), false, true);
+ Capacity capacity2 = Capacity.fromCount(5, new NodeResources(1, 1, 1), false, true);
tester.activate(nodeAdminApp, clusterNodeAdminApp, allHosts);
tester.activate(app1, clusterApp1, capacity1);
tester.activate(app2, clusterApp2, capacity2);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
index a55211a112a..9d61f5414d6 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AclProvisioningTest.java
@@ -6,6 +6,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.hosted.provision.Node;
@@ -15,6 +16,7 @@ import org.junit.Test;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
+import java.util.Comparator;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
@@ -36,26 +38,26 @@ public class AclProvisioningTest {
@Test
public void trusted_nodes_for_allocated_node() {
- List<Node> configServers = tester.makeConfigServers(3, "default", Version.fromString("6.123.456"));
+ List<Node> configServers = tester.makeConfigServers(3, "d-1-1-1", Version.fromString("6.123.456"));
// Populate repo
- tester.makeReadyNodes(10, "default");
- List<Node> dockerHost = tester.makeReadyNodes(1, "default", NodeType.host);
+ tester.makeReadyNodes(10, "d-1-1-1");
+ List<Node> dockerHost = tester.makeReadyNodes(1, "d-1-1-1", NodeType.host);
ApplicationId zoneApplication = tester.makeApplicationId();
deploy(zoneApplication, Capacity.fromRequiredNodeType(NodeType.host));
- tester.makeReadyVirtualDockerNodes(1, "default", dockerHost.get(0).hostname());
- List<Node> proxyNodes = tester.makeReadyNodes(3, "default", NodeType.proxy);
+ tester.makeReadyVirtualDockerNodes(1, NodeResources.fromLegacyName("d-1-1-1"), dockerHost.get(0).hostname());
+ List<Node> proxyNodes = tester.makeReadyNodes(3, "d-1-1-1", NodeType.proxy);
// Allocate 2 nodes
ApplicationId application = tester.makeApplicationId();
- List<Node> activeNodes = deploy(application, 2);
+ List<Node> activeNodes = deploy(application, Capacity.fromCount(2, NodeResources.fromLegacyName("d-1-1-1"), false, true));
assertEquals(2, activeNodes.size());
// Get trusted nodes for the first active node
Node node = activeNodes.get(0);
Supplier<List<NodeAcl>> nodeAcls = () -> tester.nodeRepository().getNodeAcls(node, false);
- // Trusted nodes is active nodes in same application, proxy nodes and config servers
+ // Trusted nodes are active nodes in same application, proxy nodes and config servers
assertAcls(Arrays.asList(activeNodes, proxyNodes, configServers, dockerHost),
ImmutableSet.of("10.2.3.0/24", "10.4.5.0/24"),
nodeAcls.get());
@@ -130,7 +132,7 @@ public class AclProvisioningTest {
// Populate repo
List<Node> dockerHostNodes = tester.makeReadyNodes(2, "default", NodeType.host);
Node dockerHostNodeUnderTest = dockerHostNodes.get(0);
- List<Node> dockerNodes = tester.makeReadyVirtualDockerNodes(5, "dockerSmall",
+ List<Node> dockerNodes = tester.makeReadyVirtualDockerNodes(5, new NodeResources(1, 1, 1),
dockerHostNodeUnderTest.hostname());
List<NodeAcl> acls = tester.nodeRepository().getNodeAcls(dockerHostNodeUnderTest, true);
@@ -211,12 +213,16 @@ public class AclProvisioningTest {
}
private static void assertAcls(List<List<Node>> expectedNodes, Set<String> expectedNetworks, List<NodeAcl> actual) {
- Set<Node> expectedTrustedNodes = expectedNodes.stream()
+ List<Node> expectedTrustedNodes = expectedNodes.stream()
.flatMap(Collection::stream)
- .collect(Collectors.toSet());
- Set<Node> actualTrustedNodes = actual.stream()
+ .distinct()
+ .sorted(Comparator.comparing(Node::hostname))
+ .collect(Collectors.toList());
+ List<Node> actualTrustedNodes = actual.stream()
.flatMap(acl -> acl.trustedNodes().stream())
- .collect(Collectors.toSet());
+ .distinct()
+ .sorted(Comparator.comparing(Node::hostname))
+ .collect(Collectors.toList());
assertEquals(expectedTrustedNodes, actualTrustedNodes);
Set<String> actualTrustedNetworks = actual.stream()
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AllocationSimulator.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AllocationSimulator.java
index 78fbca554f0..242bb7df146 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AllocationSimulator.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AllocationSimulator.java
@@ -118,7 +118,6 @@ public class AllocationSimulator {
public void addCluster(String task, int count, Flavor flavor, String id) {
// TODO: Implement
- NodeSpec.CountNodeSpec nodeSpec = new NodeSpec.CountNodeSpec(count, flavor, false, true);
nodes = new NodeList(nodes.asList());
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java
index 4ab9beacf15..9e61cbe98ab 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacityTest.java
@@ -97,17 +97,17 @@ public class DockerHostCapacityTest {
@Test
public void getCapacityTotal() {
ResourceCapacity total = capacity.getCapacityTotal();
- assertEquals(21.0, total.getCpu(), 0.1);
- assertEquals(30.0, total.getMemory(), 0.1);
- assertEquals(36.0, total.getDisk(), 0.1);
+ assertEquals(21.0, total.vcpu(), 0.1);
+ assertEquals(30.0, total.memoryGb(), 0.1);
+ assertEquals(36.0, total.diskGb(), 0.1);
}
@Test
public void getFreeCapacityTotal() {
ResourceCapacity totalFree = capacity.getFreeCapacityTotal();
- assertEquals(15.0, totalFree.getCpu(), 0.1);
- assertEquals(14.0, totalFree.getMemory(), 0.1);
- assertEquals(24.0, totalFree.getDisk(), 0.1);
+ assertEquals(15.0, totalFree.vcpu(), 0.1);
+ assertEquals(14.0, totalFree.memoryGb(), 0.1);
+ assertEquals(24.0, totalFree.diskGb(), 0.1);
}
@Test
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
index 0fdf857e97f..003593a7d1d 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DockerProvisioningTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeType;
@@ -36,7 +37,7 @@ import static org.junit.Assert.fail;
*/
public class DockerProvisioningTest {
- private static final String dockerFlavor = "dockerSmall";
+ private static final NodeResources dockerFlavor = new NodeResources(1, 1, 1);
@Test
public void docker_application_deployment() {
@@ -55,7 +56,7 @@ public class DockerProvisioningTest {
NodeList nodes = tester.getNodes(application1, Node.State.active);
assertEquals(nodeCount, nodes.size());
- assertEquals(dockerFlavor, nodes.asList().get(0).flavor().canonicalName());
+ assertEquals(dockerFlavor, nodes.asList().get(0).flavor().resources());
// Upgrade Vespa version on nodes
Version upgradedWantedVespaVersion = Version.fromString("6.40");
@@ -65,7 +66,7 @@ public class DockerProvisioningTest {
tester.activate(application1, new HashSet<>(upgradedHosts));
NodeList upgradedNodes = tester.getNodes(application1, Node.State.active);
assertEquals(nodeCount, upgradedNodes.size());
- assertEquals(dockerFlavor, upgradedNodes.asList().get(0).flavor().canonicalName());
+ assertEquals(dockerFlavor, upgradedNodes.asList().get(0).flavor().resources());
assertEquals(hosts, upgradedHosts);
}
@@ -74,7 +75,7 @@ public class DockerProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
ApplicationId zoneApplication = tester.makeApplicationId();
- List<Node> parents = tester.makeReadyVirtualDockerHosts(10, "large");
+ List<Node> parents = tester.makeReadyVirtualDockerHosts(10, new NodeResources(2, 2, 2));
for (Node parent : parents)
tester.makeReadyVirtualDockerNodes(1, dockerFlavor, parent.hostname());
@@ -204,7 +205,7 @@ public class DockerProvisioningTest {
}
catch (Exception e) {
assertEquals("No room for 3 nodes as 2 of 4 hosts are exclusive",
- "Could not satisfy request for 3 nodes of flavor 'dockerSmall' for container cluster 'myContainer' group 0 6.39 in tenant1.app1: Not enough nodes available due to host exclusivity constraints.",
+ "Could not satisfy request for 3 nodes with [vcpu: 1.0, memory: 1.0 Gb, disk 1.0 Gb] for container cluster 'myContainer' group 0 6.39 in tenant1.app1: Not enough nodes available due to host exclusivity constraints.",
e.getMessage());
}
@@ -225,7 +226,7 @@ public class DockerProvisioningTest {
NodeList nodes = tester.getNodes(application1, Node.State.active);
assertEquals(1, nodes.size());
- assertEquals(dockerFlavor, nodes.asList().get(0).flavor().canonicalName());
+ assertEquals("[vcpu: 1.0, memory: 1.0 Gb, disk 1.0 Gb]", nodes.asList().get(0).flavor().canonicalName());
}
private Set<String> hostsOf(NodeList nodes) {
@@ -235,7 +236,7 @@ public class DockerProvisioningTest {
private void prepareAndActivate(ApplicationId application, int nodeCount, boolean exclusive, ProvisioningTester tester) {
Set<HostSpec> hosts = new HashSet<>(tester.prepare(application,
ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Version.fromString("6.39"), exclusive, Collections.emptySet()),
- Capacity.fromNodeCount(nodeCount, Optional.of(dockerFlavor), false, true),
+ Capacity.fromCount(nodeCount, Optional.of(dockerFlavor), false, true),
1));
tester.activate(application, hosts);
}
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 74541677714..76425fb5d4a 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
@@ -9,6 +9,7 @@ import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.OutOfCapacityException;
@@ -64,7 +65,7 @@ public class DynamicDockerAllocationTest {
tester.makeReadyNodes(4, "host-small", NodeType.host, 32);
deployZoneApp(tester);
List<Node> dockerHosts = tester.nodeRepository().getNodes(NodeType.host, Node.State.active);
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
+ NodeResources flavor = new NodeResources(1, 1, 1);
// Application 1
ApplicationId application1 = makeApplicationId("t1", "a1");
@@ -107,7 +108,7 @@ public class DynamicDockerAllocationTest {
tester.makeReadyNodes(5, "host-small", NodeType.host, 32);
deployZoneApp(tester);
List<Node> dockerHosts = tester.nodeRepository().getNodes(NodeType.host, Node.State.active);
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
+ NodeResources flavor = new NodeResources(1, 1, 1);
// Application 1
ApplicationId application1 = makeApplicationId("t1", "a1");
@@ -164,7 +165,7 @@ public class DynamicDockerAllocationTest {
tester.makeReadyNodes(2, "host-small", NodeType.host, 32);
deployZoneApp(tester);
List<Node> dockerHosts = tester.nodeRepository().getNodes(NodeType.host, Node.State.active);
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
+ NodeResources flavor = new NodeResources(1, 1, 1);
// Application 1
ApplicationId application1 = makeApplicationId("t1", "a1");
@@ -190,11 +191,10 @@ public class DynamicDockerAllocationTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).flavorsConfig(flavorsConfig()).build();
tester.makeReadyNodes(5, "host-small", NodeType.host, 32);
deployZoneApp(tester);
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-1");
//Deploy an application having 6 nodes (3 nodes in 2 groups). We only have 5 docker hosts available
ApplicationId application1 = tester.makeApplicationId();
- tester.prepare(application1, clusterSpec("myContent.t1.a1"), 6, 2, flavor.canonicalName());
+ tester.prepare(application1, clusterSpec("myContent.t1.a1"), 6, 2, new NodeResources(1, 1, 1));
fail("Two groups have been allocated to the same parent host");
}
@@ -212,27 +212,27 @@ public class DynamicDockerAllocationTest {
ApplicationId application1 = tester.makeApplicationId();
tester.makeReadyNodes(5, "host-small", NodeType.host, 32);
deployZoneApp(tester);
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3");
+ NodeResources flavor = new NodeResources(1, 1, 1);
// Deploy initial state (can max deploy 3 nodes due to redundancy requirements)
ClusterSpec clusterSpec = clusterSpec("myContent.t1.a1");
- List<HostSpec> hosts = tester.prepare(application1, clusterSpec, 3, 1, flavor.canonicalName());
+ List<HostSpec> hosts = tester.prepare(application1, clusterSpec, 3, 1, flavor);
tester.activate(application1, ImmutableSet.copyOf(hosts));
DockerHostCapacity capacity = new DockerHostCapacity(tester.nodeRepository().getNodes(Node.State.values()));
- assertThat(capacity.freeCapacityInFlavorEquivalence(flavor), greaterThan(0));
+ assertThat(capacity.freeCapacityInFlavorEquivalence(new Flavor(flavor)), greaterThan(0));
List<Node> initialSpareCapacity = findSpareCapacity(tester);
assertThat(initialSpareCapacity.size(), is(2));
try {
- hosts = tester.prepare(application1, clusterSpec, 4, 1, flavor.canonicalName());
+ hosts = tester.prepare(application1, clusterSpec, 4, 1, flavor);
fail("Was able to deploy with 4 nodes, should not be able to use spare capacity");
} catch (OutOfCapacityException e) {
}
tester.fail(hosts.get(0));
- hosts = tester.prepare(application1, clusterSpec, 3, 1, flavor.canonicalName());
+ hosts = tester.prepare(application1, clusterSpec, 3, 1, flavor);
tester.activate(application1, ImmutableSet.copyOf(hosts));
List<Node> finalSpareCapacity = findSpareCapacity(tester);
@@ -245,10 +245,8 @@ public class DynamicDockerAllocationTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.perf, RegionName.from("us-east"))).flavorsConfig(flavorsConfig()).build();
tester.makeReadyNodes(3, "host-small", NodeType.host, 32);
deployZoneApp(tester);
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3");
-
ApplicationId application1 = tester.makeApplicationId();
- List<HostSpec> hosts = tester.prepare(application1, clusterSpec("myContent.t1.a1"), 3, 1, flavor.canonicalName());
+ List<HostSpec> hosts = tester.prepare(application1, clusterSpec("myContent.t1.a1"), 3, 1, new NodeResources(1, 1, 1));
tester.activate(application1, ImmutableSet.copyOf(hosts));
List<Node> initialSpareCapacity = findSpareCapacity(tester);
@@ -262,8 +260,7 @@ public class DynamicDockerAllocationTest {
deployZoneApp(tester);
ApplicationId application = tester.makeApplicationId();
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3");
- tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, flavor.canonicalName());
+ tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, new NodeResources(1, 1, 1));
}
@Test
@@ -273,8 +270,7 @@ public class DynamicDockerAllocationTest {
deployZoneApp(tester);
ApplicationId application = tester.makeApplicationId();
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("d-3");
- List<HostSpec> hosts = tester.prepare(application, clusterSpec("myContent.t1.a1"), 2, 1, flavor.canonicalName());
+ List<HostSpec> hosts = tester.prepare(application, clusterSpec("myContent.t1.a1"), 2, 1, new NodeResources(1, 1, 1));
tester.activate(application, hosts);
List<Node> activeNodes = tester.nodeRepository().getNodes(application);
@@ -286,13 +282,13 @@ public class DynamicDockerAllocationTest {
return ApplicationId.from(tenant, appName, "default");
}
- private void deployApp(ApplicationId id, ClusterSpec spec, Flavor flavor, ProvisioningTester tester, int nodeCount) {
- List<HostSpec> hostSpec = tester.prepare(id, spec, nodeCount, 1, flavor.canonicalName());
+ private void deployApp(ApplicationId id, ClusterSpec spec, NodeResources flavor, ProvisioningTester tester, int nodeCount) {
+ List<HostSpec> hostSpec = tester.prepare(id, spec, nodeCount, 1, flavor);
tester.activate(id, new HashSet<>(hostSpec));
}
- private void addAndAssignNode(ApplicationId id, String hostname, String parentHostname, ClusterSpec clusterSpec, Flavor flavor, int index, ProvisioningTester tester) {
- Node node1a = Node.create("open1", Collections.singleton("127.0.0.100"), new HashSet<>(), hostname, Optional.of(parentHostname), Optional.empty(), flavor, NodeType.tenant);
+ private void addAndAssignNode(ApplicationId id, String hostname, String parentHostname, ClusterSpec clusterSpec, NodeResources flavor, int index, ProvisioningTester tester) {
+ Node node1a = Node.create("open1", Collections.singleton("127.0.0.100"), new HashSet<>(), hostname, Optional.of(parentHostname), Optional.empty(), new Flavor(flavor), NodeType.tenant);
ClusterMembership clusterMembership1 = ClusterMembership.from(
clusterSpec.with(Optional.of(ClusterSpec.Group.from(0))), index); // Need to add group here so that group is serialized in node allocation
Node node1aAllocation = node1a.allocate(id, clusterMembership1, Instant.now());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
index 60e9289b9bf..121819700ea 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerProvisionTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.flags.Flags;
@@ -44,10 +45,10 @@ public class DynamicDockerProvisionTest {
assertEquals(0, tester.nodeRepository().list().size());
ApplicationId application1 = tester.makeApplicationId();
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("dockerSmall");
+ NodeResources flavor = new NodeResources(1, 1, 1);
mockHostProvisioner(hostProvisioner, tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("small"));
- List<HostSpec> hostSpec = tester.prepare(application1, clusterSpec("myContent.t1.a1"), 4, 1, flavor.canonicalName());
+ List<HostSpec> hostSpec = tester.prepare(application1, clusterSpec("myContent.t1.a1"), 4, 1, flavor);
verify(hostProvisioner).provisionHosts(List.of(100, 101, 102, 103), flavor);
// Total of 8 nodes should now be in node-repo, 4 hosts in state provisioned, and 4 reserved nodes
@@ -64,21 +65,21 @@ public class DynamicDockerProvisionTest {
deployZoneApp(tester);
ApplicationId application = tester.makeApplicationId();
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("dockerSmall");
+ NodeResources flavor = new NodeResources(1, 1, 1);
mockHostProvisioner(hostProvisioner, tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("small"));
- tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, flavor.canonicalName());
+ tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, flavor);
verify(hostProvisioner).provisionHosts(List.of(100, 101), flavor);
}
@Test
public void allocates_to_hosts_already_hosting_nodes_by_this_tenant() {
ApplicationId application = tester.makeApplicationId();
- Flavor flavor = tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("dockerSmall");
+ NodeResources flavor = new NodeResources(1, 1, 1);
List<Integer> expectedProvisionIndexes = List.of(100, 101);
mockHostProvisioner(hostProvisioner, tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("large"));
- tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, flavor.canonicalName());
+ tester.prepare(application, clusterSpec("myContent.t2.a2"), 2, 1, flavor);
verify(hostProvisioner).provisionHosts(expectedProvisionIndexes, flavor);
// Ready the provisioned hosts, add an IP addreses to pool and activate them
@@ -92,7 +93,7 @@ public class DynamicDockerProvisionTest {
deployZoneApp(tester);
mockHostProvisioner(hostProvisioner, tester.nodeRepository().getAvailableFlavors().getFlavorOrThrow("small"));
- tester.prepare(application, clusterSpec("another-id"), 2, 1, flavor.canonicalName());
+ tester.prepare(application, clusterSpec("another-id"), 2, 1, flavor);
// Verify there was only 1 call to provision hosts (during the first prepare)
verify(hostProvisioner).provisionHosts(any(), any());
@@ -124,9 +125,9 @@ public class DynamicDockerProvisionTest {
private static void mockHostProvisioner(HostProvisioner hostProvisioner, Flavor hostFlavor) {
doAnswer(invocation -> {
List<Integer> provisionIndexes = (List<Integer>) invocation.getArguments()[0];
- Flavor nodeFlavor = (Flavor) invocation.getArguments()[1];
+ NodeResources nodeResources = (NodeResources) invocation.getArguments()[1];
return provisionIndexes.stream()
- .map(i -> new ProvisionedHost("id-" + i, "host-" + i, hostFlavor, "host-" + i + "-1", nodeFlavor))
+ .map(i -> new ProvisionedHost("id-" + i, "host-" + i, hostFlavor, "host-" + i + "-1", nodeResources))
.collect(Collectors.toList());
}).when(hostProvisioner).provisionHosts(any(), any());
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
index 4f7e09d0bd7..58c0b3ed9cc 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/LoadBalancerProvisionerTest.java
@@ -5,6 +5,7 @@ import com.google.common.collect.Iterators;
import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostName;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.RotationName;
@@ -136,10 +137,10 @@ public class LoadBalancerProvisionerTest {
}
private Set<HostSpec> prepare(ApplicationId application, ClusterSpec... specs) {
- tester.makeReadyNodes(specs.length * 2, "default");
+ tester.makeReadyNodes(specs.length * 2, "d-1-1-1");
Set<HostSpec> allNodes = new LinkedHashSet<>();
for (ClusterSpec spec : specs) {
- allNodes.addAll(tester.prepare(application, spec, 2, 1, "default"));
+ allNodes.addAll(tester.prepare(application, spec, 2, 1, new NodeResources(1, 1, 1)));
}
return allNodes;
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
index b266f546b49..14720d4215c 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/MultigroupProvisioningTest.java
@@ -149,6 +149,8 @@ public class MultigroupProvisioningTest {
private void deploy(ApplicationId application, int nodeCount, int groupCount, ProvisioningTester tester) {
deploy(application, Capacity.fromNodeCount(nodeCount, Optional.of("default"), false, true), groupCount, tester);
}
+
+ @SuppressWarnings("deprecation") // TODO: Remove
private void deploy(ApplicationId application, Capacity capacity, int wantedGroups, ProvisioningTester tester) {
int nodeCount = capacity.nodeCount();
String flavor = capacity.flavor().get();
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizerTest.java
index f7caea060ad..b2b80c6f4e4 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizerTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Flavor;
import com.yahoo.config.provision.NodeFlavors;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provisioning.FlavorsConfig;
import com.yahoo.vespa.hosted.provision.Node;
@@ -31,20 +32,20 @@ public class NodePrioritizerTest {
public void relocated_nodes_are_preferred() {
List<Node> nodes = new ArrayList<>();
Node parent = createParent("parent");
- Node b = createNode(parent, "b", "d2");
+ Node b = createNode(parent, "b", new NodeResources(2, 2, 2));
nodes.add(b);
// Only one node - should be obvious what to prefer
Assert.assertTrue(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, b, parent));
// Two equal nodes - choose lexically
- Node a = createNode(parent, "a", "d2");
+ Node a = createNode(parent, "a", new NodeResources(2, 2, 2));
nodes.add(a);
Assert.assertTrue(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, a, parent));
Assert.assertFalse(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, b, parent));
// Smallest node should be preferred
- Node c = createNode(parent, "c", "d1");
+ Node c = createNode(parent, "c", new NodeResources(1, 1, 1));
nodes.add(c);
Assert.assertTrue(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, c, parent));
@@ -53,7 +54,7 @@ public class NodePrioritizerTest {
c = c.allocate(ApplicationId.defaultId(), ClusterMembership.from(spec, 0), Instant.now());
nodes.remove(c);
nodes.add(c);
- Node d = createNode(parent, "d", "d1");
+ Node d = createNode(parent, "d", new NodeResources(1, 1, 1));
nodes.add(d);
Assert.assertTrue(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, d, parent));
Assert.assertFalse(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, c, parent));
@@ -67,9 +68,9 @@ public class NodePrioritizerTest {
Assert.assertTrue(NodePrioritizer.isPreferredNodeToBeRelocated(nodes, d, parent));
}
- private static Node createNode(Node parent, String hostname, String flavor) {
+ private static Node createNode(Node parent, String hostname, NodeResources resources) {
return Node.createDockerNode(Collections.singleton("127.0.0.1"), new HashSet<>(), hostname, Optional.of(parent.hostname()),
- flavors.getFlavorOrThrow(flavor), NodeType.tenant);
+ resources, NodeType.tenant);
}
private static Node createParent(String hostname) {
@@ -80,8 +81,6 @@ public class NodePrioritizerTest {
private static FlavorsConfig flavorsConfig() {
FlavorConfigBuilder b = new FlavorConfigBuilder();
b.addFlavor("host-large", 6., 6., 6, Flavor.Type.BARE_METAL);
- b.addFlavor("d1", 1, 1., 1, Flavor.Type.DOCKER_CONTAINER);
- b.addFlavor("d2", 2, 2., 2, Flavor.Type.DOCKER_CONTAINER);
return b.build();
}
}
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 f1caa52a1b5..2c237d94715 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
@@ -10,10 +10,12 @@ import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NodeFlavors;
+import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.OutOfCapacityException;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.TenantName;
@@ -65,37 +67,37 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
ApplicationId application2 = tester.makeApplicationId();
- tester.makeReadyNodes(21, "default");
+ tester.makeReadyNodes(21, "d-1-1-1");
// deploy
- SystemState state1 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state1 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state1.allHosts);
// redeploy
- SystemState state2 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state2 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
state2.assertEquals(state1);
tester.activate(application1, state2.allHosts);
// deploy another application
- SystemState state1App2 = prepare(application2, 2, 2, 3, 3, "default", tester);
+ SystemState state1App2 = prepare(application2, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
assertFalse("Hosts to different apps are disjunct", state1App2.allHosts.removeAll(state1.allHosts));
tester.activate(application2, state1App2.allHosts);
// prepare twice
- SystemState state3 = prepare(application1, 2, 2, 3, 3, "default", tester);
- SystemState state4 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state3 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
+ SystemState state4 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
state3.assertEquals(state2);
state4.assertEquals(state3);
tester.activate(application1, state4.allHosts);
// remove nodes before deploying
- SystemState state5 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state5 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
HostSpec removed = tester.removeOne(state5.allHosts);
tester.activate(application1, state5.allHosts);
assertEquals(removed.hostname(), tester.nodeRepository().getNodes(application1, Node.State.inactive).get(0).hostname());
// remove some of the clusters
- SystemState state6 = prepare(application1, 0, 2, 0, 3, "default", tester);
+ SystemState state6 = prepare(application1, 0, 2, 0, 3, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state6.allHosts);
assertEquals(5, tester.getNodes(application1, Node.State.active).size());
assertEquals(5, tester.getNodes(application1, Node.State.inactive).size());
@@ -114,14 +116,14 @@ public class ProvisioningTest {
HostSpec failed = tester.removeOne(state1App2.allHosts);
tester.fail(failed);
assertEquals(9, tester.getNodes(application2, Node.State.active).size());
- SystemState state2App2 = prepare(application2, 2, 2, 3, 3, "default", tester);
+ SystemState state2App2 = prepare(application2, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
assertFalse("Hosts to different apps are disjunct", state2App2.allHosts.removeAll(state1.allHosts));
assertEquals("A new node was reserved to replace the failed one", 10, state2App2.allHosts.size());
assertFalse("The new host is not the failed one", state2App2.allHosts.contains(failed));
tester.activate(application2, state2App2.allHosts);
// deploy first app again
- SystemState state7 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state7 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
state7.assertEquals(state1);
tester.activate(application1, state7.allHosts);
assertEquals(0, tester.getNodes(application1, Node.State.inactive).size());
@@ -145,10 +147,10 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
- tester.makeReadyNodes(4, "default");
+ tester.makeReadyNodes(4, "d-1-1-1");
// deploy
- SystemState state1 = prepare(application1, 1, 1, 1, 1, "default", tester);
+ SystemState state1 = prepare(application1, 1, 1, 1, 1, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state1.allHosts);
HostSpec host1 = state1.container0.iterator().next();
@@ -157,7 +159,7 @@ public class ProvisioningTest {
tester.nodeRepository().write(node1.with(node1.status().withVespaVersion(Version.fromString("1.2.3"))));
// redeploy
- SystemState state2 = prepare(application1, 1, 1, 1, 1, "default", tester);
+ SystemState state2 = prepare(application1, 1, 1, 1, 1, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state2.allHosts);
host1 = state2.container0.iterator().next();
@@ -170,20 +172,20 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
- tester.makeReadyNodes(24, "default");
+ tester.makeReadyNodes(24, "d-1-1-1");
// deploy
- SystemState state1 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state1 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state1.allHosts);
// redeploy with increased sizes
- SystemState state2 = prepare(application1, 3, 4, 4, 5, "default", tester);
+ SystemState state2 = prepare(application1, 3, 4, 4, 5, new NodeResources(1, 1, 1), tester);
state2.assertExtends(state1);
assertEquals("New nodes are reserved", 6, tester.getNodes(application1, Node.State.reserved).size());
tester.activate(application1, state2.allHosts);
// decrease again
- SystemState state3 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state3 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state3.allHosts);
assertEquals("Superfluous container nodes are deactivated",
3-2 + 4-2, tester.getNodes(application1, Node.State.inactive).size());
@@ -191,7 +193,7 @@ public class ProvisioningTest {
4-3 + 5-3, tester.getNodes(application1, Node.State.active).retired().size());
// increase even more, and remove one node before deploying
- SystemState state4 = prepare(application1, 4, 5, 5, 6, "default", tester);
+ SystemState state4 = prepare(application1, 4, 5, 5, 6, new NodeResources(1, 1, 1), tester);
assertEquals("Inactive nodes are reused", 0, tester.getNodes(application1, Node.State.inactive).size());
assertEquals("Earlier retired nodes are not unretired before activate",
4-3 + 5-3, tester.getNodes(application1, Node.State.active).retired().size());
@@ -207,7 +209,7 @@ public class ProvisioningTest {
0, tester.getNodes(application1, Node.State.active).retired().size());
// decrease again
- SystemState state5 = prepare(application1, 2, 2, 3, 3, "default", tester);
+ SystemState state5 = prepare(application1, 2, 2, 3, 3, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state5.allHosts);
assertEquals("Superfluous container nodes are also deactivated",
4-2 + 5-2 + 1, tester.getNodes(application1, Node.State.inactive).size()); //
@@ -215,13 +217,13 @@ public class ProvisioningTest {
5-3 + 6-3 - 1, tester.getNodes(application1, Node.State.active).retired().size());
// increase content slightly
- SystemState state6 = prepare(application1, 2, 2, 4, 3, "default", tester);
+ SystemState state6 = prepare(application1, 2, 2, 4, 3, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state6.allHosts);
assertEquals("One content node is unretired",
5-4 + 6-3 - 1, tester.getNodes(application1, Node.State.active).retired().size());
// Then reserve more
- SystemState state7 = prepare(application1, 8, 2, 2, 2, "default", tester);
+ SystemState state7 = prepare(application1, 8, 2, 2, 2, new NodeResources(1, 1, 1), tester);
// delete app
NestedTransaction removeTransaction = new NestedTransaction();
@@ -237,27 +239,30 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
- tester.makeReadyNodes(12, "small");
- tester.makeReadyNodes(16, "large");
+ tester.makeReadyNodes(12, "d-1-1-1");
+ tester.makeReadyNodes(16, "d-2-2-2");
+
+ NodeResources small = new NodeResources(1, 1, 1);
+ NodeResources large = new NodeResources(2, 2, 2);
// deploy
- SystemState state1 = prepare(application1, 2, 2, 4, 4, "small", tester);
+ SystemState state1 = prepare(application1, 2, 2, 4, 4, small, tester);
tester.activate(application1, state1.allHosts);
// redeploy with reduced size (to cause us to have retired nodes before switching flavor)
- SystemState state2 = prepare(application1, 2, 2, 3, 3, "small", tester);
+ SystemState state2 = prepare(application1, 2, 2, 3, 3, small, tester);
tester.activate(application1, state2.allHosts);
// redeploy with increased sizes and new flavor
- SystemState state3 = prepare(application1, 3, 4, 4, 5, "large", tester);
+ SystemState state3 = prepare(application1, 3, 4, 4, 5, large, tester);
assertEquals("New nodes are reserved", 16, tester.nodeRepository().getNodes(application1, Node.State.reserved).size());
tester.activate(application1, state3.allHosts);
- assertEquals("'small' container nodes are retired because we are swapping the entire cluster",
- 2 + 2, tester.getNodes(application1, Node.State.active).retired().type(ClusterSpec.Type.container).flavor("small").size());
- assertEquals("'small' content nodes are retired",
- 4 + 4, tester.getNodes(application1, Node.State.active).retired().type(ClusterSpec.Type.content).flavor("small").size());
- assertEquals("No 'large' content nodes are retired",
- 0, tester.getNodes(application1, Node.State.active).retired().flavor("large").size());
+ assertEquals("small container nodes are retired because we are swapping the entire cluster",
+ 2 + 2, tester.getNodes(application1, Node.State.active).retired().type(ClusterSpec.Type.container).resources(small).size());
+ assertEquals("'small content nodes are retired",
+ 4 + 4, tester.getNodes(application1, Node.State.active).retired().type(ClusterSpec.Type.content).resources(small).size());
+ assertEquals("No large content nodes are retired",
+ 0, tester.getNodes(application1, Node.State.active).retired().resources(large).size());
}
// TODO: Enable when this feature is re-enabled
@@ -268,14 +273,14 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
- tester.makeReadyNodes(14, "dockerLarge");
+ tester.makeReadyNodes(14, "d-2-2-2", NodeType.host);
// deploy
- SystemState state1 = prepare(application1, 2, 2, 4, 4, "dockerLarge", tester);
+ SystemState state1 = prepare(application1, 2, 2, 4, 4, new NodeResources(2, 2, 2), tester);
tester.activate(application1, state1.allHosts);
// redeploy with smaller docker flavor - causes in-place flavor change
- SystemState state2 = prepare(application1, 2, 2, 4, 4, "dockerSmall", tester);
+ SystemState state2 = prepare(application1, 2, 2, 4, 4, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state2.allHosts);
assertEquals(12, tester.getNodes(application1, Node.State.active).size());
@@ -320,11 +325,13 @@ public class ProvisioningTest {
tester.makeReadyNodes(8, "large-variant");
// deploy with flavor which will be fulfilled by some old and new nodes
- SystemState state1 = prepare(application1, 2, 2, 4, 4, "old-large1", tester);
+ SystemState state1 = prepare(application1, 2, 2, 4, 4,
+ NodeResources.fromLegacyName("old-large1"), tester);
tester.activate(application1, state1.allHosts);
// redeploy with increased sizes, this will map to the remaining old/new nodes
- SystemState state2 = prepare(application1, 3, 4, 4, 5, "old-large2", tester);
+ SystemState state2 = prepare(application1, 3, 4, 4, 5,
+ NodeResources.fromLegacyName("old-large2"), tester);
assertEquals("New nodes are reserved", 4, tester.getNodes(application1, Node.State.reserved).size());
tester.activate(application1, state2.allHosts);
assertEquals("All nodes are used",
@@ -333,12 +340,14 @@ public class ProvisioningTest {
0, tester.getNodes(application1, Node.State.active).retired().size());
// This is a noop as we are already using large nodes and nodes which replace large
- SystemState state3 = prepare(application1, 3, 4, 4, 5, "large", tester);
+ SystemState state3 = prepare(application1, 3, 4, 4, 5,
+ NodeResources.fromLegacyName("large"), tester);
assertEquals("Noop", 0, tester.getNodes(application1, Node.State.reserved).size());
tester.activate(application1, state3.allHosts);
try {
- SystemState state4 = prepare(application1, 3, 4, 4, 5, "large-variant", tester);
+ SystemState state4 = prepare(application1, 3, 4, 4, 5,
+ NodeResources.fromLegacyName("large-variant"), tester);
fail("Should fail as we don't have that many large-variant nodes");
}
catch (OutOfCapacityException expected) {
@@ -346,7 +355,8 @@ public class ProvisioningTest {
// make enough nodes to complete the switch to large-variant
tester.makeReadyNodes(8, "large-variant");
- SystemState state4 = prepare(application1, 3, 4, 4, 5, "large-variant", tester);
+ SystemState state4 = prepare(application1, 3, 4, 4, 5,
+ NodeResources.fromLegacyName("large-variant"), tester);
assertEquals("New 'large-variant' nodes are reserved", 8, tester.getNodes(application1, Node.State.reserved).size());
tester.activate(application1, state4.allHosts);
// (we can not check for the precise state here without carrying over from earlier as the distribution of
@@ -359,22 +369,25 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
- tester.makeReadyNodes(5, "default");
+ tester.makeReadyNodes(5, "d-1-1-1");
// deploy
- SystemState state1 = prepare(application1, 2, 0, 3, 0, "default", tester);
+ SystemState state1 = prepare(application1, 2, 0, 3, 0,
+ new NodeResources(1, 1, 1), tester);
tester.activate(application1, state1.allHosts);
// redeploy a too large application
try {
- SystemState state2 = prepare(application1, 3, 0, 3, 0, "default", tester);
+ SystemState state2 = prepare(application1, 3, 0, 3, 0,
+ new NodeResources(1, 1, 1), tester);
fail("Expected out of capacity exception");
}
catch (OutOfCapacityException expected) {
}
// deploy first state again
- SystemState state3 = prepare(application1, 2, 0, 3, 0, "default", tester);
+ SystemState state3 = prepare(application1, 2, 0, 3, 0,
+ new NodeResources(1, 1, 1), tester);
tester.activate(application1, state3.allHosts);
}
@@ -383,8 +396,9 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(4, "default");
- SystemState state = prepare(application, 2, 2, 3, 3, "default", tester);
+ tester.makeReadyNodes(4, "d-1-1-1");
+ SystemState state = prepare(application, 2, 2, 3, 3,
+ new NodeResources(1, 1, 1), tester);
assertEquals(4, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -394,8 +408,8 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(4, "default");
- SystemState state = prepare(application, 2, 2, 3, 3, "default", Version.fromString("6.91"), tester);
+ tester.makeReadyNodes(4, "d-1-1-1");
+ SystemState state = prepare(application, 2, 2, 3, 3, new NodeResources(1, 1, 1), Version.fromString("6.91"), tester);
assertEquals(4, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -405,8 +419,9 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.test, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(4, "default");
- SystemState state = prepare(application, 2, 2, 3, 3, "default", tester);
+ tester.makeReadyNodes(4, "d-1-1-1");
+ SystemState state = prepare(application, 2, 2, 3, 3,
+ new NodeResources(1, 1, 1), tester);
assertEquals(4, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -416,8 +431,9 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(10, "default");
- prepare(application, 1, 2, 3, 3, "default", tester);
+ tester.makeReadyNodes(10, "d-1-1-1");
+ prepare(application, 1, 2, 3, 3,
+ new NodeResources(1, 1, 1), tester);
}
/** Dev always uses the zone default flavor */
@@ -426,8 +442,9 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(4, "default");
- SystemState state = prepare(application, 2, 2, 3, 3, "large", tester);
+ tester.makeReadyNodes(4, "d-2-2-2");
+ SystemState state = prepare(application, 2, 2, 3, 3,
+ new NodeResources(2, 2, 2), tester);
assertEquals(4, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -438,8 +455,9 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.test, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(4, "default");
- SystemState state = prepare(application, 2, 2, 3, 3, "large", tester);
+ tester.makeReadyNodes(4, "d-2-2-2");
+ SystemState state = prepare(application, 2, 2, 3, 3,
+ new NodeResources(2, 2, 2), tester);
assertEquals(4, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -449,8 +467,9 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.staging, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(14, "default");
- SystemState state = prepare(application, 1, 1, 1, 64, "default", tester); // becomes 1, 1, 1, 6
+ tester.makeReadyNodes(14, "d-1-1-1");
+ SystemState state = prepare(application, 1, 1, 1, 64,
+ new NodeResources(1, 1, 1), tester); // becomes 1, 1, 1, 6
assertEquals(9, state.allHosts.size());
tester.activate(application, state.allHosts);
}
@@ -459,9 +478,10 @@ public class ProvisioningTest {
public void activate_after_reservation_timeout() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- tester.makeReadyNodes(10, "default");
+ tester.makeReadyNodes(10, "d-1-1-1");
ApplicationId application = tester.makeApplicationId();
- SystemState state = prepare(application, 2, 2, 3, 3, "default", tester);
+ SystemState state = prepare(application, 2, 2, 3, 3,
+ new NodeResources(1, 1, 1), tester);
// Simulate expiry
NestedTransaction deactivateTransaction = new NestedTransaction();
@@ -481,10 +501,11 @@ public class ProvisioningTest {
public void out_of_capacity() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
- tester.makeReadyNodes(9, "default"); // need 2+2+3+3=10
+ tester.makeReadyNodes(9, "d-1-1-1"); // need 2+2+3+3=10
ApplicationId application = tester.makeApplicationId();
try {
- prepare(application, 2, 2, 3, 3, "default", tester);
+ prepare(application, 2, 2, 3, 3,
+ new NodeResources(1, 1, 1), tester);
fail("Expected exception");
}
catch (OutOfCapacityException e) {
@@ -495,7 +516,7 @@ public class ProvisioningTest {
@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, "default");
+ tester.makeReadyNodes(4, "d-1-1-1");
ApplicationId application = tester.makeApplicationId();
ClusterSpec cluster = ClusterSpec.request(ClusterSpec.Type.content,
ClusterSpec.Id.from("music"),
@@ -513,11 +534,12 @@ public class ProvisioningTest {
tester.makeReadyNodes( 9, "large"); // need 2+2+3+3=10
ApplicationId application = tester.makeApplicationId();
try {
- prepare(application, 2, 2, 3, 3, "large", tester);
+ prepare(application, 2, 2, 3, 3,
+ NodeResources.fromLegacyName("large"), tester);
fail("Expected exception");
}
catch (OutOfCapacityException e) {
- assertTrue(e.getMessage().startsWith("Could not satisfy request for 3 nodes of flavor 'large'"));
+ assertTrue(e.getMessage().startsWith("Could not satisfy request for 3 nodes with flavor 'large'"));
}
}
@@ -537,8 +559,8 @@ public class ProvisioningTest {
ApplicationId application = tester.makeApplicationId();
try {
- prepare(application, 2, 0, 2, 0, flavorToRetire,
- tester);
+ prepare(application, 2, 0, 2, 0,
+ NodeResources.fromLegacyName(flavorToRetire), tester);
fail("Expected exception");
} catch (OutOfCapacityException e) {
assertTrue(e.getMessage().startsWith("Could not satisfy request"));
@@ -551,11 +573,12 @@ public class ProvisioningTest {
ApplicationId application = tester.makeApplicationId();
// Flag all nodes for retirement
- List<Node> readyNodes = tester.makeReadyNodes(5, "default");
+ List<Node> readyNodes = tester.makeReadyNodes(5, "d-1-1-1");
readyNodes.forEach(node -> tester.patchNode(node.with(node.status().withWantToRetire(true))));
try {
- prepare(application, 2, 0, 2, 0, "default", tester);
+ prepare(application, 2, 0, 2, 0,
+ new NodeResources(1, 1, 1), tester);
fail("Expected exception");
} catch (OutOfCapacityException e) {
assertTrue(e.getMessage().startsWith("Could not satisfy request"));
@@ -568,7 +591,8 @@ public class ProvisioningTest {
ApplicationId application = tester.makeApplicationId();
try {
- prepare(application, 2, 2, 3, 3, "nonexisting", tester);
+ prepare(application, 2, 2, 3, 3,
+ NodeResources.fromLegacyName("nonexisting"), tester);
fail("Expected exception");
}
catch (IllegalArgumentException e) {
@@ -582,14 +606,14 @@ public class ProvisioningTest {
ApplicationId application1 = tester.makeApplicationId();
- tester.makeReadyNodes(14, "default");
+ tester.makeReadyNodes(14, "d-1-1-1");
// deploy
- SystemState state1 = prepare(application1, 3, 3, 4, 4, "default", tester);
+ SystemState state1 = prepare(application1, 3, 3, 4, 4, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state1.allHosts);
// decrease cluster sizes
- SystemState state2 = prepare(application1, 2, 2, 2, 2, "default", tester);
+ SystemState state2 = prepare(application1, 2, 2, 2, 2, new NodeResources(1, 1, 1), tester);
tester.activate(application1, state2.allHosts);
// content0
@@ -607,12 +631,12 @@ public class ProvisioningTest {
@Test
public void application_deployment_prefers_cheapest_stock_nodes() {
- assertCorrectFlavorPreferences(true);
+ assertCorrectBareMetalFlavorPreferences(true);
}
@Test
public void application_deployment_prefers_exact_nonstock_nodes() {
- assertCorrectFlavorPreferences(false);
+ assertCorrectBareMetalFlavorPreferences(false);
}
@Test
@@ -635,7 +659,7 @@ public class ProvisioningTest {
.flavorsConfig(b.build()).curator(curator).nameResolver(nameResolver).build();
tester.makeReadyNodes(4, flavorToRetire);
SystemState state = prepare(application, 2, 0, 2, 0,
- flavorToRetire, tester);
+ NodeResources.fromLegacyName(flavorToRetire), tester);
tester.activate(application, state.allHosts);
}
@@ -655,7 +679,7 @@ public class ProvisioningTest {
tester.makeReadyNodes(4, replacementFlavor);
SystemState state = prepare(application, 2, 0, 2, 0,
- flavorToRetire, tester);
+ NodeResources.fromLegacyName(flavorToRetire), tester);
tester.activate(application, state.allHosts);
@@ -686,7 +710,7 @@ public class ProvisioningTest {
tester.makeReadyNodes(4, replacementFlavor);
SystemState state = prepare(application, 2, 0, 2, 0,
- flavorToRetire, tester);
+ NodeResources.fromLegacyName(flavorToRetire), tester);
tester.activate(application, state.allHosts);
@@ -700,12 +724,12 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(10, "default");
+ tester.makeReadyNodes(10, "d-1-1-1");
// Deploy application
{
SystemState state = prepare(application, 2, 0, 2, 0,
- "default", tester);
+ new NodeResources(1, 1, 1), tester);
tester.activate(application, state.allHosts);
assertEquals(4, tester.getNodes(application, Node.State.active).size());
}
@@ -715,7 +739,7 @@ public class ProvisioningTest {
List<Node> nodesToRetire = tester.getNodes(application, Node.State.active).asList().subList(0, 2);
nodesToRetire.forEach(node -> tester.patchNode(node.with(node.status().withWantToRetire(true))));
- SystemState state = prepare(application, 2, 0, 2, 0, "default", tester);
+ SystemState state = prepare(application, 2, 0, 2, 0, new NodeResources(1, 1, 1), tester);
tester.activate(application, state.allHosts);
List<Node> retiredNodes = tester.getNodes(application).retired().asList();
@@ -729,24 +753,24 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
- tester.makeReadyNodes(2, "default");
+ tester.makeReadyNodes(2, "d-1-1-1");
// Deploy fails with out of capacity
try {
prepare(application, 2, 0, 2, 0,
- "default", tester);
+ new NodeResources(1, 1, 1), tester);
fail("Expected exception");
} catch (OutOfCapacityException ignored) {}
assertEquals("Reserved a subset of required nodes", 2,
tester.getNodes(application, Node.State.reserved).size());
// Enough nodes become available
- tester.makeReadyNodes(2, "default");
+ tester.makeReadyNodes(2, "d-1-1-1");
// Deploy is retried after a few minutes
tester.clock().advance(Duration.ofMinutes(2));
SystemState state = prepare(application, 2, 0, 2, 0,
- "default", tester);
+ new NodeResources(1, 1, 1), tester);
List<Node> reserved = tester.getNodes(application, Node.State.reserved).asList();
assertEquals("Reserved required nodes", 4, reserved.size());
assertTrue("Time of event is updated for all nodes",
@@ -772,12 +796,12 @@ public class ProvisioningTest {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
ApplicationId application = tester.makeApplicationId();
try {
- prepare(application, 1, 0, 1, 0, true, "default", Version.fromString("6.42"), tester);
+ prepare(application, 1, 0, 1, 0, true, new NodeResources(1, 1, 1), Version.fromString("6.42"), tester);
fail("Expected exception");
} catch (IllegalArgumentException ignored) {}
}
- private void assertCorrectFlavorPreferences(boolean largeIsStock) {
+ private void assertCorrectBareMetalFlavorPreferences(boolean largeIsStock) {
FlavorConfigBuilder b = new FlavorConfigBuilder();
b.addFlavor("large", 4., 8., 100, Flavor.Type.BARE_METAL).cost(10).stock(largeIsStock);
FlavorsConfig.Flavor.Builder largeVariant = b.addFlavor("large-variant", 3., 9., 101, Flavor.Type.BARE_METAL).cost(9);
@@ -795,8 +819,10 @@ public class ProvisioningTest {
ClusterSpec contentClusterSpec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.42"), false, Collections.emptySet());
ClusterSpec containerClusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Version.fromString("6.42"), false, Collections.emptySet());
- List<HostSpec> containerNodes = tester.prepare(applicationId, containerClusterSpec, 5, 1, "large");
- List<HostSpec> contentNodes = tester.prepare(applicationId, contentClusterSpec, 10, 1, "large");
+ List<HostSpec> containerNodes = tester.prepare(applicationId, containerClusterSpec, 5, 1,
+ NodeResources.fromLegacyName("large"));
+ List<HostSpec> contentNodes = tester.prepare(applicationId, contentClusterSpec, 10, 1,
+ NodeResources.fromLegacyName("large"));
if (largeIsStock) { // 'large' is replaced by 'large-variant' when possible, as it is cheaper
tester.assertNumberOfNodesWithFlavor(containerNodes, "large-variant", 5);
@@ -813,19 +839,19 @@ public class ProvisioningTest {
}
private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size,
- int content1Size, String flavor, ProvisioningTester tester) {
+ int content1Size, NodeResources flavor, ProvisioningTester tester) {
return prepare(application, container0Size, container1Size, content0Size, content1Size, flavor,
Version.fromString("6.42"), tester);
}
private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size,
- int content1Size, String flavor, Version wantedVersion, ProvisioningTester tester) {
+ int content1Size, NodeResources flavor, Version wantedVersion, ProvisioningTester tester) {
return prepare(application, container0Size, container1Size, content0Size, content1Size, false, flavor,
wantedVersion, tester);
}
private SystemState prepare(ApplicationId application, int container0Size, int container1Size, int content0Size,
- int content1Size, boolean required, String flavor, Version wantedVersion,
+ int content1Size, boolean required, NodeResources flavor, Version wantedVersion,
ProvisioningTester tester) {
// "deploy prepare" with a two container clusters and a storage cluster having of two groups
ClusterSpec containerCluster0 = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("container0"), wantedVersion, false, Collections.emptySet());
@@ -868,7 +894,7 @@ public class ProvisioningTest {
}
private Set<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, int nodeCount, int groups,
- boolean required, String flavor, ProvisioningTester tester) {
+ boolean required, NodeResources flavor, ProvisioningTester tester) {
if (nodeCount == 0) return Collections.emptySet(); // this is a shady practice
return new HashSet<>(tester.prepare(application, cluster, nodeCount, groups, required, flavor));
}
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 8e41ddc0c0c..708ccf486f7 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
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.Capacity;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.DockerImage;
import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostFilter;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.InstanceName;
@@ -129,12 +130,12 @@ public class ProvisioningTester {
public void patchNode(Node node) { nodeRepository.write(node); }
- public List<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, int nodeCount, int groups, String flavor) {
+ public List<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, int nodeCount, int groups, NodeResources flavor) {
return prepare(application, cluster, nodeCount, groups, false, flavor);
}
- public List<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, int nodeCount, int groups, boolean required, String flavor) {
- return prepare(application, cluster, Capacity.fromNodeCount(nodeCount, Optional.ofNullable(flavor), required, true), groups);
+ public List<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, int nodeCount, int groups, boolean required, NodeResources flavor) {
+ return prepare(application, cluster, Capacity.fromCount(nodeCount, Optional.ofNullable(flavor), required, true), groups);
}
public List<HostSpec> prepare(ApplicationId application, ClusterSpec cluster, Capacity capacity, int groups) {
@@ -234,7 +235,7 @@ public class ProvisioningTester {
return makeProvisionedNodes(count, flavor, type, ipAddressPoolSize, false);
}
- public List<Node> makeProvisionedNodes(int n, String flavor, NodeType type, int ipAddressPoolSize, boolean dualStack) {
+ public List<Node> makeProvisionedNodes(int n, String flavorName, NodeType type, int ipAddressPoolSize, boolean dualStack) {
List<Node> nodes = new ArrayList<>(n);
for (int i = 0; i < n; i++) {
@@ -271,6 +272,13 @@ public class ProvisioningTester {
nameResolver.addRecord(String.format("node-%d-of-%s", poolIp, hostname), ipv4Addr);
}
}
+ Optional<Flavor> flavor = nodeFlavors.getFlavor(flavorName);
+ if (flavor.isEmpty()) {
+ if (type == NodeType.tenant) // Tenant nodes can have any (docker) flavor
+ flavor = Optional.of(new Flavor(NodeResources.fromLegacyName(flavorName)));
+ else
+ throw new IllegalArgumentException("No flavor '" + flavorName + "'");
+ }
nodes.add(nodeRepository.createNode(hostname,
hostname,
@@ -278,7 +286,7 @@ public class ProvisioningTester {
ipAddressPool,
Optional.empty(),
Optional.empty(),
- nodeFlavors.getFlavorOrThrow(flavor),
+ flavor.get(),
type));
}
nodes = nodeRepository.addNodes(nodes);
@@ -328,37 +336,37 @@ public class ProvisioningTester {
}
/** Creates a set of virtual docker hosts */
- public List<Node> makeReadyVirtualDockerHosts(int n, String flavor) {
+ public List<Node> makeReadyVirtualDockerHosts(int n, NodeResources flavor) {
return makeReadyVirtualNodes(n, 1, flavor, Optional.empty(),
i -> "dockerHost" + i, NodeType.host);
}
/** Creates a set of virtual docker nodes on a single docker host starting with index 1 and increasing */
- public List<Node> makeReadyVirtualDockerNodes(int n, String flavor, String dockerHostId) {
+ public List<Node> makeReadyVirtualDockerNodes(int n, NodeResources flavor, String dockerHostId) {
return makeReadyVirtualNodes(n, 1, flavor, Optional.of(dockerHostId),
i -> String.format("%s-%03d", dockerHostId, i), NodeType.tenant);
}
/** Creates a single of virtual docker node on a single parent host */
- public List<Node> makeReadyVirtualDockerNode(int index, String flavor, String dockerHostId) {
+ public List<Node> makeReadyVirtualDockerNode(int index, NodeResources flavor, String dockerHostId) {
return makeReadyVirtualNodes(1, index, flavor, Optional.of(dockerHostId),
i -> String.format("%s-%03d", dockerHostId, i), NodeType.tenant);
}
/** Creates a set of virtual nodes without a parent host */
- public List<Node> makeReadyVirtualNodes(int n, String flavor) {
+ public List<Node> makeReadyVirtualNodes(int n, NodeResources flavor) {
return makeReadyVirtualNodes(n, 0, flavor, Optional.empty(),
i -> UUID.randomUUID().toString(), NodeType.tenant);
}
/** Creates a set of virtual nodes on a single parent host */
- private List<Node> makeReadyVirtualNodes(int count, int startIndex, String flavor, Optional<String> parentHostId,
+ private List<Node> makeReadyVirtualNodes(int count, int startIndex, NodeResources flavor, Optional<String> parentHostId,
Function<Integer, String> nodeNamer, NodeType nodeType) {
List<Node> nodes = new ArrayList<>(count);
for (int i = startIndex; i < count + startIndex; i++) {
String hostname = nodeNamer.apply(i);
nodes.add(nodeRepository.createNode("openstack-id", hostname, parentHostId,
- nodeFlavors.getFlavorOrThrow(flavor), nodeType));
+ new Flavor(flavor), nodeType));
}
nodes = nodeRepository.addNodes(nodes);
nodes = nodeRepository.setDirty(nodes, Agent.system, getClass().getSimpleName());
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityTest.java
index 7883d9e58ed..5a021466e58 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ResourceCapacityTest.java
@@ -51,29 +51,34 @@ public class ResourceCapacityTest {
assertFalse(capacityOfHostSmall.hasCapacityFor(d3CPUFlavor));
// Compare it to various flavors
- assertEquals(1, capacityOfHostSmall.compare(nodeCapacity(d1Flavor)));
- assertEquals(1, capacityOfHostSmall.compare(nodeCapacity(d2Flavor)));
- assertEquals(0, capacityOfHostSmall.compare(nodeCapacity(d3Flavor)));
- assertEquals(-1, capacityOfHostSmall.compare(nodeCapacity(d3DiskFlavor)));
- assertEquals(-1, capacityOfHostSmall.compare(nodeCapacity(d3CPUFlavor)));
- assertEquals(-1, capacityOfHostSmall.compare(nodeCapacity(d3MemFlavor)));
+ assertEquals(1, compare(capacityOfHostSmall, nodeCapacity(d1Flavor)));
+ assertEquals(1, compare(capacityOfHostSmall, nodeCapacity(d2Flavor)));
+ assertEquals(0, compare(capacityOfHostSmall, nodeCapacity(d3Flavor)));
+ assertEquals(-1, compare(capacityOfHostSmall, nodeCapacity(d3DiskFlavor)));
+ assertEquals(-1, compare(capacityOfHostSmall, nodeCapacity(d3CPUFlavor)));
+ assertEquals(-1, compare(capacityOfHostSmall, nodeCapacity(d3MemFlavor)));
// Change free capacity and assert on rest capacity
capacityOfHostSmall = capacityOfHostSmall.subtract(ResourceCapacity.of(d1Flavor));
- assertEquals(0, capacityOfHostSmall.compare(nodeCapacity(d2Flavor)));
+ assertEquals(0, compare(capacityOfHostSmall, nodeCapacity(d2Flavor)));
// Assert on rest capacity
assertTrue(capacityOfHostSmall.hasCapacityFor(d1Flavor));
assertFalse(capacityOfHostSmall.hasCapacityFor(d3Flavor));
// At last compare the disk and cpu and mem variations
- assertEquals(-1, nodeCapacity(d3Flavor).compare(nodeCapacity(d3DiskFlavor)));
- assertEquals(1, nodeCapacity(d3DiskFlavor).compare(nodeCapacity(d3CPUFlavor)));
- assertEquals(-1, nodeCapacity(d3CPUFlavor).compare(nodeCapacity(d3MemFlavor)));
- assertEquals(1, nodeCapacity(d3MemFlavor).compare(nodeCapacity(d3DiskFlavor)));
+ assertEquals(-1, compare(nodeCapacity(d3Flavor), nodeCapacity(d3DiskFlavor)));
+ assertEquals(1, compare(nodeCapacity(d3DiskFlavor), nodeCapacity(d3CPUFlavor)));
+ assertEquals(-1, compare(nodeCapacity(d3CPUFlavor), nodeCapacity(d3MemFlavor)));
+ assertEquals(1, compare(nodeCapacity(d3MemFlavor), nodeCapacity(d3DiskFlavor)));
}
private ResourceCapacity nodeCapacity(Flavor flavor) {
return ResourceCapacity.of(flavor);
}
+
+ private int compare(ResourceCapacity a, ResourceCapacity b) {
+ return ResourceCapacityComparator.defaultOrder().compare(a, b);
+ }
+
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
index 0d9ce179d5c..1f03db8f7c2 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/VirtualNodeProvisioningTest.java
@@ -5,6 +5,7 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.OutOfCapacityException;
import com.yahoo.config.provision.RegionName;
@@ -34,7 +35,7 @@ import static org.junit.Assert.assertNotNull;
// to remove these tests
public class VirtualNodeProvisioningTest {
- private static final String flavor = "v-4-8-100";
+ private static final NodeResources flavor = new NodeResources(4, 8, 100);
private static final ClusterSpec contentClusterSpec = ClusterSpec.request(ClusterSpec.Type.content, ClusterSpec.Id.from("myContent"), Version.fromString("6.42"), false, Collections.emptySet());
private static final ClusterSpec containerClusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from("myContainer"), Version.fromString("6.42"), false, Collections.emptySet());
@@ -63,13 +64,13 @@ public class VirtualNodeProvisioningTest {
// Go down to 3 nodes in container cluster
List<HostSpec> containerHosts2 = prepare(containerClusterSpec, containerNodeCount - 1, groups);
activate(containerHosts2);
- final List<Node> nodes2 = getNodes(applicationId);
+ List<Node> nodes2 = getNodes(applicationId);
assertDistinctParentHosts(nodes2, ClusterSpec.Type.container, containerNodeCount - 1);
// Go up to 4 nodes again in container cluster
List<HostSpec> containerHosts3 = prepare(containerClusterSpec, containerNodeCount, groups);
activate(containerHosts3);
- final List<Node> nodes3 = getNodes(applicationId);
+ List<Node> nodes3 = getNodes(applicationId);
assertDistinctParentHosts(nodes3, ClusterSpec.Type.container, containerNodeCount);
}
@@ -81,11 +82,12 @@ public class VirtualNodeProvisioningTest {
// Allowed to use same parent host for several nodes in same cluster in dev
{
+ NodeResources flavor = new NodeResources(1, 1, 1);
tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
- tester.makeReadyVirtualDockerNodes(4, "default", "parentHost1");
+ tester.makeReadyVirtualDockerNodes(4, flavor, "parentHost1");
- List<HostSpec> containerHosts = prepare(containerClusterSpec, containerNodeCount, groups);
- List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
+ List<HostSpec> containerHosts = prepare(containerClusterSpec, containerNodeCount, groups, flavor);
+ List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups, flavor);
activate(containerHosts, contentHosts);
// downscaled to 1 node per cluster in dev, so 2 in total
@@ -251,9 +253,9 @@ public class VirtualNodeProvisioningTest {
public void unknown_distribution_with_known_and_unknown_ready_nodes() {
tester.makeReadyVirtualNodes(3, flavor);
- final int contentNodeCount = 3;
- final int groups = 1;
- final List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
+ int contentNodeCount = 3;
+ int groups = 1;
+ List<HostSpec> contentHosts = prepare(contentClusterSpec, contentNodeCount, groups);
activate(contentHosts);
assertEquals(3, getNodes(applicationId).size());
@@ -293,6 +295,10 @@ public class VirtualNodeProvisioningTest {
return tester.prepare(applicationId, clusterSpec, nodeCount, groups, flavor);
}
+ private List<HostSpec> prepare(ClusterSpec clusterSpec, int nodeCount, int groups, NodeResources flavor) {
+ return tester.prepare(applicationId, clusterSpec, nodeCount, groups, flavor);
+ }
+
@SafeVarargs
private final void activate(List<HostSpec>... hostLists) {
HashSet<HostSpec> hosts = new HashSet<>();
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java
index 75995245274..d75cdaa3a2b 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java
@@ -798,7 +798,7 @@ public class RestApiTest {
return "{\"hostname\":\"" + hostname + "\", \"parentHostname\":\"" + parentHostname + "\"," +
createIpAddresses(ipAddress) +
createAdditionalIpAddresses(additionalIpCount) +
- "\"openStackId\":\"" + hostname + "\",\"flavor\":\"docker\"}";
+ "\"openStackId\":\"" + hostname + "\",\"flavor\":\"d-1-1-100\"}";
}
private String asNodeJson(String hostname, String flavor, String... ipAddress) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/NodeIdentifierTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/NodeIdentifierTest.java
index 2a9a1c4fa3b..914a2e62164 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/NodeIdentifierTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/filter/NodeIdentifierTest.java
@@ -6,13 +6,12 @@ import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.Environment;
-import com.yahoo.config.provision.Flavor;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
import com.yahoo.config.provision.Zone;
import com.yahoo.config.provisioning.ConfigServerSecurityConfig;
-import com.yahoo.config.provisioning.FlavorsConfig;
import com.yahoo.security.KeyUtils;
import com.yahoo.security.Pkcs10Csr;
import com.yahoo.security.Pkcs10CsrBuilder;
@@ -22,7 +21,6 @@ import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeRepositoryTester;
import com.yahoo.vespa.hosted.provision.node.Allocation;
import com.yahoo.vespa.hosted.provision.node.Generation;
-import com.yahoo.vespa.hosted.provision.provisioning.FlavorConfigBuilder;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;
@@ -243,7 +241,7 @@ public class NodeIdentifierTest {
emptySet(),
HOSTNAME,
Optional.of("parenthost"),
- new Flavor(createFlavourConfig().flavor(0)),
+ new NodeResources(1, 2, 50),
NodeType.tenant)
.with(
new Allocation(
@@ -271,10 +269,4 @@ public class NodeIdentifierTest {
}
- private static FlavorsConfig createFlavourConfig() {
- FlavorConfigBuilder b = new FlavorConfigBuilder();
- b.addFlavor("docker", 1., 2., 50, Flavor.Type.DOCKER_CONTAINER).cost(1);
- return b.build();
- }
-
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-container1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-container1.json
index c98fbb46ff8..5c3829bd5ff 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-container1.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-container1.json
@@ -6,14 +6,13 @@
"hostname": "test-container-1",
"parentHostname": "dockerhost3.yahoo.com",
"openStackId": "fake-test-container-1",
- "flavor": "docker",
- "canonicalFlavor": "docker",
+ "flavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
+ "canonicalFlavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
"minDiskAvailableGb": 100.0,
- "minMainMemoryAvailableGb": 0.5,
- "description": "Flavor-name-is-docker",
- "minCpuCores": 0.2,
+ "minMainMemoryAvailableGb": 1.0,
+ "minCpuCores": 1.0,
"fastDisk": true,
- "bandwidth":0.0,
+ "bandwidth":1.0,
"environment": "DOCKER_CONTAINER",
"owner": {
"tenant": "tenant3",
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node11.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node11.json
index b1329eebb2d..0733473c2fe 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node11.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node11.json
@@ -6,14 +6,13 @@
"hostname": "host11.yahoo.com",
"parentHostname": "parent.host.yahoo.com",
"openStackId": "host11.yahoo.com",
- "flavor": "docker",
- "canonicalFlavor": "docker",
+ "flavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
+ "canonicalFlavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
"minDiskAvailableGb": 100.0,
- "minMainMemoryAvailableGb": 0.5,
- "description": "Flavor-name-is-docker",
- "minCpuCores": 0.2,
+ "minMainMemoryAvailableGb": 1.0,
+ "minCpuCores": 1.0,
"fastDisk": true,
- "bandwidth":0.0,
+ "bandwidth":1.0,
"environment": "DOCKER_CONTAINER",
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json
index a02035efd88..1cb1f6657e4 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4.json
@@ -6,14 +6,13 @@
"hostname": "host4.yahoo.com",
"parentHostname": "dockerhost1.yahoo.com",
"openStackId": "node4",
- "flavor": "docker",
- "canonicalFlavor": "docker",
+ "flavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
+ "canonicalFlavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
"minDiskAvailableGb": 100.0,
- "minMainMemoryAvailableGb": 0.5,
- "description": "Flavor-name-is-docker",
- "minCpuCores": 0.2,
+ "minMainMemoryAvailableGb": 1.0,
+ "minCpuCores": 1.0,
"fastDisk": true,
- "bandwidth":0.0,
+ "bandwidth":1.0,
"environment": "DOCKER_CONTAINER",
"owner": {
"tenant": "tenant3",
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5-after-changes.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5-after-changes.json
index 8eb3a74ce2a..8a5c80212c7 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5-after-changes.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5-after-changes.json
@@ -6,14 +6,13 @@
"hostname": "host5.yahoo.com",
"parentHostname": "dockerhost2.yahoo.com",
"openStackId": "node5",
- "flavor": "docker",
- "canonicalFlavor": "docker",
+ "flavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
+ "canonicalFlavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
"minDiskAvailableGb": 100.0,
- "minMainMemoryAvailableGb": 0.5,
- "description": "Flavor-name-is-docker",
- "minCpuCores": 0.2,
+ "minMainMemoryAvailableGb": 1.0,
+ "minCpuCores": 1.0,
"fastDisk": true,
- "bandwidth":0.0,
+ "bandwidth": 1.0,
"environment": "DOCKER_CONTAINER",
"rebootGeneration": 1,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5.json
index a14443e096d..08817a67324 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node5.json
@@ -6,14 +6,13 @@
"hostname": "host5.yahoo.com",
"parentHostname": "dockerhost2.yahoo.com",
"openStackId": "node5",
- "flavor": "docker",
- "canonicalFlavor": "docker",
+ "flavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
+ "canonicalFlavor": "[vcpu: 1.0, memory: 1.0 Gb, disk 100.0 Gb]",
"minDiskAvailableGb": 100.0,
- "minMainMemoryAvailableGb": 0.5,
- "description": "Flavor-name-is-docker",
- "minCpuCores": 0.2,
+ "minMainMemoryAvailableGb": 1.0,
+ "minCpuCores": 1.0,
"fastDisk": true,
- "bandwidth":0.0,
+ "bandwidth": 1.0,
"environment": "DOCKER_CONTAINER",
"rebootGeneration": 1,
"currentRebootGeneration": 0,