From b85e50a93d0af8537898526f93f1278eda3dfcca Mon Sep 17 00:00:00 2001 From: Valerij Fredriksen Date: Tue, 26 Feb 2019 16:54:22 +0100 Subject: Make Flavor interface --- config-provisioning/abi-spec.json | 111 +++++++++---- .../java/com/yahoo/config/provision/Flavor.java | 174 +++++++-------------- .../com/yahoo/config/provision/NodeFlavors.java | 72 +-------- .../config/provision/internal/ConfigFlavor.java | 172 ++++++++++++++++++++ .../provision/internal/ConfigNodeFlavors.java | 83 ++++++++++ .../main/resources/configdefinitions/flavors.def | 21 +-- 6 files changed, 404 insertions(+), 229 deletions(-) create mode 100644 config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigFlavor.java create mode 100644 config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigNodeFlavors.java diff --git a/config-provisioning/abi-spec.json b/config-provisioning/abi-spec.json index af61fb46e50..32027a9e48c 100644 --- a/config-provisioning/abi-spec.json +++ b/config-provisioning/abi-spec.json @@ -343,7 +343,48 @@ "public static final enum com.yahoo.config.provision.Environment perf" ] }, - "com.yahoo.config.provision.Flavor$Type": { + "com.yahoo.config.provision.Flavor$Bandwidth": { + "superClass": "java.lang.Object", + "interfaces": [], + "attributes": [ + "public", + "interface", + "abstract" + ], + "methods": [ + "public abstract double mbits()" + ], + "fields": [] + }, + "com.yahoo.config.provision.Flavor$Cpu": { + "superClass": "java.lang.Object", + "interfaces": [], + "attributes": [ + "public", + "interface", + "abstract" + ], + "methods": [ + "public abstract double cores()" + ], + "fields": [] + }, + "com.yahoo.config.provision.Flavor$Disk": { + "superClass": "java.lang.Object", + "interfaces": [], + "attributes": [ + "public", + "interface", + "abstract" + ], + "methods": [ + "public abstract double sizeInBase10Gb()", + "public double sizeInBase2Gb()", + "public abstract boolean isFast()" + ], + "fields": [] + }, + "com.yahoo.config.provision.Flavor$Environment": { "superClass": "java.lang.Enum", "interfaces": [], "attributes": [ @@ -352,46 +393,49 @@ "enum" ], "methods": [ - "public static com.yahoo.config.provision.Flavor$Type[] values()", - "public static com.yahoo.config.provision.Flavor$Type valueOf(java.lang.String)" + "public static com.yahoo.config.provision.Flavor$Environment[] values()", + "public static com.yahoo.config.provision.Flavor$Environment valueOf(java.lang.String)" ], "fields": [ - "public static final enum com.yahoo.config.provision.Flavor$Type undefined", - "public static final enum com.yahoo.config.provision.Flavor$Type BARE_METAL", - "public static final enum com.yahoo.config.provision.Flavor$Type VIRTUAL_MACHINE", - "public static final enum com.yahoo.config.provision.Flavor$Type DOCKER_CONTAINER" + "public static final enum com.yahoo.config.provision.Flavor$Environment BARE_METAL", + "public static final enum com.yahoo.config.provision.Flavor$Environment VIRTUAL_MACHINE", + "public static final enum com.yahoo.config.provision.Flavor$Environment DOCKER_CONTAINER" ] }, + "com.yahoo.config.provision.Flavor$Memory": { + "superClass": "java.lang.Object", + "interfaces": [], + "attributes": [ + "public", + "interface", + "abstract" + ], + "methods": [ + "public abstract double sizeInGb()" + ], + "fields": [] + }, "com.yahoo.config.provision.Flavor": { "superClass": "java.lang.Object", "interfaces": [], "attributes": [ - "public" + "public", + "interface", + "abstract" ], "methods": [ - "public void (com.yahoo.config.provisioning.FlavorsConfig$Flavor)", - "public java.lang.String name()", - "public int cost()", - "public boolean isStock()", - "public double getMinMainMemoryAvailableGb()", - "public double getMinDiskAvailableGb()", - "public boolean hasFastDisk()", - "public double getBandwidth()", - "public double getMinCpuCores()", - "public java.lang.String getDescription()", - "public boolean isRetired()", - "public com.yahoo.config.provision.Flavor$Type getType()", - "public boolean isDocker()", - "public int getIdealHeadroom()", + "public abstract java.lang.String flavorName()", "public java.lang.String canonicalName()", - "public boolean isCanonical()", - "public java.util.List replaces()", + "public abstract int cost()", + "public abstract boolean isStock()", + "public abstract boolean isRetired()", "public boolean satisfies(com.yahoo.config.provision.Flavor)", - "public void freeze()", - "public boolean isLargerThan(com.yahoo.config.provision.Flavor)", - "public int hashCode()", - "public boolean equals(java.lang.Object)", - "public java.lang.String toString()" + "public abstract com.yahoo.config.provision.Flavor$Cpu cpu()", + "public abstract com.yahoo.config.provision.Flavor$Memory memory()", + "public abstract com.yahoo.config.provision.Flavor$Disk disk()", + "public abstract com.yahoo.config.provision.Flavor$Bandwidth bandwidth()", + "public abstract com.yahoo.config.provision.Flavor$Environment environment()", + "public abstract java.util.List replaces()" ], "fields": [] }, @@ -547,12 +591,13 @@ "superClass": "java.lang.Object", "interfaces": [], "attributes": [ - "public" + "public", + "interface", + "abstract" ], "methods": [ - "public void (com.yahoo.config.provisioning.FlavorsConfig)", - "public java.util.List getFlavors()", - "public java.util.Optional getFlavor(java.lang.String)", + "public abstract java.util.List getFlavors()", + "public abstract java.util.Optional getFlavor(java.lang.String)", "public com.yahoo.config.provision.Flavor getFlavorOrThrow(java.lang.String)" ], "fields": [] 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 79a17c23dd7..e2c39d6efda 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 @@ -1,93 +1,17 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.provision; -import com.google.common.collect.ImmutableList; -import com.yahoo.config.provisioning.FlavorsConfig; - -import java.util.ArrayList; import java.util.List; /** - * A host flavor (type). This is a value object where the identity is the name. - * Use {@link NodeFlavors} to create a flavor. + * A host flavor (type). * * @author bratseth */ -public class Flavor { - - private final String name; - private final int cost; - private final boolean isStock; - private final Type type; - private final double minCpuCores; - private final double minMainMemoryAvailableGb; - private final double minDiskAvailableGb; - private final boolean fastDisk; - private final double bandwidth; - private final String description; - private final boolean retired; - private List replacesFlavors; - private int idealHeadroom; // Note: Not used after Vespa 6.282 - - /** - * Creates a Flavor, but does not set the replacesFlavors. - * @param flavorConfig config to be used for Flavor. - */ - public Flavor(FlavorsConfig.Flavor flavorConfig) { - this.name = flavorConfig.name(); - this.replacesFlavors = new ArrayList<>(); - this.cost = flavorConfig.cost(); - this.isStock = flavorConfig.stock(); - this.type = Type.valueOf(flavorConfig.environment()); - this.minCpuCores = flavorConfig.minCpuCores(); - this.minMainMemoryAvailableGb = flavorConfig.minMainMemoryAvailableGb(); - this.minDiskAvailableGb = flavorConfig.minDiskAvailableGb(); - this.fastDisk = flavorConfig.fastDisk(); - this.bandwidth = flavorConfig.bandwidth(); - this.description = flavorConfig.description(); - this.retired = flavorConfig.retired(); - this.idealHeadroom = flavorConfig.idealHeadroom(); - } - - /** Returns the unique identity of this flavor */ - public String name() { return name; } - - /** - * Get the monthly cost (total cost of ownership) in USD for this flavor, typically total cost - * divided by 36 months. - * - * @return monthly cost in USD - */ - public int cost() { return cost; } - - public boolean isStock() { return isStock; } - - public double getMinMainMemoryAvailableGb() { return minMainMemoryAvailableGb; } +public interface Flavor { - public double getMinDiskAvailableGb() { return minDiskAvailableGb; } - - public boolean hasFastDisk() { return fastDisk; } - - public double getBandwidth() { return bandwidth; } - - public double getMinCpuCores() { return minCpuCores; } - - public String getDescription() { return description; } - - /** Returns whether the flavor is retired */ - public boolean isRetired() { - return retired; - } - - public Type getType() { return type; } - - /** Convenience, returns getType() == Type.DOCKER_CONTAINER */ - public boolean isDocker() { return type == Type.DOCKER_CONTAINER; } - - /** The free capacity we would like to preserve for this flavor */ - public int getIdealHeadroom() { - return idealHeadroom; - } + /** @return the unique identity of this flavor */ + String flavorName(); /** * Returns the canonical name of this flavor - which is the name which should be used as an interface to users. @@ -102,69 +26,85 @@ public class Flavor { * replace the canonical name we want. However, if a node replaces multiple names, we have no basis for choosing one * of them as the canonical, so we return the current as canonical. */ - public String canonicalName() { - return isCanonical() ? name : replacesFlavors.get(0).canonicalName(); - } - - /** Returns whether this is a canonical flavor */ - public boolean isCanonical() { - return replacesFlavors.size() != 1; + default String canonicalName() { + return replaces().size() != 1 ? flavorName() : replaces().get(0).canonicalName(); } + /** @return the cost associated with usage of this flavor */ + int cost(); + /** - * The flavors this (directly) replaces. - * This is immutable if this is frozen, and a mutable list otherwise. + * A stock flavor is any flavor we expect more of in the future. + * Stock flavors are assigned to applications by cost priority. + * + * Non-stock flavors are used for nodes for which a fixed amount has already been added + * to the system for some historical reason. These nodes are assigned to applications + * when available by exact match and ignoring cost. */ - public List replaces() { return replacesFlavors; } + boolean isStock(); + + /** Returns whether the flavor is retired (should no longer be allocated) */ + boolean isRetired(); /** * Returns whether this flavor satisfies the requested flavor, either directly * (by being the same), or by directly or indirectly replacing it */ - public boolean satisfies(Flavor flavor) { - if (this.equals(flavor)) { + default boolean satisfies(Flavor flavor) { + if (equals(flavor)) { return true; } - if (this.retired) { + if (isRetired()) { return false; } - for (Flavor replaces : replacesFlavors) + for (Flavor replaces : replaces()) if (replaces.satisfies(flavor)) return true; return false; } - /** Irreversibly freezes the content of this */ - public void freeze() { - replacesFlavors = ImmutableList.copyOf(replacesFlavors); - } - - /** Returns whether this flavor has at least as much as each hardware resource as the given flavor */ - public boolean isLargerThan(Flavor other) { - return this.minCpuCores >= other.minCpuCores && - this.minDiskAvailableGb >= other.minDiskAvailableGb && - this.minMainMemoryAvailableGb >= other.minMainMemoryAvailableGb && - this.fastDisk || ! other.fastDisk; + Cpu cpu(); + + Memory memory(); + + Disk disk(); + + Bandwidth bandwidth(); + + Environment environment(); + + /** The flavors this (directly) replaces. */ + List replaces(); + + + interface Disk { + + /** @return Disk size in GB in base 10 (1GB = 10^9 bytes) */ + double sizeInBase10Gb(); + + /** @return Disk size in GB in base 2, also known as GiB (1GiB = 2^30 bytes), rounded to nearest integer value */ + default double sizeInBase2Gb() { + return Math.round(sizeInBase10Gb() / Math.pow(1.024, 3)); + } + + boolean isFast(); } - @Override - public int hashCode() { return name.hashCode(); } + interface Memory { + double sizeInGb(); + } - @Override - public boolean equals(Object other) { - if (other == this) return true; - if ( ! (other instanceof Flavor)) return false; - return ((Flavor)other).name.equals(this.name); + interface Cpu { + double cores(); } - @Override - public String toString() { return "flavor '" + name + "'"; } + interface Bandwidth { + double mbits(); + } - public enum Type { - undefined, // Default value in config (flavors.def) + enum Environment { BARE_METAL, VIRTUAL_MACHINE, DOCKER_CONTAINER } - } diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java index e64028e216f..43ef5602d8a 100644 --- a/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/NodeFlavors.java @@ -1,88 +1,30 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.provision; -import com.google.common.collect.ImmutableMap; -import com.google.inject.Inject; -import com.yahoo.config.provisioning.FlavorsConfig; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; /** * All the available node flavors. * - * @author bratseth + * @author freva */ -public class NodeFlavors { - - /** Flavors which are configured in this zone */ - private final ImmutableMap flavors; - - @Inject - public NodeFlavors(FlavorsConfig config) { - ImmutableMap.Builder b = new ImmutableMap.Builder<>(); - for (Flavor flavor : toFlavors(config)) - b.put(flavor.name(), flavor); - this.flavors = b.build(); - } +public interface NodeFlavors { - public List getFlavors() { - return new ArrayList<>(flavors.values()); - } + /** Returns list of all available flavors in the system */ + List getFlavors(); /** Returns a flavor by name, or empty if there is no flavor with this name. */ - public Optional getFlavor(String name) { - return Optional.ofNullable(flavors.get(name)); - } + Optional getFlavor(String name); /** Returns the flavor with the given name or throws an IllegalArgumentException if it does not exist */ - public Flavor getFlavorOrThrow(String flavorName) { + default Flavor getFlavorOrThrow(String flavorName) { return getFlavor(flavorName).orElseThrow(() -> new IllegalArgumentException("Unknown flavor '" + flavorName + "'. Flavors are " + canonicalFlavorNames())); } private List canonicalFlavorNames() { - return flavors.values().stream().map(Flavor::canonicalName).distinct().sorted().collect(Collectors.toList()); + return getFlavors().stream().map(Flavor::canonicalName).distinct().sorted().collect(Collectors.toList()); } - - private static Collection toFlavors(FlavorsConfig config) { - Map flavors = new HashMap<>(); - // First pass, create all flavors, but do not include flavorReplacesConfig. - for (FlavorsConfig.Flavor flavorConfig : config.flavor()) { - flavors.put(flavorConfig.name(), new Flavor(flavorConfig)); - } - // Second pass, set flavorReplacesConfig to point to correct flavor. - for (FlavorsConfig.Flavor flavorConfig : config.flavor()) { - Flavor flavor = flavors.get(flavorConfig.name()); - for (FlavorsConfig.Flavor.Replaces flavorReplacesConfig : flavorConfig.replaces()) { - if (! flavors.containsKey(flavorReplacesConfig.name())) { - throw new IllegalStateException("Replaces for " + flavor.name() + - " pointing to a non existing flavor: " + flavorReplacesConfig.name()); - } - flavor.replaces().add(flavors.get(flavorReplacesConfig.name())); - } - flavor.freeze(); - } - // Third pass, ensure that retired flavors have a replacement - for (Flavor flavor : flavors.values()) { - if (flavor.isRetired() && !hasReplacement(flavors.values(), flavor)) { - throw new IllegalStateException( - String.format("Flavor '%s' is retired, but has no replacement", flavor.name()) - ); - } - } - return flavors.values(); - } - - private static boolean hasReplacement(Collection flavors, Flavor flavor) { - return flavors.stream() - .filter(f -> !f.equals(flavor)) - .anyMatch(f -> f.satisfies(flavor)); - } - } diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigFlavor.java b/config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigFlavor.java new file mode 100644 index 00000000000..e70476455cd --- /dev/null +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigFlavor.java @@ -0,0 +1,172 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.provision.internal; + +import com.google.common.collect.ImmutableList; +import com.yahoo.config.provision.Flavor; +import com.yahoo.config.provisioning.FlavorsConfig; + +import java.util.ArrayList; +import java.util.List; + +/** + * A {@link Flavor} generated from config. + * + * @author freva + */ +public class ConfigFlavor implements Flavor { + + private final String name; + private final int cost; + private final boolean isStock; + private final Environment environment; + private final Cpu cpu; + private final Memory memory; + private final Disk disk; + private final Bandwidth bandwidth; + private final boolean retired; + private List replacesFlavors; + + /** + * Creates a Flavor, but does not set the replacesFlavors. + * @param flavorConfig config to be used for Flavor. + */ + public ConfigFlavor(FlavorsConfig.Flavor flavorConfig) { + this.name = flavorConfig.name(); + this.replacesFlavors = new ArrayList<>(); + this.cost = flavorConfig.cost(); + this.isStock = flavorConfig.stock(); + this.environment = Environment.valueOf(flavorConfig.environment()); + this.cpu = new ConfigCpu(flavorConfig.cpu()); + this.memory = new ConfigMemory(flavorConfig.memory()); + this.disk = new ConfigDisk(flavorConfig.disk()); + this.bandwidth = new ConfigBandwidth(flavorConfig.bandwidth()); + this.retired = flavorConfig.retired(); + } + + @Override + public String flavorName() { + return name; + } + + @Override + public int cost() { + return cost; + } + + @Override + public boolean isStock() { + return isStock; + } + + @Override + public boolean isRetired() { + return retired; + } + + @Override + public Cpu cpu() { + return cpu; + } + + @Override + public Memory memory() { + return memory; + } + + @Override + public Disk disk() { + return disk; + } + + @Override + public Bandwidth bandwidth() { + return bandwidth; + } + + @Override + public Environment environment() { + return environment; + } + + @Override + public List replaces() { + return replacesFlavors; + } + + /** Irreversibly freezes the content of this */ + public void freeze() { + replacesFlavors = ImmutableList.copyOf(replacesFlavors); + } + + @Override + public int hashCode() { return name.hashCode(); } + + @Override + public boolean equals(Object other) { + if (other == this) return true; + if ( ! (other instanceof ConfigFlavor)) return false; + return ((ConfigFlavor)other).name.equals(this.name); + } + + @Override + public String toString() { return "flavor '" + name + "'"; } + + private class ConfigCpu implements Flavor.Cpu { + private final double cores; + + private ConfigCpu(FlavorsConfig.Flavor.Cpu cpu) { + this.cores = cpu.cores(); + } + + @Override + public double cores() { + return cores; + } + } + + private class ConfigMemory implements Flavor.Memory { + private final double sizeInGb; + + private ConfigMemory(FlavorsConfig.Flavor.Memory memory) { + this.sizeInGb = memory.sizeInGb(); + } + + @Override + public double sizeInGb() { + return sizeInGb; + } + } + + private class ConfigDisk implements Flavor.Disk { + private final double sizeInBase10; + private final boolean isFast; + + private ConfigDisk(FlavorsConfig.Flavor.Disk disk) { + this.sizeInBase10 = disk.sizeInGb(); + this.isFast = disk.fast(); + } + + @Override + public double sizeInBase10Gb() { + return sizeInBase10; + } + + @Override + public boolean isFast() { + return isFast; + } + } + + private class ConfigBandwidth implements Flavor.Bandwidth { + private final double mbits; + + private ConfigBandwidth(FlavorsConfig.Flavor.Bandwidth bandwidth) { + this.mbits = bandwidth.mbits(); + } + + @Override + public double mbits() { + return mbits; + } + } +} diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigNodeFlavors.java b/config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigNodeFlavors.java new file mode 100644 index 00000000000..c67a3faf36f --- /dev/null +++ b/config-provisioning/src/main/java/com/yahoo/config/provision/internal/ConfigNodeFlavors.java @@ -0,0 +1,83 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.config.provision.internal; + +import com.google.common.collect.ImmutableMap; +import com.google.inject.Inject; +import com.yahoo.config.provision.Flavor; +import com.yahoo.config.provision.NodeFlavors; +import com.yahoo.config.provisioning.FlavorsConfig; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; + +/** + * {@link NodeFlavors} generated from config + * + * @author bratseth + */ +public class ConfigNodeFlavors implements NodeFlavors { + + /** Flavors which are configured in this zone */ + private final Map flavors; + + @Inject + public ConfigNodeFlavors(FlavorsConfig config) { + this(toFlavors(config)); + } + + public ConfigNodeFlavors(Collection flavors) { + ImmutableMap.Builder b = new ImmutableMap.Builder<>(); + for (Flavor flavor : flavors) + b.put(flavor.flavorName(), flavor); + this.flavors = b.build(); + } + + public List getFlavors() { + return new ArrayList<>(flavors.values()); + } + + /** Returns a flavor by name, or empty if there is no flavor with this name. */ + public Optional getFlavor(String name) { + return Optional.ofNullable(flavors.get(name)); + } + + private static Collection toFlavors(FlavorsConfig config) { + Map flavors = new HashMap<>(); + // First pass, create all flavors, but do not include flavorReplacesConfig. + for (FlavorsConfig.Flavor flavorConfig : config.flavor()) { + flavors.put(flavorConfig.name(), new ConfigFlavor(flavorConfig)); + } + // Second pass, set flavorReplacesConfig to point to correct flavor. + for (FlavorsConfig.Flavor flavorConfig : config.flavor()) { + Flavor flavor = flavors.get(flavorConfig.name()); + for (FlavorsConfig.Flavor.Replaces flavorReplacesConfig : flavorConfig.replaces()) { + if (! flavors.containsKey(flavorReplacesConfig.name())) { + throw new IllegalStateException("Replaces for " + flavor.flavorName() + + " pointing to a non existing flavor: " + flavorReplacesConfig.name()); + } + flavor.replaces().add(flavors.get(flavorReplacesConfig.name())); + } + ((ConfigFlavor) flavor).freeze(); + } + // Third pass, ensure that retired flavors have a replacement + for (Flavor flavor : flavors.values()) { + if (flavor.isRetired() && !hasReplacement(flavors.values(), flavor)) { + throw new IllegalStateException( + String.format("Flavor '%s' is retired, but has no replacement", flavor.flavorName()) + ); + } + } + return flavors.values(); + } + + private static boolean hasReplacement(Collection flavors, Flavor flavor) { + return flavors.stream() + .filter(f -> !f.equals(flavor)) + .anyMatch(f -> f.satisfies(flavor)); + } + +} diff --git a/config-provisioning/src/main/resources/configdefinitions/flavors.def b/config-provisioning/src/main/resources/configdefinitions/flavors.def index 1e40f6f8f36..d46f49b728d 100644 --- a/config-provisioning/src/main/resources/configdefinitions/flavors.def +++ b/config-provisioning/src/main/resources/configdefinitions/flavors.def @@ -26,29 +26,22 @@ flavor[].cost int default=0 flavor[].stock bool default=true # The type of node: BARE_METAL, VIRTUAL_MACHINE or DOCKER_CONTAINER -flavor[].environment string default="undefined" +flavor[].environment string default="BARE_METAL" # The minimum number of CPU cores available. -flavor[].minCpuCores double default=0.0 +flavor[].cpu.cores double default=0.0 # The minimum amount of main memory available. -flavor[].minMainMemoryAvailableGb double default=0.0 +flavor[].memory.sizeInGb double default=0.0 -# The minimum amount of disk available. -flavor[].minDiskAvailableGb double default=0.0 +# The minimum amount of disk available in GB in base 10 (1GB = 10^9 bytes) +flavor[].disk.sizeInGb double default=0.0 # Whether the disk is fast (typically SSD) or slow (typically spinning HDD). -flavor[].fastDisk bool default=true +flavor[].disk.fast bool default=true # Expected network interface bandwidth available for this flavor, in Mbit/s. -flavor[].bandwidth double default=0.0 - -# Human readable free text for description of node. -flavor[].description string default="" +flavor[].bandwidth.mbits double default=0.0 # The flavor is retired and should no longer be used. flavor[].retired bool default=false - -# The free capacity we would like to preserve for this flavor -# Note: Not used after Vespa 6.282 -flavor[].idealHeadroom int default=0 -- cgit v1.2.3