Search in sources :

Example 21 with Node

use of com.yahoo.vespa.hosted.provision.Node in project vespa by vespa-engine.

the class RetiredExpirer method canRemove.

/**
 * Checks if the node can be removed:
 * if the node is a docker host, it will only be removed if it has no children,
 * or all its children are parked or failed
 * Otherwise, a removal is allowed if either of these are true:
 * - The node has been in state {@link History.Event.Type#retired} for longer than {@link #retiredExpiry}
 * - Orchestrator allows it
 */
private boolean canRemove(Node node) {
    if (node.type().isDockerHost()) {
        return nodeRepository().getChildNodes(node.hostname()).stream().allMatch(child -> child.state() == Node.State.parked || child.state() == Node.State.failed);
    }
    Optional<Instant> timeOfRetiredEvent = node.history().event(History.Event.Type.retired).map(History.Event::at);
    Optional<Instant> retireAfter = timeOfRetiredEvent.map(retiredEvent -> retiredEvent.plus(retiredExpiry));
    boolean shouldRetireNowBecauseExpried = retireAfter.map(time -> time.isBefore(clock.instant())).orElse(false);
    if (shouldRetireNowBecauseExpried) {
        return true;
    }
    try {
        orchestrator.acquirePermissionToRemove(new HostName(node.hostname()));
        return true;
    } catch (OrchestrationException e) {
        log.info("Did not get permission to remove retired " + node + ": " + e.getMessage());
        return false;
    }
}
Also used : OrchestrationException(com.yahoo.vespa.orchestrator.OrchestrationException) Deployer(com.yahoo.config.provision.Deployer) ApplicationId(com.yahoo.config.provision.ApplicationId) Deployment(com.yahoo.config.provision.Deployment) NodeType(com.yahoo.config.provision.NodeType) Orchestrator(com.yahoo.vespa.orchestrator.Orchestrator) Node(com.yahoo.vespa.hosted.provision.Node) Instant(java.time.Instant) Collectors(java.util.stream.Collectors) Level(java.util.logging.Level) NodeRepository(com.yahoo.vespa.hosted.provision.NodeRepository) List(java.util.List) History(com.yahoo.vespa.hosted.provision.node.History) HostName(com.yahoo.vespa.applicationmodel.HostName) Duration(java.time.Duration) Map(java.util.Map) Clock(java.time.Clock) Optional(java.util.Optional) Instant(java.time.Instant) OrchestrationException(com.yahoo.vespa.orchestrator.OrchestrationException) HostName(com.yahoo.vespa.applicationmodel.HostName)

Example 22 with Node

use of com.yahoo.vespa.hosted.provision.Node in project vespa by vespa-engine.

the class CuratorDatabaseClient method writeTo.

/**
 * Writes the given nodes to the given state (whether or not they are already in this state or another),
 * and returns a copy of the incoming nodes in their persisted state.
 *
 * @param  toState the state to write the nodes to
 * @param  nodes the list of nodes to write
 * @param  agent the agent causing this change
 * @return the nodes in their persisted state
 */
public List<Node> writeTo(Node.State toState, List<Node> nodes, Agent agent, Optional<String> reason) {
    try (NestedTransaction nestedTransaction = new NestedTransaction()) {
        List<Node> writtenNodes = writeTo(toState, nodes, agent, reason, nestedTransaction);
        nestedTransaction.commit();
        return writtenNodes;
    }
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node) NestedTransaction(com.yahoo.transaction.NestedTransaction)

Example 23 with Node

use of com.yahoo.vespa.hosted.provision.Node in project vespa by vespa-engine.

the class Activator method updateFrom.

/**
 * Returns the input nodes with the changes resulting from applying the settings in hosts to the given list of nodes.
 */
private List<Node> updateFrom(Collection<HostSpec> hosts, List<Node> nodes) {
    List<Node> updated = new ArrayList<>();
    for (Node node : nodes) {
        HostSpec hostSpec = getHost(node.hostname(), hosts);
        node = hostSpec.membership().get().retired() ? node.retire(nodeRepository.clock().instant()) : node.unretire();
        node = node.with(node.allocation().get().with(hostSpec.membership().get()));
        if (// Docker nodes may change flavor
        hostSpec.flavor().isPresent())
            node = node.with(hostSpec.flavor().get());
        updated.add(node);
    }
    return updated;
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node) ArrayList(java.util.ArrayList) HostSpec(com.yahoo.config.provision.HostSpec)

Example 24 with Node

use of com.yahoo.vespa.hosted.provision.Node in project vespa by vespa-engine.

the class NodePrioritizer method toNodePriority.

/**
 * Convert a list of nodes to a list of node priorities. This includes finding, calculating
 * parameters to the priority sorting procedure.
 */
