diff options
author | Henning Baldersheim <balder@yahoo-inc.com> | 2022-02-07 12:09:52 +0100 |
---|---|---|
committer | Henning Baldersheim <balder@yahoo-inc.com> | 2022-02-07 12:09:52 +0100 |
commit | 2c4ea0a81062c3effa25ec42d44d0fc86adb1980 (patch) | |
tree | 0c9584645b17b637e602573792345e06de6ae4dc | |
parent | db2e29ca7f14e0e95f457402bd62203ff077923f (diff) |
- Adde featureflag for controlling environment variables.
- Use general environment mechanism for existing ad-hoc environment variables.
22 files changed, 223 insertions, 191 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 fb878f2c75f..c4a120fc10c 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 @@ -156,6 +156,7 @@ public interface ModelContext { default List<String> tlsCiphersOverride() { return List.of(); } default List<String> zoneDnsSuffixes() { return List.of(); } + List<String> environmentVariables(); } @Retention(RetentionPolicy.RUNTIME) 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 62e78db0e6f..f76cb6e43cc 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 @@ -1,7 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.config.model.deploy; -import com.google.common.collect.ImmutableList; import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.api.EndpointCertificateSecrets; @@ -75,6 +74,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea private double persistenceThrottlingWsDecrementFactor = 1.2; private double persistenceThrottlingWsBackoff = 0.95; private boolean useV8GeoPositions = false; + private List<String> environmentVariables = List.of(); @Override public ModelContext.FeatureFlags featureFlags() { return this; } @Override public boolean multitenant() { return multitenant; } @@ -129,6 +129,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea @Override public double persistenceThrottlingWsDecrementFactor() { return persistenceThrottlingWsDecrementFactor; } @Override public double persistenceThrottlingWsBackoff() { return persistenceThrottlingWsBackoff; } @Override public boolean useV8GeoPositions() { return useV8GeoPositions; } + @Override public List<String> environmentVariables() { return environmentVariables; } public TestProperties maxUnCommittedMemory(int maxUnCommittedMemory) { this.maxUnCommittedMemory = maxUnCommittedMemory; @@ -222,7 +223,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea } public TestProperties setConfigServerSpecs(List<Spec> configServerSpecs) { - this.configServerSpecs = ImmutableList.copyOf(configServerSpecs); + this.configServerSpecs = List.copyOf(configServerSpecs); return this; } @@ -341,6 +342,11 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea return this; } + public TestProperties setEnvironmentVariables(List<String> value) { + this.environmentVariables = value; + return this; + } + public static class Spec implements ConfigServerSpec { private final String hostName; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java b/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java index 78cbb722bc7..6777e2fb741 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/AbstractService.java @@ -4,6 +4,7 @@ package com.yahoo.vespa.model; import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.api.PortInfo; import com.yahoo.config.model.api.ServiceInfo; +import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.producer.AbstractConfigProducer; import com.yahoo.vespa.defaults.Defaults; @@ -16,6 +17,8 @@ import java.util.HashMap; import java.util.Map; import java.util.Optional; import java.util.Set; +import java.util.TreeMap; +import java.util.stream.Collectors; import static com.yahoo.text.Lowercase.toLowerCase; @@ -54,19 +57,7 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon // Please keep non-null, as passed to command line in service startup private String preload = null; - // If larger or equal to 0 it mean that explicit mmaps shall not be included in coredump. - private long mmapNoCoreLimit = -1L; - - // If this is true it will dump core when OOM - private boolean coreOnOOM = false; - - // If greater than 0, controls the number of threads used by open mp - private int ompNumThreads = 0; - - private String noVespaMalloc = ""; - private String vespaMalloc = ""; - private String vespaMallocDebug = ""; - private String vespaMallocDebugStackTrace = ""; + private final Map<String, Object> environmentVariables = new TreeMap<>(); /** The ports metainfo object */ protected PortsMeta portsMeta = new PortsMeta(); @@ -97,6 +88,8 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon */ public AbstractService(AbstractConfigProducer<?> parent, String name) { super(parent, name); + environmentVariables.put("OMP_NUM_THREADS", 1); + environmentVariables.put("VESPA_SILENCE_CORE_ON_OOM", true); } /** @@ -105,7 +98,7 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon * @param name the name of this service. */ public AbstractService(String name) { - super(name); + this(null, name); } @Override @@ -139,7 +132,7 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon * @param hostResource The physical host on which this service should run. * @param userPort The wanted port given by the user. */ - private void initService(DeployLogger deployLogger, HostResource hostResource, int userPort) { + private void initService(DeployState deployState, HostResource hostResource, int userPort) { if (initialized) { throw new IllegalStateException("Service '" + getConfigId() + "' already initialized."); } @@ -148,16 +141,19 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon "The hostalias is probably missing from hosts.xml."); } id = getIndex(hostResource); - ports = hostResource.allocateService(deployLogger, this, getInstanceWantedPort(userPort)); + ports = hostResource.allocateService(deployState.getDeployLogger(), this, getInstanceWantedPort(userPort)); initialized = true; + for(String envVar : deployState.getProperties().environmentVariables()) { + addEnvironmentVariable(envVar); + } } /** * Called by builder class which has not given the host or port in a constructor, hence * initService is not yet run for this. */ - public void initService(DeployLogger deployLogger) { - initService(deployLogger, this.hostResource, this.basePort); + public void initService(DeployState deployState) { + initService(deployState, this.hostResource, this.basePort); } /** @@ -381,60 +377,44 @@ public abstract class AbstractService extends AbstractConfigProducer<AbstractCon public void setPreLoad(String preload) { this.preload = preload; } - public long getMMapNoCoreLimit() { return mmapNoCoreLimit; } - public void setMMapNoCoreLimit(long noCoreLimit) { this.mmapNoCoreLimit = noCoreLimit; } - public boolean getCoreOnOOM() { return coreOnOOM; } - public void setCoreOnOOM(boolean coreOnOOM) { this.coreOnOOM = coreOnOOM; } - public int getOmpNumThreads() { return ompNumThreads; } - public void setOmpNumThreads(int value) { ompNumThreads = value; } - - public String getNoVespaMalloc() { return noVespaMalloc; } - public String getVespaMalloc() { return vespaMalloc; } - public String getVespaMallocDebug() { return vespaMallocDebug; } - public String getVespaMallocDebugStackTrace() { return vespaMallocDebugStackTrace; } - public void setNoVespaMalloc(String s) { noVespaMalloc = s; } - public void setVespaMalloc(String s) { vespaMalloc = s; } - public void setVespaMallocDebug(String s) { vespaMallocDebug = s; } - public void setVespaMallocDebugStackTrace(String s) { vespaMallocDebugStackTrace = s; } - - public String getMMapNoCoreEnvVariable() { - return (getMMapNoCoreLimit() >= 0L) - ? "VESPA_MMAP_NOCORE_LIMIT=" + getMMapNoCoreLimit() + " " - : ""; - } - - public String getCoreOnOOMEnvVariable() { - return getCoreOnOOM() ? "" : "VESPA_SILENCE_CORE_ON_OOM=true "; - } - public String getOmpNumThreadsEnvVariable() { - return (getOmpNumThreads() == 0) - ? "" - : "OMP_NUM_THREADS=" + getOmpNumThreads() + " "; - } - public String getNoVespaMallocEnvVariable() { - return "".equals(getNoVespaMalloc()) - ? "" - : "VESPA_USE_NO_VESPAMALLOC=\"" + getNoVespaMalloc() + "\" "; - } - public String getVespaMallocEnvVariable() { - return "".equals(getVespaMalloc()) - ? "" - : "VESPA_USE_VESPAMALLOC=\"" + getVespaMalloc() + "\" "; - } - public String getVespaMallocDebugEnvVariable() { - return "".equals(getVespaMallocDebug()) - ? "" - : "VESPA_USE_VESPAMALLOC_D=\"" + getVespaMallocDebug() + "\" "; - } - public String getVespaMallocDebugStackTraceEnvVariable() { - return "".equals(getVespaMallocDebugStackTrace()) - ? "" - : "VESPA_USE_VESPAMALLOC_DST=\"" + getVespaMallocDebugStackTrace() + "\" "; - } - - public String getEnvVariables() { - return getCoreOnOOMEnvVariable() + getOmpNumThreadsEnvVariable() + getMMapNoCoreEnvVariable() + getNoVespaMallocEnvVariable() + - getVespaMallocEnvVariable() + getVespaMallocDebugEnvVariable() + getVespaMallocDebugStackTraceEnvVariable(); + /** If larger or equal to 0 it mean that explicit mmaps shall not be included in coredump.*/ + public void setMMapNoCoreLimit(long noCoreLimit) { + if (noCoreLimit >= 0) { + environmentVariables.put("VESPA_MMAP_NOCORE_LIMIT", noCoreLimit); + } else { + environmentVariables.remove("VESPA_MMAP_NOCORE_LIMIT"); + } + } + public void setCoreOnOOM(boolean coreOnOOM) { + if ( ! coreOnOOM) { + environmentVariables.put("VESPA_SILENCE_CORE_ON_OOM", true); + } else { + environmentVariables.remove("VESPA_SILENCE_CORE_ON_OOM"); + } + } + + public void setNoVespaMalloc(String s) { environmentVariables.put("VESPA_USE_NO_VESPAMALLOC", s); } + public void setVespaMalloc(String s) { environmentVariables.put("VESPA_USE_VESPAMALLOC", s); } + public void setVespaMallocDebug(String s) { environmentVariables.put("VESPA_USE_VESPAMALLOC_D", s); } + public void setVespaMallocDebugStackTrace(String s) { environmentVariables.put("VESPA_USE_VESPAMALLOC_DST", s); } + + private static String toEnvValue(Object o) { + if (o instanceof Number || o instanceof Boolean) { + return o.toString(); + } + return '"' + o.toString() + '"'; + } + + public void addEnvironmentVariable(String nameAndValue) { + int pos = nameAndValue.indexOf('='); + environmentVariables.put(nameAndValue.substring(0, pos), nameAndValue.substring(pos+1)); + } + public void addEnvironmentVariable(String name, Object value) { + environmentVariables.put(name, value); + } + + public String getEnv() { + return environmentVariables.entrySet().stream().map(e -> e.getKey() + '=' + toEnvValue(e.getValue())).collect(Collectors.joining(" ")); } /** diff --git a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java index 2692d676d2b..e299689d1c7 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/admin/Admin.java @@ -5,7 +5,6 @@ import com.yahoo.config.model.api.ModelContext; import com.yahoo.cloud.config.SlobroksConfig; import com.yahoo.cloud.config.ZookeepersConfig; import com.yahoo.cloud.config.log.LogdConfig; -import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ConfigModelContext.ApplicationType; import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.producer.AbstractConfigProducer; @@ -168,7 +167,7 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable Slobrok slobrok = new Slobrok(this, clusterController.index(), deployState.featureFlags()); slobrok.setHostResource(clusterController.getHostResource()); slobroks.add(slobrok); - slobrok.initService(deployState.getDeployLogger()); + slobrok.initService(deployState); } return slobroks; } @@ -237,16 +236,16 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable // Send hostname to be used in configId (instead of index), as the sorting of hosts seems to be unstable // between config changes, even when the set of hosts is unchanged. var container = new MetricsProxyContainer(metricsProxyCluster, host, index, deployState); - addAndInitializeService(deployState.getDeployLogger(), host, container); + addAndInitializeService(deployState, host, container); metricsProxyCluster.addContainer(container); } } private void addCommonServices(HostResource host, DeployState deployState) { - addConfigSentinel(deployState.getDeployLogger(), host, deployState.getProperties().applicationId(), deployState.zone(), + addConfigSentinel(deployState, host, deployState.getProperties().applicationId(), deployState.zone(), deployState.featureFlags()); - addLogd(deployState.getDeployLogger(), host); - addConfigProxy(deployState.getDeployLogger(), host); + addLogd(deployState, host); + addConfigProxy(deployState, host); addFileDistribution(host); if (logForwarderConfig != null) { boolean actuallyAdd = true; @@ -259,34 +258,34 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable } } if (actuallyAdd) { - addLogForwarder(deployState.getDeployLogger(), host); + addLogForwarder(deployState, host); } } } - private void addConfigSentinel(DeployLogger deployLogger, HostResource host, + private void addConfigSentinel(DeployState deployState, HostResource host, ApplicationId applicationId, Zone zone, ModelContext.FeatureFlags featureFlags) { ConfigSentinel configSentinel = new ConfigSentinel(host.getHost(), applicationId, zone, featureFlags); - addAndInitializeService(deployLogger, host, configSentinel); + addAndInitializeService(deployState, host, configSentinel); host.getHost().setConfigSentinel(configSentinel); } - private void addLogForwarder(DeployLogger deployLogger, HostResource host) { - addAndInitializeService(deployLogger, host, new LogForwarder(host.getHost(), logForwarderConfig)); + private void addLogForwarder(DeployState deployState, HostResource host) { + addAndInitializeService(deployState, host, new LogForwarder(host.getHost(), logForwarderConfig)); } - private void addLogd(DeployLogger deployLogger, HostResource host) { - addAndInitializeService(deployLogger, host, new Logd(host.getHost())); + private void addLogd(DeployState deployState, HostResource host) { + addAndInitializeService(deployState, host, new Logd(host.getHost())); } - private void addConfigProxy(DeployLogger deployLogger, HostResource host) { - addAndInitializeService(deployLogger, host, new ConfigProxy(host.getHost())); + private void addConfigProxy(DeployState deployState, HostResource host) { + addAndInitializeService(deployState, host, new ConfigProxy(host.getHost())); } - public void addAndInitializeService(DeployLogger deployLogger, HostResource host, AbstractService service) { + public void addAndInitializeService(DeployState deployState, HostResource host, AbstractService service) { service.setHostResource(host); - service.initService(deployLogger); + service.initService(deployState); } private void addFileDistribution(HostResource host) { @@ -300,7 +299,7 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable List<Slobrok> slobs = new ArrayList<>(); if (logserver != null) { Slobrok slobrok = new Slobrok(this, 0, deployState.featureFlags()); - addAndInitializeService(deployState.getDeployLogger(), logserver.getHostResource(), slobrok); + addAndInitializeService(deployState, logserver.getHostResource(), slobrok); slobs.add(slobrok); } @@ -309,7 +308,7 @@ public class Admin extends AbstractConfigProducer<Admin> implements Serializable HostResource host = hosts.get(n); if ((logserver== null || host != logserver.getHostResource()) && ! host.getHost().runsConfigServer()) { Slobrok newSlobrok = new Slobrok(this, slobs.size(), deployState.featureFlags()); - addAndInitializeService(deployState.getDeployLogger(), host, newSlobrok); + addAndInitializeService(deployState, host, newSlobrok); slobs.add(newSlobrok); } n++; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java index 56f462805bd..4c74282c061 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminBuilderBase.java @@ -45,7 +45,7 @@ public abstract class DomAdminBuilderBase extends VespaDomBuilder.DomConfigProdu this.configServerSpecs = configServerSpecs; } - List<Configserver> getConfigServersFromSpec(DeployLogger deployLogger, AbstractConfigProducer<?> parent) { + List<Configserver> getConfigServersFromSpec(DeployState deployState, AbstractConfigProducer<?> parent) { List<Configserver> configservers = new ArrayList<>(); for (ConfigServerSpec spec : configServerSpecs) { HostSystem hostSystem = parent.hostSystem(); @@ -54,7 +54,7 @@ public abstract class DomAdminBuilderBase extends VespaDomBuilder.DomConfigProdu Configserver configserver = new Configserver(parent, spec.getHostName(), spec.getConfigServerPort()); configserver.setHostResource(host); configserver.setBasePort(configserver.getWantedPort()); - configserver.initService(deployLogger); + configserver.initService(deployState); configservers.add(configserver); } return configservers; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java index 5aaba9550d2..8e7c543b67b 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/DomAdminV2Builder.java @@ -53,7 +53,7 @@ public class DomAdminV2Builder extends DomAdminBuilderBase { private List<Configserver> parseConfigservers(DeployState deployState, Admin admin, Element adminE) { List<Configserver> configservers; if (multitenant) - configservers = getConfigServersFromSpec(deployState.getDeployLogger(), admin); + configservers = getConfigServersFromSpec(deployState, admin); else configservers = getConfigServers(deployState, admin, adminE); if (configservers.isEmpty() && ! multitenant) @@ -129,7 +129,7 @@ public class DomAdminV2Builder extends DomAdminBuilderBase { SimpleConfigProducer<?> configServers = new SimpleConfigProducer<>(parent, "configservers"); Configserver configServer = new Configserver(configServers, "configserver", Configserver.defaultRpcPort); configServer.setHostResource(parent.hostSystem().getHost(Container.SINGLENODE_CONTAINER_SERVICESPEC)); - configServer.initService(deployState.getDeployLogger()); + configServer.initService(deployState); return List.of(configServer); } 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 41baf2db3aa..a91a7949ad8 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 @@ -1,7 +1,6 @@ // Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.vespa.model.builder.xml.dom; -import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ConfigModelContext; import com.yahoo.config.model.api.ConfigServerSpec; import com.yahoo.config.model.deploy.DeployState; @@ -44,7 +43,7 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { @Override protected void doBuildAdmin(DeployState deployState, Admin admin, Element w3cAdminElement) { ModelElement adminElement = new ModelElement(w3cAdminElement); - admin.addConfigservers(getConfigServersFromSpec(deployState.getDeployLogger(), admin)); + admin.addConfigservers(getConfigServersFromSpec(deployState, admin)); // Note: These two elements only exists in admin version 4.0 // This build handles admin version 3.0 by ignoring its content (as the content is not useful) @@ -79,13 +78,13 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { Collection<HostResource> hosts = allocateHosts(admin.hostSystem(), "logserver", nodesSpecification); if (hosts.isEmpty()) return; // No log server can be created (and none is needed) - Logserver logserver = createLogserver(deployState.getDeployLogger(), admin, hosts); + Logserver logserver = createLogserver(deployState, admin, hosts); createContainerOnLogserverHost(deployState, admin, logserver.getHostResource()); } else if (containerModels.iterator().hasNext()) { List<HostResource> hosts = sortedContainerHostsFrom(containerModels.iterator().next(), nodesSpecification.minResources().nodes(), false); if (hosts.isEmpty()) return; // No log server can be created (and none is needed) - createLogserver(deployState.getDeployLogger(), admin, hosts); + createLogserver(deployState, admin, hosts); } else { context.getDeployLogger().logApplicationPackage(Level.INFO, "No container host available to use for running logserver"); } @@ -110,9 +109,9 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { LogserverContainer container = new LogserverContainer(logServerCluster, deployState); container.setHostResource(hostResource); - container.initService(deployState.getDeployLogger()); + container.initService(deployState); logServerCluster.addContainer(container); - admin.addAndInitializeService(deployState.getDeployLogger(), hostResource, container); + admin.addAndInitializeService(deployState, hostResource, container); admin.setLogserverContainerCluster(logServerCluster); context.getConfigModelRepoAdder().add(logserverClusterModel); } @@ -169,11 +168,11 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { return hosts.subList(0, Math.min(count, hosts.size())); } - private Logserver createLogserver(DeployLogger deployLogger, Admin admin, Collection<HostResource> hosts) { + private Logserver createLogserver(DeployState deployState, Admin admin, Collection<HostResource> hosts) { Logserver logserver = new Logserver(admin); logserver.setHostResource(hosts.iterator().next()); admin.setLogserver(logserver); - logserver.initService(deployLogger); + logserver.initService(deployState); return logserver; } @@ -185,7 +184,7 @@ public class DomAdminV4Builder extends DomAdminBuilderBase { Slobrok slobrok = new Slobrok(admin, index++, deployState.featureFlags()); slobrok.setHostResource(host); slobroks.add(slobrok); - slobrok.initService(deployState.getDeployLogger()); + slobrok.initService(deployState); } admin.addSlobroks(slobroks); } 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 cb19df16fd8..0be3ac01f71 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 @@ -183,7 +183,7 @@ public class VespaDomBuilder extends VespaModelBuilder { // This depends on which constructor in AbstractService is used, but the best way // is to let this method do initialize. if (!t.isInitialized()) { - t.initService(deployState.getDeployLogger()); + t.initService(deployState); } } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java index 2e5126dcc44..4b1c03a170c 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/container/Container.java @@ -168,11 +168,11 @@ public abstract class Container extends AbstractService implements public void addBuiltinHandlers() { } @Override - public void initService(DeployLogger deployLogger) { + public void initService(DeployState deployState) { if (isInitialized()) return; // XXX: Must be called first, to set the baseport - super.initService(deployLogger); + super.initService(deployState); if (getHttp() == null) { initDefaultJettyConnector(); 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 b89c48931b2..8e856e5e962 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 @@ -814,7 +814,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { false, !deployState.getProperties().isBootstrap()); var hosts = hostSystem.allocateHosts(clusterSpec, capacity, log); - return createNodesFromHosts(log, hosts, cluster, context.getDeployState()); + return createNodesFromHosts(hosts, cluster, context.getDeployState()); } else { return singleHostContainerCluster(cluster, hostSystem.getHost(Container.SINGLENODE_CONTAINER_SERVICESPEC), context); @@ -824,7 +824,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { private List<ApplicationContainer> singleHostContainerCluster(ApplicationContainerCluster cluster, HostResource host, ConfigModelContext context) { ApplicationContainer node = new ApplicationContainer(cluster, "container.0", 0, context.getDeployState()); node.setHostResource(host); - node.initService(context.getDeployLogger()); + node.initService(context.getDeployState()); return List.of(node); } @@ -835,7 +835,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { ClusterSpec.Id.from(cluster.getName()), log, hasZooKeeper(containerElement)); - return createNodesFromHosts(context.getDeployLogger(), hosts, cluster, context.getDeployState()); + return createNodesFromHosts(hosts, cluster, context.getDeployState()); } private List<ApplicationContainer> createNodesFromNodeType(ApplicationContainerCluster cluster, Element nodesElement, ConfigModelContext context) { @@ -847,7 +847,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { Map<HostResource, ClusterMembership> hosts = cluster.getRoot().hostSystem().allocateHosts(clusterSpec, Capacity.fromRequiredNodeType(type), log); - return createNodesFromHosts(context.getDeployLogger(), hosts, cluster, context.getDeployState()); + return createNodesFromHosts(hosts, cluster, context.getDeployState()); } private List<ApplicationContainer> createNodesFromContentServiceReference(ApplicationContainerCluster cluster, Element nodesElement, ConfigModelContext context) { @@ -865,11 +865,10 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { referenceId, cluster.getRoot().hostSystem(), context.getDeployLogger()); - return createNodesFromHosts(context.getDeployLogger(), hosts, cluster, context.getDeployState()); + return createNodesFromHosts(hosts, cluster, context.getDeployState()); } - private List<ApplicationContainer> createNodesFromHosts(DeployLogger deployLogger, - Map<HostResource, ClusterMembership> hosts, + private List<ApplicationContainer> createNodesFromHosts(Map<HostResource, ClusterMembership> hosts, ApplicationContainerCluster cluster, DeployState deployState) { List<ApplicationContainer> nodes = new ArrayList<>(); @@ -877,7 +876,7 @@ public class ContainerModelBuilder extends ConfigModelBuilder<ContainerModel> { String id = "container." + entry.getValue().index(); ApplicationContainer container = new ApplicationContainer(cluster, id, entry.getValue().retired(), entry.getValue().index(), deployState); container.setHostResource(entry.getKey()); - container.initService(deployLogger); + container.initService(deployState); nodes.add(container); } return nodes; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java b/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java index e69dd9abf47..dcf0be48f7b 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/Content.java @@ -312,7 +312,7 @@ public class Content extends ConfigModel { index++; docprocService.useDynamicPorts(); docprocService.setHostResource(host); - docprocService.initService(modelContext.getDeployLogger()); + docprocService.initService(modelContext.getDeployState()); nodes.add(docprocService); processedHosts.add(host); } diff --git a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java index 6d21e0ad10e..22b752777e9 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/content/ContentSearchCluster.java @@ -300,11 +300,11 @@ public class ContentSearchCluster extends AbstractConfigProducer<SearchCluster> clusterName, node, flushOnShutdown, tuning, resourceLimits, parentGroup.isHosted(), fractionOfMemoryReserved); searchNode.setHostResource(node.getHostResource()); - searchNode.initService(deployState.getDeployLogger()); + searchNode.initService(deployState); tls = new TransactionLogServer(searchNode, clusterName, syncTransactionLog); tls.setHostResource(searchNode.getHostResource()); - tls.initService(deployState.getDeployLogger()); + tls.initService(deployState); } else { searchNode = new SearchNode.Builder(""+node.getDistributionKey(), spec, clusterName, node, flushOnShutdown, tuning, resourceLimits, fractionOfMemoryReserved) 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 de50ba6ea21..88739e92567 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 @@ -280,15 +280,13 @@ public class StorageGroup { /** The nodes explicitly specified as a nodes tag in this group, or empty if none */ private final Optional<NodesSpecification> nodeRequirement; - private final DeployLogger deployLogger; private GroupBuilder(StorageGroup storageGroup, List<GroupBuilder> subGroups, List<XmlNodeBuilder> nodeBuilders, - Optional<NodesSpecification> nodeRequirement, DeployLogger deployLogger) { + Optional<NodesSpecification> nodeRequirement) { this.storageGroup = storageGroup; this.subGroups = subGroups; this.nodeBuilders = nodeBuilders; this.nodeRequirement = nodeRequirement; - this.deployLogger = deployLogger; } /** @@ -319,11 +317,11 @@ public class StorageGroup { StorageNode searchNode = new StorageNode(deployState.getProperties(), parent.getStorageCluster(), 1.0, distributionKey , false); searchNode.setHostResource(parent.hostSystem().getHost(Container.SINGLENODE_CONTAINER_SERVICESPEC)); PersistenceEngine provider = parent.getPersistence().create(deployState, searchNode, storageGroup, null); - searchNode.initService(deployLogger); + searchNode.initService(deployState); Distributor distributor = new Distributor(deployState.getProperties(), parent.getDistributorNodes(), distributionKey, null, provider); distributor.setHostResource(searchNode.getHostResource()); - distributor.initService(deployLogger); + distributor.initService(deployState); return searchNode; } @@ -339,7 +337,7 @@ public class StorageGroup { throw new IllegalArgumentException("Specifying individual groups is not supported on hosted applications"); Map<HostResource, ClusterMembership> hostMapping = nodeRequirement.isPresent() ? - provisionHosts(nodeRequirement.get(), owner.getStorageCluster().getClusterName(), owner.getRoot().hostSystem(), deployLogger) : + provisionHosts(nodeRequirement.get(), owner.getStorageCluster().getClusterName(), owner.getRoot().hostSystem(), deployState.getDeployLogger()) : Collections.emptyMap(); Map<Optional<ClusterSpec.Group>, Map<HostResource, ClusterMembership>> hostGroups = collectAllocatedSubgroups(hostMapping); @@ -450,7 +448,7 @@ public class StorageGroup { else // Nodes or groups explicitly listed - resolve in GroupBuilder nodeRequirement = Optional.empty(); - return new GroupBuilder(group, subGroups, explicitNodes, nodeRequirement, context.getDeployLogger()); + return new GroupBuilder(group, subGroups, explicitNodes, nodeRequirement); } private Optional<String> childAsString(Optional<ModelElement> element, String childTagName) { @@ -503,13 +501,13 @@ public class StorageGroup { private static StorageNode createStorageNode(DeployState deployState, ContentCluster parent, HostResource hostResource, StorageGroup parentGroup, ClusterMembership clusterMembership) { StorageNode sNode = new StorageNode(deployState.getProperties(), parent.getStorageCluster(), null, clusterMembership.index(), clusterMembership.retired()); sNode.setHostResource(hostResource); - sNode.initService(deployState.getDeployLogger()); + sNode.initService(deployState); // TODO: Supplying null as XML is not very nice PersistenceEngine provider = parent.getPersistence().create(deployState, sNode, parentGroup, null); Distributor d = new Distributor(deployState.getProperties(), parent.getDistributorNodes(), clusterMembership.index(), null, provider); d.setHostResource(sNode.getHostResource()); - d.initService(deployState.getDeployLogger()); + d.initService(deployState); return sNode; } } 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 4a88e02be45..eda70ffb2bc 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 @@ -367,7 +367,7 @@ public class ContentCluster extends AbstractConfigProducer<AbstractConfigProduce boolean retired = host.spec().membership().map(ClusterMembership::retired).orElse(false); var clusterControllerContainer = new ClusterControllerContainer(clusterControllers, ccIndex, runStandaloneZooKeeper, deployState, retired); clusterControllerContainer.setHostResource(host); - clusterControllerContainer.initService(deployState.getDeployLogger()); + clusterControllerContainer.initService(deployState); clusterControllerContainer.setProp("clustertype", "admin"); containers.add(clusterControllerContainer); ++index; diff --git a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java index 28d1fbe72ef..6e3f3e1ebf5 100644 --- a/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java +++ b/config-model/src/main/java/com/yahoo/vespa/model/search/SearchNode.java @@ -123,7 +123,6 @@ public class SearchNode extends AbstractService implements boolean flushOnShutdown, Optional<Tuning> tuning, Optional<ResourceLimits> resourceLimits, boolean isHostedVespa, double fractionOfMemoryReserved) { super(parent, name); - setOmpNumThreads(1); this.isHostedVespa = isHostedVespa; this.fractionOfMemoryReserved = fractionOfMemoryReserved; this.nodeSpec = nodeSpec; @@ -239,10 +238,7 @@ public class SearchNode extends AbstractService implements @Override public String getStartupCommand() { - if (getOmpNumThreads() != 1) { - throw new IllegalStateException("ompNumThreads must be 1"); - } - String startup = getEnvVariables() + "exec $ROOT/sbin/vespa-proton " + "--identity " + getConfigId(); + String startup = getEnv() + " exec $ROOT/sbin/vespa-proton " + "--identity " + getConfigId(); if (serviceLayerService != null) { startup = startup + " --serviceidentity " + serviceLayerService.getConfigId(); } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/HostResourceTest.java b/config-model/src/test/java/com/yahoo/vespa/model/HostResourceTest.java index 80a388a822e..4d8dd3dacfd 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/HostResourceTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/HostResourceTest.java @@ -26,7 +26,7 @@ public class HostResourceTest { TestService service = new TestService(root, 1); try { - service.initService(root.deployLogger()); + service.initService(root.getDeployState()); } catch (RuntimeException e) { assertTrue(e.getMessage().endsWith("No host found for service 'hostresourcetest$testservice0'. " + "The hostalias is probably missing from hosts.xml.")); diff --git a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java index c746db168ee..77fa0b685fb 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/builder/xml/dom/ContentBuilderTest.java @@ -13,6 +13,7 @@ import com.yahoo.vespa.config.ConfigDefinitionKey; import com.yahoo.vespa.config.ConfigPayloadBuilder; import com.yahoo.vespa.config.GenericConfig; import com.yahoo.vespa.config.search.core.ProtonConfig; +import com.yahoo.vespa.model.AbstractService; import com.yahoo.vespa.model.HostResource; import com.yahoo.vespa.model.Service; import com.yahoo.vespa.model.VespaModel; @@ -35,7 +36,6 @@ import java.util.List; import static com.yahoo.config.model.api.container.ContainerServiceType.CLUSTERCONTROLLER_CONTAINER; import static com.yahoo.config.model.api.container.ContainerServiceType.METRICS_PROXY_CONTAINER; import static com.yahoo.vespa.config.search.core.ProtonConfig.Feeding.Shared_field_writer_executor; -import static org.hamcrest.Matchers.containsString; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; @@ -328,10 +328,64 @@ public class ContentBuilderTest extends DomBuilderTest { assertEquals(200000, b.getRootGroup().getMmapNoCoreLimit().get().longValue()); assertEquals(2, s.getSearchNodes().size()); - assertEquals(200000, s.getSearchNodes().get(0).getMMapNoCoreLimit()); - assertEquals(200000, s.getSearchNodes().get(1).getMMapNoCoreLimit()); - assertEquals("VESPA_MMAP_NOCORE_LIMIT=200000 ", s.getSearchNodes().get(0).getMMapNoCoreEnvVariable()); - assertEquals("VESPA_MMAP_NOCORE_LIMIT=200000 ", s.getSearchNodes().get(1).getMMapNoCoreEnvVariable()); + assertTrue(s.getSearchNodes().get(0).getEnv().contains("VESPA_MMAP_NOCORE_LIMIT=200000")); + assertTrue(s.getSearchNodes().get(1).getEnv().contains("VESPA_MMAP_NOCORE_LIMIT=200000")); + } + + @Test + public void canAddEnvironmentVariable() { + ContentCluster b = createContent( + "<content version =\"1.0\" id=\"b\">" + + " <redundancy>1</redundancy>" + + " <documents>" + + " <document type='music' mode='index'/>" + + " </documents>" + + " <group>" + + " <node hostalias=\"mockhost\" distribution-key=\"0\" />" + + " </group>" + + "</content>"); + ContentSearchCluster s; + + s = b.getSearch(); + assertTrue(s.hasIndexedCluster()); + assertNotNull(s.getIndexed()); + assertEquals(1, b.getStorageCluster().getChildren().size()); + + assertEquals(1, s.getSearchNodes().size()); + AbstractService node = s.getSearchNodes().get(0); + node.addEnvironmentVariable("MY_ENV_1", 7); + node.addEnvironmentVariable("MY_ENV_2", "7 8"); + assertTrue(node.getEnv().contains("MY_ENV_1=7")); + assertTrue(node.getEnv().contains("MY_ENV_2=\"7 8\"")); + node.addEnvironmentVariable("MY_PARSED_ENV_1=7"); + node.addEnvironmentVariable("MY_PARSED_ENV_2=7 8"); + assertTrue(node.getEnv().contains("MY_PARSED_ENV_1=\"7\"")); + assertTrue(node.getEnv().contains("MY_PARSED_ENV_2=\"7 8\"")); + } + + @Test + public void addsEnvironmentVariablesfromFeatureFlag() { + ContentCluster b = createContent( + "<content version =\"1.0\" id=\"b\">" + + " <redundancy>1</redundancy>" + + " <documents>" + + " <document type='music' mode='index'/>" + + " </documents>" + + " <group>" + + " <node hostalias=\"mockhost\" distribution-key=\"0\" />" + + " </group>" + + "</content>", new TestProperties().setEnvironmentVariables(List.of("MY_1_ENV=xyz abc", "MY_2_ENV=2"))); + ContentSearchCluster s; + + s = b.getSearch(); + assertTrue(s.hasIndexedCluster()); + assertNotNull(s.getIndexed()); + assertEquals(1, b.getStorageCluster().getChildren().size()); + + assertEquals(1, s.getSearchNodes().size()); + AbstractService node = s.getSearchNodes().get(0); + assertTrue(node.getEnv().contains("MY_1_ENV=\"xyz abc\"")); + assertTrue(node.getEnv().contains("MY_2_ENV=\"2\"")); } @Test @@ -357,10 +411,8 @@ public class ContentBuilderTest extends DomBuilderTest { assertTrue(b.getRootGroup().getCoreOnOOM().get()); assertEquals(2, s.getSearchNodes().size()); - assertTrue(s.getSearchNodes().get(0).getCoreOnOOM()); - assertTrue(s.getSearchNodes().get(1).getCoreOnOOM()); - assertEquals("", s.getSearchNodes().get(0).getCoreOnOOMEnvVariable()); - assertEquals("", s.getSearchNodes().get(1).getCoreOnOOMEnvVariable()); + assertFalse(s.getSearchNodes().get(0).getEnv().contains("VESPA_SILENCE_CORE_ON_OOM=true")); + assertFalse(s.getSearchNodes().get(1).getEnv().contains("VESPA_SILENCE_CORE_ON_OOM=true")); } @Test @@ -383,10 +435,8 @@ public class ContentBuilderTest extends DomBuilderTest { assertFalse(b.getRootGroup().getCoreOnOOM().isPresent()); assertEquals(2, s.getSearchNodes().size()); - assertFalse(s.getSearchNodes().get(0).getCoreOnOOM()); - assertFalse(s.getSearchNodes().get(1).getCoreOnOOM()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true ", s.getSearchNodes().get(0).getCoreOnOOMEnvVariable()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true ", s.getSearchNodes().get(1).getCoreOnOOMEnvVariable()); + assertTrue(s.getSearchNodes().get(0).getEnv().contains("VESPA_SILENCE_CORE_ON_OOM=true")); + assertTrue(s.getSearchNodes().get(1).getEnv().contains("VESPA_SILENCE_CORE_ON_OOM=true")); } @Test @@ -409,10 +459,8 @@ public class ContentBuilderTest extends DomBuilderTest { assertFalse(b.getRootGroup().getMmapNoCoreLimit().isPresent()); assertEquals(2, s.getSearchNodes().size()); - assertEquals(200000, s.getSearchNodes().get(0).getMMapNoCoreLimit()); - assertEquals(-1, s.getSearchNodes().get(1).getMMapNoCoreLimit()); - assertEquals("VESPA_MMAP_NOCORE_LIMIT=200000 ", s.getSearchNodes().get(0).getMMapNoCoreEnvVariable()); - assertEquals("", s.getSearchNodes().get(1).getMMapNoCoreEnvVariable()); + assertTrue(s.getSearchNodes().get(0).getEnv().contains("VESPA_MMAP_NOCORE_LIMIT=200000")); + assertFalse(s.getSearchNodes().get(1).getEnv().contains("VESPA_MMAP_NOCORE_LIMIT=")); } @Test @@ -435,10 +483,8 @@ public class ContentBuilderTest extends DomBuilderTest { assertFalse(b.getRootGroup().getCoreOnOOM().isPresent()); assertEquals(2, s.getSearchNodes().size()); - assertTrue(s.getSearchNodes().get(0).getCoreOnOOM()); - assertFalse(s.getSearchNodes().get(1).getCoreOnOOM()); - assertEquals("", s.getSearchNodes().get(0).getCoreOnOOMEnvVariable()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true ", s.getSearchNodes().get(1).getCoreOnOOMEnvVariable()); + assertFalse(s.getSearchNodes().get(0).getEnv().contains("VESPA_SILENCE_CORE_ON_OOM=true")); + assertTrue(s.getSearchNodes().get(1).getEnv().contains("VESPA_SILENCE_CORE_ON_OOM=true")); } @Test @@ -471,15 +517,7 @@ public class ContentBuilderTest extends DomBuilderTest { assertEquals(4, s.getSearchNodes().size()); for (SearchNode n : s.getSearchNodes()) { - assertEquals("proton", n.getNoVespaMalloc()); - assertEquals("VESPA_USE_NO_VESPAMALLOC=\"proton\" ", n.getNoVespaMallocEnvVariable()); - assertEquals("distributord", n.getVespaMallocDebug()); - assertEquals("VESPA_USE_VESPAMALLOC=\"storaged\" ", n.getVespaMallocEnvVariable()); - assertEquals("all", n.getVespaMallocDebugStackTrace()); - assertEquals("VESPA_USE_VESPAMALLOC_D=\"distributord\" ", n.getVespaMallocDebugEnvVariable()); - assertEquals("storaged", n.getVespaMalloc()); - assertEquals("VESPA_USE_VESPAMALLOC_DST=\"all\" ", n.getVespaMallocDebugStackTraceEnvVariable()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true OMP_NUM_THREADS=1 VESPA_USE_NO_VESPAMALLOC=\"proton\" VESPA_USE_VESPAMALLOC=\"storaged\" VESPA_USE_VESPAMALLOC_D=\"distributord\" VESPA_USE_VESPAMALLOC_DST=\"all\" ", n.getEnvVariables()); + assertEquals("OMP_NUM_THREADS=1 VESPA_SILENCE_CORE_ON_OOM=true VESPA_USE_NO_VESPAMALLOC=\"proton\" VESPA_USE_VESPAMALLOC=\"storaged\" VESPA_USE_VESPAMALLOC_D=\"distributord\" VESPA_USE_VESPAMALLOC_DST=\"all\"", n.getEnv()); } } @@ -508,10 +546,10 @@ public class ContentBuilderTest extends DomBuilderTest { assertFalse(b.getRootGroup().getVespaMallocDebugStackTrace().isPresent()); assertEquals(4, s.getSearchNodes().size()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true OMP_NUM_THREADS=1 VESPA_USE_NO_VESPAMALLOC=\"proton\" ", s.getSearchNodes().get(0).getEnvVariables()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true OMP_NUM_THREADS=1 VESPA_USE_VESPAMALLOC_D=\"distributord\" ", s.getSearchNodes().get(1).getEnvVariables()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true OMP_NUM_THREADS=1 VESPA_USE_VESPAMALLOC_DST=\"all\" ", s.getSearchNodes().get(2).getEnvVariables()); - assertEquals("VESPA_SILENCE_CORE_ON_OOM=true OMP_NUM_THREADS=1 VESPA_USE_VESPAMALLOC=\"storaged\" ", s.getSearchNodes().get(3).getEnvVariables()); + assertEquals("OMP_NUM_THREADS=1 VESPA_SILENCE_CORE_ON_OOM=true VESPA_USE_NO_VESPAMALLOC=\"proton\"", s.getSearchNodes().get(0).getEnv()); + assertEquals("OMP_NUM_THREADS=1 VESPA_SILENCE_CORE_ON_OOM=true VESPA_USE_VESPAMALLOC_D=\"distributord\"", s.getSearchNodes().get(1).getEnv()); + assertEquals("OMP_NUM_THREADS=1 VESPA_SILENCE_CORE_ON_OOM=true VESPA_USE_VESPAMALLOC_DST=\"all\"", s.getSearchNodes().get(2).getEnv()); + assertEquals("OMP_NUM_THREADS=1 VESPA_SILENCE_CORE_ON_OOM=true VESPA_USE_VESPAMALLOC=\"storaged\"", s.getSearchNodes().get(3).getEnv()); } @Test @@ -908,6 +946,9 @@ public class ContentBuilderTest extends DomBuilderTest { } private ContentCluster createContent(String xml) { + return createContent(xml, new TestProperties()); + } + private ContentCluster createContent(String xml, TestProperties props) { String combined = "" + "<services>"+ " <admin version='2.0'>" + @@ -917,12 +958,13 @@ public class ContentBuilderTest extends DomBuilderTest { "</services>"; + var deployStateBuilder = new DeployState.Builder().properties(props); VespaModel m = new VespaModelCreatorWithMockPkg(new MockApplicationPackage.Builder() - .withHosts(getHosts()) - .withServices(combined) - .withSearchDefinition(MockApplicationPackage.MUSIC_SEARCHDEFINITION) - .build()) - .create(); + .withHosts(getHosts()) + .withServices(combined) + .withSearchDefinition(MockApplicationPackage.MUSIC_SEARCHDEFINITION) + .build()) + .create(deployStateBuilder); return m.getContentClusters().isEmpty() ? null 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 14a90130a57..36adee5ff15 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 @@ -6,7 +6,6 @@ import com.yahoo.cloud.config.ConfigserverConfig; import com.yahoo.cloud.config.CuratorConfig; import com.yahoo.cloud.config.ZookeeperServerConfig; import com.yahoo.component.ComponentId; -import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.api.ApplicationClusterEndpoint; import com.yahoo.config.model.api.ContainerEndpoint; import com.yahoo.config.model.deploy.DeployState; @@ -178,7 +177,7 @@ public class ContainerClusterTest { public void testClusterControllerResourceUsage() { MockRoot root = createRoot(false); ClusterControllerContainerCluster cluster = createClusterControllerCluster(root); - addClusterController(root.deployLogger(), cluster, "host-c1", root.getDeployState()); + addClusterController(cluster, "host-c1", root.getDeployState()); assertEquals(1, cluster.getContainers().size()); QrStartConfig.Builder qrBuilder = new QrStartConfig.Builder(); cluster.getConfig(qrBuilder); @@ -198,7 +197,7 @@ public class ContainerClusterTest { public void testThatLinguisticsIsExcludedForClusterControllerCluster() { MockRoot root = createRoot(false); ClusterControllerContainerCluster cluster = createClusterControllerCluster(root); - addClusterController(root.deployLogger(), cluster, "host-c1", root.getDeployState()); + addClusterController(cluster, "host-c1", root.getDeployState()); assertFalse(contains("com.yahoo.language.provider.DefaultLinguisticsProvider", cluster.getAllComponents())); } @@ -493,17 +492,16 @@ public class ContainerClusterTest { HostResource hostResource) { ApplicationContainer container = new ApplicationContainer(cluster, name, 0, root.getDeployState()); container.setHostResource(hostResource); - container.initService(root.deployLogger()); + container.initService(root.getDeployState()); cluster.addContainer(container); } - private static void addClusterController(DeployLogger deployLogger, - ClusterControllerContainerCluster cluster, + private static void addClusterController(ClusterControllerContainerCluster cluster, String hostName, DeployState deployState) { ClusterControllerContainer container = new ClusterControllerContainer(cluster, 1, false, deployState, false); container.setHostResource(new HostResource(new Host(null, hostName))); - container.initService(deployLogger); + container.initService(deployState); cluster.addContainer(container); } diff --git a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java index 226045f4d8a..a347c0a9c43 100644 --- a/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java +++ b/config-model/src/test/java/com/yahoo/vespa/model/search/test/SchemaNodeTest.java @@ -40,11 +40,11 @@ public class SchemaNodeTest { TransactionLogServer tls = new TransactionLogServer(root, "mycluster", useFsync); tls.setHostResource(new HostResource(host)); tls.setBasePort(100); - tls.initService(root.deployLogger()); + tls.initService(root.getDeployState()); node.setTls(tls); node.setHostResource(new HostResource(host)); node.setBasePort(200); - node.initService(root.deployLogger()); + node.initService(root.getDeployState()); root.freezeModelTopology(); } @@ -78,7 +78,7 @@ public class SchemaNodeTest { MockRoot root = new MockRoot(""); SearchNode node = createSearchNode(root, "mynode", 3, new NodeSpec(7, 5), false, root.getDeployState().isHosted()); node.setHostResource(new HostResource(new Host(node, "mynbode"))); - node.initService(root.deployLogger()); + node.initService(root.getDeployState()); assertFalse(node.getPreShutdownCommand().isPresent()); } @@ -87,7 +87,7 @@ public class SchemaNodeTest { MockRoot root = new MockRoot(""); SearchNode node = createSearchNode(root, "mynode2", 4, new NodeSpec(7, 5), true, root.getDeployState().isHosted()); node.setHostResource(new HostResource(new Host(node, "mynbode2"))); - node.initService(root.deployLogger()); + node.initService(root.getDeployState()); assertTrue(node.getPreShutdownCommand().isPresent()); assertTrue(node.getPreShutdownCommand().get().contains("vespa-proton-cmd " + node.getRpcPort() + " prepareRestart")); } 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 3388f9d2670..3de8cfe540f 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 @@ -2,7 +2,6 @@ package com.yahoo.vespa.model.test; import com.yahoo.component.ComponentId; -import com.yahoo.config.application.api.DeployLogger; import com.yahoo.config.model.ConfigModel; import com.yahoo.config.model.ConfigModelContext; import com.yahoo.config.model.ConfigModelRegistry; @@ -10,6 +9,7 @@ import com.yahoo.config.model.MapConfigModelRegistry; import com.yahoo.config.model.admin.AdminModel; import com.yahoo.config.model.builder.xml.ConfigModelBuilder; import com.yahoo.config.model.builder.xml.ConfigModelId; +import com.yahoo.config.model.deploy.DeployState; import com.yahoo.config.model.producer.AbstractConfigProducer; import com.yahoo.vespa.defaults.Defaults; import com.yahoo.vespa.model.AbstractService; @@ -152,13 +152,13 @@ public class ModelAmendingTestCase { @Override public void doBuild(AdminModelAmender model, Element spec, ConfigModelContext modelContext) { for (AdminModel adminModel : model.adminModels) - amend(modelContext.getDeployLogger(), adminModel); + amend(modelContext.getDeployState(), adminModel); } - private void amend(DeployLogger deployLogger, AdminModel adminModel) { + private void amend(DeployState deployState, AdminModel adminModel) { for (HostResource host : adminModel.getAdmin().hostSystem().getHosts()) { if ( ! host.getHost().getChildrenByTypeRecursive(AmendedService.class).isEmpty()) continue; // already amended - adminModel.getAdmin().addAndInitializeService(deployLogger, host, new AmendedService(host.getHost())); + adminModel.getAdmin().addAndInitializeService(deployState, host, new AmendedService(host.getHost())); } } 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 056ca4b6c0d..547494efcba 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 @@ -357,6 +357,7 @@ public class ModelContextImpl implements ModelContext { private final List<X509Certificate> operatorCertificates; private final List<String> tlsCiphersOverride; private final List<String> zoneDnsSuffixes; + private final List<String> environmentVariables; public Properties(ApplicationId applicationId, ConfigserverConfig configserverConfig, @@ -389,13 +390,15 @@ public class ModelContextImpl implements ModelContext { this.tenantSecretStores = tenantSecretStores; this.secretStore = secretStore; this.jvmGCOptionsFlag = PermanentFlags.JVM_GC_OPTIONS.bindTo(flagSource) - .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()); + .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()); this.allowDisableMtls = PermanentFlags.ALLOW_DISABLE_MTLS.bindTo(flagSource) .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); this.operatorCertificates = operatorCertificates; this.tlsCiphersOverride = PermanentFlags.TLS_CIPHERS_OVERRIDE.bindTo(flagSource) .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); this.zoneDnsSuffixes = configserverConfig.zoneDnsSuffixes(); + this.environmentVariables = PermanentFlags.ENVIRONMENT_VARIABLES.bindTo(flagSource) + .with(FetchVector.Dimension.APPLICATION_ID, applicationId.serializedForm()).value(); } @Override public ModelContext.FeatureFlags featureFlags() { return featureFlags; } @@ -477,6 +480,9 @@ public class ModelContextImpl implements ModelContext { .value(); } + @Override + public List<String> environmentVariables() { return environmentVariables; } + } } diff --git a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java index 75d6cab273a..ceb5e483934 100644 --- a/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java +++ b/flags/src/main/java/com/yahoo/vespa/flags/PermanentFlags.java @@ -198,6 +198,14 @@ public class PermanentFlags { APPLICATION_ID, HOSTNAME ); + public static final UnboundListFlag<String> ENVIRONMENT_VARIABLES = defineListFlag( + "environment-variables", List.of(), String.class, + "A list of environment variables set for all services. " + + "Each item should be on the form <ENV_VAR>=<VALUE>", + "Takes effect on service restart", + ZONE_ID, APPLICATION_ID + ); + public static final UnboundStringFlag CONFIG_PROXY_JVM_ARGS = defineStringFlag( "config-proxy-jvm-args", "", "Sets jvm args for config proxy (added at the end of startup command, will override existing ones)", |