diff options
author | Harald Musum <musum@yahooinc.com> | 2022-02-23 13:31:22 +0100 |
---|---|---|
committer | Harald Musum <musum@yahooinc.com> | 2022-02-23 13:31:22 +0100 |
commit | 7eae707c3084ec702f85aa2d27eaae1e11e42ab2 (patch) | |
tree | f09bc035b4f413512af18adcf84b585e854c7453 /config-provisioning/src | |
parent | 13e5f28849839fc674dbd4b37683e5d7bbff5c57 (diff) |
Add support for achitecture in node resources
Diffstat (limited to 'config-provisioning/src')
6 files changed, 108 insertions, 19 deletions
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 37a3e6a3c4b..1b0fe246401 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 @@ -34,7 +34,8 @@ public class Flavor { flavorConfig.minDiskAvailableGb(), flavorConfig.bandwidth() / 1000, flavorConfig.fastDisk() ? NodeResources.DiskSpeed.fast : NodeResources.DiskSpeed.slow, - flavorConfig.remoteStorage() ? NodeResources.StorageType.remote : NodeResources.StorageType.local), + flavorConfig.remoteStorage() ? NodeResources.StorageType.remote : NodeResources.StorageType.local, + NodeResources.Architecture.valueOf(flavorConfig.architecture())), Optional.empty(), Type.valueOf(flavorConfig.environment()), true, 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 70db2c6b5d0..3d87d5f77eb 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 @@ -89,28 +89,65 @@ public class NodeResources { } + public enum Architecture { + + x86_64, + aarch64, + any; + + public static int compare(Architecture a, Architecture b) { + if (a == any) a = x86_64; + if (b == any) b = x86_64; + + if (a == x86_64 && b == aarch64) return -1; + if (a == aarch64 && b == x86_64) return 1; + return 0; + } + + public boolean compatibleWith(Architecture other) { + return this == any || other == any || other == this; + } + + private Architecture combineWith(Architecture 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 boolean isDefault() { return this == getDefault(); } + public static Architecture getDefault() { return x86_64; } + + } + private final double vcpu; private final double memoryGb; private final double diskGb; private final double bandwidthGbps; private final DiskSpeed diskSpeed; private final StorageType storageType; + private final Architecture architecture; public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps) { this(vcpu, memoryGb, diskGb, bandwidthGbps, DiskSpeed.getDefault()); } public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed) { - this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, StorageType.getDefault()); + this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, StorageType.getDefault(), Architecture.getDefault()); } public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed, StorageType storageType) { + this(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, Architecture.getDefault()); + } + + public NodeResources(double vcpu, double memoryGb, double diskGb, double bandwidthGbps, DiskSpeed diskSpeed, StorageType storageType, Architecture architecture) { this.vcpu = validate(vcpu, "vcpu"); this.memoryGb = validate(memoryGb, "memory"); this.diskGb = validate(diskGb, "disk"); this.bandwidthGbps = validate(bandwidthGbps, "bandwidth"); this.diskSpeed = diskSpeed; this.storageType = storageType; + this.architecture = architecture; } public double vcpu() { return vcpu; } @@ -119,6 +156,7 @@ public class NodeResources { public double bandwidthGbps() { return bandwidthGbps; } public DiskSpeed diskSpeed() { return diskSpeed; } public StorageType storageType() { return storageType; } + public Architecture architecture() { return architecture; } /** Returns the standard cost of these resources, in dollars per hour */ public double cost() { @@ -128,37 +166,37 @@ public class NodeResources { public NodeResources withVcpu(double vcpu) { ensureSpecified(); if (vcpu == this.vcpu) return this; - return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } public NodeResources withMemoryGb(double memoryGb) { ensureSpecified(); if (memoryGb == this.memoryGb) return this; - return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } public NodeResources withDiskGb(double diskGb) { ensureSpecified(); if (diskGb == this.diskGb) return this; - return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } public NodeResources withBandwidthGbps(double bandwidthGbps) { ensureSpecified(); if (bandwidthGbps == this.bandwidthGbps) return this; - return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } public NodeResources with(DiskSpeed diskSpeed) { ensureSpecified(); if (diskSpeed == this.diskSpeed) return this; - return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } public NodeResources with(StorageType storageType) { ensureSpecified(); if (storageType == this.storageType) return this; - return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return new NodeResources(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } /** Returns this with disk speed and storage type set to any */ @@ -183,7 +221,8 @@ public class NodeResources { diskGb - other.diskGb, bandwidthGbps - other.bandwidthGbps, this.diskSpeed.combineWith(other.diskSpeed), - this.storageType.combineWith(other.storageType)); + this.storageType.combineWith(other.storageType), + this.architecture.combineWith(other.architecture)); } public NodeResources add(NodeResources other) { @@ -195,7 +234,8 @@ public class NodeResources { diskGb + other.diskGb, bandwidthGbps + other.bandwidthGbps, this.diskSpeed.combineWith(other.diskSpeed), - this.storageType.combineWith(other.storageType)); + this.storageType.combineWith(other.storageType), + this.architecture.combineWith(other.architecture)); } private boolean isInterchangeableWith(NodeResources other) { @@ -205,6 +245,8 @@ public class NodeResources { return false; if (this.storageType != StorageType.any && other.storageType != StorageType.any && this.storageType != other.storageType) return false; + if (this.architecture != other.architecture) + return false; return true; } @@ -219,12 +261,13 @@ public class NodeResources { if ( ! equal(this.bandwidthGbps, other.bandwidthGbps)) return false; if (this.diskSpeed != other.diskSpeed) return false; if (this.storageType != other.storageType) return false; + if (this.architecture != other.architecture) return false; return true; } @Override public int hashCode() { - return Objects.hash(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType); + return Objects.hash(vcpu, memoryGb, diskGb, bandwidthGbps, diskSpeed, storageType, architecture); } private static StringBuilder appendDouble(StringBuilder sb, double d) { @@ -256,6 +299,7 @@ public class NodeResources { if ( !storageType.isDefault()) { sb.append(", storage type: ").append(storageType); } + sb.append(", architecture: ").append(architecture); sb.append(']'); return sb.toString(); } @@ -277,6 +321,9 @@ public class NodeResources { // Same reasoning as the above if (other.storageType != StorageType.any && other.storageType != this.storageType) return false; + // Same reasoning as the above + if (other.architecture != Architecture.any && other.architecture != this.architecture) return false; + return true; } @@ -288,6 +335,7 @@ public class NodeResources { if ( ! equal(this.bandwidthGbps, other.bandwidthGbps)) return false; if ( ! this.diskSpeed.compatibleWith(other.diskSpeed)) return false; if ( ! this.storageType.compatibleWith(other.storageType)) return false; + if ( ! this.architecture.compatibleWith(other.architecture)) return false; return true; } @@ -339,10 +387,10 @@ 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.getDefault(), StorageType.getDefault()); + return new NodeResources(cpu, mem, dsk, 0.3, DiskSpeed.getDefault(), StorageType.getDefault(), Architecture.x86_64); } - private double validate(double value, String valueName) { + private double validate(double value, String valueName) { if (Double.isNaN(value)) throw new IllegalArgumentException(valueName + " cannot be NaN"); if (Double.isInfinite(value)) throw new IllegalArgumentException(valueName + " cannot be infinite"); return value; 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 68ac4d3151c..19bdfd0a358 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 @@ -51,6 +51,7 @@ public class AllocatedHostsSerializer { private static final String bandwidthKey = "bandwidth"; private static final String diskSpeedKey = "diskSpeed"; private static final String storageTypeKey = "storageType"; + private static final String architectureKey = "architecture"; /** Wanted version */ private static final String hostSpecVespaVersionKey = "vespaVersion"; @@ -81,9 +82,7 @@ public class AllocatedHostsSerializer { host.membership().ifPresent(membership -> { object.setString(hostSpecMembershipKey, membership.stringValue()); object.setString(hostSpecVespaVersionKey, membership.cluster().vespaVersion().toFullString()); - membership.cluster().dockerImageRepo().ifPresent(repo -> { - object.setString(hostSpecDockerImageRepoKey, repo.untagged()); - }); + membership.cluster().dockerImageRepo().ifPresent(repo -> object.setString(hostSpecDockerImageRepoKey, repo.untagged())); }); toSlime(host.realResources(), object.setObject(realResourcesKey)); toSlime(host.advertisedResources(), object.setObject(advertisedResourcesKey)); @@ -106,6 +105,7 @@ public class AllocatedHostsSerializer { resourcesObject.setDouble(bandwidthKey, resources.bandwidthGbps()); resourcesObject.setString(diskSpeedKey, diskSpeedToString(resources.diskSpeed())); resourcesObject.setString(storageTypeKey, storageTypeToString(resources.storageType())); + //resourcesObject.setString(architectureKey, architectureToString(resources.architecture())); // TODO: Add when architecture names have been decided } public static AllocatedHosts fromJson(byte[] json) { @@ -154,6 +154,7 @@ public class AllocatedHostsSerializer { resources.field(bandwidthKey).asDouble(), diskSpeedFromSlime(resources.field(diskSpeedKey)), storageTypeFromSlime(resources.field(storageTypeKey))); + //architectureFromSlime(resources.field(architectureKey))); // TODO: Add when architecture names have been decided } private static NodeResources optionalNodeResourcesFromSlime(Inspector resources) { @@ -197,6 +198,29 @@ public class AllocatedHostsSerializer { } } + + /* + private static NodeResources.Architecture architectureFromSlime(Inspector architecture) { + if ( ! architecture.valid()) return NodeResources.Architecture.x86_64; + switch (architecture.asString()) { + case "x86_64" : return NodeResources.Architecture.x86_64; + case "aarch64" : return NodeResources.Architecture.aarch64; + case "any" : return NodeResources.Architecture.any; + default: throw new IllegalStateException("Illegal architecture value '" + architecture.asString() + "'"); + } + } + + */ + + private static String architectureToString(NodeResources.Architecture architecture) { + switch (architecture) { + case x86_64: return "x86_64"; + case aarch64: return "aarch64"; + case any : return "any"; + default: throw new IllegalStateException("Illegal architecture value '" + architecture + "'"); + } + } + private static ClusterMembership membershipFromSlime(Inspector object) { return ClusterMembership.from(object.field(hostSpecMembershipKey).asString(), com.yahoo.component.Version.fromString(object.field(hostSpecVespaVersionKey).asString()), diff --git a/config-provisioning/src/main/resources/configdefinitions/config.provisioning.flavors.def b/config-provisioning/src/main/resources/configdefinitions/config.provisioning.flavors.def index e4fc934e6ae..765d6c2f812 100644 --- a/config-provisioning/src/main/resources/configdefinitions/config.provisioning.flavors.def +++ b/config-provisioning/src/main/resources/configdefinitions/config.provisioning.flavors.def @@ -35,3 +35,6 @@ flavor[].remoteStorage bool default=true # Expected network interface bandwidth available for this flavor, in Mbit/s. flavor[].bandwidth double default=0.0 + +# The architecture for this flavor +flavor[].architecture string default="x86_64" diff --git a/config-provisioning/src/test/java/com/yahoo/config/provision/NodeResourcesTest.java b/config-provisioning/src/test/java/com/yahoo/config/provision/NodeResourcesTest.java index 807c5d0a273..564c53eeff0 100644 --- a/config-provisioning/src/test/java/com/yahoo/config/provision/NodeResourcesTest.java +++ b/config-provisioning/src/test/java/com/yahoo/config/provision/NodeResourcesTest.java @@ -15,11 +15,11 @@ public class NodeResourcesTest { @Test public void testToString() { - assertEquals("[vcpu: 1.0, memory: 10.0 Gb, disk 100.0 Gb]", + assertEquals("[vcpu: 1.0, memory: 10.0 Gb, disk 100.0 Gb, architecture: x86_64]", new NodeResources(1., 10., 100., 0).toString()); - assertEquals("[vcpu: 0.3, memory: 3.3 Gb, disk 33.3 Gb, bandwidth: 0.3 Gbps]", + assertEquals("[vcpu: 0.3, memory: 3.3 Gb, disk 33.3 Gb, bandwidth: 0.3 Gbps, architecture: x86_64]", new NodeResources(1/3., 10/3., 100/3., 0.3).toString()); - assertEquals("[vcpu: 0.7, memory: 9.0 Gb, disk 66.7 Gb, bandwidth: 0.7 Gbps]", + assertEquals("[vcpu: 0.7, memory: 9.0 Gb, disk 66.7 Gb, bandwidth: 0.7 Gbps, architecture: x86_64]", new NodeResources(2/3., 8.97, 200/3., 0.67).toString()); } 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 4c5982708fa..3363c920bbd 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 @@ -28,6 +28,7 @@ public class AllocatedHostsSerializerTest { private static final NodeResources smallSlowDiskSpeedNode = new NodeResources(0.5, 3.1, 4, 1, NodeResources.DiskSpeed.slow); private static final NodeResources bigSlowDiskSpeedNode = new NodeResources(1.0, 6.2, 8, 2, NodeResources.DiskSpeed.slow); private static final NodeResources anyDiskSpeedNode = new NodeResources(0.5, 3.1, 4, 1, NodeResources.DiskSpeed.any); + private static final NodeResources aaarch64Node = new NodeResources(0.5, 3.1, 4, 1, NodeResources.DiskSpeed.any, NodeResources.StorageType.any, NodeResources.Architecture.aarch64); @Test public void testAllocatedHostsSerialization() throws IOException { @@ -70,6 +71,18 @@ public class AllocatedHostsSerializerTest { Optional.of(new NetworkPorts(List.of(new NetworkPorts.Allocation(1234, "service1", "configId1", "suffix1"), new NetworkPorts.Allocation(4567, "service2", "configId2", "suffix2")))), Optional.empty())); + /* + hosts.add(new HostSpec("aaarch64", + aaarch64Node, + aaarch64Node, + aaarch64Node, + ClusterMembership.from("container/test/0/0", Version.fromString("6.73.1"), + Optional.empty()), + Optional.empty(), + Optional.of(new NetworkPorts(List.of(new NetworkPorts.Allocation(1234, "service1", "configId1", "suffix1"), + new NetworkPorts.Allocation(4567, "service2", "configId2", "suffix2")))), + Optional.empty())); + */ assertAllocatedHosts(AllocatedHosts.withHosts(hosts)); } |