summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cloud-tenant-base-dependencies-enforcer/pom.xml2
-rw-r--r--config-model-api/abi-spec.json3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java3
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java1
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/ValidationOverrideTest.java15
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/DeployState.java8
-rw-r--r--config-model/src/main/java/com/yahoo/config/model/deploy/TestProperties.java7
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java10
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java3
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java1
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidator.java44
-rw-r--r--config-model/src/test/java/com/yahoo/config/model/MockModelContext.java5
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/VespaModelFactoryTest.java1
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidatorTest.java8
-rw-r--r--config-model/src/test/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidatorTest.java64
-rw-r--r--config-provisioning/src/main/java/com/yahoo/config/provision/ApplicationLockException.java6
-rw-r--r--configd/src/apps/sentinel/connectivity.cpp58
-rw-r--r--configd/src/apps/sentinel/connectivity.h19
-rw-r--r--configd/src/apps/sentinel/env.cpp111
-rw-r--r--configd/src/apps/sentinel/env.h1
-rw-r--r--configd/src/apps/sentinel/sentinel.cpp20
-rw-r--r--configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java7
-rw-r--r--configserver/src/test/apps/app_sdbundles/services.xml2
-rw-r--r--configserver/src/test/apps/hosted-no-write-access-control/services.xml2
-rw-r--r--configserver/src/test/apps/hosted/services.xml2
-rw-r--r--configserver/src/test/apps/zkapp/services.xml2
-rw-r--r--configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java2
-rw-r--r--configserver/src/test/resources/deploy/advancedapp/services.xml2
-rw-r--r--container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java2
-rw-r--r--flags/src/main/java/com/yahoo/vespa/flags/Flags.java2
-rw-r--r--fnet/src/vespa/fnet/frt/supervisor.cpp4
-rw-r--r--fnet/src/vespa/fnet/frt/supervisor.h1
-rw-r--r--model-integration/src/test/java/ai/vespa/modelintegration/evaluator/OnnxEvaluatorTest.java2
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeReports.java2
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java4
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java8
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java2
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepositoryTest.java10
-rw-r--r--parent/pom.xml2
-rw-r--r--slobrok/src/tests/registerapi/registerapi.cpp2
-rw-r--r--vespalib/src/vespa/vespalib/util/exception.h3
41 files changed, 289 insertions, 164 deletions
diff --git a/cloud-tenant-base-dependencies-enforcer/pom.xml b/cloud-tenant-base-dependencies-enforcer/pom.xml
index 16045d5dc75..340123ae659 100644
--- a/cloud-tenant-base-dependencies-enforcer/pom.xml
+++ b/cloud-tenant-base-dependencies-enforcer/pom.xml
@@ -34,7 +34,7 @@
<jetty-alpn.version>1.1.3.v20160715</jetty-alpn.version>
<junit5.version>5.7.0</junit5.version>
<junit5.platform.version>1.7.0</junit5.platform.version>
- <onnxruntime.version>1.7.0</onnxruntime.version>
+ <onnxruntime.version>1.8.0</onnxruntime.version>
<org.lz4.version>1.7.1</org.lz4.version>
<org.json.version>20090211</org.json.version><!-- TODO Vespa 8: remove as provided dependency -->
<slf4j.version>1.7.30</slf4j.version>
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 1ffa5c00426..9de674ca820 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -539,7 +539,8 @@
"public static final enum com.yahoo.config.application.api.ValidationId skipOldConfigModels",
"public static final enum com.yahoo.config.application.api.ValidationId accessControl",
"public static final enum com.yahoo.config.application.api.ValidationId globalEndpointChange",
- "public static final enum com.yahoo.config.application.api.ValidationId redundancyIncrease"
+ "public static final enum com.yahoo.config.application.api.ValidationId redundancyIncrease",
+ "public static final enum com.yahoo.config.application.api.ValidationId redundancyOne"
]
},
"com.yahoo.config.application.api.ValidationOverrides$Allow": {
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java
index 24730ada3ab..7aa6788b86d 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationId.java
@@ -24,7 +24,8 @@ public enum ValidationId {
skipOldConfigModels("skip-old-config-models"), // Internal use
accessControl("access-control"), // Internal use, used in zones where there should be no access-control
globalEndpointChange("global-endpoint-change"), // Changing global endpoints
- redundancyIncrease("redundancy-increase"); // Increasing redundancy - may easily cause feed blocked
+ redundancyIncrease("redundancy-increase"), // Increasing redundancy - may easily cause feed blocked
+ redundancyOne("redundancy-one"); // redundancy=1 requires a validation override on first deployment
private final String id;
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java
index ea27b7f70d8..3221df38d4f 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/ValidationOverrides.java
@@ -177,6 +177,7 @@ public class ValidationOverrides {
}
+ // TODO: Remove this class after June 2021
public static class AllowAllValidationOverrides extends ValidationOverrides {
private final DeployLogger logger;
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/ValidationOverrideTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/ValidationOverrideTest.java
index 2943b0bab34..f7ef059c5f2 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/ValidationOverrideTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/ValidationOverrideTest.java
@@ -4,16 +4,10 @@ package com.yahoo.config.application.api;
import com.yahoo.test.ManualClock;
import org.junit.Assert;
import org.junit.Test;
-import org.xml.sax.SAXException;
-
-import java.io.IOException;
import java.io.StringReader;
-import java.time.Clock;
import java.time.Instant;
-import java.util.Optional;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
/**
* @author bratseth
@@ -82,15 +76,6 @@ public class ValidationOverrideTest {
assertEquals(empty.xmlForm(), emptyReserialized.xmlForm());
}
- @Test
- public void testAll() {
- ValidationOverrides all = ValidationOverrides.all;
- assertTrue(all.allows(ValidationId.deploymentRemoval, Clock.systemUTC().instant()));
- assertTrue(all.allows(ValidationId.contentClusterRemoval, Clock.systemUTC().instant()));
- assertTrue(all.allows(ValidationId.indexModeChange, Clock.systemUTC().instant()));
- assertTrue(all.allows(ValidationId.fieldTypeChange, Clock.systemUTC().instant()));
- }
-
private void assertOverridden(String validationId, ValidationOverrides overrides, Instant now) {
overrides.invalid(ValidationId.from(validationId).get(), "message", now); // should not throw exception
}
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 68924dde3e1..dd66861f2ce 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
@@ -142,12 +142,8 @@ public class DeployState implements ConfigDefinitionStore {
this.semanticRules = semanticRules; // TODO: Remove this by seeing how pagetemplates are propagated
this.importedModels = importMlModels(applicationPackage, modelImporters, deployLogger);
- ValidationOverrides suppliedValidationOverrides = applicationPackage.getValidationOverrides().map(ValidationOverrides::fromXml)
- .orElse(ValidationOverrides.empty);
- this.validationOverrides =
- zone.environment().isManuallyDeployed() // // Warn but allow in manually deployed zones
- ? new ValidationOverrides.AllowAllValidationOverrides(suppliedValidationOverrides, deployLogger)
- : suppliedValidationOverrides;
+ this.validationOverrides = applicationPackage.getValidationOverrides().map(ValidationOverrides::fromXml)
+ .orElse(ValidationOverrides.empty);
this.wantedNodeVespaVersion = wantedNodeVespaVersion;
this.now = now;
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 2927df57bc1..e08c57a6fb4 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
@@ -42,6 +42,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
private double defaultTermwiseLimit = 1.0;
private String jvmGCOptions = null;
private String sequencerType = "LATENCY";
+ private boolean firstTimeDeployment = false;
private String responseSequencerType = "ADAPTIVE";
private int responseNumThreads = 2;
private Optional<EndpointCertificateSecrets> endpointCertificateSecrets = Optional.empty();
@@ -77,7 +78,7 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
@Override public String jvmGCOptions(Optional<ClusterSpec.Type> clusterType) { return jvmGCOptions; }
@Override public String feedSequencerType() { return sequencerType; }
@Override public boolean isBootstrap() { return false; }
- @Override public boolean isFirstTimeDeployment() { return false; }
+ @Override public boolean isFirstTimeDeployment() { return firstTimeDeployment; }
@Override public boolean useDedicatedNodeForLogserver() { return useDedicatedNodeForLogserver; }
@Override public Optional<EndpointCertificateSecrets> endpointCertificateSecrets() { return endpointCertificateSecrets; }
@Override public double defaultTermwiseLimit() { return defaultTermwiseLimit; }
@@ -133,6 +134,10 @@ public class TestProperties implements ModelContext.Properties, ModelContext.Fea
responseSequencerType = type;
return this;
}
+ public TestProperties setFirstTimeDeployment(boolean firstTimeDeployment) {
+ this.firstTimeDeployment = firstTimeDeployment;
+ return this;
+ }
public TestProperties setResponseNumThreads(int numThreads) {
responseNumThreads = numThreads;
return this;
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
index d6673cd49e9..b576d1cb5d2 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/VespaModelFactory.java
@@ -6,6 +6,7 @@ import com.google.inject.Inject;
import com.yahoo.component.Version;
import com.yahoo.component.provider.ComponentRegistry;
import com.yahoo.config.application.api.ApplicationPackage;
+import com.yahoo.config.application.api.ValidationOverrides;
import com.yahoo.config.model.ConfigModelRegistry;
import com.yahoo.config.model.MapConfigModelRegistry;
import com.yahoo.config.model.NullConfigModelRegistry;
@@ -23,6 +24,7 @@ import com.yahoo.config.provision.TransientException;
import com.yahoo.config.provision.Zone;
import com.yahoo.vespa.config.VespaVersion;
import com.yahoo.vespa.model.application.validation.Validation;
+import com.yahoo.yolean.Exceptions;
import org.xml.sax.SAXException;
import java.io.IOException;
@@ -31,6 +33,7 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.logging.Level;
import java.util.logging.Logger;
/**
@@ -170,6 +173,13 @@ public class VespaModelFactory implements ModelFactory {
private List<ConfigChangeAction> validateModel(VespaModel model, DeployState deployState, ValidationParameters validationParameters) {
try {
return Validation.validate(model, validationParameters, deployState);
+ } catch (ValidationOverrides.ValidationException e) {
+ if (deployState.isHosted() && zone.environment().isManuallyDeployed())
+ deployState.getDeployLogger().logApplicationPackage(Level.WARNING,
+ "Auto-overriding validation which would be disallowed in production: " +
+ Exceptions.toMessageString(e));
+ else
+ rethrowUnlessIgnoreErrors(e, validationParameters.ignoreValidationErrors());
} catch (IllegalArgumentException | TransientException e) {
rethrowUnlessIgnoreErrors(e, validationParameters.ignoreValidationErrors());
} catch (Exception e) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
index eccb54780d6..84c7a48a998 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/Validation.java
@@ -25,6 +25,7 @@ import com.yahoo.vespa.model.application.validation.change.ResourcesReductionVal
import com.yahoo.vespa.model.application.validation.change.StartupCommandChangeValidator;
import com.yahoo.vespa.model.application.validation.change.StreamingSearchClusterChangeValidator;
import com.yahoo.vespa.model.application.validation.first.AccessControlOnFirstDeploymentValidator;
+import com.yahoo.vespa.model.application.validation.first.RedundancyOnFirstDeploymentValidator;
import java.time.Instant;
import java.util.Arrays;
@@ -54,6 +55,7 @@ public class Validation {
* between the previous and current model
*
* @return a list of required changes needed to make this configuration live
+ * @throws ValidationOverrides.ValidationException if the change fails validation
*/
public static List<ConfigChangeAction> validate(VespaModel model, ValidationParameters validationParameters, DeployState deployState) {
if (validationParameters.checkRouting()) {
@@ -124,6 +126,7 @@ public class Validation {
private static void validateFirstTimeDeployment(VespaModel model, DeployState deployState) {
new AccessControlOnFirstDeploymentValidator().validate(model, deployState);
+ new RedundancyOnFirstDeploymentValidator().validate(model, deployState);
}
private static void deferConfigChangesForClustersToBeRestarted(List<ConfigChangeAction> actions, VespaModel model) {
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java
index b720cc13f42..4222d22563d 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/change/ChangeValidator.java
@@ -25,6 +25,7 @@ public interface ChangeValidator {
* @param now the instant to use as now
* @return a list of actions specifying what needs to be done in order to activate the new model.
* Return an empty list if nothing needs to be done
+ * @throws IllegalArgumentException if the change fails validation
*/
List<ConfigChangeAction> validate(VespaModel current, VespaModel next, ValidationOverrides overrides, Instant now);
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidator.java b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidator.java
new file mode 100644
index 00000000000..e6117299269
--- /dev/null
+++ b/config-model/src/main/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidator.java
@@ -0,0 +1,44 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation.first;
+
+import com.yahoo.config.application.api.ValidationId;
+import com.yahoo.config.model.ConfigModelContext.ApplicationType;
+import com.yahoo.config.model.deploy.DeployState;
+import com.yahoo.vespa.model.VespaModel;
+import com.yahoo.vespa.model.application.validation.Validator;
+import com.yahoo.vespa.model.container.ApplicationContainerCluster;
+import com.yahoo.vespa.model.container.Container;
+import com.yahoo.vespa.model.container.ContainerCluster;
+import com.yahoo.vespa.model.content.cluster.ContentCluster;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static com.yahoo.collections.CollectionUtil.mkString;
+import static com.yahoo.config.provision.InstanceName.defaultName;
+import static com.yahoo.vespa.model.container.http.AccessControl.hasHandlerThatNeedsProtection;
+
+/**
+ * Validates that applications in prod zones do not have redundancy 1 (without a validation override).
+ *
+ * @author bratseth
+ */
+public class RedundancyOnFirstDeploymentValidator extends Validator {
+
+ @Override
+ public void validate(VespaModel model, DeployState deployState) {
+ if ( ! deployState.isHosted()) return;
+ if ( ! deployState.zone().environment().isProduction()) return;
+
+ for (ContentCluster cluster : model.getContentClusters().values()) {
+ if (cluster.redundancy().finalRedundancy() == 1
+ && cluster.redundancy().totalNodes() > cluster.redundancy().groups())
+ deployState.validationOverrides().invalid(ValidationId.redundancyOne,
+ cluster + " has redundancy 1, which will cause it to lose data " +
+ "if a node fails. This requires an override on first deployment " +
+ "in a production zone",
+ deployState.now());
+ }
+ }
+
+}
diff --git a/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java b/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java
index f8469aa6fa1..59af3193b79 100644
--- a/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java
+++ b/config-model/src/test/java/com/yahoo/config/model/MockModelContext.java
@@ -20,8 +20,8 @@ import com.yahoo.config.model.test.MockApplicationPackage;
import java.util.Optional;
/**
-* @author hmusum
-*/
+ * @author hmusum
+ */
public class MockModelContext implements ModelContext {
private final ApplicationPackage applicationPackage;
@@ -82,4 +82,5 @@ public class MockModelContext implements ModelContext {
public Properties properties() {
return new TestProperties();
}
+
}
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/VespaModelFactoryTest.java b/config-model/src/test/java/com/yahoo/vespa/model/VespaModelFactoryTest.java
index e3e0edd7896..a3e3a768b05 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/VespaModelFactoryTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/VespaModelFactoryTest.java
@@ -19,7 +19,6 @@ import com.yahoo.config.provision.ClusterSpec;
import com.yahoo.config.provision.HostSpec;
import com.yahoo.config.provision.NodeResources;
import com.yahoo.config.provision.ProvisionLogger;
-import com.yahoo.vespa.model.builder.xml.dom.NodesSpecification;
import org.junit.Before;
import org.junit.Test;
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidatorTest.java
index c8fdb8348c3..45f3b0fcf60 100644
--- a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidatorTest.java
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/change/ContentTypeRemovalValidatorTest.java
@@ -45,14 +45,6 @@ public class ContentTypeRemovalValidatorTest {
tester.deploy(previous, getServices("book"), Environment.prod, removalOverride); // Allowed due to override
}
- @Test
- public void testNoOverrideNeededinDev() {
- ValidationTester tester = new ValidationTester();
-
- VespaModel previous = tester.deploy(null, getServices("music"), Environment.prod, null).getFirst();
- tester.deploy(previous, getServices("book"), Environment.dev, null);
- }
-
private static String getServices(String documentType) {
return "<services version='1.0'>" +
" <content id='test' version='1.0'>" +
diff --git a/config-model/src/test/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidatorTest.java b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidatorTest.java
new file mode 100644
index 00000000000..d59b2f7227c
--- /dev/null
+++ b/config-model/src/test/java/com/yahoo/vespa/model/application/validation/first/RedundancyOnFirstDeploymentValidatorTest.java
@@ -0,0 +1,64 @@
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+package com.yahoo.vespa.model.application.validation.first;
+
+import com.yahoo.config.application.api.ValidationId;
+import com.yahoo.config.application.api.ValidationOverrides;
+import com.yahoo.config.model.deploy.TestProperties;
+import com.yahoo.config.provision.Environment;
+import com.yahoo.vespa.model.application.validation.ValidationTester;
+import com.yahoo.yolean.Exceptions;
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+/**
+ * @author bratseth
+ */
+public class RedundancyOnFirstDeploymentValidatorTest {
+
+ private final ValidationTester tester = new ValidationTester(7, false,
+ new TestProperties().setFirstTimeDeployment(true)
+ .setHostedVespa(true));
+
+ @Test
+ public void testRedundancyOnFirstDeploymentValidation() {
+ try {
+ tester.deploy(null, getServices(1), Environment.prod, null);
+ fail("Expected exception due to redundancy 1");
+ }
+ catch (IllegalArgumentException expected) {
+ assertEquals("redundancy-one: " +
+ "content cluster 'contentClusterId' has redundancy 1, which will cause it to lose data if a node fails. " +
+ "This requires an override on first deployment in a production zone. " +
+ ValidationOverrides.toAllowMessage(ValidationId.redundancyOne),
+ Exceptions.toMessageString(expected));
+ }
+ }
+
+ @Test
+ public void testOverridingRedundancyOnFirstDeploymentValidation() {
+ tester.deploy(null, getServices(1), Environment.prod, redundancyOneOverride); // Allowed due to override
+ }
+
+ private static String getServices(int redundancy) {
+ return "<services version='1.0'>" +
+ " <content id='contentClusterId' version='1.0'>" +
+ " <redundancy>" + redundancy + "</redundancy>" +
+ " <engine>" +
+ " <proton/>" +
+ " </engine>" +
+ " <documents>" +
+ " <document type='music' mode='index'/>" +
+ " </documents>" +
+ " <nodes count='3'/>" +
+ " </content>" +
+ "</services>";
+ }
+
+ private static final String redundancyOneOverride =
+ "<validation-overrides>\n" +
+ " <allow until='2000-01-03'>redundancy-one</allow>\n" +
+ "</validation-overrides>\n";
+
+}
diff --git a/config-provisioning/src/main/java/com/yahoo/config/provision/ApplicationLockException.java b/config-provisioning/src/main/java/com/yahoo/config/provision/ApplicationLockException.java
index e9fe669269c..8f71d4f5061 100644
--- a/config-provisioning/src/main/java/com/yahoo/config/provision/ApplicationLockException.java
+++ b/config-provisioning/src/main/java/com/yahoo/config/provision/ApplicationLockException.java
@@ -1,4 +1,4 @@
-// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.config.provision;
/**
@@ -13,4 +13,8 @@ public class ApplicationLockException extends RuntimeException {
super(e);
}
+ public ApplicationLockException(String message) {
+ super(message);
+ }
+
}
diff --git a/configd/src/apps/sentinel/connectivity.cpp b/configd/src/apps/sentinel/connectivity.cpp
index 9cced1d3475..132b57fc884 100644
--- a/configd/src/apps/sentinel/connectivity.cpp
+++ b/configd/src/apps/sentinel/connectivity.cpp
@@ -1,5 +1,6 @@
// Copyright Verizon Media. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
+#include "config-owner.h"
#include "connectivity.h"
#include "outward-check.h"
#include <vespa/defaults.h>
@@ -16,19 +17,14 @@ using namespace std::chrono_literals;
namespace config::sentinel {
-Connectivity::Connectivity(const SentinelConfig::Connectivity & config, RpcServer &rpcServer)
- : _config(config),
- _rpcServer(rpcServer)
-{
- LOG(config, "connectivity.maxBadReverseCount = %d", _config.maxBadReverseCount);
- LOG(config, "connectivity.maxBadOutPercent = %d", _config.maxBadOutPercent);
-}
+constexpr std::chrono::milliseconds MODEL_TIMEOUT_MS = 60s;
+Connectivity::Connectivity() = default;
Connectivity::~Connectivity() = default;
namespace {
-const char *toString(CcResult value) {
+std::string toString(CcResult value) {
switch (value) {
case CcResult::UNKNOWN: return "BAD: missing result"; // very very bad
case CcResult::REVERSE_FAIL: return "connect OK, but reverse check FAILED"; // very bad
@@ -65,16 +61,28 @@ std::map<std::string, std::string> specsFrom(const ModelConfig &model) {
}
-Connectivity::CheckResult
-Connectivity::checkConnectivity(const ModelConfig &model) {
- const auto checkSpecs = specsFrom(model);
- size_t clusterSize = checkSpecs.size();
+void Connectivity::configure(const SentinelConfig::Connectivity &config) {
+ _config = config;
+ LOG(config, "connectivity.maxBadReverseCount = %d", _config.maxBadReverseCount);
+ LOG(config, "connectivity.maxBadOutPercent = %d", _config.maxBadOutPercent);
+ if (auto up = ConfigOwner::fetchModelConfig(MODEL_TIMEOUT_MS)) {
+ _checkSpecs = specsFrom(*up);
+ }
+}
+
+bool
+Connectivity::checkConnectivity(RpcServer &rpcServer) {
+ size_t clusterSize = _checkSpecs.size();
+ if (clusterSize == 0) {
+ LOG(warning, "could not get model config, skipping connectivity checks");
+ return true;
+ }
OutwardCheckContext checkContext(clusterSize,
vespa::Defaults::vespaHostname(),
- _rpcServer.getPort(),
- _rpcServer.orb());
+ rpcServer.getPort(),
+ rpcServer.orb());
std::map<std::string, OutwardCheck> connectivityMap;
- for (const auto & [ hn, spec ] : checkSpecs) {
+ for (const auto & [ hn, spec ] : _checkSpecs) {
connectivityMap.try_emplace(hn, spec, checkContext);
}
checkContext.latch.await();
@@ -82,6 +90,12 @@ Connectivity::checkConnectivity(const ModelConfig &model) {
size_t numFailedReverse = 0;
bool allChecksOk = true;
for (const auto & [hostname, check] : connectivityMap) {
+ std::string detail = toString(check.result());
+ std::string prev = _detailsPerHost[hostname];
+ if (prev != detail) {
+ LOG(info, "Connectivity check details: %s -> %s", hostname.c_str(), detail.c_str());
+ }
+ _detailsPerHost[hostname] = detail;
LOG_ASSERT(check.result() != CcResult::UNKNOWN);
if (check.result() == CcResult::CONN_FAIL) ++numFailedConns;
if (check.result() == CcResult::REVERSE_FAIL) ++numFailedReverse;
@@ -97,16 +111,12 @@ Connectivity::checkConnectivity(const ModelConfig &model) {
numFailedConns, clusterSize, pct, _config.maxBadOutPercent);
allChecksOk = false;
}
- std::vector<std::string> details;
- for (const auto & [hostname, check] : connectivityMap) {
- std::string detail = fmt("%s -> %s", hostname.c_str(), toString(check.result()));
- details.push_back(detail);
+ if (allChecksOk && (numFailedConns == 0) && (numFailedReverse == 0)) {
+ LOG(info, "All connectivity checks OK, proceeding with service startup");
+ } else if (allChecksOk) {
+ LOG(info, "Enough connectivity checks OK, proceeding with service startup");
}
- CheckResult result{false, false, {}};
- result.enoughOk = allChecksOk;
- result.allOk = (numFailedConns == 0) && (numFailedReverse == 0);
- result.details = std::move(details);
- return result;
+ return allChecksOk;
}
}
diff --git a/configd/src/apps/sentinel/connectivity.h b/configd/src/apps/sentinel/connectivity.h
index 0e32b5243e0..1c7ee8ddc57 100644
--- a/configd/src/apps/sentinel/connectivity.h
+++ b/configd/src/apps/sentinel/connectivity.h
@@ -6,7 +6,7 @@
#include <vespa/config-sentinel.h>
#include <vespa/config-model.h>
#include <string>
-#include <vector>
+#include <map>
using cloud::config::SentinelConfig;
using cloud::config::ModelConfig;
@@ -18,19 +18,14 @@ namespace config::sentinel {
**/
class Connectivity {
public:
- Connectivity(const SentinelConfig::Connectivity & config, RpcServer &rpcServer);
+ Connectivity();
~Connectivity();
-
- struct CheckResult {
- bool enoughOk;
- bool allOk;
- std::vector<std::string> details;
- };
-
- CheckResult checkConnectivity(const ModelConfig &model);
+ void configure(const SentinelConfig::Connectivity &config);
+ bool checkConnectivity(RpcServer &rpcServer);
private:
- const SentinelConfig::Connectivity _config;
- RpcServer &_rpcServer;
+ SentinelConfig::Connectivity _config;
+ std::map<std::string, std::string> _checkSpecs;
+ std::map<std::string, std::string> _detailsPerHost;
};
}
diff --git a/configd/src/apps/sentinel/env.cpp b/configd/src/apps/sentinel/env.cpp
index e4174ee450d..5bbbfd8f0bd 100644
--- a/configd/src/apps/sentinel/env.cpp
+++ b/configd/src/apps/sentinel/env.cpp
@@ -2,11 +2,12 @@
#include "env.h"
#include "check-completion-handler.h"
-#include "outward-check.h"
+#include "connectivity.h"
#include <vespa/defaults.h>
#include <vespa/log/log.h>
#include <vespa/config/common/exceptions.h>
#include <vespa/vespalib/util/exceptions.h>
+#include <vespa/vespalib/util/signalhandler.h>
#include <vespa/vespalib/util/stringfmt.h>
#include <thread>
#include <chrono>
@@ -18,8 +19,20 @@ using namespace std::chrono_literals;
namespace config::sentinel {
+namespace {
+
+void maybeStopNow() {
+ if (vespalib::SignalHandler::INT.check() ||
+ vespalib::SignalHandler::TERM.check())
+ {
+ throw vespalib::FatalException("got signal during boot()");
+ }
+}
+
constexpr std::chrono::milliseconds CONFIG_TIMEOUT_MS = 3min;
-constexpr std::chrono::milliseconds MODEL_TIMEOUT_MS = 1500ms;
+constexpr int maxConnectivityRetries = 100;
+
+} // namespace <unnamed>
Env::Env()
: _cfgOwner(),
@@ -31,6 +44,7 @@ Env::Env()
_statePort(0)
{
_startMetrics.startedTime = vespalib::steady_clock::now();
+ _stateApi.myHealth.setFailed("initializing...");
}
Env::~Env() = default;
@@ -38,17 +52,36 @@ Env::~Env() = default;
void Env::boot(const std::string &configId) {
LOG(debug, "Reading configuration for ID: %s", configId.c_str());
_cfgOwner.subscribe(configId, CONFIG_TIMEOUT_MS);
- bool ok = _cfgOwner.checkForConfigUpdate();
// subscribe() should throw if something is not OK
- LOG_ASSERT(ok && _cfgOwner.hasConfig());
- const auto & cfg = _cfgOwner.getConfig();
- LOG(config, "Booting sentinel '%s' with [stateserver port %d] and [rpc port %d]",
- configId.c_str(), cfg.port.telnet, cfg.port.rpc);
- rpcPort(cfg.port.rpc);
- statePort(cfg.port.telnet);
- if (auto up = ConfigOwner::fetchModelConfig(MODEL_TIMEOUT_MS)) {
- waitForConnectivity(*up);
+ Connectivity checker;
+ for (int retry = 0; retry < maxConnectivityRetries; ++retry) {
+ bool changed = _cfgOwner.checkForConfigUpdate();
+ LOG_ASSERT(changed || retry > 0);
+ if (changed) {
+ LOG_ASSERT(_cfgOwner.hasConfig());
+ const auto & cfg = _cfgOwner.getConfig();
+ LOG(config, "Booting sentinel '%s' with [stateserver port %d] and [rpc port %d]",
+ configId.c_str(), cfg.port.telnet, cfg.port.rpc);
+ rpcPort(cfg.port.rpc);
+ statePort(cfg.port.telnet);
+ checker.configure(cfg.connectivity);
+ }
+ if (checker.checkConnectivity(*_rpcServer)) {
+ _stateApi.myHealth.setOk();
+ return;
+ } else {
+ _stateApi.myHealth.setFailed("FAILED connectivity check");
+ if ((retry % 10) == 0) {
+ LOG(warning, "Bad network connectivity (try %d)", 1+retry);
+ }
+ for (int i = 0; i < 5; ++i) {
+ respondAsEmpty();
+ maybeStopNow();
+ std::this_thread::sleep_for(600ms);
+ }
+ }
}
+ throw vespalib::FatalException("Giving up - too many connectivity check failures");
}
void Env::rpcPort(int port) {
@@ -93,60 +126,4 @@ void Env::respondAsEmpty() {
}
}
-namespace {
-
-const char *toString(CcResult value) {
- switch (value) {
- case CcResult::UNKNOWN: return "unknown";
- case CcResult::CONN_FAIL: return "failed to connect";
- case CcResult::REVERSE_FAIL: return "connect OK, but reverse check FAILED";
- case CcResult::REVERSE_UNAVAIL: return "connect OK, but reverse check unavailable";
- case CcResult::ALL_OK: return "both ways connectivity OK";
- }
- LOG(error, "Unknown CcResult enum value: %d", (int)value);
- LOG_ABORT("Unknown CcResult enum value");
-}
-
-std::map<std::string, std::string> specsFrom(const ModelConfig &model) {
- std::map<std::string, std::string> checkSpecs;
- for (const auto & h : model.hosts) {
- bool foundSentinelPort = false;
- for (const auto & s : h.services) {
- if (s.name == "config-sentinel") {
- for (const auto & p : s.ports) {
- if (p.tags.find("rpc") != p.tags.npos) {
- auto spec = fmt("tcp/%s:%d", h.name.c_str(), p.number);
- checkSpecs[h.name] = spec;
- foundSentinelPort = true;
- }
- }
- }
- }
- if (! foundSentinelPort) {
- LOG(warning, "Did not find 'config-sentinel' RPC port in model for host %s [%zd services]",
- h.name.c_str(), h.services.size());
- }
- }
- return checkSpecs;
-}
-
-}
-
-void Env::waitForConnectivity(const ModelConfig &model) {
- auto checkSpecs = specsFrom(model);
- OutwardCheckContext checkContext(checkSpecs.size(),
- vespa::Defaults::vespaHostname(),
- _rpcServer->getPort(),
- _rpcServer->orb());
- std::map<std::string, OutwardCheck> connectivityMap;
- for (const auto & [ hn, spec ] : checkSpecs) {
- connectivityMap.try_emplace(hn, spec, checkContext);
- }
- checkContext.latch.await();
- for (const auto & [hostname, check] : connectivityMap) {
- LOG(info, "outward check status for host %s is: %s",
- hostname.c_str(), toString(check.result()));
- }
-}
-
}
diff --git a/configd/src/apps/sentinel/env.h b/configd/src/apps/sentinel/env.h
index f117854f006..f71fb537068 100644
--- a/configd/src/apps/sentinel/env.h
+++ b/configd/src/apps/sentinel/env.h
@@ -32,7 +32,6 @@ public:
void notifyConfigUpdated();
private:
void respondAsEmpty();
- void waitForConnectivity(const ModelConfig &model);
ConfigOwner _cfgOwner;
CommandQueue _rpcCommandQueue;
std::unique_ptr<RpcServer> _rpcServer;
diff --git a/configd/src/apps/sentinel/sentinel.cpp b/configd/src/apps/sentinel/sentinel.cpp
index 7f3ddcc5882..ebed1549106 100644
--- a/configd/src/apps/sentinel/sentinel.cpp
+++ b/configd/src/apps/sentinel/sentinel.cpp
@@ -63,16 +63,20 @@ main(int argc, char **argv)
LOG(debug, "Reading configuration");
try {
environment.boot(configId);
+ } catch (vespalib::FatalException& ex) {
+ LOG(error, "Stopping before boot complete: %s", ex.message());
+ EV_STOPPING("config-sentinel", ex.message());
+ return EXIT_FAILURE;
} catch (ConfigTimeoutException & ex) {
- LOG(warning, "Timeout getting config, please check your setup. Will exit and restart: %s", ex.getMessage().c_str());
- EV_STOPPING("config-sentinel", ex.what());
+ LOG(warning, "Timeout getting config, please check your setup. Will exit and restart: %s", ex.message());
+ EV_STOPPING("config-sentinel", ex.message());
return EXIT_FAILURE;
} catch (InvalidConfigException& ex) {
- LOG(error, "Fatal: Invalid configuration, please check your setup: %s", ex.getMessage().c_str());
- EV_STOPPING("config-sentinel", ex.what());
+ LOG(error, "Fatal: Invalid configuration, please check your setup: %s", ex.message());
+ EV_STOPPING("config-sentinel", ex.message());
return EXIT_FAILURE;
} catch (ConfigRuntimeException& ex) {
- LOG(error, "Fatal: Could not get config, please check your setup: %s", ex.getMessage().c_str());
+ LOG(error, "Fatal: Could not get config, please check your setup: %s", ex.message());
EV_STOPPING("config-sentinel", ex.what());
return EXIT_FAILURE;
}
@@ -84,13 +88,13 @@ main(int argc, char **argv)
vespalib::SignalHandler::CHLD.clear();
manager.doWork(); // Check for child procs & commands
} catch (InvalidConfigException& ex) {
- LOG(warning, "Configuration problem: (ignoring): %s", ex.what());
+ LOG(warning, "Configuration problem: (ignoring): %s", ex.message());
} catch (vespalib::PortListenException& ex) {
- LOG(error, "Fatal: %s", ex.getMessage().c_str());
+ LOG(error, "Fatal: %s", ex.message());
EV_STOPPING("config-sentinel", ex.what());
return EXIT_FAILURE;
} catch (vespalib::FatalException& ex) {
- LOG(error, "Fatal: %s", ex.getMessage().c_str());
+ LOG(error, "Fatal: %s", ex.message());
EV_STOPPING("config-sentinel", ex.what());
return EXIT_FAILURE;
}
diff --git a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java
index 2d4aa78bcf6..4c25708dca2 100644
--- a/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java
+++ b/configserver/src/main/java/com/yahoo/vespa/config/server/modelfactory/ModelsBuilder.java
@@ -208,10 +208,11 @@ public abstract class ModelsBuilder<MODELRESULT extends ModelResult> {
builtModelVersions.add(modelVersion);
} catch (RuntimeException e) {
// allow failure to create old config models if there is a validation override that allow skipping old
- // config models (which is always true for manually deployed zones)
- if (builtModelVersions.size() > 0 && builtModelVersions.get(0).getModel().skipOldConfigModels(now))
+ // config models or we're manually deploying
+ if (builtModelVersions.size() > 0 &&
+ ( builtModelVersions.get(0).getModel().skipOldConfigModels(now) || zone().environment().isManuallyDeployed()))
log.log(Level.INFO, applicationId + ": Failed to build version " + version +
- ", but allow failure due to validation override ´skipOldConfigModels´");
+ ", but allow failure due to validation override or manual deployment");
else {
log.log(Level.SEVERE, applicationId + ": Failed to build version " + version);
throw e;
diff --git a/configserver/src/test/apps/app_sdbundles/services.xml b/configserver/src/test/apps/app_sdbundles/services.xml
index f1eabb7d1ef..29c736fb41b 100644
--- a/configserver/src/test/apps/app_sdbundles/services.xml
+++ b/configserver/src/test/apps/app_sdbundles/services.xml
@@ -11,7 +11,7 @@
</admin>
<content version="1.0">
- <redundancy>1</redundancy>
+ <redundancy>2</redundancy>
<documents>
<document type="music" mode="index"/>
</documents>
diff --git a/configserver/src/test/apps/hosted-no-write-access-control/services.xml b/configserver/src/test/apps/hosted-no-write-access-control/services.xml
index b12f630ef80..429995c03a4 100644
--- a/configserver/src/test/apps/hosted-no-write-access-control/services.xml
+++ b/configserver/src/test/apps/hosted-no-write-access-control/services.xml
@@ -15,7 +15,7 @@
</container>
<content id="music" version="1.0">
- <redundancy>1</redundancy>
+ <redundancy>2</redundancy>
<documents>
<document type="music" mode="index" />
</documents>
diff --git a/configserver/src/test/apps/hosted/services.xml b/configserver/src/test/apps/hosted/services.xml
index a5c8fa1d26f..456a41c6994 100644
--- a/configserver/src/test/apps/hosted/services.xml
+++ b/configserver/src/test/apps/hosted/services.xml
@@ -18,7 +18,7 @@
</container>
<content id="music" version="1.0">
- <redundancy>1</redundancy>
+ <redundancy>2</redundancy>
<documents>
<document type="music" mode="index" />
</documents>
diff --git a/configserver/src/test/apps/zkapp/services.xml b/configserver/src/test/apps/zkapp/services.xml
index 58ecf41707d..037c8e75677 100644
--- a/configserver/src/test/apps/zkapp/services.xml
+++ b/configserver/src/test/apps/zkapp/services.xml
@@ -19,7 +19,7 @@
</container>
<content version="1.0">
- <redundancy>1</redundancy>
+ <redundancy>2</redundancy>
<documents>
<document type="music" mode="index"/>
</documents>
diff --git a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
index f2722fb49e1..cca26cbb4f1 100644
--- a/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
+++ b/configserver/src/test/java/com/yahoo/vespa/config/server/deploy/DeployTester.java
@@ -209,7 +209,7 @@ public class DeployTester {
@Override
public ModelCreateResult createAndValidateModel(ModelContext modelContext, ValidationParameters validationParameters) {
if ( ! validationParameters.ignoreValidationErrors())
- throw new IllegalArgumentException("Validation fails");
+ throw new IllegalArgumentException("Model building fails");
return new ModelCreateResult(createModel(modelContext), Collections.emptyList());
}
diff --git a/configserver/src/test/resources/deploy/advancedapp/services.xml b/configserver/src/test/resources/deploy/advancedapp/services.xml
index b8e93b14317..77fa426041f 100644
--- a/configserver/src/test/resources/deploy/advancedapp/services.xml
+++ b/configserver/src/test/resources/deploy/advancedapp/services.xml
@@ -18,7 +18,7 @@
</container>
<content version="1.0">
- <redundancy>1</redundancy>
+ <redundancy>2</redundancy>
<documents>
<document type="keyvalue" mode="index"/>
</documents>
diff --git a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java
index 4ad39f91a83..ad682273d0d 100644
--- a/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java
+++ b/container-core/src/main/java/com/yahoo/jdisc/http/server/jetty/ConnectorFactory.java
@@ -75,7 +75,7 @@ public class ConnectorFactory {
connector.setName(connectorConfig.name());
connector.setAcceptQueueSize(connectorConfig.acceptQueueSize());
connector.setReuseAddress(connectorConfig.reuseAddress());
- connector.setIdleTimeout(toMillis(connector.getIdleTimeout()));
+ connector.setIdleTimeout(toMillis(connectorConfig.idleTimeout()));
return connector;
}
diff --git a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
index 9904ef77513..136f64abec6 100644
--- a/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
+++ b/flags/src/main/java/com/yahoo/vespa/flags/Flags.java
@@ -268,7 +268,7 @@ public class Flags {
public static final UnboundBooleanFlag THROW_EXCEPTION_IF_RESOURCE_LIMITS_SPECIFIED = defineFeatureFlag(
"throw-exception-if-resource-limits-specified", false,
- List.of("mpolden"), "2021-06-07", "2021-07-07",
+ List.of("hmusum"), "2021-06-07", "2021-08-07",
"Whether to throw an exception in hosted Vespa if the application specifies resource limits in services.xml",
"Takes effect on next deployment through controller",
APPLICATION_ID);
diff --git a/fnet/src/vespa/fnet/frt/supervisor.cpp b/fnet/src/vespa/fnet/frt/supervisor.cpp
index 388d754ece4..d992567f776 100644
--- a/fnet/src/vespa/fnet/frt/supervisor.cpp
+++ b/fnet/src/vespa/fnet/frt/supervisor.cpp
@@ -430,4 +430,8 @@ StandaloneFRT::~StandaloneFRT()
_transport->ShutDown(true);
}
+void StandaloneFRT::shutdown() {
+ _transport->ShutDown(true);
+}
+
}
diff --git a/fnet/src/vespa/fnet/frt/supervisor.h b/fnet/src/vespa/fnet/frt/supervisor.h
index 1332bbe3ddb..2743cafae26 100644
--- a/fnet/src/vespa/fnet/frt/supervisor.h
+++ b/fnet/src/vespa/fnet/frt/supervisor.h
@@ -133,6 +133,7 @@ public:
explicit StandaloneFRT(std::shared_ptr<vespalib::CryptoEngine> crypto);
~StandaloneFRT();
FRT_Supervisor & supervisor() { return *_supervisor; }
+ void shutdown();
private:
std::unique_ptr<FastOS_ThreadPool> _threadPool;
std::unique_ptr<FNET_Transport> _transport;
diff --git a/model-integration/src/test/java/ai/vespa/modelintegration/evaluator/OnnxEvaluatorTest.java b/model-integration/src/test/java/ai/vespa/modelintegration/evaluator/OnnxEvaluatorTest.java
index 4b42e18d75e..a7186aae5fe 100644
--- a/model-integration/src/test/java/ai/vespa/modelintegration/evaluator/OnnxEvaluatorTest.java
+++ b/model-integration/src/test/java/ai/vespa/modelintegration/evaluator/OnnxEvaluatorTest.java
@@ -74,7 +74,7 @@ public class OnnxEvaluatorTest {
assertEvaluate("cast_int8_float.onnx", "tensor<float>(d0[1]):[-128]", "tensor<int8>(d0[1]):[128]");
assertEvaluate("cast_float_int8.onnx", "tensor<int8>(d0[1]):[-1]", "tensor<float>(d0[1]):[255]");
- // ONNX Runtime 1.7.0 does not support much of bfloat16 yet
+ // ONNX Runtime 1.8.0 does not support much of bfloat16 yet
// assertEvaluate("cast_bfloat16_float.onnx", "tensor<float>(d0[1]):[1]", "tensor<bfloat16>(d0[1]):[1]");
}
diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeReports.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeReports.java
index 70ce548916a..ad9ce84f590 100644
--- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeReports.java
+++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/configserver/noderepository/NodeReports.java
@@ -42,6 +42,8 @@ public class NodeReports {
reports.put(reportId, jsonNode);
}
+ public boolean hasReport(String reportId) { return reports.containsKey(reportId); }
+
public <T> Optional<T> getReport(String reportId, Class<T> jacksonClass) {
return Optional.ofNullable(reports.get(reportId)).map(r -> uncheck(() -> mapper.treeToValue(r, jacksonClass)));
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java
index ccd5af1cb64..fe363bf3786 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/applications/Applications.java
@@ -2,8 +2,8 @@
package com.yahoo.vespa.hosted.provision.applications;
import com.yahoo.config.provision.ApplicationId;
+import com.yahoo.config.provision.ApplicationLockException;
import com.yahoo.config.provision.ApplicationTransaction;
-import com.yahoo.config.provision.ProvisionLock;
import com.yahoo.transaction.Mutex;
import com.yahoo.transaction.NestedTransaction;
import com.yahoo.vespa.hosted.provision.persistence.CuratorDatabaseClient;
@@ -28,6 +28,8 @@ public class Applications {
for (ApplicationId id : ids()) {
try (Mutex lock = db.lock(id)) {
get(id).ifPresent(application -> put(application, lock));
+ } catch (ApplicationLockException e) {
+ throw new ApplicationLockException(e.getMessage()); // No need for stack trace here
}
}
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java
index 3afe5824af5..ec1bfba6996 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/Nodes.java
@@ -161,6 +161,14 @@ public class Nodes {
node = node.with(node.status().withFailCount(existing.get().status().failCount()));
if (existing.get().status().firmwareVerifiedAt().isPresent())
node = node.with(node.status().withFirmwareVerifiedAt(existing.get().status().firmwareVerifiedAt().get()));
+ // Preserve wantToRebuild/wantToRetire when rebuilding as the fields shouldn't be cleared until the
+ // host is readied (i.e. we know it is up and rebuild completed)
+ boolean rebuilding = existing.get().status().wantToRebuild();
+ if (rebuilding) {
+ node = node.with(node.status().withWantToRetire(existing.get().status().wantToRetire(),
+ false,
+ rebuilding));
+ }
nodesToRemove.add(existing.get());
}
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
index fb4799be29c..364af6308a1 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/persistence/CuratorDatabaseClient.java
@@ -71,7 +71,7 @@ public class CuratorDatabaseClient {
private static final Path firmwareCheckPath = root.append("firmwareCheck");
private static final Path archiveUrisPath = root.append("archiveUris");
- private static final Duration defaultLockTimeout = Duration.ofMinutes(6);
+ private static final Duration defaultLockTimeout = Duration.ofMinutes(10);
private final NodeSerializer nodeSerializer;
private final CuratorDatabase db;
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepositoryTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepositoryTest.java
index 351f9fe44ee..4bfe01375c1 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepositoryTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/NodeRepositoryTest.java
@@ -197,8 +197,16 @@ public class NodeRepositoryTest {
}
tester.nodeRepository().nodes().removeRecursively("host1");
+ // Set host 2 properties and deprovision it
+ try (var lock = tester.nodeRepository().nodes().lockAndGetRequired("host2")) {
+ Node host2 = lock.node().withWantToRetire(true, false, true, Agent.system, tester.nodeRepository().clock().instant());
+ tester.nodeRepository().nodes().write(host2, lock);
+ }
+ tester.nodeRepository().nodes().removeRecursively("host2");
+
// Host 1 is deprovisioned and unwanted properties are cleared
Node host1 = tester.nodeRepository().nodes().node("host1").get();
+ Node host2 = tester.nodeRepository().nodes().node("host2").get();
assertEquals(Node.State.deprovisioned, host1.state());
assertTrue(host1.history().hasEventAfter(History.Event.Type.deprovisioned, testStart));
@@ -214,6 +222,8 @@ public class NodeRepositoryTest {
assertTrue("Transferred from deprovisioned host", host1.status().firmwareVerifiedAt().isPresent());
assertEquals("Transferred from deprovisioned host", 1, host1.status().failCount());
assertEquals("Transferred from deprovisioned host", 1, host1.reports().getReports().size());
+ assertTrue("Transferred from rebuilt host", host2.status().wantToRetire());
+ assertTrue("Transferred from rebuilt host", host2.status().wantToRebuild());
}
@Test
diff --git a/parent/pom.xml b/parent/pom.xml
index 6f1d6f23f51..2a763dcc6ac 100644
--- a/parent/pom.xml
+++ b/parent/pom.xml
@@ -885,7 +885,7 @@
<maven-site-plugin.version>3.3</maven-site-plugin.version>
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
<prometheus.client.version>0.6.0</prometheus.client.version>
- <onnxruntime.version>1.7.0</onnxruntime.version>
+ <onnxruntime.version>1.8.0</onnxruntime.version>
<protobuf.version>3.11.4</protobuf.version>
<spifly.version>1.3.3</spifly.version>
<surefire.version>2.22.0</surefire.version>
diff --git a/slobrok/src/tests/registerapi/registerapi.cpp b/slobrok/src/tests/registerapi/registerapi.cpp
index 59bc4690985..696812e2a3d 100644
--- a/slobrok/src/tests/registerapi/registerapi.cpp
+++ b/slobrok/src/tests/registerapi/registerapi.cpp
@@ -6,6 +6,7 @@
#include <vespa/slobrok/sbregister.h>
#include <vespa/slobrok/server/slobrokserver.h>
#include <vespa/fnet/frt/supervisor.h>
+#include <vespa/fnet/transport.h>
#include <sstream>
#include <algorithm>
#include <thread>
@@ -217,5 +218,6 @@ Test::Main()
.add("F/y/w", myspec.c_str())));
mock.stop();
+ server.shutdown();
TEST_DONE();
}
diff --git a/vespalib/src/vespa/vespalib/util/exception.h b/vespalib/src/vespa/vespalib/util/exception.h
index 097ecc131c7..6fb53c035eb 100644
--- a/vespalib/src/vespa/vespalib/util/exception.h
+++ b/vespalib/src/vespa/vespalib/util/exception.h
@@ -216,6 +216,9 @@ public:
/** @brief Returns the msg parameter that this Exception was constructed with */
const string &getMessage() const { return _msg; }
+ /** @brief Returns the message string */
+ const char *message() const { return _msg.c_str(); }
+
/** @brief Returns the location parameter that this Exception was constructed with */
const string &getLocation() const { return _location; }