diff options
author | Arnstein Ressem <aressem@gmail.com> | 2021-03-04 22:05:54 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-04 22:05:54 +0100 |
commit | 9e35b8bd77a255ec359f78fb62028968aa0627ba (patch) | |
tree | 056f3173792a4ccdd092b67474e4bcb0e5f05548 /configserver | |
parent | 311e77aad06f187c70864a80a0703082f72bb3d8 (diff) |
Revert "Jonmv/new hosted apps use dedicated cluster controllers"
Diffstat (limited to 'configserver')
7 files changed, 85 insertions, 39 deletions
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 4704958781e..9529e25b37b 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 @@ -79,7 +79,6 @@ public class ApplicationCuratorDatabase { try (Lock lock = lock(id)) { curator.create(applicationPath(id)); modifyReindexing(id, ApplicationReindexing.empty(), UnaryOperator.identity()); - setDedicatedClusterControllerCluster(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..415c73ed37f 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 @@ -360,7 +360,7 @@ public class ModelContextImpl implements ModelContext { @Override public String jvmGCOptions() { return jvmGcOptions; } - @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && dedicatedClusterControllerCluster; } + @Override public boolean dedicatedClusterControllerCluster() { return dedicatedClusterControllerCluster; } private static <V> V flagValue(FlagSource source, ApplicationId appId, UnboundFlag<? extends V, ?, ?> flag) { return flag.bindTo(source) 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..2201ce47d84 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 @@ -42,6 +42,7 @@ import com.yahoo.vespa.config.server.modelfactory.PreparedModelsBuilder; import com.yahoo.vespa.config.server.provision.HostProvisionerProvider; import com.yahoo.vespa.config.server.tenant.ApplicationRolesStore; import com.yahoo.vespa.config.server.tenant.ContainerEndpointsCache; +import com.yahoo.vespa.config.server.tenant.EndpointCertificateMetadataSerializer; import com.yahoo.vespa.config.server.tenant.EndpointCertificateMetadataStore; import com.yahoo.vespa.config.server.tenant.EndpointCertificateRetriever; import com.yahoo.vespa.config.server.tenant.SecretStoreExternalIdRetriever; @@ -127,7 +128,7 @@ public class SessionPreparer { AllocatedHosts allocatedHosts = preparation.buildModels(now); preparation.makeResult(allocatedHosts); if ( ! params.isDryRun()) { - preparation.writeStateZK(); + preparation.writeStateZK(preparation.distributeApplicationPackage()); preparation.writeEndpointCertificateMetadataZK(); preparation.writeContainerEndpointsZK(); preparation.writeApplicationRoles(); @@ -233,7 +234,7 @@ public class SessionPreparer { } } - Optional<FileReference> distributedApplicationPackage() { + Optional<FileReference> distributeApplicationPackage() { FileRegistry fileRegistry = fileDistributionProvider.getFileRegistry(); FileReference fileReference = fileRegistry.addApplicationPackage(); FileDistribution fileDistribution = fileDistributionProvider.getFileDistribution(); @@ -268,16 +269,16 @@ public class SessionPreparer { checkTimeout("making result from models"); } - void writeStateZK() { + void writeStateZK(Optional<FileReference> distributedApplicationPackage) { log.log(Level.FINE, "Writing application package state to zookeeper"); writeStateToZooKeeper(sessionZooKeeperClient, preprocessedApplicationPackage, applicationId, - distributedApplicationPackage(), + distributedApplicationPackage, dockerImageRepository, vespaVersion, logger, - prepareResult.getFileRegistries(), + prepareResult.getFileRegistries(), prepareResult.allocatedHosts(), athenzDomain, params.quota(), diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java index 9a08375887c..83184ef6d47 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/ConfigServerBootstrapTest.java @@ -61,7 +61,7 @@ public class ConfigServerBootstrapTest { @Test public void testBootstrap() throws Exception { ConfigserverConfig configserverConfig = createConfigserverConfig(temporaryFolder); - InMemoryProvisioner provisioner = new InMemoryProvisioner(7, false); + InMemoryProvisioner provisioner = new InMemoryProvisioner(true, false, "host0", "host1", "host3", "host4"); DeployTester tester = new DeployTester.Builder().modelFactory(createHostedModelFactory()) .configserverConfig(configserverConfig).hostProvisioner(provisioner).build(); tester.deployApp("src/test/apps/hosted/"); @@ -94,7 +94,7 @@ public class ConfigServerBootstrapTest { @Test public void testBootstrapWithVipStatusFile() throws Exception { ConfigserverConfig configserverConfig = createConfigserverConfig(temporaryFolder); - InMemoryProvisioner provisioner = new InMemoryProvisioner(7, false); + InMemoryProvisioner provisioner = new InMemoryProvisioner(true, false, "host0", "host1", "host3", "host4"); DeployTester tester = new DeployTester.Builder().modelFactory(createHostedModelFactory()) .configserverConfig(configserverConfig).hostProvisioner(provisioner).build(); tester.deployApp("src/test/apps/hosted/"); diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java index f2722fb49e1..0149b23dcb6 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java @@ -180,7 +180,7 @@ public class DeployTester { } private static HostProvisioner createProvisioner() { - return new InMemoryProvisioner(7, false); + return new InMemoryProvisioner(true, false, "host0", "host1", "host2", "host3", "host4", "host5"); } private static class FailingModelFactory implements ModelFactory { diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java index 11e14192c74..231dcf728dd 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/HostedDeployTest.java @@ -18,6 +18,7 @@ import com.yahoo.config.provision.ApplicationId; import com.yahoo.config.provision.ClusterSpec; import com.yahoo.config.provision.DockerImage; import com.yahoo.config.provision.Environment; +import com.yahoo.config.provision.NodeResources; import com.yahoo.config.provision.RegionName; import com.yahoo.config.provision.Zone; import com.yahoo.test.ManualClock; @@ -41,12 +42,12 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.stream.Collectors; import java.util.stream.IntStream; import static com.yahoo.vespa.config.server.deploy.DeployTester.CountingModelFactory; import static com.yahoo.vespa.config.server.deploy.DeployTester.createFailingModelFactory; import static com.yahoo.vespa.config.server.deploy.DeployTester.createHostedModelFactory; -import static java.util.stream.Collectors.toList; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; @@ -117,7 +118,7 @@ public class HostedDeployTest { createHostedModelFactory(Version.fromString("7.0.0"))); DeployTester tester = new DeployTester.Builder().modelFactories(modelFactories).configserverConfig(createConfigserverConfig()).build(); tester.deployApp("src/test/apps/hosted/", "6.2.0"); - assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); } /** @@ -126,7 +127,10 @@ public class HostedDeployTest { */ @Test public void testCreateOnlyNeededModelVersions() throws IOException { - List<Host> hosts = createHosts(7, "6.0.0", "6.1.0", null, "6.1.0"); // Use a host without a version as well. + List<Host> hosts = List.of(createHost("host1", "6.0.0"), + createHost("host2", "6.1.0"), + createHost("host3"), // Use a host with no version as well + createHost("host4", "6.1.0")); CountingModelFactory factory600 = createHostedModelFactory(Version.fromString("6.0.0")); CountingModelFactory factory610 = createHostedModelFactory(Version.fromString("6.1.0")); @@ -140,7 +144,7 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone); // Deploy with version that does not exist on hosts, the model for this version should also be created tester.deployApp("src/test/apps/hosted/", "7.0.0"); - assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); // Check >0 not ==0 as the session watcher thread is running and will redeploy models in the background assertTrue(factory600.creationCount() > 0); @@ -157,7 +161,7 @@ public class HostedDeployTest { */ @Test public void testCreateOnlyNeededModelVersionsNewNodes() throws IOException { - List<Host> hosts = createHosts(7, (String) null); + List<Host> hosts = List.of(createHost("host1"), createHost("host2"), createHost("host3"), createHost("host4")); CountingModelFactory factory600 = createHostedModelFactory(Version.fromString("6.0.0")); CountingModelFactory factory610 = createHostedModelFactory(Version.fromString("6.1.0")); @@ -168,7 +172,7 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone); // Deploy with version that does not exist on hosts, the model for this version should also be created tester.deployApp("src/test/apps/hosted/", "7.0.0"); - assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); // Check >0 not ==0 as the session watcher thread is running and will redeploy models in the background assertTrue(factory700.creationCount() > 0); @@ -181,7 +185,8 @@ public class HostedDeployTest { */ @Test public void testCreateNeededModelVersionsForManuallyDeployedApps() throws IOException { - List<Host> hosts = createHosts(5, "7.0.0"); + List<Host> hosts = List.of(createHost("host1", "7.0.0"), createHost("host2", "7.0.0"), + createHost("host3", "7.0.0"), createHost("host4", "7.0.0")); CountingModelFactory factory700 = createHostedModelFactory(Version.fromString("7.0.0"), devZone); CountingModelFactory factory710 = createHostedModelFactory(Version.fromString("7.1.0"), devZone); @@ -191,7 +196,7 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, devZone); // Deploy with version that does not exist on hosts, the model for this version should also be created tester.deployApp("src/test/apps/hosted/", "7.2.0"); - assertEquals(5, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); // Check >0 not ==0 as the session watcher thread is running and will redeploy models in the background // Nodes are on 7.0.0 (should be created), no nodes on 7.1.0 (should not be created), 7.2.0 should always be created @@ -206,7 +211,8 @@ public class HostedDeployTest { */ @Test public void testCreateModelVersionsForManuallyDeployedAppsWhenCreatingFailsForOneVersion() throws IOException { - List<Host> hosts = createHosts(5, "7.0.0"); + List<Host> hosts = List.of(createHost("host1", "7.0.0"), createHost("host2", "7.0.0"), + createHost("host3", "7.0.0"), createHost("host4", "7.0.0")); ModelFactory factory700 = createFailingModelFactory(Version.fromString("7.0.0")); CountingModelFactory factory720 = createHostedModelFactory(Version.fromString("7.2.0"), devZone); @@ -216,7 +222,7 @@ public class HostedDeployTest { // Deploy with version that does not exist on hosts, the model for this version should be created even // if creating 7.0.0 fails tester.deployApp("src/test/apps/hosted/", "7.2.0"); - assertEquals(5, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); // Check >0 not ==0 as the session watcher thread is running and will redeploy models in the background assertTrue("Newest model for latest major version is always included", factory720.creationCount() > 0); @@ -251,7 +257,10 @@ public class HostedDeployTest { String oldestVersion = oldestMajorVersion + ".0.0"; String newestOnOldMajorVersion = oldestMajorVersion + ".1.0"; String newestOnNewMajorVersion = newestMajorVersion + ".2.0"; - List<Host> hosts = createHosts(7, oldestVersion, newestOnNewMajorVersion); + List<Host> hosts = List.of(createHost("host1", oldestVersion), + createHost("host2", newestOnOldMajorVersion), + createHost("host3", newestOnOldMajorVersion), + createHost("host4", newestOnOldMajorVersion)); CountingModelFactory factory1 = createHostedModelFactory(Version.fromString(oldestVersion)); CountingModelFactory factory2 = createHostedModelFactory(Version.fromString(newestOnOldMajorVersion)); @@ -260,7 +269,7 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone); tester.deployApp("src/test/apps/hosted/", oldestVersion); - assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); // Check >0 not ==0 as the session watcher thread is running and will redeploy models in the background assertTrue(factory1.creationCount() > 0); @@ -273,7 +282,9 @@ public class HostedDeployTest { **/ @Test(expected = InvalidApplicationException.class) public void testDeploymentFailsIfNeededModelVersionFails() throws IOException { - List<Host> hosts = createHosts(7, "7.0.0"); + List<Host> hosts = List.of(createHost("host1", "7.0.0"), + createHost("host2", "7.0.0"), + createHost("host3", "7.0.0")); List<ModelFactory> modelFactories = List.of(createFailingModelFactory(Version.fromString("7.0.0")), createHostedModelFactory(Version.fromString("7.1.0"))); @@ -293,7 +304,7 @@ public class HostedDeployTest { CountingModelFactory factory720 = createHostedModelFactory(Version.fromString("7.2.0")); List<ModelFactory> modelFactories = List.of(factory700, factory720); - DeployTester tester = createTester(createHosts(1, (String) null), modelFactories, prodZone); + DeployTester tester = createTester(List.of(createHost("host1")), modelFactories, prodZone); tester.deployApp("src/test/apps/hosted-routing-app/", "7.2.0"); assertFalse(factory700.creationCount() > 0); assertTrue("Newest is always included", factory720.creationCount() > 0); @@ -302,7 +313,7 @@ public class HostedDeployTest { @Test public void testAccessControlIsOnlyCheckedWhenNoProdDeploymentExists() throws IOException { // Provisioner does not reuse hosts, so need twice as many hosts as app requires - List<Host> hosts = createHosts(14, "6.0.0"); + List<Host> hosts = IntStream.rangeClosed(1, 8).mapToObj(i -> createHost("host" + i, "6.0.0")).collect(Collectors.toList()); List<ModelFactory> modelFactories = List.of(createHostedModelFactory(Version.fromString("6.0.0")), createHostedModelFactory(Version.fromString("6.1.0")), @@ -312,12 +323,12 @@ public class HostedDeployTest { ApplicationId applicationId = tester.applicationId(); // Deploy with oldest version tester.deployApp("src/test/apps/hosted/", "6.0.0"); - assertEquals(7, tester.getAllocatedHostsOf(applicationId).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(applicationId).getHosts().size()); // Deploy with version that does not exist on hosts and with app package that has no write access control, // validation of access control should not be done, since the app is already deployed in prod tester.deployApp("src/test/apps/hosted-no-write-access-control", "6.1.0", Instant.now()); - assertEquals(7, tester.getAllocatedHostsOf(applicationId).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(applicationId).getHosts().size()); } @Test @@ -359,7 +370,10 @@ public class HostedDeployTest { @Test public void testThatConfigChangeActionsAreCollectedFromAllModels() throws IOException { - List<Host> hosts = createHosts(7, "6.1.0", "6.2.0"); + List<Host> hosts = List.of(createHost("host1", "6.1.0"), + createHost("host2", "6.2.0"), + createHost("host3", "6.2.0"), + createHost("host4", "6.2.0")); List<ServiceInfo> services = List.of( new ServiceInfo("serviceName", "serviceType", null, new HashMap<>(), "configId", "hostName")); @@ -372,12 +386,15 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone); tester.deployApp("src/test/apps/hosted/", "6.2.0"); - assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); } @Test public void testThatAllowedConfigChangeActionsAreActedUpon() throws IOException { - List<Host> hosts = createHosts(7, "6.1.0"); + List<Host> hosts = List.of(createHost("host1", "6.1.0"), + createHost("host2", "6.1.0"), + createHost("host3", "6.1.0"), + createHost("host4", "6.1.0")); List<ServiceInfo> services = List.of( new ServiceInfo("serviceName", "serviceType", null, Map.of("clustername", "cluster"), "configId", "hostName")); @@ -391,13 +408,44 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone, clock); PrepareResult prepareResult = tester.deployApp("src/test/apps/hosted/", "6.1.0"); - assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); assertTrue(prepareResult.configChangeActions().getRestartActions().isEmpty()); // Handled by deployment. assertEquals(Optional.of(ApplicationReindexing.empty() .withPending("cluster", "music", prepareResult.sessionId())), tester.tenant().getApplicationRepo().database().readReindexingStatus(tester.applicationId())); } + @Test + public void testDedicatedClusterControllerCluster() throws IOException { + DeployTester tester = new DeployTester.Builder() + .modelFactory(createHostedModelFactory()) + .configserverConfig(createConfigserverConfig()) + .hostProvisioner(new InMemoryProvisioner(7, new NodeResources(1, 4, 10, 0.3), false)) + .build(); + ApplicationId appId = tester.applicationId(); + + // Dedicated CCC is off until turned on. + tester.deployApp("src/test/apps/hosted/"); + assertFalse(tester.applicationRepository().getActiveSession(appId).getMetaData().isInternalRedeploy()); + assertEquals(4, tester.getAllocatedHostsOf(appId).getHosts().size()); + assertFalse(tester.applicationRepository().getActiveSession(appId).getDedicatedClusterControllerCluster()); + + // Turn on dedicated CCC. + tester.applicationRepository().setDedicatedClusterControllerCluster(appId); + Optional<com.yahoo.config.provision.Deployment> deployment = tester.redeployFromLocalActive(); + assertTrue(deployment.isPresent()); + deployment.get().activate(); + assertTrue(tester.applicationRepository().getActiveSession(appId).getMetaData().isInternalRedeploy()); + assertEquals(7, tester.getAllocatedHostsOf(appId).getHosts().size()); + assertTrue(tester.applicationRepository().getActiveSession(appId).getDedicatedClusterControllerCluster()); + + // Setting persists through new deployments. + tester.deployApp("src/test/apps/hosted/"); + assertFalse(tester.applicationRepository().getActiveSession(appId).getMetaData().isInternalRedeploy()); + assertEquals(7, tester.getAllocatedHostsOf(appId).getHosts().size()); + assertTrue(tester.applicationRepository().getActiveSession(appId).getDedicatedClusterControllerCluster()); + } + private ConfigserverConfig createConfigserverConfig() throws IOException { return createConfigserverConfig(Zone.defaultZone()); } @@ -414,17 +462,15 @@ public class HostedDeployTest { .system(zone.system().value())); } - /** Create the given number of hosts using the supplied versions--the last version is repeated as needed. */ - private List<Host> createHosts(int count, String... versions) { - return IntStream.rangeClosed(1, count) - .mapToObj(i -> createHost("host" + i, versions[Math.min(i, versions.length) - 1])) - .collect(toList()); + private Host createHost(String hostname, String version) { + return new Host(hostname, Collections.emptyList(), Optional.empty(), Optional.of(Version.fromString(version))); } - private Host createHost(String hostname, String version) { - return new Host(hostname, Collections.emptyList(), Optional.empty(), Optional.ofNullable(version).map(Version::fromString)); + private Host createHost(String hostname) { + return new Host(hostname, Collections.emptyList(), Optional.empty(), Optional.empty()); } + private DeployTester createTester(List<Host> hosts, List<ModelFactory> modelFactories, Zone zone) throws IOException { return createTester(hosts, modelFactories, zone, Clock.systemUTC()); } diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java index 8d549c8d423..3afd2f185a1 100644 --- a/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java +++ b/configserver/src/test/java/com/yahoo/vespa/config/server/maintenance/MaintainerTester.java @@ -31,7 +31,7 @@ class MaintainerTester { MaintainerTester(Clock clock, TemporaryFolder temporaryFolder) throws IOException { this.curator = new MockCurator(); - InMemoryProvisioner hostProvisioner = new InMemoryProvisioner(7, false); + InMemoryProvisioner hostProvisioner = new InMemoryProvisioner(true, false, "host0", "host1", "host2", "host3", "host4"); Provisioner provisioner = new MockProvisioner().hostProvisioner(hostProvisioner); ConfigserverConfig configserverConfig = new ConfigserverConfig.Builder() .hostedVespa(true) |