diff options
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.java | 51 |
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); |