diff options
author | Harald Musum <musum@verizonmedia.com> | 2021-03-09 09:23:00 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-03-09 09:23:00 +0100 |
commit | 18a16836ba782dc6b28c585293f2e7ea522134af (patch) | |
tree | 99e189a19f3ca7988e6215165d9aa2a93da3021f /configserver | |
parent | 04abf11cba0fa0d49403c2c398219fac3ae80d7f (diff) |
Revert "Revert "Reapply "Jonmv/new hosted apps use dedicated cluster controllers"""
Diffstat (limited to 'configserver')
7 files changed, 39 insertions, 85 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 9529e25b37b..4704958781e 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,6 +79,7 @@ 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 415c73ed37f..8e6d51a55df 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 dedicatedClusterControllerCluster; } + @Override public boolean dedicatedClusterControllerCluster() { return hostedVespa && 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 2201ce47d84..d245e0a3e25 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,7 +42,6 @@ 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; @@ -128,7 +127,7 @@ public class SessionPreparer { AllocatedHosts allocatedHosts = preparation.buildModels(now); preparation.makeResult(allocatedHosts); if ( ! params.isDryRun()) { - preparation.writeStateZK(preparation.distributeApplicationPackage()); + preparation.writeStateZK(); preparation.writeEndpointCertificateMetadataZK(); preparation.writeContainerEndpointsZK(); preparation.writeApplicationRoles(); @@ -234,7 +233,7 @@ public class SessionPreparer { } } - Optional<FileReference> distributeApplicationPackage() { + Optional<FileReference> distributedApplicationPackage() { FileRegistry fileRegistry = fileDistributionProvider.getFileRegistry(); FileReference fileReference = fileRegistry.addApplicationPackage(); FileDistribution fileDistribution = fileDistributionProvider.getFileDistribution(); @@ -269,16 +268,16 @@ public class SessionPreparer { checkTimeout("making result from models"); } - void writeStateZK(Optional<FileReference> distributedApplicationPackage) { + void writeStateZK() { 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 83184ef6d47..9a08375887c 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(true, false, "host0", "host1", "host3", "host4"); + InMemoryProvisioner provisioner = new InMemoryProvisioner(7, false); 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(true, false, "host0", "host1", "host3", "host4"); + InMemoryProvisioner provisioner = new InMemoryProvisioner(7, false); 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 0149b23dcb6..f2722fb49e1 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(true, false, "host0", "host1", "host2", "host3", "host4", "host5"); + return new InMemoryProvisioner(7, false); } 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 e77009416ed..f1404b30f30 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 @@ -19,7 +19,6 @@ 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; @@ -43,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; @@ -134,7 +133,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(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); } /** @@ -143,10 +142,7 @@ public class HostedDeployTest { */ @Test public void testCreateOnlyNeededModelVersions() throws IOException { - 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")); + List<Host> hosts = createHosts(7, "6.0.0", "6.1.0", null, "6.1.0"); // Use a host without a version as well. CountingModelFactory factory600 = createHostedModelFactory(Version.fromString("6.0.0")); CountingModelFactory factory610 = createHostedModelFactory(Version.fromString("6.1.0")); @@ -160,7 +156,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(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(7, 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); @@ -177,7 +173,7 @@ public class HostedDeployTest { */ @Test public void testCreateOnlyNeededModelVersionsNewNodes() throws IOException { - List<Host> hosts = List.of(createHost("host1"), createHost("host2"), createHost("host3"), createHost("host4")); + List<Host> hosts = createHosts(7, (String) null); CountingModelFactory factory600 = createHostedModelFactory(Version.fromString("6.0.0")); CountingModelFactory factory610 = createHostedModelFactory(Version.fromString("6.1.0")); @@ -188,7 +184,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(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(7, 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); @@ -201,8 +197,7 @@ public class HostedDeployTest { */ @Test public void testCreateNeededModelVersionsForManuallyDeployedApps() throws IOException { - 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")); + List<Host> hosts = createHosts(5, "7.0.0"); CountingModelFactory factory700 = createHostedModelFactory(Version.fromString("7.0.0"), devZone); CountingModelFactory factory710 = createHostedModelFactory(Version.fromString("7.1.0"), devZone); @@ -212,7 +207,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(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(5, 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 @@ -227,8 +222,7 @@ public class HostedDeployTest { */ @Test public void testCreateModelVersionsForManuallyDeployedAppsWhenCreatingFailsForOneVersion() throws IOException { - 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")); + List<Host> hosts = createHosts(5, "7.0.0"); ModelFactory factory700 = createFailingModelFactory(Version.fromString("7.0.0")); CountingModelFactory factory720 = createHostedModelFactory(Version.fromString("7.2.0"), devZone); @@ -238,7 +232,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(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(5, 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); @@ -273,10 +267,7 @@ public class HostedDeployTest { String oldestVersion = oldestMajorVersion + ".0.0"; String newestOnOldMajorVersion = oldestMajorVersion + ".1.0"; String newestOnNewMajorVersion = newestMajorVersion + ".2.0"; - List<Host> hosts = List.of(createHost("host1", oldestVersion), - createHost("host2", newestOnOldMajorVersion), - createHost("host3", newestOnOldMajorVersion), - createHost("host4", newestOnOldMajorVersion)); + List<Host> hosts = createHosts(7, oldestVersion, newestOnNewMajorVersion); CountingModelFactory factory1 = createHostedModelFactory(Version.fromString(oldestVersion)); CountingModelFactory factory2 = createHostedModelFactory(Version.fromString(newestOnOldMajorVersion)); @@ -285,7 +276,7 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone); tester.deployApp("src/test/apps/hosted/", oldestVersion); - assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(7, 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); @@ -298,9 +289,7 @@ public class HostedDeployTest { **/ @Test(expected = InvalidApplicationException.class) public void testDeploymentFailsIfNeededModelVersionFails() throws IOException { - List<Host> hosts = List.of(createHost("host1", "7.0.0"), - createHost("host2", "7.0.0"), - createHost("host3", "7.0.0")); + List<Host> hosts = createHosts(7, "7.0.0"); List<ModelFactory> modelFactories = List.of(createFailingModelFactory(Version.fromString("7.0.0")), createHostedModelFactory(Version.fromString("7.1.0"))); @@ -320,7 +309,7 @@ public class HostedDeployTest { CountingModelFactory factory720 = createHostedModelFactory(Version.fromString("7.2.0")); List<ModelFactory> modelFactories = List.of(factory700, factory720); - DeployTester tester = createTester(List.of(createHost("host1")), modelFactories, prodZone); + DeployTester tester = createTester(createHosts(1, (String) null), 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); @@ -329,7 +318,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 = IntStream.rangeClosed(1, 8).mapToObj(i -> createHost("host" + i, "6.0.0")).collect(Collectors.toList()); + List<Host> hosts = createHosts(14, "6.0.0"); List<ModelFactory> modelFactories = List.of(createHostedModelFactory(Version.fromString("6.0.0")), createHostedModelFactory(Version.fromString("6.1.0")), @@ -339,12 +328,12 @@ public class HostedDeployTest { ApplicationId applicationId = tester.applicationId(); // Deploy with oldest version tester.deployApp("src/test/apps/hosted/", "6.0.0"); - assertEquals(4, tester.getAllocatedHostsOf(applicationId).getHosts().size()); + assertEquals(7, 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(4, tester.getAllocatedHostsOf(applicationId).getHosts().size()); + assertEquals(7, tester.getAllocatedHostsOf(applicationId).getHosts().size()); } @Test @@ -386,10 +375,7 @@ public class HostedDeployTest { @Test public void testThatConfigChangeActionsAreCollectedFromAllModels() throws IOException { - 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<Host> hosts = createHosts(7, "6.1.0", "6.2.0"); List<ServiceInfo> services = List.of( new ServiceInfo("serviceName", "serviceType", null, new HashMap<>(), "configId", "hostName")); @@ -402,15 +388,12 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone); tester.deployApp("src/test/apps/hosted/", "6.2.0"); - assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(7, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); } @Test public void testThatAllowedConfigChangeActionsAreActedUpon() throws IOException { - 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<Host> hosts = createHosts(7, "6.1.0"); List<ServiceInfo> services = List.of( new ServiceInfo("serviceName", "serviceType", null, Map.of("clustername", "cluster"), "configId", "hostName")); @@ -424,44 +407,13 @@ public class HostedDeployTest { DeployTester tester = createTester(hosts, modelFactories, prodZone, clock); PrepareResult prepareResult = tester.deployApp("src/test/apps/hosted/", "6.1.0"); - assertEquals(4, tester.getAllocatedHostsOf(tester.applicationId()).getHosts().size()); + assertEquals(7, 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()); } @@ -478,15 +430,17 @@ public class HostedDeployTest { .system(zone.system().value())); } - private Host createHost(String hostname, String version) { - return new Host(hostname, Collections.emptyList(), Optional.empty(), Optional.of(Version.fromString(version))); + /** 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) { - return new Host(hostname, Collections.emptyList(), Optional.empty(), Optional.empty()); + private Host createHost(String hostname, String version) { + return new Host(hostname, Collections.emptyList(), Optional.empty(), Optional.ofNullable(version).map(Version::fromString)); } - 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 3afd2f185a1..8d549c8d423 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(true, false, "host0", "host1", "host2", "host3", "host4"); + InMemoryProvisioner hostProvisioner = new InMemoryProvisioner(7, false); Provisioner provisioner = new MockProvisioner().hostProvisioner(hostProvisioner); ConfigserverConfig configserverConfig = new ConfigserverConfig.Builder() .hostedVespa(true) |