summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHarald Musum <musum@verizonmedia.com>2021-03-10 15:48:19 +0100
committerGitHub <noreply@github.com>2021-03-10 15:48:19 +0100
commit34868d7ae17aac147c9652983d31080797c9bca3 (patch)
tree85419a176d2df3e9db19542220864a809812d0eb
parentce58e0548f27f3084b63c6d0b00e539099ce59d4 (diff)
parent949df298d5a012aa5900e8c23f92e6e78a25b120 (diff)
Merge pull request #16818 from vespa-engine/jonmv/cluster-controller-migration-cleanup
Always use dedicated cluster controllers when hosted (except in some …
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java2
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java4
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java2
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java194
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java5
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java2
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java6
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java3
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java10
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java6
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java10
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java4
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java7
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java3
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java8
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java3
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java84
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/NodeRepositoryMaintenance.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java142
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json3
21 files changed, 159 insertions, 345 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
index abd1c7bc7f2..c4eeb41a663 100644
--- a/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
+++ b/config-model-api/src/main/java/com/yahoo/config/model/api/ModelContext.java
@@ -123,7 +123,7 @@ public interface ModelContext {
// Note: Used in unit tests (set to false in TestProperties) to avoid needing to deal with implicitly created node for logserver
default boolean useDedicatedNodeForLogserver() { return true; }
- default boolean dedicatedClusterControllerCluster() { return false; }
+ default boolean dedicatedClusterControllerCluster() { return hostedVespa(); }
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
index 77e5e98cd99..c1d45c213fb 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java
@@ -36,7 +36,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
private Zone zone;
private final Set<ContainerEndpoint> endpoints = Collections.emptySet();
private boolean useDedicatedNodeForLogserver = false;
- private boolean dedicatedClusterControllerCluster = false;
+ private boolean dedicatedClusterControllerCluster = true;
private boolean useThreePhaseUpdates = false;
private double defaultTermwiseLimit = 1.0;
private String jvmGCOptions = null;
@@ -74,7 +74,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public boolean isBootstrap() { return false; }
@Override public boolean isFirstTimeDeployment() { return false; }
@Override public boolean useDedicatedNodeForLogserver() { return useDedicatedNodeForLogserver; }
- @Override public boolean dedicatedClusterControllerCluster() { return dedicatedClusterControllerCluster; }
+ @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && dedicatedClusterControllerCluster; }
@Override public Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return endpointCertificateSecrets; }
@Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; }
@Override public boolean useThreePhaseUpdates() { return useThreePhaseUpdates; }
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
index c909aeec022..79ce9343560 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/content/cluster/ContentCluster.java
@@ -413,7 +413,7 @@ public class ContentCluster extends AbstractConfigProducer implements
}
List<HostResource> sortedHosts = new ArrayList<>(hosts);
- sortedHosts.sort((a, b) -> (a.comparePrimarilyByIndexTo(b)));
+ sortedHosts.sort(HostResource::comparePrimarilyByIndexTo);
sortedHosts = sortedHosts.subList(0, Math.min(count, hosts.size()));
return sortedHosts;
}
diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
index 711e153e2bb..5a06379a1c2 100644
--- a/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java
@@ -171,7 +171,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- int numberOfHosts = 2;
+ int numberOfHosts = 5;
tester.addHosts(numberOfHosts);
int numberOfContentNodes = 2;
VespaModel model = tester.createModel(xmlWithNodes, true);
@@ -209,7 +209,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.addHosts(5);
+ tester.addHosts(8);
VespaModel model = tester.createModel(xmlWithNodes, true);
assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size());
@@ -264,6 +264,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(2);
VespaModel model = tester.createModel(xmlWithNodes, true);
assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size());
@@ -300,7 +301,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.addHosts(4);
+ tester.addHosts(7);
VespaModel model = tester.createModel(xmlWithNodes, true);
assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size());
assertEquals("Nodes in container1", 2, model.getContainerClusters().get("container1").getContainers().size());
@@ -329,6 +330,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(2);
VespaModel model = tester.createModel(xmlWithNodes, true);
@@ -365,7 +367,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
- tester.addHosts(5);
+ tester.addHosts(8);
VespaModel model = tester.createModel(xmlWithNodes, true);
assertEquals("Nodes in content1", 2, model.getContentClusters().get("content1").getRootGroup().getNodes().size());
@@ -455,7 +457,112 @@ public class ModelProvisioningTest {
public void testUsingNodesAndGroupCountAttributes() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>\n" +
- "<services>" +
+ "<services>" +
+ " <admin version='4.0'/>" +
+ " <container version='1.0' id='foo'>" +
+ " <nodes count='10'/>" +
+ " </container>" +
+ " <content version='1.0' id='bar'>" +
+ " <redundancy>2</redundancy>" +
+ " <documents>" +
+ " <document type='type1' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='27' groups='9'/>" +
+ " </content>" +
+ " <content version='1.0' id='baz'>" +
+ " <redundancy>1</redundancy>" +
+ " <documents>" +
+ " <document type='type1' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='27' groups='27'/>" +
+ " </content>" +
+ "</services>";
+
+ int numberOfHosts = 67;
+ VespaModelTester tester = new VespaModelTester();
+ tester.addHosts(numberOfHosts);
+ VespaModel model = tester.createModel(services, true);
+ assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
+
+ // Check container cluster
+ assertEquals(1, model.getContainerClusters().size());
+ Set<HostResource> containerHosts = model.getContainerClusters().get("foo").getContainers().stream()
+ .map(Container::getHost)
+ .collect(Collectors.toSet());
+ assertEquals(10, containerHosts.size());
+
+ // Check admin clusters
+ Admin admin = model.getAdmin();
+ Set<HostResource> slobrokHosts = admin.getSlobroks().stream().map(Slobrok::getHost).collect(Collectors.toSet());
+ assertEquals(3, slobrokHosts.size());
+ assertTrue("Slobroks are assigned from container nodes", containerHosts.containsAll(slobrokHosts));
+ assertTrue("Logserver is assigned from container nodes", containerHosts.contains(admin.getLogserver().getHost()));
+ assertEquals("No in-cluster config servers in a hosted environment", 0, admin.getConfigservers().size());
+ assertEquals("Dedicated admin cluster controllers when hosted", 3, admin.getClusterControllers().getContainers().size());
+
+ // Check content clusters
+ ContentCluster cluster = model.getContentClusters().get("bar");
+ assertNull("No own cluster controllers when hosted", cluster.getClusterControllers());
+ assertEquals(0, cluster.getRootGroup().getNodes().size());
+ assertEquals(9, cluster.getRootGroup().getSubgroups().size());
+ assertEquals("0", cluster.getRootGroup().getSubgroups().get(0).getIndex());
+ assertEquals(3, cluster.getRootGroup().getSubgroups().get(0).getNodes().size());
+ assertEquals(0, cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getDistributionKey());
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getConfigId(), is("bar/storage/0"));
+ assertEquals("node-1-3-10-57", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName());
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(1).getDistributionKey(), is(1));
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(1).getConfigId(), is("bar/storage/1"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(2).getDistributionKey(), is(2));
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(2).getConfigId(), is("bar/storage/2"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getIndex(), is("1"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().size(), is(3));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getDistributionKey(), is(3));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getConfigId(), is("bar/storage/3"));
+ assertEquals("node-1-3-10-54", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName());
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(1).getDistributionKey(), is(4));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(1).getConfigId(), is("bar/storage/4"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(2).getDistributionKey(), is(5));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(2).getConfigId(), is("bar/storage/5"));
+ // ...
+ assertEquals("node-1-3-10-51", cluster.getRootGroup().getSubgroups().get(2).getNodes().get(0).getHostName());
+ // ...
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getIndex(), is("8"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().size(), is(3));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(0).getDistributionKey(), is(24));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(0).getConfigId(), is("bar/storage/24"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(1).getDistributionKey(), is(25));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(1).getConfigId(), is("bar/storage/25"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(2).getDistributionKey(), is(26));
+ assertThat(cluster.getRootGroup().getSubgroups().get(8).getNodes().get(2).getConfigId(), is("bar/storage/26"));
+
+ cluster = model.getContentClusters().get("baz");
+ assertNull("No own cluster controllers when hosted", cluster.getClusterControllers());
+ assertEquals(0, cluster.getRootGroup().getNodes().size());
+ assertEquals(27, cluster.getRootGroup().getSubgroups().size());
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getIndex(), is("0"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().size(), is(1));
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getDistributionKey(), is(0));
+ assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getConfigId(), is("baz/storage/0"));
+ assertEquals("node-1-3-10-27", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName());
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getIndex(), is("1"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().size(), is(1));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getDistributionKey(), is(1));
+ assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getConfigId(), is("baz/storage/1"));
+ assertEquals("node-1-3-10-26", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName());
+ // ...
+ assertEquals("node-1-3-10-25", cluster.getRootGroup().getSubgroups().get(2).getNodes().get(0).getHostName());
+ // ...
+ assertThat(cluster.getRootGroup().getSubgroups().get(26).getIndex(), is("26"));
+ assertThat(cluster.getRootGroup().getSubgroups().get(26).getNodes().size(), is(1));
+ assertThat(cluster.getRootGroup().getSubgroups().get(26).getNodes().get(0).getDistributionKey(), is(26));
+ assertThat(cluster.getRootGroup().getSubgroups().get(26).getNodes().get(0).getConfigId(), is("baz/storage/26"));
+ }
+
+ @Test
+ public void testUsingNodesAndGroupCountAttributesWithoutDedicatedClusterControllers() {
+ String services =
+ "<?xml version='1.0' encoding='utf-8' ?>\n" +
+ "<services>" +
" <admin version='4.0'/>" +
" <container version='1.0' id='foo'>" +
" <nodes count='10'/>" +
@@ -478,6 +585,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 64;
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(numberOfHosts);
VespaModel model = tester.createModel(services, true);
assertEquals(numberOfHosts, model.getRoot().hostSystem().getHosts().size());
@@ -584,20 +692,22 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
- int numberOfHosts = 18;
+ int numberOfHosts = 21;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
VespaModel model = tester.createModel(services, true);
assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts));
+ ClusterControllerContainerCluster clusterControllers = model.getAdmin().getClusterControllers();
+ assertEquals(3, clusterControllers.getContainers().size());
+ assertEquals("cluster-controllers", clusterControllers.getName());
+ assertEquals("node-1-3-10-03", clusterControllers.getContainers().get(0).getHostName());
+ assertEquals("node-1-3-10-02", clusterControllers.getContainers().get(1).getHostName());
+ assertEquals("node-1-3-10-01", clusterControllers.getContainers().get(2).getHostName());
+
// Check content cluster
ContentCluster cluster = model.getContentClusters().get("bar");
- ClusterControllerContainerCluster clusterControllers = cluster.getClusterControllers();
- assertEquals(3, clusterControllers.getContainers().size());
- assertEquals("bar-controllers", clusterControllers.getName());
- assertEquals("node-1-3-10-08", clusterControllers.getContainers().get(0).getHostName());
- assertEquals("node-1-3-10-07", clusterControllers.getContainers().get(1).getHostName());
- assertEquals("node-1-3-10-06", clusterControllers.getContainers().get(2).getHostName());
+ assertNull(cluster.getClusterControllers());
assertEquals(0, cluster.getRootGroup().getNodes().size());
assertEquals(8, cluster.getRootGroup().getSubgroups().size());
assertEquals(8, cluster.distributionBits());
@@ -606,19 +716,19 @@ public class ModelProvisioningTest {
assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().size(), is(1));
assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getDistributionKey(), is(0));
assertThat(cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getConfigId(), is("bar/storage/0"));
- assertEquals("node-1-3-10-08", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-10-11", cluster.getRootGroup().getSubgroups().get(0).getNodes().get(0).getHostName());
// second group
assertThat(cluster.getRootGroup().getSubgroups().get(1).getIndex(), is("1"));
assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().size(), is(1));
assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getDistributionKey(), is(1));
assertThat(cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getConfigId(), is("bar/storage/1"));
- assertEquals("node-1-3-10-07", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-10-10", cluster.getRootGroup().getSubgroups().get(1).getNodes().get(0).getHostName());
// ... last group
assertThat(cluster.getRootGroup().getSubgroups().get(7).getIndex(), is("7"));
assertThat(cluster.getRootGroup().getSubgroups().get(7).getNodes().size(), is(1));
assertThat(cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getDistributionKey(), is(7));
assertThat(cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getConfigId(), is("bar/storage/7"));
- assertEquals("node-1-3-10-01", cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getHostName());
+ assertEquals("node-1-3-10-04", cluster.getRootGroup().getSubgroups().get(7).getNodes().get(0).getHostName());
}
@Test
@@ -641,6 +751,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 18;
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(numberOfHosts);
VespaModel model = tester.createModel(services, true);
assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts));
@@ -656,43 +767,6 @@ public class ModelProvisioningTest {
}
@Test
- public void testClusterControllersIncludeNonRetiredNodes() {
- String services =
- "<?xml version='1.0' encoding='utf-8' ?>\n" +
- "<services>" +
- " <admin version='4.0'/>" +
- " <container version='1.0' id='foo'>" +
- " <nodes count='10'/>" +
- " </container>" +
- " <content version='1.0' id='bar'>" +
- " <redundancy>2</redundancy>" +
- " <documents>" +
- " <document type='type1' mode='index'/>" +
- " </documents>" +
- " <nodes count='9' groups='3'/>" +
- " </content>" +
- "</services>";
-
- int numberOfHosts = 19;
- VespaModelTester tester = new VespaModelTester();
- tester.addHosts(numberOfHosts);
- VespaModel model = tester.createModel(services, true, "node-1-3-10-09", "node-1-3-10-06", "node-1-3-10-03");
- assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts));
-
- // Check content clusters
- ContentCluster cluster = model.getContentClusters().get("bar");
- ClusterControllerContainerCluster clusterControllers = cluster.getClusterControllers();
- assertEquals(3 + 3, clusterControllers.getContainers().size()); // 3 new + 3 retired
- assertEquals("bar-controllers", clusterControllers.getName());
- assertEquals("Non-retired", "node-1-3-10-08", clusterControllers.getContainers().get(0).getHostName());
- assertEquals("Non-retired", "node-1-3-10-05", clusterControllers.getContainers().get(1).getHostName());
- assertEquals("Non-retired", "node-1-3-10-02", clusterControllers.getContainers().get(2).getHostName());
- assertEquals("Retired", "node-1-3-10-09", clusterControllers.getContainers().get(3).getHostName());
- assertEquals("Retired", "node-1-3-10-06", clusterControllers.getContainers().get(4).getHostName());
- assertEquals("Retired", "node-1-3-10-03", clusterControllers.getContainers().get(5).getHostName());
- }
-
- @Test
public void testSlobroksClustersAreExpandedToIncludeRetiredNodes() {
String services =
"<?xml version='1.0' encoding='utf-8' ?>\n" +
@@ -791,6 +865,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 2;
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(numberOfHosts);
VespaModel model = tester.createModel(services, true);
assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts));
@@ -824,7 +899,6 @@ public class ModelProvisioningTest {
int numberOfHosts = 7;
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- tester.dedicatedClusterControllerCluster(true);
VespaModel model = tester.createModel(services);
assertEquals(7, model.getRoot().hostSystem().getHosts().size());
@@ -991,6 +1065,7 @@ public class ModelProvisioningTest {
int numberOfHosts = 1; // We only have 1 content node -> 1 groups with redundancy 1
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(numberOfHosts);
VespaModel model = tester.createModel(services, false);
assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts));
@@ -1048,7 +1123,6 @@ public class ModelProvisioningTest {
int numberOfHosts = 4; // needs 2 for foo and 3 for cluster controllers.
VespaModelTester tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- tester.dedicatedClusterControllerCluster(true);
tester.createModel(services, false);
}
@@ -1157,6 +1231,7 @@ public class ModelProvisioningTest {
int totalHosts = 18;
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(new NodeResources(0.1, 0.2, 300, 0.3, NodeResources.DiskSpeed.slow), 1);// Logserver
tester.addHosts(new NodeResources(0.1, 0.3, 1, 0.5), 2); // Slobrok
tester.addHosts(new NodeResources(12, 10, 30, 0.3), 4); // Container
@@ -1188,6 +1263,7 @@ public class ModelProvisioningTest {
int totalHosts = 10;
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(new NodeResources(11.5, 10, 30, 0.3), 6);
tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20);
VespaModel model = tester.createModel(services, true);
@@ -1216,6 +1292,7 @@ public class ModelProvisioningTest {
int totalHosts = 26;
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(new NodeResources(13.5, 100, 1000, 0.3), 6);
tester.addHosts(new NodeResources(85, 200, 1000_000_000, 0.3), 20);
VespaModel model = tester.createModel(services, true, true);
@@ -1387,10 +1464,11 @@ public class ModelProvisioningTest {
tester.setHosted(true);
tester.addHosts(4);
VespaModel model = tester.createModel(new Zone(Environment.dev, RegionName.from("us-central-1")), services, true);
- assertEquals("We get 1 node per cluster and no admin node", 2, model.getHosts().size());
+ assertEquals("We get 1 node per cluster and no admin node apart from the dedicated cluster controller", 3, model.getHosts().size());
assertEquals(1, model.getContainerClusters().size());
assertEquals(1, model.getContainerClusters().get("foo").getContainers().size());
assertEquals(1, model.getContentClusters().get("bar").getRootGroup().countNodes());
+ assertEquals(1, model.getAdmin().getClusterControllers().getContainers().size());
}
/** Deploying an application with "nodes count" standalone should give a single-node deployment */
@@ -1437,6 +1515,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(3);
VespaModel model = tester.createModel(services, true);
assertEquals(3, model.getRoot().hostSystem().getHosts().size());
@@ -1737,6 +1816,7 @@ public class ModelProvisioningTest {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester();
+ tester.dedicatedClusterControllerCluster(false);
tester.addHosts(6);
VespaModel model = tester.createModel(servicesXml, true);
@@ -1851,7 +1931,7 @@ public class ModelProvisioningTest {
"</services>");
VespaModelTester tester = new VespaModelTester();
- tester.addHosts(new NodeResources(1, 3, 9, 5, NodeResources.DiskSpeed.slow), 2);
+ tester.addHosts(new NodeResources(1, 3, 10, 5, NodeResources.DiskSpeed.slow), 5);
VespaModel model = tester.createModel(services, true, 0);
ContentSearchCluster cluster = model.getContentClusters().get("test").getSearch();
assertEquals(2, cluster.getSearchNodes().size());
@@ -1903,7 +1983,7 @@ public class ModelProvisioningTest {
"</services>");
VespaModelTester tester = new VespaModelTester();
- tester.addHosts(new NodeResources(1, 3, 9, 1), 1);
+ tester.addHosts(new NodeResources(1, 3, 10, 1), 4);
tester.addHosts(new NodeResources(1, 128, 100, 0.3), 1);
VespaModel model = tester.createModel(services, true, 0);
ContentSearchCluster cluster = model.getContentClusters().get("test").getSearch();
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java
index 87db274d4f5..a11d23dbfbb 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyContainerTest.java
@@ -33,7 +33,7 @@ public class MetricsProxyContainerTest {
@Test
public void one_metrics_proxy_container_is_added_to_every_node() {
- var numberOfHosts = 4;
+ var numberOfHosts = 7;
var tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
@@ -55,7 +55,6 @@ public class MetricsProxyContainerTest {
var numberOfHosts = 7;
var tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
- tester.dedicatedClusterControllerCluster(true);
VespaModel model = tester.createModel(servicesWithManyNodes(), true);
assertThat(model.getRoot().hostSystem().getHosts().size(), is(numberOfHosts));
@@ -118,7 +117,7 @@ public class MetricsProxyContainerTest {
public void hosted_application_propagates_node_dimensions() {
String services = servicesWithContent();
VespaModel hostedModel = getModel(services, hosted);
- assertEquals(1, hostedModel.getHosts().size());
+ assertEquals(4, hostedModel.getHosts().size());
String configId = containerConfigId(hostedModel, hosted);
NodeDimensionsConfig config = getNodeDimensionsConfig(hostedModel, configId);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java
index 7fcd5c14a0f..7c31802fb4d 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/metricsproxy/MetricsProxyModelTester.java
@@ -44,7 +44,7 @@ class MetricsProxyModelTester {
}
static VespaModel getModel(String servicesXml, TestMode testMode, DeployState.Builder builder) {
- var numberOfHosts = testMode == hosted ? 2 : 1;
+ var numberOfHosts = testMode == hosted ? 4 : 1;
var tester = new VespaModelTester();
tester.addHosts(numberOfHosts);
tester.setHosted(testMode == hosted);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java
index 2d48f55d3d5..5525f00c381 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/search/ImplicitIndexingClusterTest.java
@@ -50,7 +50,7 @@ public class ImplicitIndexingClusterTest {
ModelContext.Properties properties = new TestProperties().setMultitenant(true).setHostedVespa(true);
DeployState.Builder deployStateBuilder = new DeployState.Builder()
.properties(properties)
- .modelHostProvisioner(new InMemoryProvisioner(true, false, "host1.yahoo.com", "host2.yahoo.com", "host3.yahoo.com"));
+ .modelHostProvisioner(new InMemoryProvisioner(6, false));
return new VespaModelCreatorWithMockPkg(new MockApplicationPackage.Builder()
.withServices("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + servicesXml)
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java
index ea76578ef04..811e789752e 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/content/ContentClusterTest.java
@@ -1059,7 +1059,7 @@ public class ContentClusterTest extends ContentBaseTest {
@Test
public void testDedicatedClusterControllers() {
- VespaModel noContentModel = createEnd2EndOneNode(new TestProperties().setDedicatedClusterControllerCluster(true)
+ VespaModel noContentModel = createEnd2EndOneNode(new TestProperties().setHostedVespa(true)
.setMultitenant(true),
"<?xml version='1.0' encoding='UTF-8' ?>" +
"<services version='1.0'>" +
@@ -1068,7 +1068,7 @@ public class ContentClusterTest extends ContentBaseTest {
assertEquals(Map.of(), noContentModel.getContentClusters());
assertNull("No cluster controller without content", noContentModel.getAdmin().getClusterControllers());
- VespaModel oneContentModel = createEnd2EndOneNode(new TestProperties().setDedicatedClusterControllerCluster(true)
+ VespaModel oneContentModel = createEnd2EndOneNode(new TestProperties().setHostedVespa(true)
.setMultitenant(true),
"<?xml version='1.0' encoding='UTF-8' ?>" +
"<services version='1.0'>" +
@@ -1109,7 +1109,7 @@ public class ContentClusterTest extends ContentBaseTest {
" </tuning>" +
" </content>" +
" </services>";
- VespaModel twoContentModel = createEnd2EndOneNode(new TestProperties().setDedicatedClusterControllerCluster(true)
+ VespaModel twoContentModel = createEnd2EndOneNode(new TestProperties().setHostedVespa(true)
.setMultitenant(true),
twoContentServices);
assertNull("No own cluster controller for content", twoContentModel.getContentClusters().get("storage").getClusterControllers());
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java b/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java
index 001773abb92..4a388025399 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/ModelAmendingTestCase.java
@@ -74,7 +74,7 @@ public class ModelAmendingTestCase {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester(amendingModelRepo);
- tester.addHosts(9);
+ tester.addHosts(12);
VespaModel model = tester.createModel(services);
// Check that all hosts are amended
@@ -121,7 +121,6 @@ public class ModelAmendingTestCase {
" </content>" +
"</services>";
VespaModelTester tester = new VespaModelTester(amendingModelRepo);
- tester.dedicatedClusterControllerCluster(true);
tester.addHosts(12);
VespaModel model = tester.createModel(services);
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
index 220f87001aa..eafbca09009 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java
@@ -52,7 +52,7 @@ public class VespaModelTester {
private final Map<NodeResources, Collection<Host>> hostsByResources = new HashMap<>();
private ApplicationId applicationId = ApplicationId.defaultId();
private boolean useDedicatedNodeForLogserver = false;
- private boolean dedicatedClusterControllerCluster = false;
+ private boolean dedicatedClusterControllerCluster = true;
public VespaModelTester() {
this(new NullConfigModelRegistry());
@@ -98,14 +98,14 @@ public class VespaModelTester {
applicationId = ApplicationId.from(tenant, applicationName, instanceName);
}
- public void dedicatedClusterControllerCluster(boolean dedicatedClusterControllerCluster) {
- this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster;
- }
-
public void useDedicatedNodeForLogserver(boolean useDedicatedNodeForLogserver) {
this.useDedicatedNodeForLogserver = useDedicatedNodeForLogserver;
}
+ public void dedicatedClusterControllerCluster(boolean dedicatedClusterControllerCluster) {
+ this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster;
+ }
+
/** Creates a model which uses 0 as start index and fails on out of capacity */
public VespaModel createModel(String services, String ... retiredHostNames) {
return createModel(Zone.defaultZone(), services, true, retiredHostNames);
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java b/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java
index 24dc2022e3c..20e23edddce 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/Deployer.java
@@ -71,10 +71,4 @@ public interface Deployer {
/** Timeout in server, clients can use this to set correct client timeout */
default Duration serverDeployTimeout() { return Duration.ofMinutes(30); }
- /** Turn on dedicated cluster controllers for the given application. */
- default void setDedicatedClusterControllerCluster(ApplicationId id) { }
-
- /** Get whether the given application uses dedicated cluster controllers. */
- default boolean getDedicatedClusterControllerCluster(ApplicationId id) { return false; }
-
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
index b46231d7070..5d46f3dc240 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/ApplicationRepository.java
@@ -1064,16 +1064,6 @@ public class ApplicationRepository implements com.yahoo.config.provision.Deploye
@Override
public Duration serverDeployTimeout() { return Duration.ofSeconds(configserverConfig.zookeeper().barrierTimeout()); }
- @Override
- public void setDedicatedClusterControllerCluster(ApplicationId id) {
- requireDatabase(id).setDedicatedClusterControllerCluster(id);
- }
-
- @Override
- public boolean getDedicatedClusterControllerCluster(ApplicationId id) {
- return requireDatabase(id).getDedicatedClusterControllerCluster(id);
- }
-
private static void logConfigChangeActions(ConfigChangeActions actions, DeployLogger logger) {
RestartActions restartActions = actions.getRestartActions();
if ( ! restartActions.isEmpty()) {
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java
index 078c60c1446..4704c5fcf26 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/application/ApplicationCuratorDatabase.java
@@ -113,10 +113,6 @@ public class ApplicationCuratorDatabase {
: data.map(bytes -> Long.parseLong(Utf8.toString(bytes)));
}
- public boolean getDedicatedClusterControllerCluster(ApplicationId id) {
- return curator.exists(dedicatedClusterControllerClusterPath(id));
- }
-
public void setDedicatedClusterControllerCluster(ApplicationId id) {
curator.create(dedicatedClusterControllerClusterPath(id));
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
index 8e6d51a55df..5f89903bf07 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/deploy/ModelContextImpl.java
@@ -260,7 +260,6 @@ public class ModelContextImpl implements ModelContext {
private final Quota quota;
private final List<TenantSecretStore> tenantSecretStores;
private final SecretStore secretStore;
- private final boolean dedicatedClusterControllerCluster;
private final String jvmGcOptions;
@@ -276,8 +275,7 @@ public class ModelContextImpl implements ModelContext {
Optional<ApplicationRoles> applicationRoles,
Optional<Quota> maybeQuota,
List<TenantSecretStore> tenantSecretStores,
- SecretStore secretStore,
- boolean dedicatedClusterControllerCluster) {
+ SecretStore secretStore) {
this.featureFlags = new FeatureFlags(flagSource, applicationId);
this.applicationId = applicationId;
this.multitenant = configserverConfig.multitenant() || configserverConfig.hostedVespa() || Boolean.getBoolean("multitenant");
@@ -294,7 +292,6 @@ public class ModelContextImpl implements ModelContext {
this.athenzDomain = athenzDomain;
this.applicationRoles = applicationRoles;
this.quota = maybeQuota.orElseGet(Quota::unlimited);
- this.dedicatedClusterControllerCluster = dedicatedClusterControllerCluster;
this.tenantSecretStores = tenantSecretStores;
this.secretStore = secretStore;
@@ -360,8 +357,6 @@ public class ModelContextImpl implements ModelContext {
@Override public String jvmGCOptions() { return jvmGcOptions; }
- @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && dedicatedClusterControllerCluster; }
-
private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) {
return flag.bindTo(source)
.with(FetchVector.Dimension.APPLICATION_ID, appId.serializedForm())
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
index fd04d4b58fc..cfc47223b11 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ActivatedModelsBuilder.java
@@ -164,8 +164,7 @@ public class ActivatedModelsBuilder extends ModelsBuilder<Application> {
.readApplicationRoles(applicationId),
zkClient.readQuota(),
zkClient.readTenantSecretStores(),
- secretStore,
- zkClient.readDedicatedClusterControllerCluster());
+ secretStore);
}
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
index d245e0a3e25..62052e935f1 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/session/SessionPreparer.java
@@ -116,12 +116,9 @@ public class SessionPreparer {
Optional<ApplicationSet> activeApplicationSet, Instant now, File serverDbSessionDir,
ApplicationPackage applicationPackage, SessionZooKeeperClient sessionZooKeeperClient) {
ApplicationId applicationId = params.getApplicationId();
- boolean dedicatedClusterControllerCluster = new ApplicationCuratorDatabase(applicationId.tenant(), curator).getDedicatedClusterControllerCluster(applicationId);
-
Preparation preparation = new Preparation(hostValidator, logger, params, activeApplicationSet,
TenantRepository.getTenantPath(applicationId.tenant()),
- serverDbSessionDir, applicationPackage, sessionZooKeeperClient,
- dedicatedClusterControllerCluster);
+ serverDbSessionDir, applicationPackage, sessionZooKeeperClient, true);
preparation.preprocess();
try {
AllocatedHosts allocatedHosts = preparation.buildModels(now);
@@ -207,8 +204,7 @@ public class SessionPreparer {
applicationRoles,
params.quota(),
params.tenantSecretStores(),
- secretStore,
- dedicatedClusterControllerCluster);
+ secretStore);
this.fileDistributionProvider = fileDistributionFactory.createProvider(serverDbSessionDir);
this.preparedModelsBuilder = new PreparedModelsBuilder(modelFactoryRegistry,
permanentApplicationPackage,
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java
index 0d066f748c8..7b9420b6b9e 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ModelContextImplTest.java
@@ -74,8 +74,7 @@ public class ModelContextImplTest {
Optional.empty(),
Optional.empty(),
List.of(),
- new SecretStoreProvider().get(),
- false),
+ new SecretStoreProvider().get()),
Optional.empty(),
Optional.empty(),
new Version(7),
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java
deleted file mode 100644
index 4588fc13875..00000000000
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigrator.java
+++ /dev/null
@@ -1,84 +0,0 @@
-// Copyright Verizon Media. 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.ApplicationId;
-import com.yahoo.config.provision.Deployer;
-import com.yahoo.config.provision.Environment;
-import com.yahoo.jdisc.Metric;
-import com.yahoo.vespa.flags.BooleanFlag;
-import com.yahoo.vespa.flags.FetchVector;
-import com.yahoo.vespa.flags.FlagSource;
-import com.yahoo.vespa.flags.Flags;
-import com.yahoo.vespa.hosted.provision.NodeRepository;
-import com.yahoo.vespa.orchestrator.Orchestrator;
-
-import java.time.Duration;
-import java.time.ZonedDateTime;
-import java.util.List;
-import java.util.Set;
-import java.util.logging.Level;
-
-import static java.time.DayOfWeek.SATURDAY;
-import static java.time.DayOfWeek.SUNDAY;
-import static java.util.stream.Collectors.toUnmodifiableSet;
-
-/**
- * @author jonmv
- */
-public class DedicatedClusterControllerClusterMigrator extends ApplicationMaintainer {
-
- private final BooleanFlag flag;
- private final Orchestrator orchestrator;
-
- protected DedicatedClusterControllerClusterMigrator(Deployer deployer, Metric metric, NodeRepository nodeRepository,
- Duration interval, FlagSource flags, Orchestrator orchestrator) {
- super(deployer, metric, nodeRepository, interval);
- this.flag = Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.bindTo(flags);
- this.orchestrator = orchestrator;
- }
-
- @Override
- protected Set<ApplicationId> applicationsNeedingMaintenance() {
- if (deployer().bootstrapping()) return Set.of();
-
- ZonedDateTime date = ZonedDateTime.ofInstant(clock().instant(), java.time.ZoneId.of("Europe/Oslo"));
- if ( ! nodeRepository().zone().system().isCd()
- && nodeRepository().zone().environment() != Environment.staging
- && (List.of(SATURDAY, SUNDAY).contains(date.getDayOfWeek()) || date.getHour() < 8 || 13 < date.getHour()))
- return Set.of();
-
- return nodeRepository().applications().ids().stream()
- .sorted()
- .filter(id -> ! id.instance().isTester())
- .filter(this::isEligible)
- .filter(this::hasNotSwitched)
- .filter(this::isQuiescent)
- .limit(1)
- .collect(toUnmodifiableSet());
- }
-
- @Override
- protected void deploy(ApplicationId id) {
- migrate(id);
- super.deploy(id);
- }
-
- private boolean isEligible(ApplicationId id) {
- return deployer().lastDeployTime(id).map(at -> at.isBefore(clock().instant().minus(Duration.ofMinutes(10)))).orElse(false)
- && flag.with(FetchVector.Dimension.APPLICATION_ID, id.serializedForm()).value();
- }
-
- private boolean hasNotSwitched(ApplicationId id) {
- return ! deployer().getDedicatedClusterControllerCluster(id);
- }
-
- private boolean isQuiescent(ApplicationId id) {
- return orchestrator.isQuiescent(id); // Check all content nodes are UP, have wanted state UP, and can be moved to MAINTENANCE.
- }
-
- private void migrate(ApplicationId id) {
- log.log(Level.INFO, "Migrating " + id + " to dedicated cluster controller cluster");
- deployer().setDedicatedClusterControllerCluster(id);
- }
-
-}
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 08106a94205..7f41f89f664 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
@@ -68,7 +68,6 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
maintainers.add(new AutoscalingMaintainer(nodeRepository, metricsDb, deployer, metric, defaults.autoscalingInterval));
maintainers.add(new ScalingSuggestionsMaintainer(nodeRepository, metricsDb, defaults.scalingSuggestionsInterval, metric));
maintainers.add(new SwitchRebalancer(nodeRepository, defaults.switchRebalancerInterval, metric, deployer));
- maintainers.add(new DedicatedClusterControllerClusterMigrator(deployer, metric, nodeRepository, defaults.dedicatedClusterControllerMigratorInterval, flagSource, orchestrator));
provisionServiceProvider.getLoadBalancerService(nodeRepository)
.map(lbService -> new LoadBalancerExpirer(nodeRepository, defaults.loadBalancerExpirerInterval, lbService, metric))
@@ -120,7 +119,6 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
private final Duration autoscalingInterval;
private final Duration scalingSuggestionsInterval;
private final Duration switchRebalancerInterval;
- private final Duration dedicatedClusterControllerMigratorInterval;
private final NodeFailer.ThrottlePolicy throttlePolicy;
@@ -149,8 +147,6 @@ public class NodeRepositoryMaintenance extends AbstractComponent {
switchRebalancerInterval = Duration.ofHours(1);
throttlePolicy = NodeFailer.ThrottlePolicy.hosted;
retiredExpiry = Duration.ofDays(4); // give up migrating data after 4 days
- dedicatedClusterControllerMigratorInterval = zone.environment() == Environment.staging || zone.system().isCd() ? Duration.ofMinutes(3)
- : Duration.ofHours(2);
inactiveConfigServerExpiry = Duration.ofMinutes(5);
inactiveControllerExpiry = Duration.ofMinutes(5);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java
deleted file mode 100644
index 22db730d69f..00000000000
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/maintenance/DedicatedClusterControllerClusterMigratorTest.java
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright Verizon Media. 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.ApplicationId;
-import com.yahoo.config.provision.Capacity;
-import com.yahoo.config.provision.ClusterResources;
-import com.yahoo.config.provision.Deployer;
-import com.yahoo.config.provision.Deployment;
-import com.yahoo.config.provision.HostFilter;
-import com.yahoo.config.provision.NodeResources;
-import com.yahoo.jdisc.test.MockMetric;
-import com.yahoo.vespa.flags.Flags;
-import com.yahoo.vespa.flags.InMemoryFlagSource;
-import com.yahoo.vespa.hosted.provision.applications.Application;
-import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
-import com.yahoo.vespa.hosted.provision.testutils.OrchestratorMock;
-import org.junit.Test;
-
-import java.time.Duration;
-import java.time.Instant;
-import java.util.Optional;
-import java.util.Set;
-import java.util.concurrent.ConcurrentSkipListSet;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.Phaser;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.TimeoutException;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicReference;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-/**
- * @author jonmv
- */
-public class DedicatedClusterControllerClusterMigratorTest {
-
- @Test
- public void testMigration() throws InterruptedException, TimeoutException {
- ApplicationId id1 = ApplicationId.from("t", "a", "i1"), id2 = ApplicationId.from("t", "a", "i2");
- ProvisioningTester tester = new ProvisioningTester.Builder().build();
- tester.clock().setInstant(Instant.EPOCH); // EPOCH was a week-day.
- tester.makeReadyNodes(4, new NodeResources(1.5, 8, 50, 0.3));
- tester.makeReadyHosts(1, NodeResources.unspecified());
- tester.deploy(id1, Capacity.from(new ClusterResources(2, 1, NodeResources.unspecified())));
- tester.deploy(id2, Capacity.from(new ClusterResources(2, 1, NodeResources.unspecified())));
- MockDeployer deployer = new MockDeployer();
- InMemoryFlagSource flags = new InMemoryFlagSource();
- AtomicBoolean isQuiescent = new AtomicBoolean();
- OrchestratorMock orchestrator = new OrchestratorMock() {
- @Override public boolean isQuiescent(ApplicationId id) { return isQuiescent.get(); }
- };
-
- DedicatedClusterControllerClusterMigrator migrator = new DedicatedClusterControllerClusterMigrator(deployer,
- new MockMetric(),
- tester.nodeRepository(),
- Duration.ofDays(365),
- flags,
- orchestrator);
- assertFalse(deployer.getDedicatedClusterControllerCluster(id1));
-
- // Set all conditions true except time window.
- flags.withBooleanFlag(Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.id(), true);
- isQuiescent.set(true);
- deployer.deployedAt.set(tester.clock().instant().minus(Duration.ofMinutes(15)));
- migrator.maintain();
- assertFalse(deployer.getDedicatedClusterControllerCluster(id1));
-
- // Enter time window, but no longer quiescent.
- tester.clock().advance(Duration.ofHours(8));
- isQuiescent.set(false);
- migrator.maintain();
- assertFalse(deployer.getDedicatedClusterControllerCluster(id1));
-
- // Quiescent, but no longer flagged.
- isQuiescent.set(true);
- flags.withBooleanFlag(Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.id(), false);
- migrator.maintain();
- assertFalse(deployer.getDedicatedClusterControllerCluster(id1));
-
- // Flagged, but recently deployed.
- flags.withBooleanFlag(Flags.DEDICATED_CLUSTER_CONTROLLER_CLUSTER.id(), true);
- deployer.deployedAt.set(tester.clock().instant().minus(Duration.ofMinutes(5)));
- migrator.maintain();
- assertFalse(deployer.getDedicatedClusterControllerCluster(id1));
-
- // Finally, all stars align.
- deployer.deployedAt.set(tester.clock().instant().minus(Duration.ofMinutes(15)));
- migrator.maintain();
- assertTrue(deployer.getDedicatedClusterControllerCluster(id1)); // Lex sorting, t.a.i1 before t.a.i2.
- assertFalse(deployer.getDedicatedClusterControllerCluster(id2));
- assertEquals(1, deployer.phaser.awaitAdvanceInterruptibly(deployer.phaser.arrive(), 10, TimeUnit.SECONDS));
-
- migrator.maintain();
- assertTrue(deployer.getDedicatedClusterControllerCluster(id2));
- assertEquals(2, deployer.phaser.awaitAdvanceInterruptibly(deployer.phaser.arrive(), 10, TimeUnit.SECONDS));
-
- assertEquals(Set.of(), migrator.applicationsNeedingMaintenance());
- }
-
-
- private static class MockDeployer implements Deployer {
-
- final Phaser phaser = new Phaser(2); // Test thread and deployer.
- final Set<ApplicationId> dedicatedCCC = new ConcurrentSkipListSet<>();
- final AtomicReference<Instant> deployedAt = new AtomicReference<>();
-
- @Override
- public Optional<Deployment> deployFromLocalActive(ApplicationId application, boolean bootstrap) {
- return Optional.of(new Deployment() {
- @Override public void prepare() { fail("Shouldn't run"); }
- @Override public long activate() { return phaser.arriveAndAwaitAdvance(); }
- @Override public void restart(HostFilter filter) { fail("Shouldn't run"); }
- });
- }
-
- @Override
- public Optional<Deployment> deployFromLocalActive(ApplicationId application, Duration timeout, boolean bootstrap) {
- return deployFromLocalActive(application, bootstrap);
- }
-
- @Override
- public Optional<Instant> lastDeployTime(ApplicationId application) {
- return Optional.ofNullable(deployedAt.get());
- }
-
- @Override
- public void setDedicatedClusterControllerCluster(ApplicationId id) {
- dedicatedCCC.add(id);
- }
-
- @Override
- public boolean getDedicatedClusterControllerCluster(ApplicationId id) {
- return dedicatedCCC.contains(id);
- }
-
- }
-
-}
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json
index bd4029ec0c0..b31c597e2b0 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/restapi/responses/maintenance.json
@@ -4,9 +4,6 @@
"name": "AutoscalingMaintainer"
},
{
- "name": "DedicatedClusterControllerClusterMigrator"
- },
- {
"name": "DirtyExpirer"
},
{