aboutsummaryrefslogtreecommitdiffstats
path: root/config-model-api
diff options
context:
space:
mode:
authorJon Marius Venstad <jonmv@users.noreply.github.com>2021-08-20 07:48:57 +0200
committerGitHub <noreply@github.com>2021-08-20 07:48:57 +0200
commit73c26cc07d70eb1f84837bffbda97e1d1356869c (patch)
treed985078bcec60d1c958d74d58665d94448053d8f /config-model-api
parentfcf90f90b175d568082aef28659463fae5a62ad1 (diff)
parent290dc43262a9f55589d982e066d1f5b701584925 (diff)
Merge pull request #18801 from vespa-engine/jonmv/configurable-upgrade-rollout
Jonmv/configurable upgrade rollout
Diffstat (limited to 'config-model-api')
-rw-r--r--config-model-api/abi-spec.json20
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java9
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentSpec.java12
-rw-r--r--config-model-api/src/main/java/com/yahoo/config/application/api/xml/DeploymentSpecXmlReader.java25
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecTest.java33
-rw-r--r--config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java18
6 files changed, 99 insertions, 18 deletions
diff --git a/config-model-api/abi-spec.json b/config-model-api/abi-spec.json
index 522383bc0fe..c6808f8091c 100644
--- a/config-model-api/abi-spec.json
+++ b/config-model-api/abi-spec.json
@@ -193,9 +193,10 @@
"public"
],
"methods": [
- "public void <init>(com.yahoo.config.provision.InstanceName, java.util.List, com.yahoo.config.application.api.DeploymentSpec$UpgradePolicy, java.util.List, java.util.Optional, java.util.Optional, com.yahoo.config.application.api.Notifications, java.util.List)",
+ "public void <init>(com.yahoo.config.provision.InstanceName, java.util.List, com.yahoo.config.application.api.DeploymentSpec$UpgradePolicy, com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout, java.util.List, java.util.Optional, java.util.Optional, com.yahoo.config.application.api.Notifications, java.util.List)",
"public com.yahoo.config.provision.InstanceName name()",
"public com.yahoo.config.application.api.DeploymentSpec$UpgradePolicy upgradePolicy()",
+ "public com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout upgradeRollout()",
"public java.util.List changeBlocker()",
"public java.util.Optional globalServiceId()",
"public boolean canUpgradeAt(java.time.Instant)",
@@ -350,6 +351,23 @@
"public static final enum com.yahoo.config.application.api.DeploymentSpec$UpgradePolicy conservative"
]
},
+ "com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout": {
+ "superClass": "java.lang.Enum",
+ "interfaces": [],
+ "attributes": [
+ "public",
+ "final",
+ "enum"
+ ],
+ "methods": [
+ "public static com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout[] values()",
+ "public static com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout valueOf(java.lang.String)"
+ ],
+ "fields": [
+ "public static final enum com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout separate",
+ "public static final enum com.yahoo.config.application.api.DeploymentSpec$UpgradeRollout leading"
+ ]
+ },
"com.yahoo.config.application.api.DeploymentSpec": {
"superClass": "java.lang.Object",
"interfaces": [],
diff --git a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java
index 8813eaf9c8c..cd051ecda7b 100644
--- a/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java
+++ b/config-model-api/src/main/java/com/yahoo/config/application/api/DeploymentInstanceSpec.java
@@ -27,6 +27,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
private final InstanceName name;
private final DeploymentSpec.UpgradePolicy upgradePolicy;
+ private final DeploymentSpec.UpgradeRollout upgradeRollout;
private final List<DeploymentSpec.ChangeBlocker> changeBlockers;
private final Optional<String> globalServiceId;
private final Optional<AthenzService> athenzService;
@@ -36,6 +37,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
public DeploymentInstanceSpec(InstanceName name,
List<DeploymentSpec.Step> steps,
DeploymentSpec.UpgradePolicy upgradePolicy,
+ DeploymentSpec.UpgradeRollout upgradeRollout,
List<DeploymentSpec.ChangeBlocker> changeBlockers,
Optional<String> globalServiceId,
Optional<AthenzService> athenzService,
@@ -44,6 +46,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
super(steps);
this.name = name;
this.upgradePolicy = upgradePolicy;
+ this.upgradeRollout = upgradeRollout;
this.changeBlockers = changeBlockers;
this.globalServiceId = globalServiceId;
this.athenzService = athenzService;
@@ -136,6 +139,9 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
/** Returns the upgrade policy of this, which is defaultPolicy if none is specified */
public DeploymentSpec.UpgradePolicy upgradePolicy() { return upgradePolicy; }
+ /** Returns the upgrade rollout strategy of this, which is separate if none is specified */
+ public DeploymentSpec.UpgradeRollout upgradeRollout() { return upgradeRollout; }
+
/** Returns time windows where upgrades are disallowed for these instances */
public List<DeploymentSpec.ChangeBlocker> changeBlocker() { return changeBlockers; }
@@ -181,6 +187,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
DeploymentInstanceSpec other = (DeploymentInstanceSpec) o;
return globalServiceId.equals(other.globalServiceId) &&
upgradePolicy == other.upgradePolicy &&
+ upgradeRollout == other.upgradeRollout &&
changeBlockers.equals(other.changeBlockers) &&
steps().equals(other.steps()) &&
athenzService.equals(other.athenzService) &&
@@ -190,7 +197,7 @@ public class DeploymentInstanceSpec extends DeploymentSpec.Steps {
@Override
public int hashCode() {
- return Objects.hash(globalServiceId, upgradePolicy, changeBlockers, steps(), athenzService, notifications, endpoints);
+ return Objects.hash(globalServiceId, upgradePolicy, upgradeRollout, changeBlockers, steps(), athenzService, notifications, endpoints);
}
@Override
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 24d83e2b7b1..7305f794965 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
@@ -510,6 +510,18 @@ public class DeploymentSpec {
conservative
}
+
+ /** Determines when application changes deploy, when there is already an ongoing platform upgrade. */
+ public enum UpgradeRollout {
+ /** Separate: Application changes wait for upgrade to complete, unless upgrade fails. */
+ separate,
+ /** Leading: Application changes are allowed to start and catch up to the platform upgrade. */
+ leading
+ // /** Simultaneous: Application changes deploy independently of platform upgrades. */
+ // simultaneous
+ }
+
+
/** A blocking of changes in a given time window */
public static class ChangeBlocker {
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 4bd819b3b6a..14b72f79525 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
@@ -149,6 +149,7 @@ public class DeploymentSpecXmlReader {
// Values where the parent may provide a default
DeploymentSpec.UpgradePolicy upgradePolicy = readUpgradePolicy(instanceTag, parentTag);
+ DeploymentSpec.UpgradeRollout upgradeRollout = readUpgradeRollout(instanceTag, parentTag);
List<DeploymentSpec.ChangeBlocker> changeBlockers = readChangeBlockers(instanceTag, parentTag);
Optional<AthenzService> athenzService = mostSpecificAttribute(instanceTag, athenzServiceAttribute).map(AthenzService::from);
Notifications notifications = readNotifications(instanceTag, parentTag);
@@ -165,6 +166,7 @@ public class DeploymentSpecXmlReader {
.map(name -> new DeploymentInstanceSpec(InstanceName.from(name),
steps,
upgradePolicy,
+ upgradeRollout,
changeBlockers,
globalServiceId.asOptional(),
athenzService,
@@ -404,6 +406,9 @@ public class DeploymentSpecXmlReader {
return DeploymentSpec.UpgradePolicy.defaultPolicy;
String policy = upgradeElement.getAttribute("policy");
+ if (policy.isEmpty())
+ return DeploymentSpec.UpgradePolicy.defaultPolicy;
+
switch (policy) {
case "canary": return DeploymentSpec.UpgradePolicy.canary;
case "default": return DeploymentSpec.UpgradePolicy.defaultPolicy;
@@ -413,6 +418,26 @@ public class DeploymentSpecXmlReader {
}
}
+ private DeploymentSpec.UpgradeRollout readUpgradeRollout(Element parent, Element fallbackParent) {
+ Element upgradeElement = XML.getChild(parent, upgradeTag);
+ if (upgradeElement == null)
+ upgradeElement = XML.getChild(fallbackParent, upgradeTag);
+ if (upgradeElement == null)
+ return DeploymentSpec.UpgradeRollout.separate;
+
+ String rollout = upgradeElement.getAttribute("rollout");
+ if (rollout.isEmpty())
+ return DeploymentSpec.UpgradeRollout.separate;
+
+ switch (rollout) {
+ case "separate": return DeploymentSpec.UpgradeRollout.separate;
+ case "leading": return DeploymentSpec.UpgradeRollout.leading;
+ // case "simultaneous": return DeploymentSpec.UpgradePolicy.conservative;
+ default: throw new IllegalArgumentException("Illegal upgrade policy '" + rollout + "': " +
+ "Must be one of " + Arrays.toString(DeploymentSpec.UpgradePolicy.values()));
+ }
+ }
+
private boolean readActive(Element regionTag) {
String activeValue = regionTag.getAttribute("active");
if ("true".equals(activeValue)) return true;
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 5561ebdef63..c5f07444ead 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
@@ -118,6 +118,7 @@ public class DeploymentSpecTest {
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
assertEquals(DeploymentSpec.UpgradePolicy.defaultPolicy, spec.requireInstance("default").upgradePolicy());
+ assertEquals(DeploymentSpec.UpgradeRollout.separate, spec.requireInstance("default").upgradeRollout());
}
@Test
@@ -360,33 +361,43 @@ public class DeploymentSpecTest {
}
@Test
+ public void productionSpecWithUpgradeRollout() {
+ StringReader r = new StringReader(
+ "<deployment>" +
+ " <instance id='default'>" +
+ " <upgrade rollout='leading' />" +
+ " </instance>" +
+ " <instance id='custom'/>" +
+ "</deployment>"
+ );
+ DeploymentSpec spec = DeploymentSpec.fromXml(r);
+ assertEquals("leading", spec.requireInstance("default").upgradeRollout().toString());
+ assertEquals("separate", spec.requireInstance("custom").upgradeRollout().toString());
+ }
+
+ @Test
public void productionSpecWithUpgradePolicy() {
StringReader r = new StringReader(
"<deployment>" +
" <instance id='default'>" +
" <upgrade policy='canary'/>" +
- " <prod>" +
- " <region active='true'>us-west-1</region>" +
- " <region active='true'>us-central-1</region>" +
- " <region active='true'>us-east-3</region>" +
- " </prod>" +
" </instance>" +
+ " <instance id='custom'/>" +
"</deployment>"
);
-
DeploymentSpec spec = DeploymentSpec.fromXml(r);
assertEquals("canary", spec.requireInstance("default").upgradePolicy().toString());
+ assertEquals("defaultPolicy", spec.requireInstance("custom").upgradePolicy().toString());
}
@Test
public void upgradePolicyDefault() {
StringReader r = new StringReader(
"<deployment version='1.0'>" +
- " <upgrade policy='canary'/>" +
- " <instance id='instance1'>" +
- " </instance>" +
+ " <upgrade policy='canary' rollout='leading'/>" +
+ " <instance id='instance1'/>" +
" <instance id='instance2'>" +
- " <upgrade policy='conservative'/>" +
+ " <upgrade policy='conservative' rollout='separate'/>" +
" </instance>" +
"</deployment>"
);
@@ -394,6 +405,8 @@ public class DeploymentSpecTest {
DeploymentSpec spec = DeploymentSpec.fromXml(r);
assertEquals("canary", spec.requireInstance("instance1").upgradePolicy().toString());
assertEquals("conservative", spec.requireInstance("instance2").upgradePolicy().toString());
+ assertEquals("leading", spec.requireInstance("instance1").upgradeRollout().toString());
+ assertEquals("separate", spec.requireInstance("instance2").upgradeRollout().toString());
}
@Test
diff --git a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java
index 77ce5c2175d..c71ae92b47a 100644
--- a/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java
+++ b/config-model-api/src/test/java/com/yahoo/config/application/api/DeploymentSpecWithoutInstanceTest.java
@@ -111,6 +111,7 @@ public class DeploymentSpecWithoutInstanceTest {
assertFalse(spec.requireInstance("default").globalServiceId().isPresent());
assertEquals(DeploymentSpec.UpgradePolicy.defaultPolicy, spec.requireInstance("default").upgradePolicy());
+ assertEquals(DeploymentSpec.UpgradeRollout.separate, spec.requireInstance("default").upgradeRollout());
}
@Test
@@ -277,18 +278,23 @@ public class DeploymentSpecWithoutInstanceTest {
}
@Test
+ public void productionSpecWithUpgradeRollout() {
+ StringReader r = new StringReader(
+ "<deployment>" +
+ " <upgrade rollout='leading'/>" +
+ "</deployment>"
+ );
+ DeploymentSpec spec = DeploymentSpec.fromXml(r);
+ assertEquals("leading", spec.requireInstance("default").upgradeRollout().toString());
+ }
+
+ @Test
public void productionSpecWithUpgradePolicy() {
StringReader r = new StringReader(
"<deployment>" +
" <upgrade policy='canary'/>" +
- " <prod>" +
- " <region active='true'>us-west-1</region>" +
- " <region active='true'>us-central-1</region>" +
- " <region active='true'>us-east-3</region>" +
- " </prod>" +
"</deployment>"
);
-
DeploymentSpec spec = DeploymentSpec.fromXml(r);
assertEquals("canary", spec.requireInstance("default").upgradePolicy().toString());
}