@Override public String toString() { return flavor.name() + " has " + numReady + " ready nodes and " + numActive + " active nodes"; } }
@Inject public NodeFlavors(FlavorsConfig config) { ImmutableMap.Builder<String, Flavor> b = new ImmutableMap.Builder<>(); for (Flavor flavor : toFlavors(config)) b.put(flavor.name(), flavor); this.flavors = b.build(); }
/** Returns the subset of nodes which does not have the given flavor */ public NodeList notFlavor(String flavor) { return filter(node -> ! node.flavor().name().equals(flavor)); }
/** Returns the subset of nodes of the given flavor */ public NodeList flavor(String flavor) { return filter(node -> node.flavor().name().equals(flavor)); }
private static Collection<Flavor> toFlavors(FlavorsConfig config) { Map<String, Flavor> 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(); }
retirementPolicy.shouldRetire(node).ifPresent(reason -> { log.info("Setting wantToRetire and wantToDeprovision for host " + node.hostname() + " with flavor " + node.flavor().name() + " allocated to " + node.allocation().get().owner() + ". Reason: " + reason);
@Override public boolean matches(Node node) { if ( ! filter.matches(node.hostname(), node.flavor().name(), membership(node))) return false; return nextMatches(node); }
private void toSlime(HostSpec host, Cursor cursor) { cursor.setString(hostSpecHostName, host.hostname()); host.membership().ifPresent(membership -> { cursor.setString(hostSpecMembership, membership.stringValue()); cursor.setString(hostSpecVespaVersion, membership.cluster().vespaVersion().toFullString()); }); host.flavor().ifPresent(flavor -> cursor.setString(hostSpecFlavor, flavor.name())); host.version().ifPresent(version -> cursor.setString(hostSpecCurrentVespaVersion, version.toFullString())); }
private void updateDockerMetrics(List<Node> nodes) { // Capacity flavors for docker DockerHostCapacity capacity = new DockerHostCapacity(nodes); metric.set("hostedVespa.docker.totalCapacityCpu", capacity.getCapacityTotal().getCpu(), null); metric.set("hostedVespa.docker.totalCapacityMem", capacity.getCapacityTotal().getMemory(), null); metric.set("hostedVespa.docker.totalCapacityDisk", capacity.getCapacityTotal().getDisk(), null); metric.set("hostedVespa.docker.freeCapacityCpu", capacity.getFreeCapacityTotal().getCpu(), null); metric.set("hostedVespa.docker.freeCapacityMem", capacity.getFreeCapacityTotal().getMemory(), null); metric.set("hostedVespa.docker.freeCapacityDisk", capacity.getFreeCapacityTotal().getDisk(), null); List<Flavor> dockerFlavors = nodeRepository().getAvailableFlavors().getFlavors().stream() .filter(f -> f.getType().equals(Flavor.Type.DOCKER_CONTAINER)) .collect(Collectors.toList()); for (Flavor flavor : dockerFlavors) { Metric.Context context = getContextAt("flavor", flavor.name()); metric.set("hostedVespa.docker.freeCapacityFlavor", capacity.freeCapacityInFlavorEquivalence(flavor), context); metric.set("hostedVespa.docker.hostsAvailableFlavor", capacity.getNofHostsAvailableFor(flavor), context); } } }
private void toSlime(Node node, Cursor object) { object.setString(hostnameKey, node.hostname()); toSlime(node.ipAddresses(), object.setArray(ipAddressesKey), IP::requireAddresses); toSlime(node.ipAddressPool().asSet(), object.setArray(ipAddressPoolKey), IP::requireAddressPool); object.setString(idKey, node.id()); node.parentHostname().ifPresent(hostname -> object.setString(parentHostnameKey, hostname)); object.setString(flavorKey, node.flavor().name()); object.setLong(rebootGenerationKey, node.status().reboot().wanted()); object.setLong(currentRebootGenerationKey, node.status().reboot().current()); node.status().vespaVersion().ifPresent(version -> object.setString(vespaVersionKey, version.toString())); object.setLong(failCountKey, node.status().failCount()); node.status().hardwareFailureDescription().ifPresent(failure -> object.setString(hardwareFailureKey, failure)); object.setBool(wantToRetireKey, node.status().wantToRetire()); object.setBool(wantToDeprovisionKey, node.status().wantToDeprovision()); node.allocation().ifPresent(allocation -> toSlime(allocation, object.setObject(instanceKey))); toSlime(node.history(), object.setArray(historyKey)); object.setString(nodeTypeKey, toString(node.type())); node.status().hardwareDivergence().ifPresent(hardwareDivergence -> object.setString(hardwareDivergenceKey, hardwareDivergence)); node.status().osVersion().ifPresent(version -> object.setString(osVersionKey, version.toString())); node.status().firmwareVerifiedAt().ifPresent(instant -> object.setLong(firmwareCheckKey, instant.toEpochMilli())); node.reports().toSlime(object, reportsKey); }
object.setString("flavor", node.flavor().name()); object.setString("canonicalFlavor", node.flavor().canonicalName()); object.setDouble("minDiskAvailableGb", node.flavor().getMinDiskAvailableGb());