Search in sources :

Example 6 with Node

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

the class SerializationTest method want_to_retire_defaults_to_false.

@Test
public void want_to_retire_defaults_to_false() {
    String nodeData = "{\n" + "   \"type\" : \"tenant\",\n" + "   \"flavor\" : \"large\",\n" + "   \"openStackId\" : \"myId\",\n" + "   \"hostname\" : \"myHostname\",\n" + "   \"ipAddresses\" : [\"127.0.0.1\"]\n" + "}";
    Node node = nodeSerializer.fromJson(State.provisioned, Utf8.toBytes(nodeData));
    assertFalse(node.status().wantToRetire());
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node) Test(org.junit.Test)

Example 7 with Node

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

the class SerializationTest method testRetiredNodeSerialization.

@Test
public void testRetiredNodeSerialization() {
    Node node = createNode();
    clock.advance(Duration.ofMinutes(3));
    assertEquals(0, node.history().events().size());
    node = node.allocate(ApplicationId.from(TenantName.from("myTenant"), ApplicationName.from("myApplication"), InstanceName.from("myInstance")), ClusterMembership.from("content/myId/0/0", Vtag.currentVersion), clock.instant());
    assertEquals(1, node.history().events().size());
    clock.advance(Duration.ofMinutes(2));
    node = node.retire(Agent.application, clock.instant());
    Node copy = nodeSerializer.fromJson(Node.State.provisioned, nodeSerializer.toJson(node));
    assertEquals(2, copy.history().events().size());
    assertEquals(clock.instant(), copy.history().event(History.Event.Type.retired).get().at());
    assertEquals(Agent.application, (copy.history().event(History.Event.Type.retired).get()).agent());
    assertTrue(copy.allocation().get().membership().retired());
    Node removable = copy.with(node.allocation().get().removable());
    Node removableCopy = nodeSerializer.fromJson(Node.State.provisioned, nodeSerializer.toJson(removable));
    assertTrue(removableCopy.allocation().get().isRemovable());
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node) Test(org.junit.Test)

Example 8 with Node

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

the class SerializationTest method serialize_additional_ip_addresses.

@Test
public void serialize_additional_ip_addresses() throws IOException {
    Node node = createNode();
    // Test round-trip with additional addresses
    node = node.withAdditionalIpAddresses(ImmutableSet.of("10.0.0.1", "10.0.0.2", "10.0.0.3"));
    Node copy = nodeSerializer.fromJson(node.state(), nodeSerializer.toJson(node));
    assertEquals(node.additionalIpAddresses(), copy.additionalIpAddresses());
    // Test round-trip without additional addresses (handle empty ip set)
    node = createNode();
    copy = nodeSerializer.fromJson(node.state(), nodeSerializer.toJson(node));
    assertEquals(node.additionalIpAddresses(), copy.additionalIpAddresses());
    // TODO remove after MAI 2017
    // Test deserialization of a json file without the additional ip addresses field
    String json = "{\n" + "  \"url\": \"http://localhost:8080/nodes/v2/node/host1.yahoo.com\",\n" + "  \"id\": \"host1.yahoo.com\",\n" + "  \"state\": \"active\",\n" + "  \"type\": \"tenant\",\n" + "  \"hostname\": \"host1.yahoo.com\",\n" + "  \"openStackId\": \"node1\",\n" + "  \"flavor\": \"default\",\n" + "  \"canonicalFlavor\": \"default\",\n" + "  \"minDiskAvailableGb\":400.0,\n" + "  \"minMainMemoryAvailableGb\":16.0,\n" + "  \"description\":\"Flavor-name-is-default\",\n" + "  \"minCpuCores\":2.0,\n" + "  \"environment\":\"BARE_METAL\",\n" + "  \"owner\": {\n" + "    \"tenant\": \"tenant2\",\n" + "    \"application\": \"application2\",\n" + "    \"instance\": \"instance2\"\n" + "  },\n" + "  \"membership\": {\n" + "    \"clustertype\": \"content\",\n" + "    \"clusterid\": \"id2\",\n" + "    \"group\": \"0\",\n" + "    \"index\": 0,\n" + "    \"retired\": false\n" + "  },\n" + "  \"restartGeneration\": 0,\n" + "  \"currentRestartGeneration\": 0,\n" + "  \"wantedDockerImage\":\"foo:6.42.0\",\n" + "  \"wantedVespaVersion\":\"6.42.0\",\n" + "  \"rebootGeneration\": 1,\n" + "  \"currentRebootGeneration\": 0,\n" + "  \"failCount\": 0,\n" + "  \"wantToRetire\" : false,\n" + "  \"history\":[{\"type\":\"readied\",\"at\":123,\"type\":\"system\"},{\"type\":\"reserved\",\"at\":123,\"agent\":\"application\"},{\"type\":\"activated\",\"at\":123,\"agent\":\"application\"}],\n" + "  \"ipAddresses\":[\"::1\", \"127.0.0.1\"]\n" + "}";
    node = nodeSerializer.fromJson(State.active, Utf8.toBytes(json));
    assertEquals(Collections.emptySet(), node.additionalIpAddresses());
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node) Test(org.junit.Test)

