summaryrefslogtreecommitdiffstats
path: root/config-model
diff options
context:
space:
mode:
authorHåkon Hallingstad <hakon@yahoo-inc.com>2016-09-05 15:23:45 +0200
committerHåkon Hallingstad <hakon@yahoo-inc.com>2016-09-05 15:23:45 +0200
commit0562d28182ee8326a870f7926fe17d29673ed2d1 (patch)
treef8df89f6cdaeae123eea2dcc0cf8517d4b045e4f /config-model
parent63ac82190522c63fbd6dac5f2e7439304de1ac4b (diff)
parentd0d055a239f6ffa959174e37577537b51eebf556 (diff)
Resolve merge conflict
Diffstat (limited to 'config-model')
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java3
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/Host.java21
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java100
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java21
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java8
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java5
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java1
-rwxr-xr-xconfig-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java9
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/container/xml/ContainerModelBuilder.java19
-rw-r--r--config-model/src/main/resources/schema/containercluster.rnc1
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java4
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/provision/ModelProvisioningTest.java9
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java2
-rwxr-xr-xconfig-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java25
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/test/VespaModelTester.java10
17 files changed, 141 insertions, 108 deletions
diff --git a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
index 8ca82692e98..3f229835914 100644
--- a/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
+++ b/config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java
@@ -84,7 +84,8 @@ public class DeployState implements ConfigDefinitionStore {
private DeployState(ApplicationPackage applicationPackage, SearchDocumentModel searchDocumentModel, RankProfileRegistry rankProfileRegistry,
FileRegistry fileRegistry, DeployLogger deployLogger, Optional<HostProvisioner> hostProvisioner, DeployProperties properties,
Optional<ApplicationPackage> permanentApplicationPackage, Optional<ConfigDefinitionRepo> configDefinitionRepo,
- java.util.Optional<Model> previousModel, Set<Rotation> rotations, Zone zone, QueryProfiles queryProfiles, SemanticRules semanticRules, Instant now) {
+ java.util.Optional<Model> previousModel, Set<Rotation> rotations, Zone zone, QueryProfiles queryProfiles,
+ SemanticRules semanticRules, Instant now) {
this.logger = deployLogger;
this.fileRegistry = fileRegistry;
this.rankProfileRegistry = rankProfileRegistry;
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/Host.java b/config-model/src/main/java/com/yahoo/config/model/provision/Host.java
index afe4de7ef0d..360853d0f79 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/Host.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/Host.java
@@ -1,40 +1,39 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.model.provision;
+import com.google.common.collect.ImmutableList;
+
import java.util.ArrayList;
import java.util.List;
/**
- * A hostname with zero or more aliases.
+ * A hostname with zero or more aliases. This is immutable.
*
* @author hmusum
*/
public class Host {
private final String hostname;
- private final List<String> hostAliases;
+ private final ImmutableList<String> aliases;
public Host(String hostname) {
this.hostname = hostname;
- this.hostAliases = new ArrayList<>();
+ this.aliases = ImmutableList.of();
}
public Host(String hostname, List<String> hostAliases) {
this.hostname = hostname;
- this.hostAliases = hostAliases;
+ this.aliases = ImmutableList.copyOf(hostAliases);
}
- public String getHostname() {
- return hostname;
- }
+ public String hostname() { return hostname; }
- public List<String> getHostAliases() {
- return hostAliases;
- }
+ /** Returns an immutable list of the aliases of this node, which may be empty but never null */
+ public List<String> aliases() { return aliases; }
@Override
public String toString() {
- return hostname + " (aliases: " + hostAliases + ")";
+ return hostname + (aliases.size() > 0 ? " (aliases: " + aliases + ")" : "" );
}
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java b/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java
index bfb77612d31..6a5abee7cb3 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/Hosts.java
@@ -1,8 +1,9 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.model.provision;
+import com.google.common.collect.ImmutableMap;
+import com.yahoo.cloud.config.ConfigserverConfig;
import com.yahoo.config.model.builder.xml.XmlHelper;
-import com.yahoo.log.LogLevel;
import com.yahoo.net.HostName;
import com.yahoo.text.XML;
import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder;
@@ -17,26 +18,52 @@ import java.util.*;
import java.util.logging.Logger;
/**
- * TODO: What is this?
+ * A collection of hosts
*
- * @author hmusum
+ * @author bratseth
*/
public class Hosts {
public static final Logger log = Logger.getLogger(Hosts.class.getPackage().toString());
- private final HashMap<String, Host> hosts = new LinkedHashMap<>();
- private final Map<String, String> alias2hostname = new LinkedHashMap<>();
- private final Map<String, Host> alias2host = new LinkedHashMap<>();
+ private final ImmutableMap<String, Host> hosts;
+ public Hosts(Collection<Host> hosts) {
+ validateAliases(hosts);
+
+ ImmutableMap.Builder<String, Host> hostsBuilder = new ImmutableMap.Builder<>();
+ for (Host host : hosts)
+ hostsBuilder.put(host.hostname(), host);
+ this.hosts = hostsBuilder.build();
+
+ // Don't limit zk connections on non-hosted systems
+ System.setProperty("zookeeper.vespa.clients", "");
+ }
+
+ /** Throw IllegalArgumentException if host aliases breaks invariants */
+ private void validateAliases(Collection<Host> hosts) {
+ Set<String> aliases = new HashSet<>();
+ for (Host host : hosts) {
+ if (host.aliases().size() > 0) {
+ if (host.aliases().size() < 1)
+ throw new IllegalArgumentException("Host '" + host.hostname() + "' must have at least one <alias> tag.");
+ for (String alias : host.aliases()) {
+ if (aliases.contains(alias))
+ throw new IllegalArgumentException("Alias '" + alias + "' is used by multiple hosts.");
+ aliases.add(alias);
+ }
+ }
+ }
+ }
+
/**
* Builds host system from a hosts.xml file
*
* @param hostsFile a reader for host from application package
* @return the HostSystem for this application package
*/
- public static Hosts getHosts(Reader hostsFile) {
- Hosts hosts = new Hosts();
+ public static Hosts readFrom(Reader hostsFile) {
+ List<Host> hosts = new ArrayList<>();
Document doc;
try {
doc = XmlHelper.getDocumentBuilder().parse(new InputSource(hostsFile));
@@ -55,62 +82,13 @@ public class Hosts {
if (hostAliases.isEmpty()) {
throw new IllegalArgumentException("No host aliases defined for host '" + name + "'");
}
- Host host = new Host(name, hostAliases);
- hosts.addHost(host, hostAliases);
- }
- log.log(LogLevel.DEBUG, "Created hosts:" + hosts);
- return hosts;
- }
-
- public Collection<Host> getHosts() {
- return hosts.values();
- }
-
- /**
- * Adds one host to this host system.
- *
- * @param host The host to add
- * @param aliases The aliases for this host.
- */
- public void addHost(Host host, List<String> aliases) {
- hosts.put(host.getHostname(), host);
- if ((aliases != null) && (aliases.size() > 0)) {
- addHostAliases(aliases, host);
+ hosts.add(new Host(name, hostAliases));
}
+ return new Hosts(hosts);
}
- /**
- * Add all aliases for one host
- *
- * @param hostAliases A list of host aliases
- * @param host The Host instance to add the alias for
- */
- private void addHostAliases(List<String> hostAliases, Host host) {
- if (hostAliases.size() < 1) {
- throw new RuntimeException("Host '" + host.getHostname() + "' must have at least one <alias> tag.");
- }
- for (String alias : hostAliases) {
- addHostAlias(alias, host);
- }
- }
-
- /**
- * Adds an alias for the given host
- *
- * @param alias alias (string) for a Host
- * @param host the {@link Host} to add the alias for
- */
- protected void addHostAlias(String alias, Host host) {
- if (alias2hostname.containsKey(alias)) {
- throw new RuntimeException("Alias '" + alias + "' must be used for only one host!");
- }
- alias2hostname.put(alias, host.getHostname());
- alias2host.put(alias, host);
- }
-
- public Map<String, Host> getAlias2host() {
- return alias2host;
- }
+ /** Returns an immutable collection of the hosts of this */
+ public Collection<Host> asCollection() { return hosts.values(); }
@Override
public String toString() {
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java
index bf630b74272..32a7e79d278 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/HostsXmlProvisioner.java
@@ -22,27 +22,24 @@ public class HostsXmlProvisioner implements HostProvisioner {
public static final String IMPLICIT_ADMIN_HOSTALIAS = "INTERNAL_VESPA_IMPLICIT_ADMIN";
public HostsXmlProvisioner(Reader hosts) {
- this.hosts = Hosts.getHosts(hosts);
+ this.hosts = Hosts.readFrom(hosts);
}
@Override
public HostSpec allocateHost(String alias) {
- /**
- * Some special rules to allow no admin elements as well
- * as jdisc element without nodes.
- */
+ // Some special rules to allow no admin elements as well as jdisc element without nodes.
if (alias.equals(IMPLICIT_ADMIN_HOSTALIAS)) {
- if (hosts.getHosts().size() > 1) {
- throw new IllegalArgumentException("More than 1 host specified (" + hosts.getHosts().size() + ") and <admin> not specified");
+ if (hosts.asCollection().size() > 1) {
+ throw new IllegalArgumentException("More than 1 host specified (" + hosts.asCollection().size() + ") and <admin> not specified");
} else {
return host2HostSpec(getFirstHost());
}
} else if (alias.equals(Container.SINGLENODE_CONTAINER_SERVICESPEC)) {
return host2HostSpec(getFirstHost());
}
- for (Host host : hosts.getHosts()) {
- if (host.getHostAliases().contains(alias)) {
- return new HostSpec(host.getHostname(), host.getHostAliases());
+ for (Host host : hosts.asCollection()) {
+ if (host.aliases().contains(alias)) {
+ return new HostSpec(host.hostname(), host.aliases());
}
}
throw new IllegalArgumentException("Unable to find host for alias '" + alias + "'");
@@ -54,11 +51,11 @@ public class HostsXmlProvisioner implements HostProvisioner {
}
private HostSpec host2HostSpec(Host host) {
- return new HostSpec(host.getHostname(), host.getHostAliases());
+ return new HostSpec(host.hostname(), host.aliases());
}
private Host getFirstHost() {
- return hosts.getHosts().iterator().next();
+ return hosts.asCollection().iterator().next();
}
}
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
index 69054cb7ae6..5c9d03b434f 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/InMemoryProvisioner.java
@@ -49,12 +49,12 @@ public class InMemoryProvisioner implements HostProvisioner {
/** Creates this with a set of hosts of the flavor 'default' */
public InMemoryProvisioner(Hosts hosts, boolean failOnOutOfCapacity, String ... retiredHostNames) {
- this(Collections.singletonMap("default", hosts.getHosts()), failOnOutOfCapacity, 0, retiredHostNames);
+ this(Collections.singletonMap("default", hosts.asCollection()), failOnOutOfCapacity, 0, retiredHostNames);
}
/** Creates this with a set of hosts of the flavor 'default' */
public InMemoryProvisioner(Hosts hosts, boolean failOnOutOfCapacity, int startIndexForClusters, String ... retiredHostNames) {
- this(Collections.singletonMap("default", hosts.getHosts()), failOnOutOfCapacity, startIndexForClusters, retiredHostNames);
+ this(Collections.singletonMap("default", hosts.asCollection()), failOnOutOfCapacity, startIndexForClusters, retiredHostNames);
}
public InMemoryProvisioner(Map<String, Collection<Host>> hosts, boolean failOnOutOfCapacity, int startIndexForClusters, String ... retiredHostNames) {
@@ -88,7 +88,7 @@ public class InMemoryProvisioner implements HostProvisioner {
List<Host> defaultHosts = freeNodes.get("default");
if (defaultHosts.isEmpty()) throw new IllegalArgumentException("No more hosts of default flavor available");
Host newHost = freeNodes.removeValue("default", 0);
- HostSpec hostSpec = new HostSpec(newHost.getHostname(), newHost.getHostAliases());
+ HostSpec hostSpec = new HostSpec(newHost.hostname(), newHost.aliases());
legacyMapping.put(alias, hostSpec);
return hostSpec;
}
@@ -141,7 +141,7 @@ public class InMemoryProvisioner implements HostProvisioner {
if (freeNodes.get(flavor).isEmpty()) throw new IllegalArgumentException("No nodes of flavor '" + flavor + "' available");
Host newHost = freeNodes.removeValue(flavor, 0);
ClusterMembership membership = ClusterMembership.from(clusterGroup, nextIndex++);
- allocation.add(new HostSpec(newHost.getHostname(), newHost.getHostAliases(), membership));
+ allocation.add(new HostSpec(newHost.hostname(), newHost.aliases(), membership));
}
nextIndexInCluster.put(new Pair<>(clusterGroup.type(), clusterGroup.id()), nextIndex);
diff --git a/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java b/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java
index 67e80ec95d6..1d5544873d9 100644
--- a/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java
+++ b/config-model/src/main/java/com/yahoo/config/model/provision/SingleNodeProvisioner.java
@@ -1,7 +1,6 @@
// Copyright 2016 Yahoo Inc. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.model.provision;
-import com.yahoo.config.application.api.DeployLogger;
import com.yahoo.config.model.api.HostProvisioner;
import com.yahoo.config.provision.*;
import com.yahoo.net.HostName;
@@ -31,7 +30,7 @@ public class SingleNodeProvisioner implements HostProvisioner {
} catch (UnknownHostException e) {
throw new RuntimeException(e);
}
- this.hostSpec = new HostSpec(host.getHostname(), host.getHostAliases());
+ this.hostSpec = new HostSpec(host.hostname(), host.aliases());
}
@Override
@@ -42,7 +41,7 @@ public class SingleNodeProvisioner implements HostProvisioner {
@Override
public List<HostSpec> prepare(ClusterSpec cluster, Capacity capacity, int groups, ProvisionLogger logger) { // TODO: This should fail if capacity requested is more than 1
List<HostSpec> hosts = new ArrayList<>();
- hosts.add(new HostSpec(host.getHostname(), host.getHostAliases(), ClusterMembership.from(cluster, counter++)));
+ hosts.add(new HostSpec(host.hostname(), host.aliases(), ClusterMembership.from(cluster, counter++)));
return hosts;
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java
index 08c3db81091..942c972a782 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/VespaDomBuilder.java
@@ -42,6 +42,7 @@ public class VespaDomBuilder extends VespaModelBuilder {
public static final String MMAP_NOCORE_LIMIT="mmap-nocore-limit";
private static final String CPU_SOCKET_ATTRIB_NAME = "cpu-socket";
public static final String CPU_SOCKET_AFFINITY_ATTRIB_NAME = "cpu-socket-affinity";
+ public static final String Allocated_MEMORY_ATTRIB_NAME = "allocated-memory";
public static final Logger log = Logger.getLogger(VespaDomBuilder.class.getPackage().toString());
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
index bb852d297a3..268f7a87f2c 100755
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/ContainerCluster.java
@@ -173,6 +173,7 @@ public final class ContainerCluster
private Zone zone;
private Optional<String> hostClusterId = Optional.empty();
+ private Optional<Integer> memoryPercentage = Optional.empty();
public ContainerCluster(AbstractConfigProducer<?> parent, String subId, String name) {
super(parent, subId);
@@ -791,6 +792,14 @@ public final class ContainerCluster
*/
public Optional<String> getHostClusterId() { return hostClusterId; }
+ public void setMemoryPercentage(Optional<Integer> memoryPercentage) { this.memoryPercentage = memoryPercentage; }
+
+ /**
+ * Returns the percentage of host physical memory this application has specified for nodes in this cluster,
+ * or empty if this is not specified by the application.
+ */
+ public Optional<Integer> getMemoryPercentage() { return memoryPercentage; }
+
@Override
public String toString() {
return "container cluster '" + getName() + "'";
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java
index c52a7375528..ef0f4882f1c 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/configserver/ConfigserverCluster.java
@@ -178,4 +178,5 @@ public class ConfigserverCluster extends AbstractConfigProducer
public void getConfig(HealthMonitorConfig.Builder builder) {
builder.snapshot_interval(60.0);
}
+
}
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
index 2e27dda5a62..a473514a344 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/container/search/ContainerSearch.java
@@ -38,10 +38,11 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains>
SemanticRulesConfig.Producer,
PageTemplatesConfig.Producer
{
+
private final List<AbstractSearchCluster> systems = new LinkedList<>();
private Options options = null;
- //For legacy qrs clusters only.
+ // For legacy qrs clusters only.
private BinaryScaledAmount totalCacheSize = new BinaryScaledAmount();
private QueryProfiles queryProfiles;
@@ -49,12 +50,14 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains>
private PageTemplates pageTemplates;
private final boolean hostedVespa;
private final boolean isCombinedCluster;
+ private final Optional<Integer> memoryPercentage;
public ContainerSearch(ContainerCluster cluster, SearchChains chains, Options options) {
super(chains);
this.options = options;
this.hostedVespa = cluster.isHostedVespa();
this.isCombinedCluster = cluster.getHostClusterId().isPresent();
+ this.memoryPercentage = cluster.getMemoryPercentage();
cluster.addComponent(getFS4ResourcePool());
}
@@ -122,7 +125,10 @@ public class ContainerSearch extends ContainerSubsystem<SearchChains>
@Override
public void getConfig(QrStartConfig.Builder qsB) {
QrStartConfig.Jvm.Builder internalBuilder = new QrStartConfig.Jvm.Builder();
- if (hostedVespa) {
+ if (memoryPercentage.isPresent()) {
+ internalBuilder.heapSizeAsPercentageOfPhysicalMemory(memoryPercentage.get());
+ }
+ else if (hostedVespa) {
if (isCombinedCluster)
internalBuilder.heapSizeAsPercentageOfPhysicalMemory(17);
else
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 8c4a451bb13..6d83c614044 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
@@ -387,6 +387,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
applyNodesTagJvmArgs(nodes, nodesElement.getAttribute(VespaDomBuilder.JVMARGS_ATTRIB_NAME));
applyRoutingAliasProperties(nodes, cluster);
applyDefaultPreload(nodes, nodesElement);
+ applyMemoryPercentage(cluster, nodesElement.getAttribute(VespaDomBuilder.Allocated_MEMORY_ATTRIB_NAME));
if (useCpuSocketAffinity(nodesElement))
AbstractService.distributeCpuSocketAffinity(nodes);
@@ -416,6 +417,24 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> {
}
}
+ private void applyMemoryPercentage(ContainerCluster cluster, String memoryPercentage) {
+ if (memoryPercentage == null || memoryPercentage.isEmpty()) return;
+ memoryPercentage = memoryPercentage.trim();
+
+ if ( ! memoryPercentage.endsWith("%"))
+ throw new IllegalArgumentException("The memory percentage given for nodes in " + cluster +
+ " must be an integer percentage ending by the '%' sign");
+ memoryPercentage = memoryPercentage.substring(0, memoryPercentage.length()-1).trim();
+
+ try {
+ cluster.setMemoryPercentage(Optional.of(Integer.parseInt(memoryPercentage)));
+ }
+ catch (NumberFormatException e) {
+ throw new IllegalArgumentException("The memory percentage given for nodes in " + cluster +
+ " must be an integer percentage ending by the '%' sign");
+ }
+ }
+
private HostResource allocateSingleNodeHost(ContainerCluster cluster, DeployLogger logger) {
if (cluster.isHostedVespa()) {
ClusterSpec clusterSpec = ClusterSpec.request(ClusterSpec.Type.container, ClusterSpec.Id.from(cluster.getName()), Optional.empty());
diff --git a/config-model/src/main/resources/schema/containercluster.rnc b/config-model/src/main/resources/schema/containercluster.rnc
index 287fd9f459e..e878b0faf22 100644
--- a/config-model/src/main/resources/schema/containercluster.rnc
+++ b/config-model/src/main/resources/schema/containercluster.rnc
@@ -184,6 +184,7 @@ DocumentApi = element document-api {
NodesOfContainerCluster = element nodes {
attribute jvmargs { text }? &
attribute preload { text }? &
+ attribute allocated-memory { text }? &
attribute cpu-socket-affinity { xsd:boolean }? &
(
attribute of { xsd:string }
diff --git a/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java b/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java
index 6d047c66a5a..b588805722f 100644
--- a/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java
+++ b/config-model/src/test/java/com/yahoo/config/model/provision/HostsXmlProvisionerTest.java
@@ -11,11 +11,13 @@ import java.util.*;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertEquals;
/**
* @author hmusum
*/
public class HostsXmlProvisionerTest {
+
private static final String oneHost = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" +
"<hosts>\n" +
" <host name=\"test1.yahoo.com\">\n" +
@@ -71,6 +73,8 @@ public class HostsXmlProvisionerTest {
assertThat(map.size(), is(3));
assertCorrectNumberOfHosts(map, 3);
assertTrue(map.keySet().containsAll(aliases));
+
+ assertEquals("", System.getProperty("zookeeper.vespa.clients"));
}
@Test(expected = IllegalArgumentException.class)
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 34f75d46a1c..86fabdf26bc 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
@@ -7,6 +7,7 @@ import static org.junit.Assert.*;
import java.io.StringReader;
import java.util.Collection;
import java.util.Map;
+import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
@@ -57,7 +58,7 @@ public class ModelProvisioningTest {
" <handler id='myHandler'>" +
" <component id='injected' />" +
" </handler>" +
- " <nodes count='2' jvmargs='-verbosegc' preload='lib/blablamalloc.so'/>" +
+ " <nodes count='2' allocated-memory='45%' jvmargs='-verbosegc' preload='lib/blablamalloc.so'/>" +
"</jdisc>" +
"</services>";
String hosts ="<hosts>"
@@ -81,7 +82,7 @@ public class ModelProvisioningTest {
+ " </host>"
+ "</hosts>";
VespaModelCreatorWithMockPkg creator = new VespaModelCreatorWithMockPkg(null, services);
- VespaModel model = creator.create(new DeployState.Builder().modelHostProvisioner(new InMemoryProvisioner(Hosts.getHosts(new StringReader(hosts)), true)));
+ VespaModel model = creator.create(new DeployState.Builder().modelHostProvisioner(new InMemoryProvisioner(Hosts.readFrom(new StringReader(hosts)), true)));
assertThat(model.getContainerClusters().get("mydisc").getContainers().size(), is(3));
assertThat(model.getContainerClusters().get("mydisc").getContainers().get(0).getConfigId(), is("mydisc/container.0"));
assertTrue(model.getContainerClusters().get("mydisc").getContainers().get(0).isInitialized());
@@ -102,12 +103,14 @@ public class ModelProvisioningTest {
assertThat(model.getContainerClusters().get("mydisc").getContainers().get(0).getPreLoad(), is(Defaults.getDefaults().vespaHome() + "lib64/vespa/malloc/libvespamalloc.so"));
assertThat(model.getContainerClusters().get("mydisc").getContainers().get(1).getPreLoad(), is(Defaults.getDefaults().vespaHome() + "lib64/vespa/malloc/libvespamalloc.so"));
assertThat(model.getContainerClusters().get("mydisc").getContainers().get(2).getPreLoad(), is(Defaults.getDefaults().vespaHome() + "lib64/vespa/malloc/libvespamalloc.so"));
+ assertThat(model.getContainerClusters().get("mydisc").getMemoryPercentage(), is(Optional.empty()));
assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(0).getJvmArgs(), is("-verbosegc"));
assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(1).getJvmArgs(), is("-verbosegc"));
assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(0).getPreLoad(), is("lib/blablamalloc.so"));
assertThat(model.getContainerClusters().get("mydisc2").getContainers().get(1).getPreLoad(), is("lib/blablamalloc.so"));
-
+ assertThat(model.getContainerClusters().get("mydisc2").getMemoryPercentage(), is(Optional.of(45)));
+
HostSystem hostSystem = model.getHostSystem();
assertNotNull(hostSystem.getHostByHostname("myhost0"));
assertNotNull(hostSystem.getHostByHostname("myhost1"));
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
index b4e366c1609..05f5145cfa7 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/admin/DedicatedAdminV4Test.java
@@ -47,7 +47,7 @@ public class DedicatedAdminV4Test {
+ " </host>"
+ "</hosts>";
ApplicationPackage app = new MockApplicationPackage.Builder().withHosts(hosts).withServices(services).build();
- VespaModel model = new VespaModel(new NullConfigModelRegistry(), new DeployState.Builder().applicationPackage(app).modelHostProvisioner(new InMemoryProvisioner(Hosts.getHosts(app.getHosts()), true)).build());
+ VespaModel model = new VespaModel(new NullConfigModelRegistry(), new DeployState.Builder().applicationPackage(app).modelHostProvisioner(new InMemoryProvisioner(Hosts.readFrom(app.getHosts()), true)).build());
assertEquals(3, model.getHosts().size());
Set<String> serviceNames0 = serviceNames(model.getConfig(SentinelConfig.class, "hosts/myhost0"));
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
index 5efbfe0d0dc..ef99d1a6370 100755
--- a/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/container/ContainerClusterTest.java
@@ -23,6 +23,7 @@ import org.junit.Test;
import java.util.Collections;
import java.util.Iterator;
+import java.util.Optional;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -82,29 +83,41 @@ public class ContainerClusterTest {
}
private ContainerCluster createContainerCluster(boolean isHosted, boolean isCombinedCluster) {
+ return createContainerCluster(isHosted, isCombinedCluster, Optional.empty());
+ }
+ private ContainerCluster createContainerCluster(boolean isHosted, boolean isCombinedCluster,
+ Optional<Integer> memoryPercentage) {
DeployState state = new DeployState.Builder().properties(new DeployProperties.Builder().hostedVespa(isHosted).build()).build();
MockRoot root = new MockRoot("foo", state);
ContainerCluster cluster = new ContainerCluster(root, "container0", "container1");
if (isCombinedCluster)
cluster.setHostClusterId("test-content-cluster");
+ cluster.setMemoryPercentage(memoryPercentage);
cluster.setSearch(new ContainerSearch(cluster, new SearchChains(cluster, "search-chain"), new ContainerSearch.Options()));
return cluster;
}
- private void verifyHeapSizeAsPercentageOfPhysicalMemory(boolean isHosted, boolean isCombinedCluster, int percentage) {
- ContainerCluster cluster = createContainerCluster(isHosted, isCombinedCluster);
+ private void verifyHeapSizeAsPercentageOfPhysicalMemory(boolean isHosted, boolean isCombinedCluster,
+ Optional<Integer> explicitMemoryPercentage,
+ int expectedMemoryPercentage) {
+ ContainerCluster cluster = createContainerCluster(isHosted, isCombinedCluster, explicitMemoryPercentage);
QrStartConfig.Builder qsB = new QrStartConfig.Builder();
cluster.getSearch().getConfig(qsB);
QrStartConfig qsC= new QrStartConfig(qsB);
- assertEquals(percentage, qsC.jvm().heapSizeAsPercentageOfPhysicalMemory());
+ assertEquals(expectedMemoryPercentage, qsC.jvm().heapSizeAsPercentageOfPhysicalMemory());
}
@Test
public void requireThatHeapSizeAsPercentageOfPhysicalMemoryForHostedAndNot() {
boolean hosted = true;
boolean combined = true; // a cluster running on content nodes (only relevant with hosted)
- verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, ! combined, 33);
- verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, combined, 17);
- verifyHeapSizeAsPercentageOfPhysicalMemory(! hosted, ! combined, 0);
+ verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, ! combined, Optional.empty(), 33);
+ verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, combined, Optional.empty(), 17);
+ verifyHeapSizeAsPercentageOfPhysicalMemory(! hosted, ! combined, Optional.empty(), 0);
+
+ // Explicit value overrides all defaults
+ verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, ! combined, Optional.of(67), 67);
+ verifyHeapSizeAsPercentageOfPhysicalMemory( hosted, combined, Optional.of(68), 68);
+ verifyHeapSizeAsPercentageOfPhysicalMemory(! hosted, ! combined, Optional.of(69), 69);
}
private void verifyJvmArgs(boolean isHosted, boolean hasDocproc, String expectedArgs, String jvmArgs) {
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 6eb38dd6f66..0c57d036998 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
@@ -13,9 +13,11 @@ import com.yahoo.vespa.model.VespaModel;
import com.yahoo.vespa.model.test.utils.ApplicationPackageUtils;
import com.yahoo.vespa.model.test.utils.VespaModelCreatorWithMockPkg;
+import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
/**
@@ -48,11 +50,11 @@ public class VespaModelTester {
public Hosts addHosts(int count) { return addHosts("default", count); }
/** Adds some hosts to this system */
public Hosts addHosts(String flavor, int count) {
- Hosts hosts = new Hosts();
+ List<Host> hosts = new ArrayList<>();
for (int i = 0; i < count; i++)
- hosts.addHost(new com.yahoo.config.model.provision.Host(flavor + i), Collections.emptyList());
- this.hosts.put(flavor.isEmpty() ? "default" : flavor, hosts.getHosts());
- return hosts;
+ hosts.add(new com.yahoo.config.model.provision.Host(flavor + i));
+ this.hosts.put(flavor.isEmpty() ? "default" : flavor, hosts);
+ return new Hosts(hosts);
}
/** Creates a model which uses 0 as start index and fails on out of capacity */