@Override public Optional<String> shouldRetire(Node node) { if (node.flavor().getType() == Flavor.Type.VIRTUAL_MACHINE) return Optional.empty(); boolean shouldRetire = node.ipAddresses().stream() .map(InetAddresses::forString) .allMatch(address -> address instanceof Inet4Address); return shouldRetire ? Optional.of("Node is IPv4-only") : Optional.empty(); } }
@Override protected void maintain() { // Reboot candidates: Nodes in long-term states, which we know can safely orchestrate a reboot EnumSet<Node.State> targetStates = EnumSet.of(Node.State.active, Node.State.ready); List<Node> nodesToReboot = nodeRepository().getNodes().stream() .filter(node -> targetStates.contains(node.state())) .filter(node -> node.flavor().getType() != Flavor.Type.DOCKER_CONTAINER) .filter(this::shouldReboot) .collect(Collectors.toList()); if (!nodesToReboot.isEmpty()) nodeRepository().reboot(NodeListFilter.from(nodesToReboot)); }
private boolean isDocker() { Flavor flavor = getFlavor(requestedNodes); return (flavor != null) && flavor.getType().equals(Flavor.Type.DOCKER_CONTAINER); }
node.allocation().get()); if (node.flavor().getType() == Flavor.Type.DOCKER_CONTAINER && !deletingAsChild) { if (node.state() != Node.State.ready) { throw new IllegalArgumentException( } else if (node.flavor().getType() == Flavor.Type.DOCKER_CONTAINER) { Set<Node.State> legalStates = EnumSet.of(Node.State.provisioned, Node.State.failed, Node.State.parked, Node.State.ready);
public Node markNodeAvailableForNewAllocation(String hostname, Agent agent, String reason) { Node node = getNode(hostname).orElseThrow(() -> new NotFoundException("No node with hostname '" + hostname + "'")); if (node.flavor().getType() == Flavor.Type.DOCKER_CONTAINER && node.type() == NodeType.tenant) { if (node.state() != Node.State.dirty) { throw new IllegalArgumentException( "Cannot make " + hostname + " available for new allocation, must be in state dirty, but was in " + node.state()); } return removeRecursively(node, true).get(0); } if (node.state() == Node.State.ready) return node; return setReady(Collections.singletonList(node), agent, reason).get(0); }
/** Adds a list of newly created docker container nodes to the node repository as <i>reserved</i> nodes */ // NOTE: This can only be called while holding the allocation lock, and that lock must have been held since // the nodes list was computed public List<Node> addDockerNodes(List<Node> nodes, Mutex allocationLock) { for (Node node : nodes) { if (!node.flavor().getType().equals(Flavor.Type.DOCKER_CONTAINER)) { throw new IllegalArgumentException("Cannot add " + node.hostname() + ": This is not a docker node"); } if (!node.allocation().isPresent()) { throw new IllegalArgumentException("Cannot add " + node.hostname() + ": Docker containers needs to be allocated"); } Optional<Node> existing = getNode(node.hostname()); if (existing.isPresent()) throw new IllegalArgumentException("Cannot add " + node.hostname() + ": A node with this name already exists (" + existing.get() + ", " + existing.get().history() + "). Node to be added: " + node + ", " + node.history()); } return db.addNodesInState(nodes, Node.State.reserved); }
public Flavor decideFlavor(Capacity requestedCapacity, ClusterSpec cluster) { // for now, always use the requested flavor if a docker flavor is requested Optional<String> requestedFlavor = requestedCapacity.flavor(); if (requestedFlavor.isPresent() && flavors.getFlavorOrThrow(requestedFlavor.get()).getType() == Flavor.Type.DOCKER_CONTAINER) return flavors.getFlavorOrThrow(requestedFlavor.get()); String defaultFlavorName = zone.defaultFlavor(cluster.type()); if (zone.system() == SystemName.cd) return flavors.getFlavorOrThrow(requestedFlavor.orElse(defaultFlavorName)); switch(zone.environment()) { case dev : case test : case staging : return flavors.getFlavorOrThrow(defaultFlavorName); default : return flavors.getFlavorOrThrow(requestedFlavor.orElse(defaultFlavorName)); } }
/** Returns whether the current node fail count should be used as an indicator of hardware issue */ private boolean failCountIndicatesHardwareIssue(Node node) { if (node.flavor().getType() == Flavor.Type.DOCKER_CONTAINER) return false; return (zone.environment() == Environment.prod || zone.environment() == Environment.staging) && node.status().failCount() >= maxAllowedFailures; }
private void setHwInfo(ProtonConfig.Builder builder) { builder.hwinfo.disk.size((long)nodeFlavor.getMinDiskAvailableGb() * GB); builder.hwinfo.disk.shared(nodeFlavor.getType().equals(Flavor.Type.DOCKER_CONTAINER)); builder.hwinfo.memory.size((long)nodeFlavor.getMinMainMemoryAvailableGb() * GB); builder.hwinfo.cpu.cores((int)nodeFlavor.getMinCpuCores()); }
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); } } }
object.setBool("fastDisk", node.flavor().hasFastDisk()); object.setDouble("bandwidth", node.flavor().getBandwidth()); object.setString("environment", node.flavor().getType().name()); if (node.allocation().isPresent()) { toSlime(node.allocation().get().owner(), object.setObject("owner"));