Example 9 with Node

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

the class NodeAllocation method acceptNode.

private Node acceptNode(PrioritizableNode prioritizableNode, boolean wantToRetire) {
    Node node = prioritizableNode.node;
    if (!wantToRetire) {
        if (!node.state().equals(Node.State.active)) {
            // reactivated node - make sure its not retired
            node = node.unretire();
            prioritizableNode.node = node;
        }
        acceptedOfRequestedFlavor++;
    } else {
        ++wasRetiredJustNow;
        // Retire nodes which are of an unwanted flavor, retired flavor or have an overlapping parent host
        node = node.retire(nodeRepository.clock().instant());
        prioritizableNode.node = node;
    }
    if (!node.allocation().get().membership().cluster().equals(cluster)) {
        // group may be different
        node = setCluster(cluster, node);
        prioritizableNode.node = node;
    }
    indexes.add(node.allocation().get().membership().index());
    highestIndex.set(Math.max(highestIndex.get(), node.allocation().get().membership().index()));
    nodes.add(prioritizableNode);
    return node;
}
Also used : Node(com.yahoo.vespa.hosted.provision.Node)

Example 10 with Node

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

the class NodeAllocation method finalNodes.

/**
 * Make the number of <i>non-retired</i> nodes in the list equal to the requested number
 * of nodes, and retire the rest of the list. Only retire currently active nodes.
 * Prefer to retire nodes of the wrong flavor.
 * Make as few changes to the retired set as possible.
 *
 * @param surplusNodes this will add nodes not any longer needed by this group to this list
 * @return the final list of nodes
 */
List<Node> finalNodes(List<Node> surplusNodes) {
    int currentRetiredCount = (int) nodes.stream().filter(node -> node.node.allocation().get().membership().retired()).count();
    int deltaRetiredCount = requestedNodes.idealRetiredCount(nodes.size(), currentRetiredCount) - currentRetiredCount;
    if (deltaRetiredCount > 0) {
        // retire until deltaRetiredCount is 0, prefer to retire higher indexes to minimize redistribution
        for (PrioritizableNode node : byDecreasingIndex(nodes)) {
            if (!node.node.allocation().get().membership().retired() && node.node.state().equals(Node.State.active)) {
                node.node = node.node.retire(Agent.application, nodeRepository.clock().instant());
                // offer this node to other groups
                surplusNodes.add(node.node);
                if (--deltaRetiredCount == 0)
                    break;
            }
        }
    } else if (deltaRetiredCount < 0) {
        // unretire until deltaRetiredCount is 0
        for (PrioritizableNode node : byIncreasingIndex(nodes)) {
            if (node.node.allocation().get().membership().retired() && hasCompatibleFlavor(node.node)) {
                node.node = node.node.unretire();
                if (++deltaRetiredCount == 0)
                    break;
            }
        }
    }
    for (PrioritizableNode node : nodes) {
        node.node = requestedNodes.assignRequestedFlavor(node.node);
        // Set whether the node is exclusive
        Allocation allocation = node.node.allocation().get();
        node.node = node.node.with(allocation.with(allocation.membership().with(allocation.membership().cluster().exclusive(requestedNodes.isExclusive()))));
    }
    return nodes.stream().map(n -> n.node).collect(Collectors.toList());
}
Also used : ApplicationId(com.yahoo.config.provision.ApplicationId) ClusterMembership(com.yahoo.config.provision.ClusterMembership) Collection(java.util.Collection) ClusterSpec(com.yahoo.config.provision.ClusterSpec) Set(java.util.Set) Node(com.yahoo.vespa.hosted.provision.Node) Collectors(java.util.stream.Collectors) TenantName(com.yahoo.config.provision.TenantName) Allocation(com.yahoo.vespa.hosted.provision.node.Allocation) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) NodeRepository(com.yahoo.vespa.hosted.provision.NodeRepository) MutableInteger(com.yahoo.lang.MutableInteger) List(java.util.List) Agent(com.yahoo.vespa.hosted.provision.node.Agent) Optional(java.util.Optional) Comparator(java.util.Comparator) LinkedHashSet(java.util.LinkedHashSet) Allocation(com.yahoo.vespa.hosted.provision.node.Allocation)

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