diff options
author | Valerij Fredriksen <freva@users.noreply.github.com> | 2019-06-11 19:23:44 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-06-11 19:23:44 +0200 |
commit | 9111729ff3bb3de588a9d4b4c5af313155855d18 (patch) | |
tree | 55cc17af7947925273d59b6b1ba40a2fad90a2df /node-repository | |
parent | f4c68c2c2428bd5ce2379cffbafa27063e6d8762 (diff) | |
parent | 7b4dabbd0e84169c591ac52de4df346a54b4b0ac (diff) |
Merge pull request #9735 from vespa-engine/freva/tenant-host-cleanup
Zone application cleanup
Diffstat (limited to 'node-repository')
4 files changed, 4 insertions, 187 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java index 9efde8cf673..013fd169f45 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/InactiveExpirer.java @@ -1,7 +1,6 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.hosted.provision.maintenance; -import com.yahoo.config.provision.NodeType; import com.yahoo.vespa.hosted.provision.Node; import com.yahoo.vespa.hosted.provision.NodeRepository; import com.yahoo.vespa.hosted.provision.node.Agent; @@ -51,8 +50,7 @@ public class InactiveExpirer extends Expirer { @Override protected boolean isExpired(Node node) { return super.isExpired(node) - || node.allocation().get().owner().instance().isTester() - || node.type() == NodeType.host; // TODO: Remove after removing tenant hosts from zone-app + || node.allocation().get().owner().instance().isTester(); } } diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java index 18ae7e17d6d..25549abe9ed 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java @@ -174,7 +174,7 @@ public class NodeRepositoryMaintenance extends AbstractComponent { rebootInterval = Duration.ofDays(30); nodeRetirerInterval = Duration.ofMinutes(30); metricsInterval = Duration.ofMinutes(1); - infrastructureProvisionInterval = Duration.ofMinutes(3); + infrastructureProvisionInterval = Duration.ofMinutes(1); throttlePolicy = NodeFailer.ThrottlePolicy.hosted; loadBalancerExpiry = Duration.ofHours(1); reservationExpiry = Duration.ofMinutes(20); // Need to be long enough for deployment to be finished for all config model versions diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java index 4c5310d69b6..46571fd0deb 100644 --- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java +++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/OperatorChangeApplicationMaintainer.java @@ -13,7 +13,6 @@ import java.time.Clock; import java.time.Duration; import java.time.Instant; import java.util.LinkedHashSet; -import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; @@ -30,8 +29,6 @@ import java.util.stream.Collectors; */ public class OperatorChangeApplicationMaintainer extends ApplicationMaintainer { - private static final ApplicationId ZONE_APPLICATION_ID = ApplicationId.from("hosted-vespa", "routing", "default"); - private final Clock clock; private Instant previousRun; @@ -47,9 +44,9 @@ public class OperatorChangeApplicationMaintainer extends ApplicationMaintainer { Instant windowEnd = clock.instant(); Instant windowStart = previousRun; previousRun = windowEnd; - return nodeRepository().getNodes().stream() + return nodeRepository().getNodes(NodeType.tenant).stream() .filter(node -> hasManualStateChangeSince(windowStart, node)) - .flatMap(node -> owner(node).stream()) + .flatMap(node -> node.allocation().map(Allocation::owner).stream()) .collect(Collectors.toCollection(LinkedHashSet::new)); } @@ -58,13 +55,6 @@ public class OperatorChangeApplicationMaintainer extends ApplicationMaintainer { .anyMatch(event -> event.agent() == Agent.operator && event.at().isAfter(instant)); } - private Optional<ApplicationId> owner(Node node) { - if (node.allocation().isPresent()) return node.allocation().map(Allocation::owner); - - // TODO: Remove after removing tenant hosts from zone-app - return node.type() == NodeType.host ? Optional.of(ZONE_APPLICATION_ID) : Optional.empty(); - } - /** * Deploy in the maintenance thread to avoid scheduling multiple deployments of the same application if it takes * longer to deploy than the (short) maintenance interval of this diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ZoneAppMigrationTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ZoneAppMigrationTest.java deleted file mode 100644 index ffdcea973e5..00000000000 --- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/ZoneAppMigrationTest.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.yahoo.vespa.hosted.provision.maintenance; - -import com.yahoo.component.Version; -import com.yahoo.config.provision.ApplicationId; -import com.yahoo.config.provision.Capacity; -import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.provision.HostSpec; -import com.yahoo.config.provision.NodeResources; -import com.yahoo.config.provision.NodeType; -import com.yahoo.test.ManualClock; -import com.yahoo.vespa.hosted.provision.Node; -import com.yahoo.vespa.hosted.provision.node.Agent; -import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester; -import org.junit.Before; -import org.junit.Test; - -import java.time.Duration; -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; -import java.util.Set; -import java.util.stream.Collector; -import java.util.stream.Collectors; -import java.util.stream.Stream; - -import static com.yahoo.config.provision.ClusterSpec.Type.container; -import static com.yahoo.config.provision.ClusterSpec.Type.content; -import static org.junit.Assert.assertEquals; - -/** - * This is a temporary test to verify the requirements needed for a successful migration of tenant - * host nodes out of the zone-application. - * - * TODO: Remove after removing tenant hosts from zone-app - * - * @author freva - */ -public class ZoneAppMigrationTest { - - private final ManualClock clock = new ManualClock(); - private final ProvisioningTester tester = new ProvisioningTester.Builder().build(); - private final InactiveExpirer inactiveExpirer = new InactiveExpirer(tester.nodeRepository(), clock, Duration.ofDays(99)); - - private final Version version = Version.fromString("7.42.23"); - - private final ApplicationId zoneApp = ApplicationId.from("hosted-vespa", "routing", "default"); - private final ApplicationId proxyHostApp = ApplicationId.from("hosted-vespa", "proxy-host", "default"); - private final ApplicationId tenantHostApp = ApplicationId.from("hosted-vespa", "tenant-host", "default"); - private final ApplicationId app1 = tester.makeApplicationId(); - private final ApplicationId app2 = tester.makeApplicationId(); - - - @Test - public void tenant_host_deallocation_test() { - assertEquals(5, tester.nodeRepository().getNodes(NodeType.proxy, Node.State.active).size()); - assertEquals(20, tester.nodeRepository().getNodes(NodeType.host, Node.State.active).size()); - assertEquals(15, tester.nodeRepository().getNodes(NodeType.tenant, Node.State.active).size()); - - Set<Node> tenantNodes = Set.copyOf(tester.nodeRepository().getNodes(NodeType.tenant)); - - // Activate zone-app with only proxy nodes, all tenant hosts become inactive, no change to other nodes - tester.activate(zoneApp, prepareSystemApplication(zoneApp, NodeType.proxy, "routing")); - assertEquals(5, tester.nodeRepository().getNodes(NodeType.proxy, Node.State.active).size()); - assertEquals(20, tester.nodeRepository().getNodes(NodeType.host, Node.State.inactive).size()); - assertEquals(tenantNodes, Set.copyOf(tester.nodeRepository().getNodes(NodeType.tenant))); - - // All tenant hosts become dirty, no change to other nodes - inactiveExpirer.maintain(); - assertEquals(5, tester.nodeRepository().getNodes(NodeType.proxy, Node.State.active).size()); - assertEquals(20, tester.nodeRepository().getNodes(NodeType.host, Node.State.dirty).size()); - assertEquals(tenantNodes, Set.copyOf(tester.nodeRepository().getNodes(NodeType.tenant))); - // No reboot generation incrementation - assertEquals(0, tester.nodeRepository().getNodes(NodeType.host).stream().mapToLong(node -> node.status().reboot().wanted()).sum()); - - tester.nodeRepository().getNodes(NodeType.host) - .forEach(node -> tester.nodeRepository().setReady(node.hostname(), Agent.operator, "Readied by host-admin")); - assertEquals(5, tester.nodeRepository().getNodes(NodeType.proxy, Node.State.active).size()); - assertEquals(20, tester.nodeRepository().getNodes(NodeType.host, Node.State.ready).size()); - assertEquals(tenantNodes, Set.copyOf(tester.nodeRepository().getNodes(NodeType.tenant))); - - tester.activate(tenantHostApp, prepareSystemApplication(tenantHostApp, NodeType.host, "tenant-host")); - assertEquals(5, tester.nodeRepository().getNodes(NodeType.proxy, Node.State.active).size()); - assertEquals(20, tester.nodeRepository().getNodes(NodeType.host, Node.State.active).size()); - assertEquals(tenantNodes, Set.copyOf(tester.nodeRepository().getNodes(NodeType.tenant))); - - // All tenant hosts are allocated to tenant host application - assertEquals(Set.copyOf(tester.nodeRepository().getNodes(NodeType.host)), - Set.copyOf(tester.nodeRepository().getNodes(tenantHostApp))); - - // All proxy nodes are still allocated to zone-app - assertEquals(Set.copyOf(tester.nodeRepository().getNodes(NodeType.proxy)), - Set.copyOf(tester.nodeRepository().getNodes(zoneApp))); - } - - @Test - public void conflicting_type_allocation_test() { - // Re-allocate tenant host from zone-app to tenant-host app - tester.activate(zoneApp, prepareSystemApplication(zoneApp, NodeType.proxy, "routing")); - inactiveExpirer.maintain(); - tester.nodeRepository().getNodes(NodeType.host) - .forEach(node -> tester.nodeRepository().setReady(node.hostname(), Agent.operator, "Readied by host-admin")); - tester.activate(tenantHostApp, prepareSystemApplication(tenantHostApp, NodeType.host, "tenant-host")); - - // Re-deploying zone-app with both type proxy and host has no effect (no tenant hosts are re-allocated from tenant-host app) - Set<Node> allNodes = Set.copyOf(tester.nodeRepository().getNodes()); - List<HostSpec> proxyHostSpecs = prepareSystemApplication(zoneApp, NodeType.proxy, "routing"); - List<HostSpec> nodeAdminHostSpecs = prepareSystemApplication(zoneApp, NodeType.host, "node-admin"); - List<HostSpec> zoneAppHostSpecs = concat(proxyHostSpecs, nodeAdminHostSpecs, Collectors.toList()); - tester.activate(zoneApp, zoneAppHostSpecs); - assertEquals(0, nodeAdminHostSpecs.size()); - assertEquals(allNodes, Set.copyOf(tester.nodeRepository().getNodes())); - - // Provision another host and redeploy zone-app - Node newHost = tester.makeReadyNodes(1, "large", NodeType.host).get(0); - proxyHostSpecs = prepareSystemApplication(zoneApp, NodeType.proxy, "routing"); - nodeAdminHostSpecs = prepareSystemApplication(zoneApp, NodeType.host, "node-admin"); - zoneAppHostSpecs = concat(proxyHostSpecs, nodeAdminHostSpecs, Collectors.toList()); - tester.activate(zoneApp, zoneAppHostSpecs); - - assertEquals(1, nodeAdminHostSpecs.size()); // The newly provisioned host is prepared - newHost = tester.nodeRepository().getNode(newHost.hostname()).orElseThrow(); // Update newHost after it has been allocated - Set<Node> allNodesWithNewHost = concat(allNodes, Set.of(newHost), Collectors.toSet()); - assertEquals(allNodesWithNewHost, Set.copyOf(tester.nodeRepository().getNodes())); - // The new host is allocated to zone-app, while the old ones are still allocated to tenant-host app - assertEquals(zoneApp, newHost.allocation().get().owner()); - } - - @Before - public void setup() { - tester.makeReadyNodes(5, "large", NodeType.proxyhost); - tester.makeReadyNodes(5, "large", NodeType.proxy); - tester.makeReadyNodes(20, "large", NodeType.host, 3); - - tester.activate(proxyHostApp, prepareSystemApplication(proxyHostApp, NodeType.proxyhost, "proxy-host")); - List<HostSpec> proxyHostSpecs = prepareSystemApplication(zoneApp, NodeType.proxy, "routing"); - List<HostSpec> nodeAdminHostSpecs = prepareSystemApplication(zoneApp, NodeType.host, "node-admin"); - List<HostSpec> zoneAppHostSpecs = concat(proxyHostSpecs, nodeAdminHostSpecs, Collectors.toList()); - tester.activate(zoneApp, zoneAppHostSpecs); - - activateTenantApplication(app1, 3, 4); - activateTenantApplication(app2, 5, 3); - } - - private List<HostSpec> prepareSystemApplication(ApplicationId applicationId, NodeType nodeType, String clusterId) { - return tester.prepare(applicationId, - ClusterSpec.request(container, ClusterSpec.Id.from(clusterId), version, false, Set.of()), - Capacity.fromRequiredNodeType(nodeType), - 1); - } - - private void activateTenantApplication(ApplicationId app, int numContainerNodes, int numContentNodes) { - List<HostSpec> combinedHostSpecs = new ArrayList<>(numContainerNodes + numContentNodes); - - combinedHostSpecs.addAll(tester.prepare(app, - ClusterSpec.request(container, ClusterSpec.Id.from("web"), version, false, Set.of()), - Capacity.fromCount(numContainerNodes, new NodeResources(2, 2, 50)), - 1)); - - combinedHostSpecs.addAll(tester.prepare(app, - ClusterSpec.request(content, ClusterSpec.Id.from("store"), version, false, Set.of()), - Capacity.fromCount(numContentNodes, new NodeResources(1, 4, 50)), - 1)); - - tester.activate(app, combinedHostSpecs); - } - - private <T, R, A> R concat(Collection<T> c1, Collection<T> c2, Collector<? super T, A, R> collector) { - return Stream.concat(c1.stream(), c2.stream()) - .collect(collector); - } -} |