summaryrefslogtreecommitdiffstats
path: root/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java51
1 files changed, 36 insertions, 15 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java
index bb10410d2ef..82413f21222 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/maintenance/InfrastructureUpgrader.java
@@ -10,14 +10,19 @@ import com.yahoo.vespa.hosted.controller.Controller;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.Node;
import com.yahoo.vespa.hosted.controller.api.integration.configserver.NodeFilter;
import com.yahoo.vespa.hosted.controller.application.SystemApplication;
+import com.yahoo.vespa.hosted.controller.versions.VersionTarget;
import com.yahoo.yolean.Exceptions;
import java.time.Duration;
import java.util.Comparator;
import java.util.EnumSet;
+import java.util.HashMap;
+import java.util.HashSet;
import java.util.List;
+import java.util.Map;
import java.util.Objects;
import java.util.Optional;
+import java.util.Set;
import java.util.function.Function;
import java.util.logging.Logger;
@@ -26,7 +31,7 @@ import java.util.logging.Logger;
*
* @author mpolden
*/
-public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintainer {
+public abstract class InfrastructureUpgrader<TARGET extends VersionTarget> extends ControllerMaintainer {
private static final Logger log = Logger.getLogger(InfrastructureUpgrader.class.getName());
@@ -42,17 +47,19 @@ public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintain
@Override
protected double maintain() {
- if (targetVersion().isEmpty()) return 1.0;
- return upgradeAll(targetVersion().get(), managedApplications);
+ return target().map(target -> upgradeAll(target, managedApplications))
+ .orElse(1.0);
}
/** Deploy a list of system applications until they converge on the given version */
- private double upgradeAll(VERSION target, List<SystemApplication> applications) {
+ private double upgradeAll(TARGET target, List<SystemApplication> applications) {
int attempts = 0;
int failures = 0;
- for (List<ZoneApi> zones : upgradePolicy.asList()) {
+ // Invert zone order if we're downgrading
+ UpgradePolicy policy = target.downgrade() ? upgradePolicy.inverted() : upgradePolicy;
+ for (Set<ZoneApi> step : policy.steps()) {
boolean converged = true;
- for (ZoneApi zone : zones) {
+ for (ZoneApi zone : step) {
try {
attempts++;
converged &= upgradeAll(target, applications, zone);
@@ -76,10 +83,24 @@ public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintain
}
/** Returns whether all applications have converged to the target version in zone */
- private boolean upgradeAll(VERSION target, List<SystemApplication> applications, ZoneApi zone) {
+ private boolean upgradeAll(TARGET target, List<SystemApplication> applications, ZoneApi zone) {
+ Map<SystemApplication, Set<SystemApplication>> dependenciesByApplication = new HashMap<>();
+ if (target.downgrade()) { // Invert dependencies when we're downgrading
+ for (var application : applications) {
+ dependenciesByApplication.computeIfAbsent(application, k -> new HashSet<>());
+ for (var dependency : application.dependencies()) {
+ dependenciesByApplication.computeIfAbsent(dependency, k -> new HashSet<>())
+ .add(application);
+ }
+ }
+ } else {
+ applications.forEach(app -> dependenciesByApplication.put(app, Set.copyOf(app.dependencies())));
+ }
boolean converged = true;
- for (SystemApplication application : applications) {
- if (convergedOn(target, application.dependencies(), zone)) {
+ for (var kv : dependenciesByApplication.entrySet()) {
+ SystemApplication application = kv.getKey();
+ Set<SystemApplication> dependencies = kv.getValue();
+ if (convergedOn(target, dependencies, zone)) {
if (changeTargetTo(target, application, zone)) {
upgrade(target, application, zone);
}
@@ -89,21 +110,21 @@ public abstract class InfrastructureUpgrader<VERSION> extends ControllerMaintain
return converged;
}
- private boolean convergedOn(VERSION target, List<SystemApplication> applications, ZoneApi zone) {
+ private boolean convergedOn(TARGET target, Set<SystemApplication> applications, ZoneApi zone) {
return applications.stream().allMatch(application -> convergedOn(target, application, zone));
}
/** Returns whether target version for application in zone should be changed */
- protected abstract boolean changeTargetTo(VERSION target, SystemApplication application, ZoneApi zone);
+ protected abstract boolean changeTargetTo(TARGET target, SystemApplication application, ZoneApi zone);
/** Upgrade component to target version. Implementation should be idempotent */
- protected abstract void upgrade(VERSION target, SystemApplication application, ZoneApi zone);
+ protected abstract void upgrade(TARGET target, SystemApplication application, ZoneApi zone);
/** Returns whether application has converged to target version in zone */
- protected abstract boolean convergedOn(VERSION target, SystemApplication application, ZoneApi zone);
+ protected abstract boolean convergedOn(TARGET target, SystemApplication application, ZoneApi zone);
- /** Returns the target version for the component upgraded by this, if any */
- protected abstract Optional<VERSION> targetVersion();
+ /** Returns the version target for the component upgraded by this, if any */
+ protected abstract Optional<TARGET> target();
/** Returns whether the upgrader should expect given node to upgrade */
protected abstract boolean expectUpgradeOf(Node node, SystemApplication application, ZoneApi zone);