aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJon Bratseth <bratseth@verizonmedia.com>2019-11-13 14:26:34 +0100
committerJon Bratseth <bratseth@verizonmedia.com>2019-11-13 14:26:34 +0100
commit276c047bfdc581bbbef42012b24ffd4424873430 (patch)
tree10492056209697f8404e8f7844b27c2a904089a2
parent25d00feb031fab5a34fbea78f9eeb9b6ed7cf7f8 (diff)
Add NodeResources.storageType
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java16
-rw-r--r--config-model/src/main/resources/schema/common.rnc3
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java30
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java9
-rw-r--r--config-provisioning/abi-spec.json27
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java9
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java112
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/serialization/AllocatedHostsSerializer.java23
-rw-r--r--config-provisioning/src/main/resources/configdefinitions/flavors.def3
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java4
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeSpec.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityChecker.java37
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/MetricsReporter.java10
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Rebalancer.java6
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java24
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/CapacityPolicies.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/DockerHostCapacity.java7
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodePrioritizer.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceComparator.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/PrioritizableNode.java7
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodePatcher.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodeSerializer.java9
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java12
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java4
-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/ProvisioningTest.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/RestApiTest.java12
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg1.json1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg2.json1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/controller1.json1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-container1.json5
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1-os-upgrade-complete.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node2.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node3.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node4.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node5.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/dockerhost1-with-firmware-data.json3
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node8.json1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node9.json1
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/parent2.json3
43 files changed, 309 insertions, 130 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
index 86c72221cab..c0ce5ca22db 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
@@ -171,7 +171,8 @@ public class NodesSpecification {
Optional.ofNullable(resources.stringAttribute("bandwidth"))
.map(b -> parseGbAmount(b, "BPS"))
.orElse(0.3),
- parseOptionalDiskSpeed(resources.stringAttribute("disk-speed"))));
+ parseOptionalDiskSpeed(resources.stringAttribute("disk-speed")),
+ parseOptionalStorageType(resources.stringAttribute("storage-type"))));
}
else if (nodesElement.stringAttribute("flavor") != null) { // legacy fallback
return Optional.of(NodeResources.fromLegacyName(nodesElement.stringAttribute("flavor")));
@@ -221,12 +222,23 @@ public class NodesSpecification {
switch (diskSpeedString) {
case "fast" : return NodeResources.DiskSpeed.fast;
case "slow" : return NodeResources.DiskSpeed.slow;
- case "any" : return NodeResources.DiskSpeed.any;
+ case "any" : return NodeResources.DiskSpeed.any;
default: throw new IllegalArgumentException("Illegal disk-speed value '" + diskSpeedString +
"': Legal values are 'fast', 'slow' and 'any')");
}
}
+ private static NodeResources.StorageType parseOptionalStorageType(String storageTypeString) {
+ if (storageTypeString == null) return NodeResources.StorageType.any;
+ switch (storageTypeString) {
+ case "remote" : return NodeResources.StorageType.remote;
+ case "local" : return NodeResources.StorageType.local;
+ case "any" : return NodeResources.StorageType.any;
+ default: throw new IllegalArgumentException("Illegal storage-type value '" + storageTypeString +
+ "': Legal values are 'remote', 'local' and 'any')");
+ }
+ }
+
@Override
public String toString() {
return "specification of " + count + (dedicated ? " dedicated " : " ") + "nodes" +
diff --git a/config-model/src/main/resources/schema/common.rnc b/config-model/src/main/resources/schema/common.rnc
index c5690f9c915..e3ad942e7b3 100644
--- a/config-model/src/main/resources/schema/common.rnc
+++ b/config-model/src/main/resources/schema/common.rnc
@@ -27,7 +27,8 @@ Resources = element resources {
attribute vcpu { xsd:double { minExclusive = "0.0" } } &
attribute memory { xsd:string } &
attribute disk { xsd:string } &
- attribute disk-speed { xsd:string }?
+ attribute disk-speed { xsd:string }? &
+ attribute storage-type { xsd:string }?
}
OptionalDedicatedNodes = element nodes {
diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
index b8b50ba0eaa..fae0ba062bb 100644
--- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
@@ -813,45 +813,51 @@ public class ModelProvisioningTest {
"<?xml version='1.0' encoding='utf-8' ?>\n" +
"<services>" +
" <container version='1.0' id='container'>" +
- " <nodes count='3' flavor='container-node'/>" +
+ " <nodes count='3'>" +
+ " <resources vcpu='1' memory='1Gb' disk='1Gb'/>" +
+ " </nodes>" +
" </container>" +
" <content version='1.0' id='content1'>" +
" <redundancy>2</redundancy>" +
" <documents>" +
" <document type='type1' mode='index'/>" +
" </documents>" +
- " <nodes count='2' flavor='content1-node'/>" +
+ " <nodes count='2'>" +
+ " <resources vcpu='2' memory='2Gb' disk='2Gb'/>" +
+ " </nodes>" +
" </content>" +
" <content version='1.0' id='content2'>" +
" <redundancy>2</redundancy>" +
" <documents>" +
" <document type='type1' mode='index'/>" +
" </documents>" +
- " <nodes count='2' flavor='content2-node'/>" +
+ " <nodes count='2'>" +
+ " <resources vcpu='4' memory='4Gb' disk='4Gb'/>" +
+ " </nodes>" +
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
// use different flavors to make the test clearer
- tester.addHosts("container-node", 3);
- tester.addHosts("content1-node", 2);
- tester.addHosts("content2-node", 2);
+ tester.addHosts(new NodeResources(1, 1, 1, 0.3), 3);
+ tester.addHosts(new NodeResources(2, 2, 2, 0.3), 2);
+ tester.addHosts(new NodeResources(4, 4, 4, 0.3), 2);
VespaModel model = tester.createModel(services, true);
ContentCluster cluster1 = model.getContentClusters().get("content1");
ClusterControllerContainerCluster clusterControllers1 = cluster1.getClusterControllers();
assertEquals(1, clusterControllers1.getContainers().size());
- assertEquals("content1-node0", clusterControllers1.getContainers().get(0).getHostName());
- assertEquals("content1-node1", clusterControllers1.getContainers().get(1).getHostName());
- assertEquals("container-node0", clusterControllers1.getContainers().get(2).getHostName());
+ assertEquals("node-2-2-2-02", clusterControllers1.getContainers().get(0).getHostName());
+ assertEquals("node-2-2-2-01", clusterControllers1.getContainers().get(1).getHostName());
+ assertEquals("node-1-1-1-02", clusterControllers1.getContainers().get(2).getHostName());
ContentCluster cluster2 = model.getContentClusters().get("content2");
ClusterControllerContainerCluster clusterControllers2 = cluster2.getClusterControllers();
assertEquals(3, clusterControllers2.getContainers().size());
- assertEquals("content2-node0", clusterControllers2.getContainers().get(0).getHostName());
- assertEquals("content2-node1", clusterControllers2.getContainers().get(1).getHostName());
+ assertEquals("node-4-4-4-02", clusterControllers2.getContainers().get(0).getHostName());
+ assertEquals("node-4-4-4-01", clusterControllers2.getContainers().get(1).getHostName());
assertEquals("We do not pick the container used to supplement another cluster",
- "container-node1", clusterControllers2.getContainers().get(2).getHostName());
+ "node-1-1-1-01", clusterControllers2.getContainers().get(2).getHostName());
}
@Test
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
index 63269c45e5f..b6180ab78b9 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
@@ -60,15 +60,6 @@ public class VespaModelTester {
/** Adds some nodes with resources 1, 3, 9 */
public Hosts addHosts(int count) { return addHosts(new NodeResources(1, 3, 9, 1), count); }
- /** Adds some hosts to this system */
- public Hosts addHosts(String flavor, int count) {
- return addHosts(Optional.empty(), NodeResources.fromLegacyName(flavor), count);
- }
-
- public Hosts addHosts(Flavor flavor, int count) {
- return addHosts(Optional.of(flavor), NodeResources.fromLegacyName(flavor.name()), count);
- }
-
public Hosts addHosts(NodeResources resources, int count) {
return addHosts(Optional.of(new Flavor(resources)), resources, count);
}
diff --git a/config-provisioning/abi-spec.json b/config-provisioning/abi-spec.json
index 64dba165d36..5038cc8742a 100644
--- a/config-provisioning/abi-spec.json
+++ b/config-provisioning/abi-spec.json
@@ -599,6 +599,25 @@
"public static final enum com.yahoo.config.provision.NodeResources$DiskSpeed any"
]
},
+ "com.yahoo.config.provision.NodeResources$StorageType": {
+ "superClass": "java.lang.Enum",
+ "interfaces": [],
+ "attributes": [
+ "public",
+ "final",
+ "enum"
+ ],
+ "methods": [
+ "public static com.yahoo.config.provision.NodeResources$StorageType[] values()",
+ "public static com.yahoo.config.provision.NodeResources$StorageType valueOf(java.lang.String)",
+ "public static int compare(com.yahoo.config.provision.NodeResources$StorageType, com.yahoo.config.provision.NodeResources$StorageType)"
+ ],
+ "fields": [
+ "public static final enum com.yahoo.config.provision.NodeResources$StorageType remote",
+ "public static final enum com.yahoo.config.provision.NodeResources$StorageType local",
+ "public static final enum com.yahoo.config.provision.NodeResources$StorageType any"
+ ]
+ },
"com.yahoo.config.provision.NodeResources": {
"superClass": "java.lang.Object",
"interfaces": [],
@@ -606,21 +625,23 @@
"public"
],
"methods": [
- "public void <init>(double, double, double)",
- "public void <init>(double, double, double, com.yahoo.config.provision.NodeResources$DiskSpeed)",
"public void <init>(double, double, double, double)",
"public void <init>(double, double, double, double, com.yahoo.config.provision.NodeResources$DiskSpeed)",
+ "public void <init>(double, double, double, double, com.yahoo.config.provision.NodeResources$DiskSpeed, com.yahoo.config.provision.NodeResources$StorageType)",
"public double vcpu()",
"public double memoryGb()",
"public double diskGb()",
"public double bandwidthGbps()",
"public com.yahoo.config.provision.NodeResources$DiskSpeed diskSpeed()",
+ "public com.yahoo.config.provision.NodeResources$StorageType storageType()",
"public com.yahoo.config.provision.NodeResources withVcpu(double)",
"public com.yahoo.config.provision.NodeResources withMemoryGb(double)",
"public com.yahoo.config.provision.NodeResources withDiskGb(double)",
"public com.yahoo.config.provision.NodeResources withBandwidthGbps(double)",
"public com.yahoo.config.provision.NodeResources withDiskSpeed(com.yahoo.config.provision.NodeResources$DiskSpeed)",
- "public com.yahoo.config.provision.NodeResources anySpeed()",
+ "public com.yahoo.config.provision.NodeResources with(com.yahoo.config.provision.NodeResources$DiskSpeed)",
+ "public com.yahoo.config.provision.NodeResources with(com.yahoo.config.provision.NodeResources$StorageType)",
+ "public com.yahoo.config.provision.NodeResources numbersOnly()",
"public com.yahoo.config.provision.NodeResources subtract(com.yahoo.config.provision.NodeResources)",
"public com.yahoo.config.provision.NodeResources add(com.yahoo.config.provision.NodeResources)",
"public boolean equals(java.lang.Object)",
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
index bb4aca0e34b..7a4df8febcf 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Flavor.java
@@ -38,7 +38,8 @@ public class Flavor {
flavorConfig.minMainMemoryAvailableGb(),
flavorConfig.minDiskAvailableGb(),
flavorConfig.bandwidth() / 1000,
- flavorConfig.fastDisk() ? NodeResources.DiskSpeed.fast : NodeResources.DiskSpeed.slow),
+ flavorConfig.fastDisk() ? NodeResources.DiskSpeed.fast : NodeResources.DiskSpeed.slow,
+ flavorConfig.remoteStorage() ? NodeResources.StorageType.remote : NodeResources.StorageType.local),
Optional.empty(),
Type.valueOf(flavorConfig.environment()),
true,
@@ -71,11 +72,7 @@ public class Flavor {
if (!configured)
throw new IllegalArgumentException("Cannot override non-configured flavor");
- NodeResources newResources = new NodeResources(resources.vcpu(),
- resources.memoryGb(),
- flavorOverrides.diskGb().orElseGet(resources::diskGb),
- resources.bandwidthGbps(),
- resources.diskSpeed());
+ NodeResources newResources = resources.withDiskGb(flavorOverrides.diskGb().orElseGet(resources::diskGb));
return new Flavor(name, newResources, Optional.of(flavorOverrides), type, true, cost, minCpuCores);
}
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
index 66baecf6c82..15922aa69a4 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeResources.java
@@ -12,9 +12,9 @@ public class NodeResources {
public enum DiskSpeed {
- fast, // SSD disk or similar speed is needed
- slow, // This is tuned to work with the speed of spinning disks
- any; // The performance of the cluster using this does not depend on disk speed
+ fast, // Has/requires SSD disk or similar speed
+ slow, // Has spinning disk/Is tuned to work with the speed of spinning disks
+ any; // In requests only: The performance of the cluster using this does not depend on disk speed
/**
* Compares disk speeds by cost: Slower is cheaper, and therefore before.
@@ -29,6 +29,41 @@ public class NodeResources {
return 0;
}
+ private DiskSpeed combineWith(DiskSpeed other) {
+ if (this == any) return other;
+ if (other == any) return this;
+ if (this == other) return this;
+ throw new IllegalArgumentException(this + " cannot be combined with " + other);
+ }
+
+ }
+
+ public enum StorageType {
+
+ remote, // Has remote (network) storage/Is tuned to work with network storage
+ local, // Storage is/must be attached to the local host
+ any; // In requests only: Can use both local and remote storage
+
+ /**
+ * Compares storage type by cost: Remote is cheaper, and therefore before.
+ * Any can be remote and therefore costs the same as slow.
+ */
+ public static int compare(StorageType a, StorageType b) {
+ if (a == any) a = remote;
+ if (b == any) b = remote;
+
+ if (a == remote && b == local) return -1;
+ if (a == local && b == remote) return 1;
+ return 0;
+ }
+
+ private StorageType combineWith(StorageType other) {
+ if (this == any) return other;
+ if (other == any) return this;
+ if (this == other) return this;
+ throw new IllegalArgumentException(this + " cannot be combined with " + other);
+ }
+
}
private final double vcpu;
@@ -36,18 +71,7 @@ public class NodeResources {
private final double diskGb;
private final double bandwidthGbps;
private final DiskSpeed diskSpeed;
-
- /** Create node resources requiring fast disk and no bandwidth */
- @Deprecated // Remove Oct. 2019
- public NodeResources(double vcpu, double memoryGb, double diskGb) {
- this(vcpu, memoryGb, diskGb, DiskSpeed.fast);
- }
-
- /** Create node resources requiring no bandwidth */
- @Deprecated // Remove Oct. 2019
- public NodeResources(double vcpu, double memoryGb, double diskGb, DiskSpeed diskSpeed) {
- this(vcpu, memoryGb, diskGb, 0.3, diskSpeed);
- }
+ private final StorageType storageType;
/** Create node resources requiring fast disk */
public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps) {
@@ -55,11 +79,16 @@ public class NodeResources {
}
public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed) {
+ this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, StorageType.any);
+ }
+
+ public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed, StorageType storageType) {
this.vcpu = vcpu;
this.memoryGb = memoryGb;
this.diskGb = diskGb;
this.bandwidthGbps = bandwidthGbps;
this.diskSpeed = diskSpeed;
+ this.storageType = storageType;
}
public double vcpu() { return vcpu; }
@@ -67,30 +96,40 @@ public class NodeResources {
public double diskGb() { return diskGb; }
public double bandwidthGbps() { return bandwidthGbps; }
public DiskSpeed diskSpeed() { return diskSpeed; }
+ public StorageType storageType() { return storageType; }
public NodeResources withVcpu(double vcpu) {
- return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed);
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType);
}
public NodeResources withMemoryGb(double memoryGb) {
- return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed);
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType);
}
public NodeResources withDiskGb(double diskGb) {
- return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed);
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType);
}
public NodeResources withBandwidthGbps(double bandwidthGbps) {
- return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed);
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType);
}
+ // TODO: Remove after November 2019
public NodeResources withDiskSpeed(DiskSpeed speed) {
- return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, speed);
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, speed, storageType);
+ }
+
+ public NodeResources with(DiskSpeed speed) {
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, speed, storageType);
+ }
+
+ public NodeResources with(StorageType storageType) {
+ return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType);
}
- /** A shorthand for withDiskSpeed(NodeResources.DiskSpeed.any) */
- public NodeResources anySpeed() {
- return withDiskSpeed(NodeResources.DiskSpeed.any);
+ /** Returns this with disk speed and storage type set to any */
+ public NodeResources numbersOnly() {
+ return with(NodeResources.DiskSpeed.any).with(StorageType.any);
}
public NodeResources subtract(NodeResources other) {
@@ -100,7 +139,8 @@ public class NodeResources {
memoryGb - other.memoryGb,
diskGb - other.diskGb,
bandwidthGbps - other.bandwidthGbps,
- combine(this.diskSpeed, other.diskSpeed));
+ this.diskSpeed.combineWith(other.diskSpeed),
+ this.storageType.combineWith(other.storageType));
}
public NodeResources add(NodeResources other) {
@@ -110,22 +150,18 @@ public class NodeResources {
memoryGb + other.memoryGb,
diskGb + other.diskGb,
bandwidthGbps + other.bandwidthGbps,
- combine(this.diskSpeed, other.diskSpeed));
+ this.diskSpeed.combineWith(other.diskSpeed),
+ this.storageType.combineWith(other.storageType));
}
private boolean isInterchangeableWith(NodeResources other) {
if (this.diskSpeed != DiskSpeed.any && other.diskSpeed != DiskSpeed.any && this.diskSpeed != other.diskSpeed)
return false;
+ if (this.storageType != StorageType.any && other.storageType != StorageType.any && this.storageType != other.storageType)
+ return false;
return true;
}
- private DiskSpeed combine(DiskSpeed a, DiskSpeed b) {
- if (a == DiskSpeed.any) return b;
- if (b == DiskSpeed.any) return a;
- if (a == b) return a;
- throw new IllegalArgumentException(a + " cannot be combined with " + b);
- }
-
@Override
public boolean equals(Object o) {
if (o == this) return true;
@@ -136,19 +172,21 @@ public class NodeResources {
if (this.diskGb != other.diskGb) return false;
if (this.bandwidthGbps != other.bandwidthGbps) return false;
if (this.diskSpeed != other.diskSpeed) return false;
+ if (this.storageType != other.storageType) return false;
return true;
}
@Override
public int hashCode() {
- return Objects.hash(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed);
+ return Objects.hash(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType);
}
@Override
public String toString() {
return "[vcpu: " + vcpu + ", memory: " + memoryGb + " Gb, disk " + diskGb + " Gb" +
(bandwidthGbps > 0 ? ", bandwidth: " + bandwidthGbps + " Gbps" : "") +
- (diskSpeed != DiskSpeed.fast ? ", disk speed: " + diskSpeed : "") + "]";
+ (diskSpeed != DiskSpeed.fast ? ", disk speed: " + diskSpeed : "") +
+ (storageType != StorageType.any ? ", storage type: " + storageType : "") + "]";
}
/** Returns true if all the resources of this are the same or larger than the given resources */
@@ -163,6 +201,9 @@ public class NodeResources {
// draw conclusions about performance on the basis of better resources than you think you have
if (other.diskSpeed != DiskSpeed.any && other.diskSpeed != this.diskSpeed) return false;
+ // Same reasoning as the above
+ if (other.storageType != StorageType.any && other.storageType != this.storageType) return false;
+
return true;
}
@@ -173,6 +214,7 @@ public class NodeResources {
if (this.diskGb != other.diskGb) return false;
if (this.bandwidthGbps != other.bandwidthGbps) return false;
if (other.diskSpeed != DiskSpeed.any && other.diskSpeed != this.diskSpeed) return false;
+ if (other.storageType != StorageType.any && other.storageType != this.storageType) return false;
return true;
}
@@ -195,7 +237,7 @@ public class NodeResources {
if (cpu == 0) cpu = 0.5;
if (cpu == 2 && mem == 8 ) cpu = 1.5;
if (cpu == 2 && mem == 12 ) cpu = 2.3;
- return new NodeResources(cpu, mem, dsk, 0.3, DiskSpeed.fast);
+ return new NodeResources(cpu, mem, dsk, 0.3, DiskSpeed.fast, StorageType.any);
}
}
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 4a060fb5143..c7630f06552 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
@@ -55,6 +55,7 @@ public class AllocatedHostsSerializer {
private static final String diskKey = "disk";
private static final String bandwidthKey = "bandwidth";
private static final String diskSpeedKey = "diskSpeed";
+ private static final String storageTypeKey = "storageType";
/** Wanted version */
private static final String hostSpecVespaVersionKey = "vespaVersion";
@@ -109,6 +110,7 @@ public class AllocatedHostsSerializer {
resourcesObject.setDouble(diskKey, resources.diskGb());
resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps());
resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed()));
+ resourcesObject.setString(storageTypeKey, storageTypeToString(resources.storageType()));
}
public static AllocatedHosts fromJson(byte[] json, Optional<NodeFlavors> nodeFlavors) {
@@ -152,7 +154,8 @@ public class AllocatedHostsSerializer {
resources.field(memoryKey).asDouble(),
resources.field(diskKey).asDouble(),
resources.field(bandwidthKey).asDouble(),
- diskSpeedFromSlime(resources.field(diskSpeedKey))));
+ diskSpeedFromSlime(resources.field(diskSpeedKey)),
+ storageTypeFromSlime(resources.field(storageTypeKey))));
}
private static NodeResources.DiskSpeed diskSpeedFromSlime(Inspector diskSpeed) {
@@ -171,7 +174,25 @@ public class AllocatedHostsSerializer {
case any : return "any";
default: throw new IllegalStateException("Illegal disk-speed value '" + diskSpeed + "'");
}
+ }
+
+ private static NodeResources.StorageType storageTypeFromSlime(Inspector storageType) {
+ if ( ! storageType.valid()) return NodeResources.StorageType.any; // TODO: Remove this line after December 2019
+ switch (storageType.asString()) {
+ case "remote" : return NodeResources.StorageType.remote;
+ case "local" : return NodeResources.StorageType.local;
+ case "any" : return NodeResources.StorageType.any;
+ default: throw new IllegalStateException("Illegal storage-type value '" + storageType.asString() + "'");
+ }
+ }
+ private static String storageTypeToString(NodeResources.StorageType storageType) {
+ switch (storageType) {
+ case remote : return "remote";
+ case local : return "local";
+ case any : return "any";
+ default: throw new IllegalStateException("Illegal storage-type value '" + storageType + "'");
+ }
}
private static ClusterMembership membershipFromSlime(Inspector object) {
diff --git a/config-provisioning/src/main/resources/configdefinitions/flavors.def b/config-provisioning/src/main/resources/configdefinitions/flavors.def
index dbdca724158..c5040c58b74 100644
--- a/config-provisioning/src/main/resources/configdefinitions/flavors.def
+++ b/config-provisioning/src/main/resources/configdefinitions/flavors.def
@@ -30,5 +30,8 @@ flavor[].minDiskAvailableGb double default=0.0
# Whether the disk is fast (typically SSD) or slow (typically spinning HDD).
flavor[].fastDisk bool default=true
+# Whether the storage is remote (network) or local.
+flavor[].remoteStorage bool default=true
+
# Expected network interface bandwidth available for this flavor, in Mbit/s.
flavor[].bandwidth double default=0.0
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java
index 8cb5b08bcdb..bd87e821a74 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/deployment/InternalStepRunner.java
@@ -699,8 +699,8 @@ public class InternalStepRunner implements StepRunner {
int testMemoryMb = (int) (1024 * (resources.memoryGb() - jdiscMemoryGb) / 2);
String resourceString = String.format(Locale.ENGLISH,
- "<resources vcpu=\"%.2f\" memory=\"%.2fGb\" disk=\"%.2fGb\" disk-speed=\"%s\"/>",
- resources.vcpu(), resources.memoryGb(), resources.diskGb(), resources.diskSpeed().name());
+ "<resources vcpu=\"%.2f\" memory=\"%.2fGb\" disk=\"%.2fGb\" disk-speed=\"%s\" storage-type=\"%s\"/>",
+ resources.vcpu(), resources.memoryGb(), resources.diskGb(), resources.diskSpeed().name(), resources.storageType().name());
AthenzDomain idDomain = ("vespa.vespa.cd".equals(domain.value()) ? AthenzDomain.from("vespa.vespa") : domain);
String servicesXml =
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeSpec.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeSpec.java
index c2e68bdb329..a9bb42e4dde 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeSpec.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeSpec.java
@@ -20,6 +20,7 @@ import static com.yahoo.config.provision.NodeResources.DiskSpeed.slow;
* @author stiankri
*/
public class NodeSpec {
+
private final String hostname;
private final NodeState state;
private final NodeType type;
@@ -514,7 +515,7 @@ public class NodeSpec {
}
public Builder fastDisk(boolean fastDisk) {
- return resources(resources.withDiskSpeed(fastDisk ? fast : slow));
+ return resources(resources.with(fastDisk ? fast : slow));
}
public Builder bandwidthGbps(double bandwidthGbps) {
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 49f96d65c81..fc2e89f6819 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
@@ -338,8 +338,8 @@ public final class Node {
/** Computes the allocation skew of a host node */
public static double skew(NodeResources totalHostCapacity, NodeResources freeHostCapacity) {
- NodeResources all = totalHostCapacity.anySpeed();
- NodeResources allocated = all.subtract(freeHostCapacity.anySpeed());
+ NodeResources all = totalHostCapacity.numbersOnly();
+ NodeResources allocated = all.subtract(freeHostCapacity.numbersOnly());
return new Mean(allocated.vcpu() / all.vcpu(),
allocated.memoryGb() / all.memoryGb(),
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityChecker.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityChecker.java
index 83498aa8709..de2f573550c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityChecker.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/CapacityChecker.java
@@ -132,7 +132,7 @@ public class CapacityChecker {
int occupiedIps = 0;
Set<String> ipPool = host.ipAddressPool().asSet();
for (var child : nodeChildren.get(host)) {
- hostResources = hostResources.subtract(child.flavor().resources().withDiskSpeed(NodeResources.DiskSpeed.any));
+ hostResources = hostResources.subtract(child.flavor().resources().numbersOnly());
occupiedIps += child.ipAddresses().stream().filter(ipPool::contains).count();
}
availableResources.put(host, new AllocationResources(hostResources, host.ipAddressPool().asSet().size() - occupiedIps));
@@ -299,15 +299,20 @@ public class CapacityChecker {
reason.violatesParentHostPolicy = violatesParentHostPolicy(node, host, containedAllocations);
NodeResources l = availableHostResources.nodeResources;
- NodeResources r = node.allocation()
- .map(Allocation::requestedResources)
- .orElse(node.flavor().resources());
- if (l.vcpu() < r.vcpu()) { reason.insufficientVcpu = true; }
- if (l.memoryGb() < r.memoryGb()) { reason.insufficientMemoryGb = true; }
- if (l.diskGb() < r.diskGb()) { reason.insufficientDiskGb = true; }
+ NodeResources r = node.allocation().map(Allocation::requestedResources).orElse(node.flavor().resources());
+
+ if (l.vcpu() < r.vcpu())
+ reason.insufficientVcpu = true;
+ if (l.memoryGb() < r.memoryGb())
+ reason.insufficientMemoryGb = true;
+ if (l.diskGb() < r.diskGb())
+ reason.insufficientDiskGb = true;
if (r.diskSpeed() != NodeResources.DiskSpeed.any && r.diskSpeed() != l.diskSpeed())
- { reason.incompatibleDiskSpeed = true; }
- if (availableHostResources.availableIPs < 1) { reason.insufficientAvailableIPs = true; }
+ reason.incompatibleDiskSpeed = true;
+ if (r.storageType() != NodeResources.StorageType.any && r.storageType() != l.storageType())
+ reason.incompatibleStorageType = true;
+ if (availableHostResources.availableIPs < 1)
+ reason.insufficientAvailableIPs = true;
allocationFailureReasons.add(reason);
}
@@ -406,6 +411,7 @@ public class CapacityChecker {
* Keeps track of the reason why a host rejected an allocation.
*/
private static class AllocationFailureReason {
+
Node host;
public AllocationFailureReason (Node host) {
this.host = host;
@@ -414,6 +420,7 @@ public class CapacityChecker {
public boolean insufficientMemoryGb = false;
public boolean insufficientDiskGb = false;
public boolean incompatibleDiskSpeed = false;
+ public boolean incompatibleStorageType = false;
public boolean insufficientAvailableIPs = false;
public boolean violatesParentHostPolicy = false;
@@ -435,6 +442,7 @@ public class CapacityChecker {
if (insufficientMemoryGb) reasons.add("insufficientMemoryGb");
if (insufficientDiskGb) reasons.add("insufficientDiskGb");
if (incompatibleDiskSpeed) reasons.add("incompatibleDiskSpeed");
+ if (incompatibleStorageType) reasons.add("incompatibleStorageType");
if (insufficientAvailableIPs) reasons.add("insufficientAvailableIPs");
if (violatesParentHostPolicy) reasons.add("violatesParentHostPolicy");
@@ -446,7 +454,9 @@ public class CapacityChecker {
* Provides convenient methods for tallying failures.
*/
public static class AllocationFailureReasonList {
+
private List<AllocationFailureReason> allocationFailureReasons;
+
public AllocationFailureReasonList(List<AllocationFailureReason> allocationFailureReasons) {
this.allocationFailureReasons = allocationFailureReasons;
}
@@ -455,6 +465,7 @@ public class CapacityChecker {
public long insufficientMemoryGb() { return allocationFailureReasons.stream().filter(r -> r.insufficientMemoryGb).count(); }
public long insufficientDiskGb() { return allocationFailureReasons.stream().filter(r -> r.insufficientDiskGb).count(); }
public long incompatibleDiskSpeed() { return allocationFailureReasons.stream().filter(r -> r.incompatibleDiskSpeed).count(); }
+ public long incompatibleStorageType() { return allocationFailureReasons.stream().filter(r -> r.incompatibleStorageType).count(); }
public long insufficientAvailableIps() { return allocationFailureReasons.stream().filter(r -> r.insufficientAvailableIPs).count(); }
public long violatesParentHostPolicy() { return allocationFailureReasons.stream().filter(r -> r.violatesParentHostPolicy).count(); }
@@ -471,13 +482,14 @@ public class CapacityChecker {
}
@Override
public String toString() {
- return String.format("CPU (%3d), Memory (%3d), Disk size (%3d), Disk speed (%3d), IP (%3d), Parent-Host Policy (%3d)",
- insufficientVcpu(), insufficientMemoryGb(), insufficientDiskGb(),
- incompatibleDiskSpeed(), insufficientAvailableIps(), violatesParentHostPolicy());
+ return String.format("CPU (%3d), Memory (%3d), Disk size (%3d), Disk speed (%3d), Storage type (%3d), IP (%3d), Parent-Host Policy (%3d)",
+ insufficientVcpu(), insufficientMemoryGb(), insufficientDiskGb(), incompatibleDiskSpeed(),
+ incompatibleStorageType(), insufficientAvailableIps(), violatesParentHostPolicy());
}
}
public static class AllocationHistory {
+
public static class Entry {
public Node tenant;
public Node newParent;
@@ -533,6 +545,7 @@ public class CapacityChecker {
return out.toString();
}
+
}
}
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 5c8aab4d0aa..3a2b5f2cbb9 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
@@ -220,7 +220,7 @@ public class MetricsReporter extends Maintainer {
.forEach(
(applicationId, applicationNodes) -> {
var allocatedCapacity = applicationNodes.stream()
- .map(node -> node.allocation().get().requestedResources().withDiskSpeed(any))
+ .map(node -> node.allocation().get().requestedResources().numbersOnly())
.reduce(new NodeResources(0, 0, 0, 0, any), NodeResources::add);
var context = getContextAt(
@@ -238,20 +238,20 @@ public class MetricsReporter extends Maintainer {
private static NodeResources getCapacityTotal(NodeList nodes) {
return nodes.nodeType(NodeType.host).asList().stream()
.map(host -> host.flavor().resources())
- .map(resources -> resources.withDiskSpeed(any))
+ .map(resources -> resources.numbersOnly())
.reduce(new NodeResources(0, 0, 0, 0, any), NodeResources::add);
}
private static NodeResources getFreeCapacityTotal(NodeList nodes) {
return nodes.nodeType(NodeType.host).asList().stream()
.map(n -> freeCapacityOf(nodes, n))
- .map(resources -> resources.withDiskSpeed(any))
+ .map(resources -> resources.numbersOnly())
.reduce(new NodeResources(0, 0, 0, 0, any), NodeResources::add);
}
private static NodeResources freeCapacityOf(NodeList nodes, Node dockerHost) {
return nodes.childrenOf(dockerHost).asList().stream()
- .map(node -> node.flavor().resources().withDiskSpeed(any))
- .reduce(dockerHost.flavor().resources().withDiskSpeed(any), NodeResources::subtract);
+ .map(node -> node.flavor().resources().numbersOnly())
+ .reduce(dockerHost.flavor().resources().numbersOnly(), NodeResources::subtract);
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Rebalancer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Rebalancer.java
index 1c7fcff52f7..8bb8f375cc5 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Rebalancer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/Rebalancer.java
@@ -16,9 +16,7 @@ import com.yahoo.vespa.hosted.provision.provisioning.NodePrioritizer;
import java.time.Clock;
import java.time.Duration;
-import java.util.List;
import java.util.Optional;
-import java.util.stream.Stream;
public class Rebalancer extends Maintainer {
@@ -112,14 +110,14 @@ public class Rebalancer extends Maintainer {
private double skewReductionByRemoving(Node node, Node fromHost, DockerHostCapacity capacity) {
NodeResources freeHostCapacity = capacity.freeCapacityOf(fromHost);
double skewBefore = Node.skew(fromHost.flavor().resources(), freeHostCapacity);
- double skewAfter = Node.skew(fromHost.flavor().resources(), freeHostCapacity.add(node.flavor().resources().anySpeed()));
+ double skewAfter = Node.skew(fromHost.flavor().resources(), freeHostCapacity.add(node.flavor().resources().numbersOnly()));
return skewBefore - skewAfter;
}
private double skewReductionByAdding(Node node, Node toHost, DockerHostCapacity capacity) {
NodeResources freeHostCapacity = capacity.freeCapacityOf(toHost);
double skewBefore = Node.skew(toHost.flavor().resources(), freeHostCapacity);
- double skewAfter = Node.skew(toHost.flavor().resources(), freeHostCapacity.subtract(node.flavor().resources().anySpeed()));
+ double skewAfter = Node.skew(toHost.flavor().resources(), freeHostCapacity.subtract(node.flavor().resources().numbersOnly()));
return skewBefore - skewAfter;
}
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 a7c45cf1cbc..3ac9efb8313 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
@@ -86,6 +86,7 @@ public class NodeSerializer {
private static final String diskKey = "disk";
private static final String bandwidthKey = "bandwidth";
private static final String diskSpeedKey = "diskSpeed";
+ private static final String storageTypeKey = "storageType";
// Allocation fields
private static final String tenantIdKey = "tenantId";
@@ -166,6 +167,7 @@ public class NodeSerializer {
resourcesObject.setDouble(diskKey, resources.diskGb());
resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps());
resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed()));
+ resourcesObject.setString(storageTypeKey, storageTypeToString(resources.storageType()));
}
private void toSlime(Allocation allocation, Cursor object) {
@@ -251,7 +253,8 @@ public class NodeSerializer {
resources.field(memoryKey).asDouble(),
resources.field(diskKey).asDouble(),
resources.field(bandwidthKey).asDouble(),
- diskSpeedFromSlime(resources.field(diskSpeedKey))));
+ diskSpeedFromSlime(resources.field(diskSpeedKey)),
+ storageTypeFromSlime(resources.field(storageTypeKey))));
}
private Optional<Allocation> allocationFromSlime(NodeResources assignedResources, Inspector object) {
@@ -443,6 +446,25 @@ public class NodeSerializer {
case any : return "any";
default: throw new IllegalStateException("Illegal disk-speed value '" + diskSpeed + "'");
}
+ }
+ private static NodeResources.StorageType storageTypeFromSlime(Inspector storageType) {
+ if ( ! storageType.valid()) return NodeResources.StorageType.any; // TODO: Remove this line after December 2019
+ switch (storageType.asString()) {
+ case "remote" : return NodeResources.StorageType.remote;
+ case "local" : return NodeResources.StorageType.local;
+ case "any" : return NodeResources.StorageType.any;
+ default: throw new IllegalStateException("Illegal storage-type value '" + storageType.asString() + "'");
+ }
}
+
+ private static String storageTypeToString(NodeResources.StorageType storageType) {
+ switch (storageType) {
+ case remote : return "remote";
+ case local : return "local";
+ case any : return "any";
+ default: throw new IllegalStateException("Illegal storage-type value '" + storageType + "'");
+ }
+ }
+
}
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 98d06f7e01a..8ee9a92fa46 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
@@ -45,9 +45,9 @@ public class CapacityPolicies {
NodeResources resources = requestedResources.orElse(defaultNodeResources(cluster.type()));
- // Allow slow disks in zones which are not performance sensitive
+ // Allow slow storage in zones which are not performance sensitive
if (zone.system().isCd() || zone.environment() == Environment.dev || zone.environment() == Environment.test)
- resources = resources.withDiskSpeed(NodeResources.DiskSpeed.any);
+ resources = resources.with(NodeResources.DiskSpeed.any).with(NodeResources.StorageType.any);
// Dev does not cap the cpu of containers since usage is spotty: Allocate just a small amount exclusively
// Do not cap in AWS as hosts are allocated on demand and 1-to-1, so the node can use the entire host
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 9713615f77e..9f2b558a8e7 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
@@ -3,7 +3,6 @@ package com.yahoo.vespa.hosted.provision.provisioning;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.NodeType;
-import com.yahoo.vespa.hosted.provision.LockedNodeList;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
@@ -80,9 +79,9 @@ public class DockerHostCapacity {
// can be removed when all node allocations accurately reflect the true host disk speed
return allNodes.childrenOf(host).asList().stream()
.filter(node -> !(excludeInactive && isInactiveOrRetired(node)))
- .map(node -> node.flavor().resources().anySpeed())
- .reduce(hostResources.anySpeed(), NodeResources::subtract)
- .withDiskSpeed(host.flavor().resources().diskSpeed());
+ .map(node -> node.flavor().resources().with(NodeResources.DiskSpeed.any))
+ .reduce(hostResources.with(NodeResources.DiskSpeed.any), NodeResources::subtract)
+ .with(host.flavor().resources().diskSpeed());
}
private static boolean isInactiveOrRetired(Node node) {
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 a7081060f2e..f80ccff94e9 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
@@ -160,7 +160,8 @@ public class NodePrioritizer {
Node newNode = Node.createDockerNode(allocation.get().addresses(),
allocation.get().hostname(),
host.hostname(),
- resources(requestedNodes).withDiskSpeed(host.flavor().resources().diskSpeed()),
+ resources(requestedNodes).with(host.flavor().resources().diskSpeed())
+ .with(host.flavor().resources().storageType()),
NodeType.tenant);
PrioritizableNode nodePri = toPrioritizable(newNode, false, true);
if ( ! nodePri.violatesSpares || isAllocatingForReplacement) {
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceComparator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceComparator.java
index 51174d42d4b..f11807b040a 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceComparator.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeResourceComparator.java
@@ -30,6 +30,10 @@ public class NodeResourceComparator {
if (a.diskGb() < b.diskGb()) return -1;
if (a.vcpu() > b.vcpu()) return 1;
if (a.vcpu() < b.vcpu()) return -1;
+
+ int storageTypeComparison = NodeResources.StorageType.compare(a.storageType(), b.storageType());
+ if (storageTypeComparison != 0) return storageTypeComparison;
+
return compare(a.diskSpeed(), b.diskSpeed());
}
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 72f8550d063..08359e77d8b 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
@@ -89,6 +89,11 @@ class PrioritizableNode implements Comparable<PrioritizableNode> {
other.parent.get().flavor().resources().diskSpeed());
if (diskCostDifference != 0)
return diskCostDifference;
+
+ int storageCostDifference = NodeResources.StorageType.compare(this.parent.get().flavor().resources().storageType(),
+ other.parent.get().flavor().resources().storageType());
+ if (storageCostDifference != 0)
+ return storageCostDifference;
}
int hostPriority = Double.compare(this.skewWithThis() - this.skewWithoutThis(),
@@ -112,7 +117,7 @@ class PrioritizableNode implements Comparable<PrioritizableNode> {
private double skewWith(NodeResources resources) {
if (parent.isEmpty()) return 0;
- NodeResources free = freeParentCapacity.anySpeed().subtract(resources.anySpeed());
+ NodeResources free = freeParentCapacity.numbersOnly().subtract(resources.numbersOnly());
return Node.skew(parent.get().flavor().resources(), free);
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodePatcher.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodePatcher.java
index 072dc1172e1..81cf401d358 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodePatcher.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodePatcher.java
@@ -33,6 +33,8 @@ import java.util.stream.Collectors;
import static com.yahoo.config.provision.NodeResources.DiskSpeed.fast;
import static com.yahoo.config.provision.NodeResources.DiskSpeed.slow;
+import static com.yahoo.config.provision.NodeResources.StorageType.remote;
+import static com.yahoo.config.provision.NodeResources.StorageType.local;
/**
* A class which can take a partial JSON node/v2 node JSON structure and apply it to a node object.
@@ -152,7 +154,9 @@ public class NodePatcher {
case "minCpuCores":
return node.with(node.flavor().with(node.flavor().resources().withVcpu(value.asDouble())));
case "fastDisk":
- return node.with(node.flavor().with(node.flavor().resources().withDiskSpeed(value.asBool() ? fast : slow)));
+ return node.with(node.flavor().with(node.flavor().resources().with(value.asBool() ? fast : slow)));
+ case "remoteStorage":
+ return node.with(node.flavor().with(node.flavor().resources().with(value.asBool() ? remote : local)));
case "bandwidthGbps":
return node.with(node.flavor().with(node.flavor().resources().withBandwidthGbps(value.asDouble())));
case "modelName":
@@ -205,7 +209,7 @@ public class NodePatcher {
Optional<Allocation> allocation = node.allocation();
if (allocation.isPresent())
return node.with(allocation.get().withRequestedResources(
- allocation.get().requestedResources().withDiskSpeed(NodeResources.DiskSpeed.valueOf(value))));
+ allocation.get().requestedResources().with(NodeResources.DiskSpeed.valueOf(value))));
else
throw new IllegalArgumentException("Node is not allocated");
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodeSerializer.java
index 5d31e262d2a..57695a0a22c 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodeSerializer.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodeSerializer.java
@@ -79,4 +79,13 @@ public class NodeSerializer {
}
}
+ public String toString(NodeResources.StorageType storageType) {
+ switch (storageType) {
+ case remote : return "remote";
+ case local : return "local";
+ case any : return "any";
+ default: throw new IllegalArgumentException("Unknown storage type '" + storageType.name() + "'");
+ }
+ }
+
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
index 64cc2691010..b7b987e0d3f 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesApiHandler.java
@@ -51,6 +51,9 @@ import java.util.stream.Collectors;
import static com.yahoo.config.provision.NodeResources.DiskSpeed.fast;
import static com.yahoo.config.provision.NodeResources.DiskSpeed.slow;
+import static com.yahoo.config.provision.NodeResources.StorageType.remote;
+import static com.yahoo.config.provision.NodeResources.StorageType.local;
+import static com.yahoo.config.provision.NodeResources.StorageType.any;
import static com.yahoo.vespa.config.SlimeUtils.optionalString;
/**
@@ -239,13 +242,14 @@ public class NodesApiHandler extends LoggingRequestHandler {
private Flavor flavorFromSlime(Inspector inspector) {
Inspector flavorInspector = inspector.field("flavor");
- if (!flavorInspector.valid()) {
+ if ( ! flavorInspector.valid()) {
return new Flavor(new NodeResources(
requiredField(inspector, "minCpuCores", Inspector::asDouble),
requiredField(inspector, "minMainMemoryAvailableGb", Inspector::asDouble),
requiredField(inspector, "minDiskAvailableGb", Inspector::asDouble),
requiredField(inspector, "bandwidthGbps", Inspector::asDouble),
- requiredField(inspector, "fastDisk", Inspector::asBool) ? fast : slow));
+ requiredField(inspector, "fastDisk", Inspector::asBool) ? fast : slow,
+ requiredField(inspector, "remoteStorage", Inspector::asBool) ? remote : local));
}
Flavor flavor = nodeFlavors.getFlavorOrThrow(flavorInspector.asString());
@@ -258,7 +262,9 @@ public class NodesApiHandler extends LoggingRequestHandler {
if (inspector.field("bandwidthGbps").valid())
flavor = flavor.with(flavor.resources().withBandwidthGbps(inspector.field("bandwidthGbps").asDouble()));
if (inspector.field("fastDisk").valid())
- flavor = flavor.with(flavor.resources().withDiskSpeed(inspector.field("fastDisk").asBool() ? fast : slow));
+ flavor = flavor.with(flavor.resources().with(inspector.field("fastDisk").asBool() ? fast : slow));
+ if (inspector.field("remoteStorage").valid())
+ flavor = flavor.with(flavor.resources().with(inspector.field("remoteStorage").asBool() ? remote : local));
return flavor;
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
index 018d14ef6e0..07fefe8aabb 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java
@@ -154,6 +154,8 @@ class NodesResponse extends HttpResponse {
if (node.flavor().cost() > 0)
object.setLong("cost", node.flavor().cost());
object.setBool("fastDisk", node.flavor().hasFastDisk());
+ if (node.flavor().resources().storageType() != NodeResources.StorageType.any)
+ object.setBool("remoteStorage", node.flavor().resources().storageType() == NodeResources.StorageType.remote);
object.setDouble("bandwidthGbps", node.flavor().getBandwidthGbps());
object.setString("environment", node.flavor().getType().name());
node.allocation().ifPresent(allocation -> {
@@ -220,6 +222,8 @@ class NodesResponse extends HttpResponse {
object.setDouble("diskGb", resources.diskGb());
object.setDouble("bandwidthGbps", resources.bandwidthGbps());
object.setString("diskSpeed", serializer.toString(resources.diskSpeed()));
+ if (resources.storageType() != NodeResources.StorageType.any)
+ object.setString("storageType", serializer.toString(resources.storageType()));
}
// Hack: For non-docker noder, return current docker image as default prefix + current Vespa version
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 b52380242d7..a41b61fd352 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
@@ -89,16 +89,20 @@ public class DockerHostCapacityTest {
@Test
public void freeCapacityOf() {
- assertEquals(new NodeResources(5, 4, 8, 2), capacity.freeCapacityOf(host1, false));
- assertEquals(new NodeResources(5, 6, 8, 4.5), capacity.freeCapacityOf(host3, false));
+ assertEquals(new NodeResources(5, 4, 8, 2, NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote),
+ capacity.freeCapacityOf(host1, false));
+ assertEquals(new NodeResources(5, 6, 8, 4.5, NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote),
+ capacity.freeCapacityOf(host3, false));
doAnswer(invocation -> {
NodeResources totalHostResources = (NodeResources) invocation.getArguments()[0];
return totalHostResources.subtract(new NodeResources(1, 2, 3, 0.5, NodeResources.DiskSpeed.any));
}).when(hostResourcesCalculator).availableCapacityOf(any());
- assertEquals(new NodeResources(4, 2, 5, 1.5), capacity.freeCapacityOf(host1, false));
- assertEquals(new NodeResources(4, 4, 5, 4), capacity.freeCapacityOf(host3, false));
+ assertEquals(new NodeResources(4, 2, 5, 1.5, NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote),
+ capacity.freeCapacityOf(host1, false));
+ assertEquals(new NodeResources(4, 4, 5, 4, NodeResources.DiskSpeed.fast, NodeResources.StorageType.remote),
+ capacity.freeCapacityOf(host3, false));
}
private Set<String> generateIPs(int start, int count) {
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 a8b534e02ef..f4a97ccca0a 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
@@ -330,7 +330,7 @@ public class ProvisioningTest {
{
// Deploy with disk-speed any and make sure that information is retained
SystemState state = prepare(application, 0, 0, 3, 3,
- defaultResources.anySpeed(),
+ defaultResources.numbersOnly(),
tester);
assertEquals(6, state.allHosts.size());
tester.activate(application, state.allHosts);
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 59c3ef32dcb..1bae70c8d60 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
@@ -847,7 +847,7 @@ public class RestApiTest {
Request.Method.POST),
"{\"message\":\"Added 1 nodes to the provisioned state\"}");
assertResponseContains(new Request("http://localhost:8080/nodes/v2/node/" + hostname),
- "\"minDiskAvailableGb\":1234.0,\"minMainMemoryAvailableGb\":128.0,\"minCpuCores\":64.0,\"fastDisk\":true,\"bandwidthGbps\":15.0,");
+ "\"minDiskAvailableGb\":1234.0,\"minMainMemoryAvailableGb\":128.0,\"minCpuCores\":64.0,\"fastDisk\":true,\"remoteStorage\":true,\"bandwidthGbps\":15.0,");
// Test patching with overrides
assertResponse(new Request("http://localhost:8080/nodes/v2/node/" + hostname,
@@ -861,7 +861,7 @@ public class RestApiTest {
Request.Method.PATCH),
"{\"message\":\"Updated " + hostname + "\"}");
assertResponseContains(new Request("http://localhost:8080/nodes/v2/node/" + hostname),
- "\"minDiskAvailableGb\":5432.0,\"minMainMemoryAvailableGb\":128.0,\"minCpuCores\":64.0,\"fastDisk\":true,\"bandwidthGbps\":15.0,");
+ "\"minDiskAvailableGb\":5432.0,\"minMainMemoryAvailableGb\":128.0,\"minCpuCores\":64.0,\"fastDisk\":true,\"remoteStorage\":true,\"bandwidthGbps\":15.0,");
}
@Test
@@ -878,20 +878,20 @@ public class RestApiTest {
assertResponse(new Request("http://localhost:8080/nodes/v2/node",
("[{\"hostname\":\"" + hostname + "\"," + createIpAddresses("::1") + "\"openStackId\":\"osid-123\"," +
- "\"minDiskAvailableGb\":1234,\"minMainMemoryAvailableGb\":4321,\"minCpuCores\":5,\"fastDisk\":false,\"bandwidthGbps\":0.3}]")
+ "\"minDiskAvailableGb\":1234,\"minMainMemoryAvailableGb\":4321,\"minCpuCores\":5,\"fastDisk\":false,\"remoteStorage\":false,\"bandwidthGbps\":0.3}]")
.getBytes(StandardCharsets.UTF_8),
Request.Method.POST),
"{\"message\":\"Added 1 nodes to the provisioned state\"}");
assertResponseContains(new Request("http://localhost:8080/nodes/v2/node/" + hostname),
- "\"minDiskAvailableGb\":1234.0,\"minMainMemoryAvailableGb\":4321.0,\"minCpuCores\":5.0,\"fastDisk\":false,\"bandwidthGbps\":0.3,");
+ "\"minDiskAvailableGb\":1234.0,\"minMainMemoryAvailableGb\":4321.0,\"minCpuCores\":5.0,\"fastDisk\":false,\"remoteStorage\":false,\"bandwidthGbps\":0.3,");
// Test patching with overrides
assertResponse(new Request("http://localhost:8080/nodes/v2/node/" + hostname,
- "{\"minDiskAvailableGb\":12,\"minMainMemoryAvailableGb\":34,\"minCpuCores\":56,\"fastDisk\":true,\"bandwidthGbps\":78.0}".getBytes(StandardCharsets.UTF_8),
+ "{\"minDiskAvailableGb\":12,\"minMainMemoryAvailableGb\":34,\"minCpuCores\":56,\"fastDisk\":true,\"remoteStorage\":true,\"bandwidthGbps\":78.0}".getBytes(StandardCharsets.UTF_8),
Request.Method.PATCH),
"{\"message\":\"Updated " + hostname + "\"}");
assertResponseContains(new Request("http://localhost:8080/nodes/v2/node/" + hostname),
- "\"minDiskAvailableGb\":12.0,\"minMainMemoryAvailableGb\":34.0,\"minCpuCores\":56.0,\"fastDisk\":true,\"bandwidthGbps\":78.0");
+ "\"minDiskAvailableGb\":12.0,\"minMainMemoryAvailableGb\":34.0,\"minCpuCores\":56.0,\"fastDisk\":true,\"remoteStorage\":true,\"bandwidthGbps\":78.0");
}
private static String asDockerNodeJson(String hostname, String parentHostname, String... ipAddress) {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg1.json
index ba9467edb19..b48c719826b 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg1.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg1.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 16.0,
"minCpuCores": 2.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 10.0,
"environment": "BARE_METAL",
"rebootGeneration": 1,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg2.json
index aff38ae5403..0c32768ff78 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg2.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/cfg2.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 16.0,
"minCpuCores": 2.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 10.0,
"environment": "BARE_METAL",
"rebootGeneration": 1,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/controller1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/controller1.json
index 511853d980c..e7685b3195b 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/controller1.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/controller1.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 16.0,
"minCpuCores": 2.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 10.0,
"environment": "BARE_METAL",
"rebootGeneration": 0,
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 e419d709490..8ea4c6c1328 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,12 +6,13 @@
"hostname": "test-node-pool-102-2",
"parentHostname": "dockerhost3.yahoo.com",
"openStackId": "fake-test-node-pool-102-2",
- "flavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps]",
- "canonicalFlavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps]",
+ "flavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: remote]",
+ "canonicalFlavor": "[vcpu: 1.0, memory: 4.0 Gb, disk 100.0 Gb, bandwidth: 1.0 Gbps, storage type: remote]",
"minDiskAvailableGb": 100.0,
"minMainMemoryAvailableGb": 4.0,
"minCpuCores": 1.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 1.0,
"environment": "DOCKER_CONTAINER",
"owner": {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1-os-upgrade-complete.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1-os-upgrade-complete.json
index bb4ebd3588c..b527a904a9f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1-os-upgrade-complete.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1-os-upgrade-complete.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1.json
index 7a15e49c4c1..0463a724d20 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node1.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node2.json
index fb9d8675431..0057262421a 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node2.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node2.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node3.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node3.json
index 3e750c75403..a43ef1915aa 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node3.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node3.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node4.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node4.json
index 58aa6c4f60e..b28171f9149 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node4.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node4.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node5.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node5.json
index 80b09c7460c..d090dacc4a6 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node5.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/docker-node5.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/dockerhost1-with-firmware-data.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/dockerhost1-with-firmware-data.json
index a892b6ee142..954ab33459f 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/dockerhost1-with-firmware-data.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/dockerhost1-with-firmware-data.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 32.0,
"minCpuCores": 4.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 20.0,
"environment": "BARE_METAL",
"owner": {
@@ -29,7 +30,7 @@
"currentRestartGeneration": 0,
"wantedDockerImage": "docker-registry.domain.tld:8080/dist/vespa:6.42.0",
"wantedVespaVersion": "6.42.0",
- "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast" },
+ "requestedResources": { "vcpu":4.0, "memoryGb":32.0, "diskGb":1600.0, "bandwidthGbps":20.0, "diskSpeed":"fast", "storageType":"remote" },
"allowedToBeDown": false,
"rebootGeneration": 0,
"currentRebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json
index 9d2cec94367..aea563db164 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node4-after-changes.json
@@ -12,6 +12,7 @@
"minMainMemoryAvailableGb": 8.0,
"minCpuCores": 2.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 1.0,
"environment": "DOCKER_CONTAINER",
"owner": {
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node8.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node8.json
index a6e1ced6c2f..c597d9be8b5 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node8.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node8.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 16.0,
"minCpuCores": 2.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 10.0,
"environment": "BARE_METAL",
"rebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node9.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node9.json
index c23f89050bb..1cca5079345 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node9.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/node9.json
@@ -11,6 +11,7 @@
"minMainMemoryAvailableGb": 128.0,
"minCpuCores": 64.0,
"fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 15.0,
"environment": "BARE_METAL",
"rebootGeneration": 0,
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/parent2.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/parent2.json
index ae4663edb7c..1a056fac185 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/parent2.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/v2/responses/parent2.json
@@ -10,7 +10,8 @@
"minDiskAvailableGb": 2000.0,
"minMainMemoryAvailableGb": 128.0,
"minCpuCores": 64.0,
- "fastDisk":true,
+ "fastDisk": true,
+ "remoteStorage": true,
"bandwidthGbps": 15.0,
"environment": "BARE_METAL",
"rebootGeneration": 0,