private PrioritizableNode toNodePriority(Node node, boolean isSurplusNode, boolean isNewNode) {
    PrioritizableNode pri = new PrioritizableNode();
    pri.node = node;
    pri.isSurplusNode = isSurplusNode;
    pri.isNewNode = isNewNode;
    pri.preferredOnFlavor = requestedNodes.specifiesNonStockFlavor() && node.flavor().equals(getFlavor(requestedNodes));
    pri.parent = findParentNode(node);
    if (pri.parent.isPresent()) {
        Node parent = pri.parent.get();
        pri.freeParentCapacity = capacity.freeCapacityOf(parent, false);
        if (spareHosts.contains(parent)) {
            pri.violatesSpares = true;
        }
        if (headroomHosts.containsKey(parent) && isPreferredNodeToBeReloacted(allNodes, node, parent)) {
            ResourceCapacity neededCapacity = headroomHosts.get(parent);
            // If the node is new then we need to check the headroom requirement after it has been added
            if (isNewNode) {
                neededCapacity = ResourceCapacity.composite(neededCapacity, new ResourceCapacity(node));
            }
            pri.violatesHeadroom = !capacity.hasCapacity(parent, neededCapacity);
        }
    }
    return pri;
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node)

Example 25 with Node

use of com.yahoo.vespa.hosted.provision.Node in project vespa by vespa-engine.

the class NodePrioritizer method addNewDockerNodes.

/**
 * Add a node on each docker host with enough capacity for the requested flavor
 */
void addNewDockerNodes() {
    if (!isDocker)
        return;
    DockerHostCapacity capacity = new DockerHostCapacity(allNodes);
    ResourceCapacity wantedResourceCapacity = ResourceCapacity.of(getFlavor(requestedNodes));
    NodeList list = new NodeList(allNodes);
    for (Node node : allNodes) {
        if (node.type() != NodeType.host)
            continue;
        if (node.state() != Node.State.active)
            continue;
        if (node.status().wantToRetire())
            continue;
        boolean hostHasCapacityForWantedFlavor = capacity.hasCapacity(node, wantedResourceCapacity);
        boolean conflictingCluster = list.childrenOf(node).owner(appId).asList().stream().anyMatch(child -> child.allocation().get().membership().cluster().id().equals(clusterSpec.id()));
        if (!hostHasCapacityForWantedFlavor || conflictingCluster)
            continue;
        log.log(LogLevel.DEBUG, "Trying to add new Docker node on " + node);
        Set<String> ipAddresses = DockerHostCapacity.findFreeIps(node, allNodes);
        if (ipAddresses.isEmpty())
            continue;
        String ipAddress = ipAddresses.stream().findFirst().get();
        Optional<String> hostname = nameResolver.getHostname(ipAddress);
        if (!hostname.isPresent()) {
            log.log(LogLevel.DEBUG, "Could not find hostname for " + ipAddress + ", skipping it");
            continue;
        }
        Node newNode = Node.createDockerNode("fake-" + hostname.get(), Collections.singleton(ipAddress), Collections.emptySet(), hostname.get(), Optional.of(node.hostname()), getFlavor(requestedNodes), NodeType.tenant);
        PrioritizableNode nodePri = toNodePriority(newNode, false, true);
        if (!nodePri.violatesSpares || isAllocatingForReplacement) {
            log.log(LogLevel.DEBUG, "Adding new Docker node " + newNode);
            nodes.put(newNode, nodePri);
        }
    }
}
Also used : NodeList(com.yahoo.vespa.hosted.provision.NodeList) Node(com.yahoo.vespa.hosted.provision.Node)

Aggregations

Node (com.yahoo.vespa.hosted.provision.Node)121 Test (org.junit.Test)67 ApplicationId (com.yahoo.config.provision.ApplicationId)40 ClusterSpec (com.yahoo.config.provision.ClusterSpec)33 List (java.util.List)26 ArrayList (java.util.ArrayList)23 Zone (com.yahoo.config.provision.Zone)22 Flavor (com.yahoo.config.provision.Flavor)21 HashSet (java.util.HashSet)19 Collectors (java.util.stream.Collectors)19 Optional (java.util.Optional)18 NodeRepository (com.yahoo.vespa.hosted.provision.NodeRepository)16 Duration (java.time.Duration)16 HostSpec (com.yahoo.config.provision.HostSpec)15 NodeType (com.yahoo.config.provision.NodeType)15 Agent (com.yahoo.vespa.hosted.provision.node.Agent)13 Map (java.util.Map)13 HashMap (java.util.HashMap)12 Collections (java.util.Collections)11 Set (java.util.Set)11