aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java15
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java21
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java38
-rw-r--r--config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java2
-rw-r--r--config-model/src/main/resources/schema/deployment.rnc13
5 files changed, 74 insertions, 15 deletions
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
index 4308e0c2a0e..fdaa7d57074 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java
@@ -435,15 +435,16 @@ public class DeploymentSpec {
private final Optional<RegionName> region;
private final Optional<AthenzService> athenzService;
private final Optional<String> testerFlavor;
+ private final Optional<String> testerNodes;
private final Map<CloudName, CloudAccount> cloudAccounts;
private final Optional<Duration> hostTTL;
public DeclaredZone(Environment environment) {
- this(environment, Optional.empty(), Optional.empty(), Optional.empty(), Map.of(), Optional.empty());
+ this(environment, Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty(), Map.of(), Optional.empty());
}
- public DeclaredZone(Environment environment, Optional<RegionName> region,
- Optional<AthenzService> athenzService, Optional<String> testerFlavor,
+ public DeclaredZone(Environment environment, Optional<RegionName> region, Optional<AthenzService> athenzService,
+ Optional<String> testerFlavor, Optional<String> testerNodes,
Map<CloudName, CloudAccount> cloudAccounts, Optional<Duration> hostTTL) {
if (environment != Environment.prod && region.isPresent())
illegal("Non-prod environments cannot specify a region");
@@ -454,6 +455,7 @@ public class DeploymentSpec {
this.region = Objects.requireNonNull(region);
this.athenzService = Objects.requireNonNull(athenzService);
this.testerFlavor = Objects.requireNonNull(testerFlavor);
+ this.testerNodes = Objects.requireNonNull(testerNodes);
this.cloudAccounts = Map.copyOf(cloudAccounts);
this.hostTTL = Objects.requireNonNull(hostTTL);
}
@@ -463,11 +465,12 @@ public class DeploymentSpec {
/** The region name, or empty if not declared */
public Optional<RegionName> region() { return region; }
- // TODO(mpolden): Remove after Vespa < 8.203 is no longer in use
- public boolean active() { return true; }
-
+ // TODO jonmv: remove after 8.350.
public Optional<String> testerFlavor() { return testerFlavor; }
+ /** The XML &lt;nodes&gt; tag of the tester application for this zone, if specified. */
+ public Optional<String> testerNodes() { return testerNodes; }
+
Optional<AthenzService> athenzService() { return athenzService; }
Map<CloudName, CloudAccount> cloudAccounts() { return cloudAccounts; }
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
index 23471264960..1f5fa228d8f 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java
@@ -92,6 +92,8 @@ public class DeploymentSpecXmlReader {
private static final String athenzServiceAttribute = "athenz-service";
private static final String athenzDomainAttribute = "athenz-domain";
private static final String testerFlavorAttribute = "tester-flavor";
+ private static final String testerTag = "tester";
+ private static final String nodesTag = "nodes";
private static final String majorVersionAttribute = "major-version";
private static final String cloudAccountAttribute = "cloud-account";
private static final String hostTTLAttribute = "empty-host-ttl";
@@ -265,6 +267,7 @@ public class DeploymentSpecXmlReader {
private List<Step> readNonInstanceSteps(Element stepTag, Map<String, String> prodAttributes, Element parentTag, Bcp defaultBcp) {
Optional<AthenzService> athenzService = mostSpecificAttribute(stepTag, athenzServiceAttribute).map(AthenzService::from);
Optional<String> testerFlavor = mostSpecificAttribute(stepTag, testerFlavorAttribute);
+ Optional<String> testerNodes = mostSpecificSibling(stepTag, testerTag).map(tester -> XML.getChild(tester, nodesTag)).map(XML::toString);
switch (stepTag.getTagName()) {
case testTag:
@@ -273,7 +276,7 @@ public class DeploymentSpecXmlReader {
return List.of(new DeclaredTest(RegionName.from(XML.getValue(stepTag).trim()), readHostTTL(stepTag))); // A production test
}
case devTag, perfTag, stagingTag: // Intentional fallthrough from test tag.
- return List.of(new DeclaredZone(Environment.from(stepTag.getTagName()), Optional.empty(), athenzService, testerFlavor, readCloudAccounts(stepTag), readHostTTL(stepTag)));
+ return List.of(new DeclaredZone(Environment.from(stepTag.getTagName()), Optional.empty(), athenzService, testerFlavor, testerNodes, readCloudAccounts(stepTag), readHostTTL(stepTag)));
case prodTag: // regions, delay and parallel may be nested within, but we can flatten them
return XML.getChildren(stepTag).stream()
.flatMap(child -> readNonInstanceSteps(child, prodAttributes, stepTag, defaultBcp).stream())
@@ -291,7 +294,7 @@ public class DeploymentSpecXmlReader {
.flatMap(child -> readSteps(child, prodAttributes, parentTag, defaultBcp).stream())
.toList()));
case regionTag:
- return List.of(readDeclaredZone(Environment.prod, athenzService, testerFlavor, stepTag));
+ return List.of(readDeclaredZone(Environment.prod, athenzService, testerFlavor, testerNodes, stepTag));
default:
return List.of();
}
@@ -680,9 +683,9 @@ public class DeploymentSpecXmlReader {
}
private DeclaredZone readDeclaredZone(Environment environment, Optional<AthenzService> athenzService,
- Optional<String> testerFlavor, Element regionTag) {
+ Optional<String> testerFlavor, Optional<String> testerNodes, Element regionTag) {
return new DeclaredZone(environment, Optional.of(RegionName.from(XML.getValue(regionTag).trim())),
- athenzService, testerFlavor,
+ athenzService, testerFlavor, testerNodes,
readCloudAccounts(regionTag), readHostTTL(regionTag));
}
@@ -808,6 +811,16 @@ public class DeploymentSpecXmlReader {
return mostSpecificAttribute(tag, attributeName, true);
}
+ /** Returns the first encountered sibling with the given name, or sibling of parent, or sibling of grandparent, etc.. */
+ private static Optional<Element> mostSpecificSibling(Element tag, String siblingName) {
+ return Stream.iterate(tag, Objects::nonNull, Node::getParentNode)
+ .filter(Element.class::isInstance)
+ .map(Element.class::cast)
+ .map(element -> XML.getChild(element, siblingName))
+ .filter(Objects::nonNull)
+ .findFirst();
+ }
+
/**
* Returns a string consisting of a number followed by "m", "h" or "d" to a duration given in that unit,
* or zero duration if null or blank.
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
index 05807ae6cc1..a3df216eea7 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java
@@ -1128,7 +1128,7 @@ public class DeploymentSpecTest {
}
@Test
- public void customTesterFlavor() {
+ public void customLegacyTesterFlavor() {
DeploymentSpec spec = DeploymentSpec.fromXml("""
<deployment>
<instance id='default'>
@@ -1145,6 +1145,42 @@ public class DeploymentSpecTest {
}
@Test
+ public void customTesterFlavor() {
+ DeploymentSpec spec = DeploymentSpec.fromXml("""
+ <deployment>
+ <instance id='default'>
+ <test>
+ <tester>
+ <nodes docker-image="foo">
+ <resources vcpu="1" memory="3.5Gb" disk="30Gb" architecture="arm64" />
+ </nodes>
+ </tester>
+ </test>
+ <staging />
+ <prod>
+ <tester>
+ <nodes>
+ <resources vcpu="2" memory="7Gb" disk="30Gb" />
+ </nodes>
+ </tester>
+ <region>us-north-7</region>
+ </prod>
+ </instance>
+ </deployment>""");
+ assertEquals(Optional.of("""
+ <nodes docker-image="foo">
+ <resources architecture="arm64" disk="30Gb" memory="3.5Gb" vcpu="1"/>
+ </nodes>"""),
+ spec.requireInstance("default").steps().get(0).zones().get(0).testerNodes());
+ assertEquals(Optional.empty(), spec.requireInstance("default").steps().get(1).zones().get(0).testerNodes());
+ assertEquals(Optional.of("""
+ <nodes>
+ <resources disk="30Gb" memory="7Gb" vcpu="2"/>
+ </nodes>"""),
+ spec.requireInstance("default").steps().get(2).zones().get(0).testerNodes());
+ }
+
+ @Test
public void noEndpoints() {
DeploymentSpec spec = DeploymentSpec.fromXml("""
<deployment>
diff --git a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
index d877600db13..11f4c9794aa 100644
--- a/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
+++ b/config-model/src/main/java/com/yahoo/vespa/model/builder/xml/dom/NodesSpecification.java
@@ -137,7 +137,7 @@ public class NodesSpecification {
int defaultMinGroups = nodes.from().orElse(1) / groupSize.to().orElse(nodes.from().orElse(1));
int defaultMaxGroups = groupSize.isEmpty() ? 1 : nodes.to().orElse(1) / groupSize.from().orElse(1);
- var min = new ClusterResources(nodes.from().orElse(1), groups.from().orElse(defaultMinGroups), nodeResources(nodesElement).getFirst());
+ var min = new ClusterResources(nodes.from().orElse(1), groups.from().orElse(defaultMinGroups), nodeResources(nodesElement).getFirst());
var max = new ClusterResources(nodes.to().orElse(1), groups.to().orElse(defaultMaxGroups), nodeResources(nodesElement).getSecond());
return new ResourceConstraints(min, max, groupSize);
}
diff --git a/config-model/src/main/resources/schema/deployment.rnc b/config-model/src/main/resources/schema/deployment.rnc
index 3491d868f20..f79fc614a53 100644
--- a/config-model/src/main/resources/schema/deployment.rnc
+++ b/config-model/src/main/resources/schema/deployment.rnc
@@ -2,6 +2,8 @@
# RELAX NG Compact Syntax
# Vespa Deployment file
+include "common.rnc"
+
start = element deployment {
attribute version { "1.0" } &
attribute major-version { text }? &
@@ -100,7 +102,7 @@ Test = element test {
attribute tester-flavor { xsd:string }? &
attribute cloud-account { xsd:string }? &
attribute empty-host-ttl { xsd:string }? &
- text
+ Tester?
}
Staging = element staging {
@@ -108,7 +110,7 @@ Staging = element staging {
attribute tester-flavor { xsd:string }? &
attribute cloud-account { xsd:string }? &
attribute empty-host-ttl { xsd:string }? &
- text
+ Tester?
}
Dev = element dev {
@@ -129,7 +131,8 @@ Prod = element prod {
Region* &
Delay* &
ProdTest* &
- ParallelSteps*
+ ParallelSteps* &
+ Tester?
}
ProdTest = element test {
@@ -197,3 +200,7 @@ MemberRegion = element region {
attribute fraction { xsd:double }? &
text
}
+
+Tester = element tester {
+ Nodes?
+} \ No newline at end of file