aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@oath.com>2019-10-30 14:22:33 +0100
committerGitHub <noreply@github.com>2019-10-30 14:22:33 +0100
commit4cf03f690d911842bbbf28d4f493e67ad955596e (patch)
tree79b550a9c5ef239bace09dd6fae5f95ab66c34cb
parent1d027b60ff6e7a443ffd5e3420ba52d7d02e9cd8 (diff)
parent8e79f3112d9481f8a0a62461ceea78adcc9f6dd5 (diff)
Merge pull request #11155 from vespa-engine/bratseth/remember-requested-resources
Remember requested resources on nodes
-rw-r--r--athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java2
-rw-r--r--athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java6
-rw-r--r--config-provisioning/abi-spec.json2
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java20
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializer.java79
-rw-r--r--config-provisioning/src/test/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializerTest.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java29
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java47
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java16
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeAllocation.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeSpec.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporterTest.java7
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java32
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/AllocationSimulator.java5
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/DynamicDockerAllocationTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTest.java32
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/ProvisioningTester.java3
24 files changed, 219 insertions, 118 deletions
diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java
index a55f325523b..3ea3892e398 100644
--- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java
+++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/identitydocument/IdentityDocumentGeneratorTest.java
@@ -7,6 +7,7 @@ import com.yahoo.config.provision.ApplicationName;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.Environment;
import com.yahoo.config.provision.InstanceName;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.config.provision.RegionName;
import com.yahoo.config.provision.SystemName;
@@ -54,6 +55,7 @@ public class IdentityDocumentGeneratorTest {
TenantName.from("tenant"), ApplicationName.from("application"), InstanceName.from("default"));
Allocation allocation = new Allocation(appid,
ClusterMembership.from("container/default/0/0", Version.fromString("1.2.3")),
+ new NodeResources(1, 1, 1, 1),
Generation.initial(),
false);
Node parentNode = Node.create("ostkid",
diff --git a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java
index cac6685a51e..5ce0f3cdd7e 100644
--- a/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java
+++ b/athenz-identity-provider-service/src/test/java/com/yahoo/vespa/hosted/athenz/instanceproviderservice/instanceconfirmation/InstanceValidatorTest.java
@@ -11,6 +11,7 @@ import com.yahoo.config.model.api.SuperModel;
import com.yahoo.config.model.api.SuperModelProvider;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
+import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.athenz.api.AthenzService;
import com.yahoo.vespa.athenz.identityprovider.api.EntityBindingsMapper;
@@ -228,7 +229,10 @@ public class InstanceValidatorTest {
private List<Node> allocateNode(List<Node> nodeList, Node node, ApplicationId applicationId) {
nodeList.removeIf(n -> n.id().equals(node.id()));
- nodeList.add(node.allocate(applicationId, ClusterMembership.from("container/default/0/0", Version.fromString("6.123.4")), Instant.now()));
+ nodeList.add(node.allocate(applicationId,
+ ClusterMembership.from("container/default/0/0", Version.fromString("6.123.4")),
+ new NodeResources(1, 1, 1, 1),
+ Instant.now()));
return nodeList;
}
}
diff --git a/config-provisioning/abi-spec.json b/config-provisioning/abi-spec.json
index 4e50d31d74a..d8b17009b65 100644
--- a/config-provisioning/abi-spec.json
+++ b/config-provisioning/abi-spec.json
@@ -477,12 +477,14 @@
"public void <init>(java.lang.String, java.util.List, java.util.Optional, java.util.Optional)",
"public void <init>(java.lang.String, java.util.List, java.util.Optional, java.util.Optional, java.util.Optional)",
"public void <init>(java.lang.String, java.util.List, java.util.Optional, java.util.Optional, java.util.Optional, java.util.Optional)",
+ "public void <init>(java.lang.String, java.util.List, java.util.Optional, java.util.Optional, java.util.Optional, java.util.Optional, java.util.Optional)",
"public java.lang.String hostname()",
"public java.util.List aliases()",
"public java.util.Optional flavor()",
"public java.util.Optional version()",
"public java.util.Optional membership()",
"public java.util.Optional networkPorts()",
+ "public java.util.Optional requestedResources()",
"public java.lang.String toString()",
"public boolean equals(java.lang.Object)",
"public int hashCode()",
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java b/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java
index ba7a3c2f06b..a046df1ac9a 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/HostSpec.java
@@ -29,6 +29,8 @@ public class HostSpec implements Comparable<HostSpec> {
private final Optional<NetworkPorts> networkPorts;
+ private Optional<NodeResources> requestedResources;
+
public HostSpec(String hostname, Optional<ClusterMembership> membership) {
this(hostname, new ArrayList<>(), Optional.empty(), membership);
}
@@ -61,15 +63,22 @@ public class HostSpec implements Comparable<HostSpec> {
public HostSpec(String hostname, List<String> aliases, Optional<Flavor> flavor,
Optional<ClusterMembership> membership, Optional<com.yahoo.component.Version> version,
Optional<NetworkPorts> networkPorts) {
+ this(hostname, aliases, flavor, membership, version, networkPorts, Optional.empty());
+ }
+
+ public HostSpec(String hostname, List<String> aliases, Optional<Flavor> flavor,
+ Optional<ClusterMembership> membership, Optional<com.yahoo.component.Version> version,
+ Optional<NetworkPorts> networkPorts, Optional<NodeResources> requestedResources) {
if (hostname == null || hostname.isEmpty()) throw new IllegalArgumentException("Hostname must be specified");
- Objects.requireNonNull(version, "Version cannot be null but can be empty");
- Objects.requireNonNull(networkPorts, "Network ports cannot be null but can be empty");
+
+
this.hostname = hostname;
this.aliases = List.copyOf(aliases);
this.flavor = flavor;
this.membership = membership;
- this.version = version;
- this.networkPorts = networkPorts;
+ this.version = Objects.requireNonNull(version, "Version cannot be null but can be empty");;
+ this.networkPorts = Objects.requireNonNull(networkPorts, "Network ports cannot be null but can be empty");;
+ this.requestedResources = Objects.requireNonNull(requestedResources, "RequestedResources cannot be null");
}
/** Returns the name identifying this host */
@@ -89,6 +98,9 @@ public class HostSpec implements Comparable<HostSpec> {
/** Returns the network port allocations on this host, or empty if not present */
public Optional<NetworkPorts> networkPorts() { return networkPorts; }
+ /** Returns the requested resources leading to this host being provisioned, or empty if not known */
+ public Optional<NodeResources> requestedResources() { return requestedResources; }
+
@Override
public String toString() {
return hostname +
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializer.java b/config-provisioning/src/main/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializer.java
index a7ba286baa7..4a060fb5143 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializer.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializer.java
@@ -49,6 +49,7 @@ public class AllocatedHostsSerializer {
private static final String flavorKey = "flavor";
private static final String resourcesKey = "resources";
+ private static final String requestedResourcesKey = "requestedResources";
private static final String vcpuKey = "vcpu";
private static final String memoryKey = "memory";
private static final String diskKey = "disk";
@@ -75,16 +76,17 @@ public class AllocatedHostsSerializer {
toSlime(host, array.addObject().setObject(hostSpecKey));
}
- private static void toSlime(HostSpec host, Cursor cursor) {
- cursor.setString(hostSpecHostNameKey, host.hostname());
- aliasesToSlime(host, cursor);
+ private static void toSlime(HostSpec host, Cursor object) {
+ object.setString(hostSpecHostNameKey, host.hostname());
+ aliasesToSlime(host, object);
host.membership().ifPresent(membership -> {
- cursor.setString(hostSpecMembershipKey, membership.stringValue());
- cursor.setString(hostSpecVespaVersionKey, membership.cluster().vespaVersion().toFullString());
+ object.setString(hostSpecMembershipKey, membership.stringValue());
+ object.setString(hostSpecVespaVersionKey, membership.cluster().vespaVersion().toFullString());
});
- host.flavor().ifPresent(flavor -> toSlime(flavor, cursor));
- host.version().ifPresent(version -> cursor.setString(hostSpecCurrentVespaVersionKey, version.toFullString()));
- host.networkPorts().ifPresent(ports -> NetworkPortsSerializer.toSlime(ports, cursor.setArray(hostSpecNetworkPortsKey)));
+ host.flavor().ifPresent(flavor -> toSlime(flavor, object));
+ host.requestedResources().ifPresent(resources -> toSlime(resources, object.setObject(requestedResourcesKey)));
+ host.version().ifPresent(version -> object.setString(hostSpecCurrentVespaVersionKey, version.toFullString()));
+ host.networkPorts().ifPresent(ports -> NetworkPortsSerializer.toSlime(ports, object.setArray(hostSpecNetworkPortsKey)));
}
private static void aliasesToSlime(HostSpec spec, Cursor cursor) {
@@ -95,20 +97,19 @@ public class AllocatedHostsSerializer {
}
private static void toSlime(Flavor flavor, Cursor object) {
- if (flavor.isConfigured()) {
+ 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());
- resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps());
- resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed()));
- }
+ else
+ toSlime(flavor.resources(), object.setObject(resourcesKey));
}
+ private static void toSlime(NodeResources resources, Cursor resourcesObject) {
+ resourcesObject.setDouble(vcpuKey, resources.vcpu());
+ resourcesObject.setDouble(memoryKey, resources.memoryGb());
+ resourcesObject.setDouble(diskKey, resources.diskGb());
+ resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps());
+ resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed()));
+ }
public static AllocatedHosts fromJson(byte[] json, Optional<NodeFlavors> nodeFlavors) {
return fromSlime(SlimeUtils.jsonToSlime(json).get(), nodeFlavors);
@@ -122,14 +123,13 @@ public class AllocatedHostsSerializer {
}
private static HostSpec hostFromSlime(Inspector object, Optional<NodeFlavors> nodeFlavors) {
- Optional<ClusterMembership> membership =
- object.field(hostSpecMembershipKey).valid() ? Optional.of(membershipFromSlime(object)) : Optional.empty();
- Optional<Flavor> flavor = flavorFromSlime(object, nodeFlavors);
- Optional<com.yahoo.component.Version> version =
- optionalString(object.field(hostSpecCurrentVespaVersionKey)).map(com.yahoo.component.Version::new);
- Optional<NetworkPorts> networkPorts =
- NetworkPortsSerializer.fromSlime(object.field(hostSpecNetworkPortsKey));
- return new HostSpec(object.field(hostSpecHostNameKey).asString(), aliasesFromSlime(object), flavor, membership, version, networkPorts);
+ return new HostSpec(object.field(hostSpecHostNameKey).asString(),
+ aliasesFromSlime(object),
+ flavorFromSlime(object, nodeFlavors),
+ object.field(hostSpecMembershipKey).valid() ? Optional.of(membershipFromSlime(object)) : Optional.empty(),
+ optionalString(object.field(hostSpecCurrentVespaVersionKey)).map(com.yahoo.component.Version::new),
+ NetworkPortsSerializer.fromSlime(object.field(hostSpecNetworkPortsKey)),
+ nodeResourcesFromSlime(object.field(requestedResourcesKey)));
}
private static List<String> aliasesFromSlime(Inspector object) {
@@ -140,20 +140,19 @@ public class AllocatedHostsSerializer {
}
private static Optional<Flavor> flavorFromSlime(Inspector object, Optional<NodeFlavors> nodeFlavors) {
- if (object.field(flavorKey).valid() && nodeFlavors.isPresent() && nodeFlavors.get().exists(object.field(flavorKey).asString())) {
+ if (object.field(flavorKey).valid() && nodeFlavors.isPresent() && nodeFlavors.get().exists(object.field(flavorKey).asString()))
return nodeFlavors.get().getFlavor(object.field(flavorKey).asString());
- }
- else if (object.field(resourcesKey).valid()) {
- Inspector resources = object.field(resourcesKey);
- return Optional.of(new Flavor(new NodeResources(resources.field(vcpuKey).asDouble(),
- resources.field(memoryKey).asDouble(),
- resources.field(diskKey).asDouble(),
- resources.field(bandwidthKey).asDouble(),
- diskSpeedFromSlime(resources.field(diskSpeedKey)))));
- }
- else {
- return Optional.empty();
- }
+ else
+ return nodeResourcesFromSlime(object.field(resourcesKey)).map(resources -> new Flavor(resources));
+ }
+
+ private static Optional<NodeResources> nodeResourcesFromSlime(Inspector resources) {
+ if ( ! resources.valid()) return Optional.empty();
+ return Optional.of(new NodeResources(resources.field(vcpuKey).asDouble(),
+ resources.field(memoryKey).asDouble(),
+ resources.field(diskKey).asDouble(),
+ resources.field(bandwidthKey).asDouble(),
+ diskSpeedFromSlime(resources.field(diskSpeedKey))));
}
private static NodeResources.DiskSpeed diskSpeedFromSlime(Inspector diskSpeed) {
diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializerTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializerTest.java
index a5af9aa0cb5..afec242de0b 100644
--- a/config-provisioning/src/test/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializerTest.java
+++ b/config-provisioning/src/test/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializerTest.java
@@ -42,7 +42,12 @@ public class AllocatedHostsSerializerTest {
hosts.add(new HostSpec("flavor-from-resources-1",
Collections.emptyList(), new Flavor(new NodeResources(0.5, 3.1, 4, 1))));
hosts.add(new HostSpec("flavor-from-resources-2",
- Collections.emptyList(), new Flavor(new NodeResources(0.5, 3.1, 4, 1, NodeResources.DiskSpeed.any))));
+ Collections.emptyList(),
+ Optional.of(new Flavor(new NodeResources(0.5, 3.1, 4, 1, NodeResources.DiskSpeed.slow))),
+ Optional.empty(),
+ Optional.empty(),
+ Optional.empty(),
+ Optional.of(new NodeResources(0.5, 3.1, 4, 1, NodeResources.DiskSpeed.any))));
hosts.add(new HostSpec("configured-flavor",
Collections.emptyList(), configuredFlavors.getFlavorOrThrow("C/12/45/100")));
hosts.add(new HostSpec("with-version",
@@ -67,6 +72,7 @@ public class AllocatedHostsSerializerTest {
assertEquals(expectedHost.version(), deserializedHost.version());
assertEquals(expectedHost.networkPorts(), deserializedHost.networkPorts());
assertEquals(expectedHost.aliases(), deserializedHost.aliases());
+ assertEquals(expectedHost.requestedResources(), deserializedHost.requestedResources());
}
}
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 80b59bb40d0..49f96d65c81 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
@@ -249,8 +249,9 @@ public final class Node {
}
/** Returns a copy of this with allocation set as specified. <code>node.state</code> is *not* changed. */
- public Node allocate(ApplicationId owner, ClusterMembership membership, Instant at) {
- return this.with(new Allocation(owner, membership, new Generation(0, 0), false))
+ public Node allocate(ApplicationId owner, ClusterMembership membership, NodeResources requestedResources, Instant at) {
+ return this
+ .with(new Allocation(owner, membership, requestedResources, new Generation(0, 0), false))
.with(history.with(new History.Event(History.Event.Type.reserved, Agent.application, at)));
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java
index 53e1ae3721e..30ef84c6927 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java
@@ -4,6 +4,7 @@ package com.yahoo.vespa.hosted.provision.node;
import com.yahoo.config.provision.ApplicationId;
import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.NetworkPorts;
+import com.yahoo.config.provision.NodeResources;
import java.util.Optional;
@@ -17,6 +18,8 @@ public class Allocation {
private final ApplicationId owner;
private final ClusterMembership clusterMembership;
+ private final NodeResources requestedResources;
+
/**
* Restart generation, see {@link com.yahoo.vespa.hosted.provision.node.Generation},
* wanted is increased when a restart of the services on the node is needed, current is updated
@@ -30,15 +33,16 @@ public class Allocation {
private final Optional<NetworkPorts> networkPorts;
- public Allocation(ApplicationId owner, ClusterMembership clusterMembership,
+ public Allocation(ApplicationId owner, ClusterMembership clusterMembership, NodeResources requestedResources,
Generation restartGeneration, boolean removable) {
- this(owner, clusterMembership, restartGeneration, removable, Optional.empty());
+ this(owner, clusterMembership, requestedResources, restartGeneration, removable, Optional.empty());
}
- public Allocation(ApplicationId owner, ClusterMembership clusterMembership,
+ public Allocation(ApplicationId owner, ClusterMembership clusterMembership, NodeResources requestedResources,
Generation restartGeneration, boolean removable, Optional<NetworkPorts> networkPorts) {
this.owner = owner;
this.clusterMembership = clusterMembership;
+ this.requestedResources = requestedResources;
this.restartGeneration = restartGeneration;
this.removable = removable;
this.networkPorts = networkPorts;
@@ -50,6 +54,9 @@ public class Allocation {
/** Returns the role this node is allocated to */
public ClusterMembership membership() { return clusterMembership; }
+ /** Returns the node resources requested, leading to this allocation on this node */
+ public NodeResources requestedResources() { return requestedResources; }
+
/** Returns the restart generation (wanted and current) of this */
public Generation restartGeneration() { return restartGeneration; }
@@ -58,33 +65,37 @@ public class Allocation {
/** Returns a copy of this which is retired */
public Allocation retire() {
- return new Allocation(owner, clusterMembership.retire(), restartGeneration, removable, networkPorts);
+ return new Allocation(owner, clusterMembership.retire(), requestedResources, restartGeneration, removable, networkPorts);
}
/** Returns a copy of this which is not retired */
public Allocation unretire() {
- return new Allocation(owner, clusterMembership.unretire(), restartGeneration, removable, networkPorts);
+ return new Allocation(owner, clusterMembership.unretire(), requestedResources, restartGeneration, removable, networkPorts);
}
/** Return whether this node is ready to be removed from the application */
public boolean isRemovable() { return removable; }
+ public Allocation withRequestedResources(NodeResources resources) {
+ return new Allocation(owner, clusterMembership, resources, restartGeneration, removable, networkPorts);
+ }
+
/** Returns a copy of this with the current restart generation set to generation */
public Allocation withRestart(Generation generation) {
- return new Allocation(owner, clusterMembership, generation, removable, networkPorts);
+ return new Allocation(owner, clusterMembership, requestedResources, generation, removable, networkPorts);
}
/** Returns a copy of this allocation where removable is set to true */
public Allocation removable() {
- return new Allocation(owner, clusterMembership, restartGeneration, true, networkPorts);
+ return new Allocation(owner, clusterMembership, requestedResources, restartGeneration, true, networkPorts);
}
public Allocation with(ClusterMembership newMembership) {
- return new Allocation(owner, newMembership, restartGeneration, removable, networkPorts);
+ return new Allocation(owner, newMembership, requestedResources, restartGeneration, removable, networkPorts);
}
public Allocation withNetworkPorts(NetworkPorts ports) {
- return new Allocation(owner, clusterMembership, restartGeneration, removable, Optional.of(ports));
+ return new Allocation(owner, clusterMembership, requestedResources, restartGeneration, removable, Optional.of(ports));
}
@Override
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 f4277408956..39473ed0b3a 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
@@ -92,6 +92,7 @@ public class NodeSerializer {
private static final String applicationIdKey = "applicationId";
private static final String instanceIdKey = "instanceId";
private static final String serviceIdKey = "serviceId"; // legacy name, TODO: change to membership with backwards compat
+ private static final String requestedResourcesKey = "requestedResources";
private static final String restartGenerationKey = "restartGeneration";
private static final String currentRestartGenerationKey = "currentRestartGeneration";
private static final String removableKey = "removable";
@@ -155,17 +156,20 @@ public class NodeSerializer {
}
}
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());
- resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps());
- resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed()));
+ toSlime(flavor.resources(), object.setObject(resourcesKey));
}
}
+ private void toSlime(NodeResources resources, Cursor resourcesObject) {
+ resourcesObject.setDouble(vcpuKey, resources.vcpu());
+ resourcesObject.setDouble(memoryKey, resources.memoryGb());
+ resourcesObject.setDouble(diskKey, resources.diskGb());
+ resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps());
+ resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed()));
+ }
+
private void toSlime(Allocation allocation, Cursor object) {
+ toSlime(allocation.requestedResources(), object.setObject(requestedResourcesKey));
object.setString(tenantIdKey, allocation.owner().tenant().value());
object.setString(applicationIdKey, allocation.owner().application().value());
object.setString(instanceIdKey, allocation.owner().instance().value());
@@ -200,15 +204,16 @@ public class NodeSerializer {
}
private Node nodeFromSlime(Node.State state, Inspector object) {
+ Flavor flavor = flavorFromSlime(object);
return new Node(object.field(idKey).asString(),
new IP.Config(ipAddressesFromSlime(object, ipAddressesKey),
ipAddressesFromSlime(object, ipAddressPoolKey)),
object.field(hostnameKey).asString(),
parentHostnameFromSlime(object),
- flavorFromSlime(object),
+ flavor,
statusFromSlime(object),
state,
- allocationFromSlime(object.field(instanceKey)),
+ allocationFromSlime(flavor.resources(), object.field(instanceKey)),
historyFromSlime(object.field(historyKey)),
nodeTypeFromString(object.field(nodeTypeKey).asString()),
Reports.fromSlime(object.field(reportsKey)),
@@ -235,18 +240,25 @@ public class NodeSerializer {
return flavor.with(FlavorOverrides.ofDisk(resources.field(diskKey).asDouble()));
}
else {
- return new Flavor(new NodeResources(resources.field(vcpuKey).asDouble(),
- resources.field(memoryKey).asDouble(),
- resources.field(diskKey).asDouble(),
- resources.field(bandwidthKey).asDouble(),
- diskSpeedFromSlime(resources.field(diskSpeedKey))));
+ return new Flavor(resourcesFromSlime(resources).get());
}
}
- private Optional<Allocation> allocationFromSlime(Inspector object) {
- if ( ! object.valid()) return Optional.empty();
+ private Optional<NodeResources> resourcesFromSlime(Inspector resources) {
+ if ( ! resources.valid()) return Optional.empty();
+
+ return Optional.of(new NodeResources(resources.field(vcpuKey).asDouble(),
+ resources.field(memoryKey).asDouble(),
+ resources.field(diskKey).asDouble(),
+ resources.field(bandwidthKey).asDouble(),
+ diskSpeedFromSlime(resources.field(diskSpeedKey))));
+ }
+
+ private Optional<Allocation> allocationFromSlime(NodeResources assignedResources, Inspector object) {
+ if ( ! object.valid()) return Optional.empty(); // TODO: Remove this line (and to the simplifications that follows) after November 2019
return Optional.of(new Allocation(applicationIdFromSlime(object),
clusterMembershipFromSlime(object),
+ resourcesFromSlime(object.field(requestedResourcesKey)).orElse(assignedResources),
generationFromSlime(object, restartGenerationKey, currentRestartGenerationKey),
object.field(removableKey).asBool(),
NetworkPortsSerializer.fromSlime(object.field(networkPortsKey))));
@@ -367,8 +379,6 @@ public class NodeSerializer {
}
private Agent eventAgentFromSlime(Inspector eventAgentField) {
- if ( ! eventAgentField.valid()) return Agent.system; // TODO: Remove after April 2017
-
switch (eventAgentField.asString()) {
case "application" : return Agent.application;
case "system" : return Agent.system;
@@ -416,7 +426,6 @@ public class NodeSerializer {
}
private static NodeResources.DiskSpeed diskSpeedFromSlime(Inspector diskSpeed) {
- if ( ! diskSpeed.valid()) return NodeResources.DiskSpeed.fast; // TODO: Remove this line after June 2019
switch (diskSpeed.asString()) {
case "fast" : return NodeResources.DiskSpeed.fast;
case "slow" : return NodeResources.DiskSpeed.slow;
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
index 8a6f308eb34..e994e86d07c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java
@@ -138,21 +138,21 @@ class Activator {
return notFoundHosts.isEmpty();
}
- /**
- * Returns the input nodes with the changes resulting from applying the settings in hosts to the given list of nodes.
- */
+ /** Returns the input nodes with the changes resulting from applying the settings in hosts to the given list of nodes. */
private List<Node> updateFrom(Collection<HostSpec> hosts, List<Node> nodes) {
List<Node> updated = new ArrayList<>();
for (Node node : nodes) {
HostSpec hostSpec = getHost(node.hostname(), hosts);
node = hostSpec.membership().get().retired() ? node.retire(nodeRepository.clock().instant()) : node.unretire();
- Allocation allocation = node.allocation().get().with(hostSpec.membership().get());
- if (hostSpec.networkPorts().isPresent()) {
- allocation = allocation.withNetworkPorts(hostSpec.networkPorts().get());
- }
- node = node.with(allocation);
if (hostSpec.flavor().isPresent()) // Docker nodes may change flavor
node = node.with(hostSpec.flavor().get());
+ Allocation allocation = node.allocation().get()
+ .with(hostSpec.membership().get())
+ .withRequestedResources(hostSpec.requestedResources()
+ .orElse(node.flavor().resources()));
+ if (hostSpec.networkPorts().isPresent())
+ allocation = allocation.withNetworkPorts(hostSpec.networkPorts().get());
+ node = node.with(allocation);
updated.add(node);
}
return updated;
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 f6822f64570..e381fdc654e 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
@@ -140,6 +140,7 @@ class NodeAllocation {
}
offeredPriority.node = offered.allocate(application,
ClusterMembership.from(cluster, highestIndex.add(1)),
+ requestedNodes.resources().orElse(offeredPriority.node.flavor().resources()),
clock.instant());
accepted.add(acceptNode(offeredPriority, false));
}
@@ -223,6 +224,10 @@ class NodeAllocation {
private Node acceptNode(PrioritizableNode prioritizableNode, boolean wantToRetire) {
Node node = prioritizableNode.node;
+
+ if (node.allocation().isPresent()) // Record the currently requested resources
+ node = node.with(node.allocation().get().withRequestedResources(requestedNodes.resources().orElse(node.flavor().resources())));
+
if (! wantToRetire) {
if ( ! node.state().equals(Node.State.active)) {
// reactivated node - make sure its not retired
@@ -278,14 +283,13 @@ class NodeAllocation {
* Returns {@link FlavorCount} describing the docker node deficit for the given {@link NodeSpec}.
*
* @return empty if the requested spec is not count based or the requested flavor type is not docker or
- * the request is already fulfilled. Otherwise returns {@link FlavorCount} containing the required flavor
- * and node count to cover the deficit.
+ * the request is already fulfilled. Otherwise returns {@link FlavorCount} containing the required flavor
+ * and node count to cover the deficit.
*/
Optional<FlavorCount> getFulfilledDockerDeficit() {
return Optional.of(requestedNodes)
.filter(NodeSpec.CountNodeSpec.class::isInstance)
- .map(NodeSpec.CountNodeSpec.class::cast)
- .map(spec -> new FlavorCount(spec.resources(), spec.fulfilledDeficitCount(acceptedOfRequestedFlavor)))
+ .map(spec -> new FlavorCount(spec.resources().get(), spec.fulfilledDeficitCount(acceptedOfRequestedFlavor)))
.filter(flavorCount -> flavorCount.getCount() > 0);
}
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 cc27b1b2196..a7081060f2e 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
@@ -219,7 +219,7 @@ public class NodePrioritizer {
private static NodeResources resources(NodeSpec requestedNodes) {
if ( ! (requestedNodes instanceof NodeSpec.CountNodeSpec)) return null;
- return ((NodeSpec.CountNodeSpec)requestedNodes).resources();
+ return requestedNodes.resources().get();
}
private boolean isDocker() {
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 e437fd4211a..f78eaf40f60 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
@@ -103,7 +103,8 @@ public class NodeRepositoryProvisioner implements Provisioner {
effectiveGroups = 1; // type request with multiple groups is not supported
}
- return asSortedHosts(preparer.prepare(application, cluster, requestedNodes, effectiveGroups));
+ return asSortedHosts(preparer.prepare(application, cluster, requestedNodes, effectiveGroups),
+ requestedCapacity.nodeResources());
}
@Override
@@ -123,7 +124,7 @@ public class NodeRepositoryProvisioner implements Provisioner {
loadBalancerProvisioner.ifPresent(lbProvisioner -> lbProvisioner.deactivate(application, transaction));
}
- private List<HostSpec> asSortedHosts(List<Node> nodes) {
+ private List<HostSpec> asSortedHosts(List<Node> nodes, Optional<NodeResources> requestedResources) {
nodes.sort(Comparator.comparingInt(node -> node.allocation().get().membership().index()));
List<HostSpec> hosts = new ArrayList<>(nodes.size());
for (Node node : nodes) {
@@ -134,7 +135,8 @@ public class NodeRepositoryProvisioner implements Provisioner {
Optional.of(node.flavor()),
Optional.of(nodeAllocation.membership()),
node.status().vespaVersion(),
- nodeAllocation.networkPorts()));
+ nodeAllocation.networkPorts(),
+ requestedResources));
if (nodeAllocation.networkPorts().isPresent()) {
log.log(LogLevel.DEBUG, () -> "Prepared node " + node.hostname() + " has port allocations");
}
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 da8d6a2ccf6..8eaa6662187 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
@@ -8,6 +8,7 @@ import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.hosted.provision.Node;
import java.util.Objects;
+import java.util.Optional;
/**
* A specification of a set of nodes.
@@ -60,6 +61,9 @@ public interface NodeSpec {
*/
Node assignRequestedFlavor(Node node);
+ /** Returns the resources requested by this or empty if none are explicitly requested */
+ Optional<NodeResources> resources();
+
static NodeSpec from(int nodeCount, NodeResources flavor, boolean exclusive, boolean canFail) {
return new CountNodeSpec(nodeCount, flavor, exclusive, canFail);
}
@@ -83,8 +87,9 @@ public interface NodeSpec {
this.canFail = canFail;
}
- public NodeResources resources() {
- return requestedNodeResources;
+ @Override
+ public Optional<NodeResources> resources() {
+ return Optional.of(requestedNodeResources);
}
@Override
@@ -199,6 +204,9 @@ public interface NodeSpec {
public Node assignRequestedFlavor(Node node) { return node; }
@Override
+ public Optional<NodeResources> resources() { return Optional.empty(); }
+
+ @Override
public String toString() { return "request for all nodes of type '" + type + "'"; }
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java
index 6054e298277..e387645888c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Preparer.java
@@ -14,6 +14,7 @@ import java.util.ArrayList;
import java.util.List;
import java.util.ListIterator;
import java.util.Optional;
+import java.util.stream.Collectors;
/**
* Performs preparation of node activation changes for an application.
@@ -51,7 +52,7 @@ class Preparer {
// Note: This operation may make persisted changes to the set of reserved and inactive nodes,
// but it may not change the set of active nodes, as the active nodes must stay in sync with the
// active config model which is changed on activate
- public List<Node> prepareNodes(ApplicationId application, ClusterSpec cluster, NodeSpec requestedNodes, int wantedGroups) {
+ private List<Node> prepareNodes(ApplicationId application, ClusterSpec cluster, NodeSpec requestedNodes, int wantedGroups) {
List<Node> surplusNodes = findNodesInRemovableGroups(application, cluster, wantedGroups);
MutableInteger highestIndex = new MutableInteger(findHighestIndex(application, cluster));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java
index 3a29204d2f4..b2bc21d1cf1 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityCheckerTester.java
@@ -266,7 +266,7 @@ public class CapacityCheckerTester {
nodeModel.parentHostname, f, nodeModel.type);
if (membership != null) {
- return node.allocate(owner, membership, Instant.now());
+ return node.allocate(owner, membership, node.flavor().resources(), Instant.now());
} else {
return node;
}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java
index 0a4ca831d3d..71788fb1a30 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DynamicProvisioningMaintainerTest.java
@@ -199,6 +199,7 @@ public class DynamicProvisioningMaintainerTest {
.map(app -> new Allocation(
app,
ClusterMembership.from("container/default/0/0", Version.fromString("7.3")),
+ flavor.resources(),
Generation.initial(),
false));
var ipConfig = new IP.Config(state == Node.State.active ? Set.of("::1") : Set.of(), Set.of());
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 db4ba661b64..ed6e6c6e9a7 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
@@ -126,12 +126,12 @@ public class MetricsReporterTest {
Node container1 = Node.createDockerNode(Set.of("::2"), "container1",
"dockerHost", new NodeResources(1, 3, 2, 1), NodeType.tenant);
- container1 = container1.with(allocation(Optional.of("app1")).get());
+ container1 = container1.with(allocation(Optional.of("app1"), container1).get());
nodeRepository.addDockerNodes(new LockedNodeList(List.of(container1), nodeRepository.lockAllocation()));
Node container2 = Node.createDockerNode(Set.of("::3"), "container2",
"dockerHost", new NodeResources(2, 4, 4, 1), NodeType.tenant);
- container2 = container2.with(allocation(Optional.of("app2")).get());
+ container2 = container2.with(allocation(Optional.of("app2"), container2).get());
nodeRepository.addDockerNodes(new LockedNodeList(List.of(container2), nodeRepository.lockAllocation()));
Orchestrator orchestrator = mock(Orchestrator.class);
@@ -171,10 +171,11 @@ public class MetricsReporterTest {
.instanceName("default").build();
}
- private Optional<Allocation> allocation(Optional<String> tenant) {
+ private Optional<Allocation> allocation(Optional<String> tenant, Node owner) {
if (tenant.isPresent()) {
Allocation allocation = new Allocation(app(tenant.get()),
ClusterMembership.from("container/id1/0/3", new Version()),
+ owner.flavor().resources(),
Generation.initial(),
false);
return Optional.of(allocation);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java
index 0cfdf80a8a1..5a4c87aaf77 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java
@@ -10,6 +10,7 @@ import com.yahoo.config.provision.ClusterMembership;
import com.yahoo.config.provision.InstanceName;
import com.yahoo.config.provision.NetworkPorts;
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.config.provision.host.FlavorOverrides;
@@ -70,6 +71,7 @@ public class SerializationTest {
@Test
public void testReservedNodeSerialization() {
Node node = createNode();
+ NodeResources requestedResources = new NodeResources(1.2, 3.4, 5.6, 7.8, NodeResources.DiskSpeed.any);
clock.advance(Duration.ofMinutes(3));
assertEquals(0, node.history().events().size());
@@ -77,6 +79,7 @@ public class SerializationTest {
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
ClusterMembership.from("content/myId/0/0", Vtag.currentVersion),
+ requestedResources,
clock.instant());
assertEquals(1, node.history().events().size());
node = node.withRestart(new Generation(1, 2));
@@ -99,6 +102,7 @@ public class SerializationTest {
assertEquals(2, copy.status().failCount());
assertEquals(node.allocation().get().owner(), copy.allocation().get().owner());
assertEquals(node.allocation().get().membership(), copy.allocation().get().membership());
+ assertEquals(node.allocation().get().requestedResources(), copy.allocation().get().requestedResources());
assertEquals(node.allocation().get().isRemovable(), copy.allocation().get().isRemovable());
assertEquals(1, copy.history().events().size());
assertEquals(clock.instant().truncatedTo(MILLIS), copy.history().event(History.Event.Type.reserved).get().at());
@@ -106,17 +110,6 @@ public class SerializationTest {
}
@Test
- public void testDefaultType() {
- Node node = createNode().allocate(ApplicationId.from(TenantName.from("myTenant"),
- ApplicationName.from("myApplication"),
- InstanceName.from("myInstance")),
- ClusterMembership.from("content/myId/0/0", Vtag.currentVersion),
- clock.instant());
- Node copy = nodeSerializer.fromJson(Node.State.provisioned, nodeSerializer.toJson(node));
- assertEquals(NodeType.host, copy.type());
- }
-
- @Test
public void testRebootAndRestartAndTypeNoCurrentValuesSerialization() {
String nodeData =
"{\n" +
@@ -127,11 +120,13 @@ public class SerializationTest {
" \"history\" : [\n" +
" {\n" +
" \"type\" : \"provisioned\",\n" +
- " \"at\" : 1444391401389\n" +
+ " \"at\" : 1444391401389,\n" +
+ " \"agent\" : \"system\"\n" +
" },\n" +
" {\n" +
" \"type\" : \"reserved\",\n" +
- " \"at\" : 1444391402611\n" +
+ " \"at\" : 1444391402611,\n" +
+ " \"agent\" : \"system\"\n" +
" }\n" +
" ],\n" +
" \"instance\" : {\n" +
@@ -172,6 +167,7 @@ public class SerializationTest {
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
ClusterMembership.from("content/myId/0/0", Vtag.currentVersion),
+ node.flavor().resources(),
clock.instant());
assertEquals(1, node.history().events().size());
clock.advance(Duration.ofMinutes(2));
@@ -221,6 +217,7 @@ public class SerializationTest {
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
ClusterMembership.from("content/myId/0/0", Vtag.currentVersion),
+ node.flavor().resources(),
clock.instant());
node = node.with(node.status().setFailCount(0));
@@ -405,6 +402,7 @@ public class SerializationTest {
ApplicationName.from("myApplication"),
InstanceName.from("myInstance")),
ClusterMembership.from("content/myId/0/0", Vtag.currentVersion),
+ node.flavor().resources(),
clock.instant());
assertTrue(node.allocation().isPresent());
node = node.with(node.allocation().get().withNetworkPorts(ports));
@@ -437,7 +435,13 @@ public class SerializationTest {
}
private Node createNode() {
- return Node.create("myId", new IP.Config(Set.of("127.0.0.1"), Set.of()), "myHostname", Optional.empty(), Optional.empty(), nodeFlavors.getFlavorOrThrow("default"), NodeType.host);
+ return Node.create("myId",
+ new IP.Config(Set.of("127.0.0.1"), Set.of()),
+ "myHostname",
+ Optional.empty(),
+ Optional.empty(),
+ nodeFlavors.getFlavorOrThrow("default"),
+ NodeType.tenant);
}
}
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 e3aefdd4512..9cd95e401a9 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
@@ -80,7 +80,7 @@ public class AllocationSimulator {
private Node node(String hostname, Flavor flavor, Optional<String> parent, Optional<String> tenant) {
var ipConfig = new IP.Config(Set.of("127.0.0.1"), parent.isPresent() ? Set.of() : getAdditionalIP());
return new Node("fake", ipConfig, hostname, parent, flavor, Status.initial(),
- parent.isPresent() ? Node.State.ready : Node.State.active, allocation(tenant), History.empty(),
+ parent.isPresent() ? Node.State.ready : Node.State.active, allocation(tenant, flavor), History.empty(),
parent.isPresent() ? NodeType.tenant : NodeType.host, new Reports(), Optional.empty());
}
@@ -90,10 +90,11 @@ public class AllocationSimulator {
return h;
}
- private Optional<Allocation> allocation(Optional<String> tenant) {
+ private Optional<Allocation> allocation(Optional<String> tenant, Flavor flavor) {
if (tenant.isPresent()) {
Allocation allocation = new Allocation(app(tenant.get()),
ClusterMembership.from("container/id1/3", new Version()),
+ flavor.resources(),
Generation.initial(),
false);
return Optional.of(allocation);
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 a3512c480d3..618df82e38b 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
@@ -426,7 +426,7 @@ public class DynamicDockerAllocationTest {
Node node1a = Node.create("open1", new IP.Config(Set.of("127.0.233." + index), Set.of()), 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());
+ Node node1aAllocation = node1a.allocate(id, clusterMembership1, node1a.flavor().resources(), Instant.now());
tester.nodeRepository().addNodes(Collections.singletonList(node1aAllocation));
NestedTransaction transaction = new NestedTransaction().add(new CuratorTransaction(tester.getCurator()));
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java
index da77bebccda..48bd091011e 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/provisioning/InfraDeployerImplTest.java
@@ -140,7 +140,7 @@ public class InfraDeployerImplTest {
Optional<Node> nodeWithAllocation = wantedVespaVersion.map(version -> {
ClusterSpec clusterSpec = application.getClusterSpecWithVersion(version).with(Optional.of(ClusterSpec.Group.from(0)));
ClusterMembership membership = ClusterMembership.from(clusterSpec, 1);
- Allocation allocation = new Allocation(application.getApplicationId(), membership, Generation.initial(), false);
+ Allocation allocation = new Allocation(application.getApplicationId(), membership, node.flavor().resources(), Generation.initial(), false);
return node.with(allocation);
});
return nodeRepository.database().writeTo(state, nodeWithAllocation.orElse(node), Agent.system, Optional.empty());
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 877038b8722..a8b534e02ef 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
@@ -320,6 +320,38 @@ public class ProvisioningTest {
}
@Test
+ public void requested_resources_info_is_retained() {
+ ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.prod, RegionName.from("us-east"))).build();
+
+ tester.makeReadyNodes(13, defaultResources, NodeType.host, 1);
+ tester.prepareAndActivateInfraApplication(tester.makeApplicationId(), NodeType.host);
+ ApplicationId application = tester.makeApplicationId();
+
+ {
+ // Deploy with disk-speed any and make sure that information is retained
+ SystemState state = prepare(application, 0, 0, 3, 3,
+ defaultResources.anySpeed(),
+ tester);
+ assertEquals(6, state.allHosts.size());
+ tester.activate(application, state.allHosts);
+ assertTrue(state.allHosts.stream().allMatch(host -> host.requestedResources().get().diskSpeed() == NodeResources.DiskSpeed.any));
+ assertTrue(tester.nodeRepository().getNodes(application).stream().allMatch(node -> node.allocation().get().requestedResources().diskSpeed() == NodeResources.DiskSpeed.any));
+ }
+
+ {
+ // Deploy (with some additional nodes) with disk-speed fast and make sure *that* information is retained
+ // even though it does not lead to new nodes
+ SystemState state = prepare(application, 0, 0, 5, 3,
+ defaultResources,
+ tester);
+ assertEquals(8, state.allHosts.size());
+ tester.activate(application, state.allHosts);
+ assertTrue(state.allHosts.stream().allMatch(host -> host.requestedResources().get().diskSpeed() == NodeResources.DiskSpeed.fast));
+ assertTrue(tester.nodeRepository().getNodes(application).stream().allMatch(node -> node.allocation().get().requestedResources().diskSpeed() == NodeResources.DiskSpeed.fast));
+ }
+ }
+
+ @Test
public void deploy_specific_vespa_version() {
ProvisioningTester tester = new ProvisioningTester.Builder().zone(new Zone(Environment.dev, RegionName.from("us-east"))).build();
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 af635ada89d..242b0d8ca9e 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
@@ -148,12 +148,13 @@ public class ProvisioningTester {
return hosts1;
}
- public void activate(ApplicationId application, Collection<HostSpec> hosts) {
+ public Collection<HostSpec> activate(ApplicationId application, Collection<HostSpec> hosts) {
NestedTransaction transaction = new NestedTransaction();
transaction.add(new CuratorTransaction(curator));
provisioner.activate(transaction, application, hosts);
transaction.commit();
assertEquals(toHostNames(hosts), toHostNames(nodeRepository.getNodes(application, Node.State.active)));
+ return hosts;
}
public void prepareAndActivateInfraApplication(ApplicationId application, NodeType nodeType, Version version) {