diff options
author | Arne H Juul <arnej27959@users.noreply.github.com> | 2019-02-21 13:19:39 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-02-21 13:19:39 +0100 |
commit | 81552c6b6014118007449547c21a0aa779c37739 (patch) | |
tree | a142f1f72129f5c5b6677bb8d833af850fb2cddc /node-repository | |
parent | 4b70f0cf44a87183c36083f2c9262f41a504d1ab (diff) | |
parent | 40596e59db99c1c6d488efeb7af9bedd05de8f60 (diff) |
Merge pull request #8574 from vespa-engine/arnej/add-network-ports-2
Arnej/add network ports 2
Diffstat (limited to 'node-repository')
7 files changed, 107 insertions, 19 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java index 668795f362b..4fef3d8ebf7 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/Node.java @@ -5,6 +5,7 @@ import com.google.common.collect.ImmutableSet; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.Flavor; +import com.yahoo.config.provision.NetworkPorts; import com.yahoo.config.provision.NodeType; import com.yahoo.vespa.hosted.provision.node.Agent; import com.yahoo.vespa.hosted.provision.node.Allocation; diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java index 8a331209efc..53e1ae3721e 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Allocation.java @@ -3,6 +3,9 @@ package com.yahoo.vespa.hosted.provision.node; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterMembership; +import com.yahoo.config.provision.NetworkPorts; + +import java.util.Optional; /** * The allocation of a node @@ -24,12 +27,21 @@ public class Allocation { /** This node can (and should) be removed from the cluster on the next deployment */ private final boolean removable; + private final Optional<NetworkPorts> networkPorts; + + public Allocation(ApplicationId owner, ClusterMembership clusterMembership, Generation restartGeneration, boolean removable) { + this(owner, clusterMembership, restartGeneration, removable, Optional.empty()); + } + + public Allocation(ApplicationId owner, ClusterMembership clusterMembership, + Generation restartGeneration, boolean removable, Optional<NetworkPorts> networkPorts) { this.owner = owner; this.clusterMembership = clusterMembership; this.restartGeneration = restartGeneration; this.removable = removable; + this.networkPorts = networkPorts; } /** Returns the id of the application this is allocated to */ @@ -41,14 +53,17 @@ public class Allocation { /** Returns the restart generation (wanted and current) of this */ public Generation restartGeneration() { return restartGeneration; } + /** Returns network ports allocations (or empty if not recorded) */ + public Optional<NetworkPorts> networkPorts() { return networkPorts; } + /** Returns a copy of this which is retired */ public Allocation retire() { - return new Allocation(owner, clusterMembership.retire(), restartGeneration, removable); + return new Allocation(owner, clusterMembership.retire(), restartGeneration, removable, networkPorts); } /** Returns a copy of this which is not retired */ public Allocation unretire() { - return new Allocation(owner, clusterMembership.unretire(), restartGeneration, removable); + return new Allocation(owner, clusterMembership.unretire(), restartGeneration, removable, networkPorts); } /** Return whether this node is ready to be removed from the application */ @@ -56,16 +71,20 @@ public class Allocation { /** Returns a copy of this with the current restart generation set to generation */ public Allocation withRestart(Generation generation) { - return new Allocation(owner, clusterMembership, generation, removable); + return new Allocation(owner, clusterMembership, generation, removable, networkPorts); } /** Returns a copy of this allocation where removable is set to true */ public Allocation removable() { - return new Allocation(owner, clusterMembership, restartGeneration, true); + return new Allocation(owner, clusterMembership, restartGeneration, true, networkPorts); } public Allocation with(ClusterMembership newMembership) { - return new Allocation(owner, newMembership, restartGeneration, removable); + return new Allocation(owner, newMembership, restartGeneration, removable, networkPorts); + } + + public Allocation withNetworkPorts(NetworkPorts ports) { + return new Allocation(owner, clusterMembership, restartGeneration, removable, Optional.of(ports)); } @Override diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java index 54668c4eda1..bb4dab3b97b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/NodeSerializer.java @@ -10,6 +10,8 @@ import com.yahoo.config.provision.Flavor; import com.yahoo.config.provision.InstanceName; import com.yahoo.config.provision.NodeFlavors; import com.yahoo.config.provision.NodeType; +import com.yahoo.config.provision.NetworkPorts; +import com.yahoo.config.provision.NetworkPortsSerializer; import com.yahoo.config.provision.TenantName; import com.yahoo.slime.ArrayTraverser; import com.yahoo.slime.Cursor; @@ -85,6 +87,9 @@ public class NodeSerializer { private static final String atKey = "at"; private static final String agentKey = "agent"; // retired events only + // Network port fields + private static final String networkPortsKey = "networkPorts"; + // ---------------- Serialization ---------------------------------------------------- public NodeSerializer(NodeFlavors flavors) { @@ -136,6 +141,7 @@ public class NodeSerializer { object.setLong(currentRestartGenerationKey, allocation.restartGeneration().current()); object.setBool(removableKey, allocation.isRemovable()); object.setString(wantedVespaVersionKey, allocation.membership().cluster().vespaVersion().toString()); + allocation.networkPorts().ifPresent(ports -> NetworkPortsSerializer.toSlime(ports, object.setArray(networkPortsKey))); } private void toSlime(History history, Cursor array) { @@ -197,7 +203,8 @@ public class NodeSerializer { return Optional.of(new Allocation(applicationIdFromSlime(object), clusterMembershipFromSlime(object), generationFromSlime(object, restartGenerationKey, currentRestartGenerationKey), - object.field(removableKey).asBool())); + object.field(removableKey).asBool(), + NetworkPortsSerializer.fromSlime(object.field(networkPortsKey)))); } private ApplicationId applicationIdFromSlime(Inspector object) { diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java index f48f0c1bdce..4626a600d2c 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/Activator.java @@ -9,6 +9,7 @@ import com.yahoo.transaction.NestedTransaction; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeList; import com.yahoo.vespa.hosted.provision.NodeRepository; +import com.yahoo.vespa.hosted.provision.node.Allocation; import java.util.ArrayList; import java.util.Collection; @@ -73,7 +74,7 @@ class Activator { activeToRemove = activeToRemove.stream().map(Node::unretire).collect(Collectors.toList()); // only active nodes can be retired nodeRepository.deactivate(activeToRemove, transaction); nodeRepository.activate(updateFrom(hosts, continuedActive), transaction); // update active with any changes - nodeRepository.activate(reservedToActivate, transaction); + nodeRepository.activate(updatePortsFrom(hosts, reservedToActivate), transaction); } } @@ -133,7 +134,11 @@ class Activator { 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())); + Allocation allocation = node.allocation().get().with(hostSpec.membership().get()); + if (hostSpec.networkPorts().isPresent()) { + allocation = allocation.withNetworkPorts(hostSpec.networkPorts().get()); + } + node = node.with(allocation); if (hostSpec.flavor().isPresent()) // Docker nodes may change flavor node = node.with(hostSpec.flavor().get()); updated.add(node); @@ -141,6 +146,23 @@ class Activator { return updated; } + /** + * Returns the input nodes with any port allocations from the hosts + */ + private List<Node> updatePortsFrom(Collection<HostSpec> hosts, List<Node> nodes) { + List<Node> updated = new ArrayList<>(); + for (Node node : nodes) { + HostSpec hostSpec = getHost(node.hostname(), hosts); + Allocation allocation = node.allocation().get(); + if (hostSpec.networkPorts().isPresent()) { + allocation = allocation.withNetworkPorts(hostSpec.networkPorts().get()); + node = node.with(allocation); + } + updated.add(node); + } + return updated; + } + private HostSpec getHost(String hostname, Collection<HostSpec> fromHosts) { for (HostSpec host : fromHosts) if (host.hostname().equals(hostname)) diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java index a0d76241533..246c56ee28b 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/provisioning/NodeRepositoryProvisioner.java @@ -22,11 +22,13 @@ import com.yahoo.vespa.flags.Flags; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.flag.FlagId; +import com.yahoo.vespa.hosted.provision.node.Allocation; import com.yahoo.vespa.hosted.provision.node.filter.ApplicationFilter; import com.yahoo.vespa.hosted.provision.node.filter.NodeHostFilter; import java.util.ArrayList; import java.util.Collection; +import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Optional; @@ -141,10 +143,16 @@ public class NodeRepositoryProvisioner implements Provisioner { List<HostSpec> hosts = new ArrayList<>(nodes.size()); for (Node node : nodes) { log.log(LogLevel.DEBUG, () -> "Prepared node " + node.hostname() + " - " + node.flavor()); + Allocation nodeAllocation = node.allocation().orElseThrow(IllegalStateException::new); hosts.add(new HostSpec(node.hostname(), - node.allocation().orElseThrow(IllegalStateException::new).membership(), - node.flavor(), - node.status().vespaVersion())); + Collections.emptyList(), + Optional.of(node.flavor()), + Optional.of(nodeAllocation.membership()), + node.status().vespaVersion(), + nodeAllocation.networkPorts())); + if (nodeAllocation.networkPorts().isPresent()) { + log.log(LogLevel.DEBUG, () -> "Prepared node " + node.hostname() + " has port allocations"); + } } return hosts; } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java index ba513db5342..1254664eb78 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/restapi/v2/NodesResponse.java @@ -3,6 +3,7 @@ package com.yahoo.vespa.hosted.provision.restapi.v2; import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterMembership; +import com.yahoo.config.provision.NetworkPortsSerializer; import com.yahoo.config.provision.NodeType; import com.yahoo.container.jdisc.HttpRequest; import com.yahoo.container.jdisc.HttpResponse; @@ -153,17 +154,18 @@ class NodesResponse extends HttpResponse { 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")); - toSlime(node.allocation().get().membership(), object.setObject("membership")); - object.setLong("restartGeneration", node.allocation().get().restartGeneration().wanted()); - object.setLong("currentRestartGeneration", node.allocation().get().restartGeneration().current()); - object.setString("wantedDockerImage", nodeRepository.dockerImage().withTag(node.allocation().get().membership().cluster().vespaVersion()).asString()); - object.setString("wantedVespaVersion", node.allocation().get().membership().cluster().vespaVersion().toFullString()); + node.allocation().ifPresent(allocation -> { + toSlime(allocation.owner(), object.setObject("owner")); + toSlime(allocation.membership(), object.setObject("membership")); + object.setLong("restartGeneration", allocation.restartGeneration().wanted()); + object.setLong("currentRestartGeneration", allocation.restartGeneration().current()); + object.setString("wantedDockerImage", nodeRepository.dockerImage().withTag(allocation.membership().cluster().vespaVersion()).asString()); + object.setString("wantedVespaVersion", allocation.membership().cluster().vespaVersion().toFullString()); + allocation.networkPorts().ifPresent(ports -> NetworkPortsSerializer.toSlime(ports, object.setArray("networkPorts"))); orchestrator.apply(new HostName(node.hostname())) .map(status -> status == HostStatus.ALLOWED_TO_BE_DOWN) .ifPresent(allowedToBeDown -> object.setBool("allowedToBeDown", allowedToBeDown)); - } + }); object.setLong("rebootGeneration", node.status().reboot().wanted()); object.setLong("currentRebootGeneration", node.status().reboot().current()); node.status().osVersion().ifPresent(version -> object.setString("currentOsVersion", version.toFullString())); diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java index 29229efc662..53f6b745da1 100644 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java +++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/persistence/SerializationTest.java @@ -8,6 +8,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ApplicationName; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.InstanceName; +import com.yahoo.config.provision.NetworkPorts; import com.yahoo.config.provision.NodeFlavors; import com.yahoo.config.provision.NodeType; import com.yahoo.config.provision.TenantName; @@ -29,8 +30,11 @@ import org.junit.Test; import java.nio.charset.StandardCharsets; import java.time.Duration; import java.time.Instant; +import java.util.ArrayList; import java.util.Arrays; +import java.util.Collection; import java.util.Collections; +import java.util.List; import java.util.Optional; import java.util.stream.Collectors; @@ -371,6 +375,31 @@ public class SerializationTest { assertEquals("some model", node.modelName().get()); } + @Test + public void testNodeWithNetworkPorts() { + Node node = createNode(); + List<NetworkPorts.Allocation> list = new ArrayList<>(); + list.add(new NetworkPorts.Allocation(8080, "container", "default/0", "http")); + list.add(new NetworkPorts.Allocation(19101, "searchnode", "other/1", "rpc")); + NetworkPorts ports = new NetworkPorts(list); + node = node.allocate(ApplicationId.from(TenantName.from("myTenant"), + ApplicationName.from("myApplication"), + InstanceName.from("myInstance")), + ClusterMembership.from("content/myId/0/0", Vtag.currentVersion), + clock.instant()); + assertTrue(node.allocation().isPresent()); + node = node.with(node.allocation().get().withNetworkPorts(ports)); + assertTrue(node.allocation().isPresent()); + assertTrue(node.allocation().get().networkPorts().isPresent()); + Node copy = nodeSerializer.fromJson(Node.State.provisioned, nodeSerializer.toJson(node)); + assertTrue(copy.allocation().isPresent()); + assertTrue(copy.allocation().get().networkPorts().isPresent()); + NetworkPorts portsCopy = node.allocation().get().networkPorts().get(); + Collection<NetworkPorts.Allocation> listCopy = portsCopy.allocations(); + assertEquals(list, listCopy); + } + + private byte[] createNodeJson(String hostname, String... ipAddress) { String ipAddressJsonPart = ""; if (ipAddress.length > 0) { |