diff options
author | Martin Polden <mpolden@mpolden.no> | 2020-11-27 13:20:28 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2020-12-01 10:50:16 +0100 |
commit | ebe7a48b000b748e2dcea00466bd4e29f86e7ffc (patch) | |
tree | eb5d7c2fb7a864c81449040d056f834d3ec1b0d4 /config-model | |
parent | fa2196703ab3587fcda0735aeb4f9c2aefe55156 (diff) |
Set stateful property for relevant clusters
Diffstat (limited to 'config-model')
6 files changed, 65 insertions, 19 deletions
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java index 12d5e8d32ed..a28475c94f3 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV4Builder.java @@ -118,7 +118,9 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { return nodesSpecification.provision(hostSystem, ClusterSpec.Type.admin, ClusterSpec.Id.from(clusterId), - context.getDeployLogger()).keySet(); + context.getDeployLogger(), + false) + .keySet(); } /** diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java index 526e88749fc..aace6818ba6 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java @@ -202,15 +202,17 @@ public class NodesSpecification { public Map<HostResource, ClusterMembership> provision(HostSystem hostSystem, ClusterSpec.Type clusterType, ClusterSpec.Id clusterId, - DeployLogger logger) { + DeployLogger logger, + boolean stateful) { if (combinedId.isPresent()) clusterType = ClusterSpec.Type.combined; ClusterSpec cluster = ClusterSpec.request(clusterType, clusterId) - .vespaVersion(version) - .exclusive(exclusive) - .combinedId(combinedId.map(ClusterSpec.Id::from)) - .dockerImageRepository(dockerImageRepo) - .build(); + .vespaVersion(version) + .exclusive(exclusive) + .combinedId(combinedId.map(ClusterSpec.Id::from)) + .dockerImageRepository(dockerImageRepo) + .stateful(stateful) + .build(); return hostSystem.allocateHosts(cluster, Capacity.from(min, max, required, canFail), logger); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java index 63426979649..eff87f6833f 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java @@ -207,8 +207,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { } private void addZooKeeper(ApplicationContainerCluster cluster, Element spec) { - Element zkElement = XML.getChild(spec, "zookeeper"); - if (zkElement == null) return; + if (!hasZooKeeper(spec)) return; Element nodesElement = XML.getChild(spec, "nodes"); boolean isCombined = nodesElement != null && nodesElement.hasAttribute("of"); if (isCombined) { @@ -617,7 +616,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { if (nodesElement == null) { cluster.addContainers(allocateWithoutNodesTag(cluster, context)); } else { - List<ApplicationContainer> nodes = createNodes(cluster, nodesElement, context); + List<ApplicationContainer> nodes = createNodes(cluster, containerElement, nodesElement, context); Element jvmElement = XML.getChild(nodesElement, "jvm"); if (jvmElement == null) { @@ -648,15 +647,15 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return sb.toString(); } - private List<ApplicationContainer> createNodes(ApplicationContainerCluster cluster, Element nodesElement, ConfigModelContext context) { + private List<ApplicationContainer> createNodes(ApplicationContainerCluster cluster, Element containerElement, Element nodesElement, ConfigModelContext context) { if (nodesElement.hasAttribute("type")) // internal use for hosted system infrastructure nodes return createNodesFromNodeType(cluster, nodesElement, context); else if (nodesElement.hasAttribute("of")) // hosted node spec referencing a content cluster return createNodesFromContentServiceReference(cluster, nodesElement, context); else if (nodesElement.hasAttribute("count")) // regular, hosted node spec - return createNodesFromNodeCount(cluster, nodesElement, context); + return createNodesFromNodeCount(cluster, containerElement, nodesElement, context); else if (cluster.isHostedVespa() && cluster.getZone().environment().isManuallyDeployed()) // default to 1 in manual zones - return createNodesFromNodeCount(cluster, nodesElement, context); + return createNodesFromNodeCount(cluster, containerElement, nodesElement, context); else // the non-hosted option return createNodesFromNodeList(context.getDeployState(), cluster, nodesElement); } @@ -720,12 +719,13 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { return List.of(node); } - private List<ApplicationContainer> createNodesFromNodeCount(ApplicationContainerCluster cluster, Element nodesElement, ConfigModelContext context) { + private List<ApplicationContainer> createNodesFromNodeCount(ApplicationContainerCluster cluster, Element containerElement, Element nodesElement, ConfigModelContext context) { NodesSpecification nodesSpecification = NodesSpecification.from(new ModelElement(nodesElement), context); Map<HostResource, ClusterMembership> hosts = nodesSpecification.provision(cluster.getRoot().hostSystem(), ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), - log); + log, + hasZooKeeper(containerElement)); return createNodesFromHosts(context.getDeployLogger(), hosts, cluster); } @@ -940,6 +940,10 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { )); } + private static boolean hasZooKeeper(Element spec) { + return XML.getChild(spec, "zookeeper") != null; + } + /** Disallow renderers named "XmlRenderer" or "JsonRenderer" */ private static void validateRendererElement(Element element) { String idAttr = element.getAttribute("id"); diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/StorageGroup.java b/config-model/src/main/java/com/yahoo/vespa/model/content/StorageGroup.java index 894022d936d..3c0f8996c22 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/StorageGroup.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/StorageGroup.java @@ -1,12 +1,11 @@ // Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.content; +import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ConfigModelContext; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.provision.ClusterMembership; import com.yahoo.config.provision.ClusterSpec; -import com.yahoo.config.application.api.DeployLogger; -import java.util.logging.Level; import com.yahoo.vespa.config.content.StorDistributionConfig; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.HostSystem; @@ -25,6 +24,7 @@ import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.logging.Level; /** * A group of storage nodes/distributors. @@ -189,7 +189,7 @@ public class StorageGroup { HostSystem hostSystem, DeployLogger logger) { ClusterSpec.Id clusterId = ClusterSpec.Id.from(clusterIdString); - return nodesSpecification.provision(hostSystem, ClusterSpec.Type.content, clusterId, logger); + return nodesSpecification.provision(hostSystem, ClusterSpec.Type.content, clusterId, logger, true); } public static class Builder { 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 8ae895b0695..93367f1a286 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 @@ -354,7 +354,7 @@ public class ContentCluster extends AbstractConfigProducer implements } private Collection<HostResource> getControllerHosts(NodesSpecification nodesSpecification, Admin admin, String clusterName, ConfigModelContext context) { - return nodesSpecification.provision(admin.hostSystem(), ClusterSpec.Type.admin, ClusterSpec.Id.from(clusterName), context.getDeployLogger()).keySet(); + return nodesSpecification.provision(admin.hostSystem(), ClusterSpec.Type.admin, ClusterSpec.Id.from(clusterName), context.getDeployLogger(), false).keySet(); } private List<HostResource> drawControllerHosts(int count, StorageGroup rootGroup, Collection<ContainerModel> containers) { 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 4ee05b56bca..f8695a76b11 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 @@ -1815,6 +1815,44 @@ public class ModelProvisioningTest { assertEquals(1, controller.getContainers().size()); } + @Test + public void testStatefulProperty() { + String servicesXml = + "<?xml version='1.0' encoding='utf-8' ?>" + + "<services>" + + " <container version='1.0' id='qrs'>" + + " <nodes count='1'/>" + + " </container>" + + " <container version='1.0' id='zk'>" + + " <zookeeper/>" + + " <nodes count='3'/>" + + " </container>" + + " <content version='1.0' id='content'>" + + " <redundancy>2</redundancy>" + + " <documents>" + + " <document type='type1' mode='index'/>" + + " </documents>" + + " <nodes count='2'/>" + + " </content>" + + "</services>"; + VespaModelTester tester = new VespaModelTester(); + tester.addHosts(6); + VespaModel model = tester.createModel(servicesXml, true); + + Map<String, Boolean> tests = Map.of("qrs", false, + "zk", true, + "content", true); + Map<String, List<HostResource>> hostsByCluster = model.hostSystem().getHosts().stream() + .collect(Collectors.groupingBy(h -> h.spec().membership().get().cluster().id().value())); + tests.forEach((clusterId, stateful) -> { + List<HostResource> hosts = hostsByCluster.getOrDefault(clusterId, List.of()); + assertFalse("Hosts are provisioned for '" + clusterId + "'", hosts.isEmpty()); + assertEquals("Hosts in cluster '" + clusterId + "' are " + (stateful ? "" : "not ") + "stateful", + stateful, + hosts.stream().allMatch(h -> h.spec().membership().get().cluster().isStateful())); + }); + } + private VespaModel createNonProvisionedMultitenantModel(String services) { return createNonProvisionedModel(true, null, services); } |