aboutsummaryrefslogtreecommitdiffstats
path: root/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
diff options
context:
space:
mode:
Diffstat (limited to 'controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java')
-rw-r--r--controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java42
1 files changed, 29 insertions, 13 deletions
diff --git a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
index f6bcbc9828b..7da67227095 100644
--- a/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
+++ b/controller-server/src/main/java/com/yahoo/vespa/hosted/controller/Controller.java
@@ -243,13 +243,20 @@ public class Controller extends AbstractComponent {
return curator.readOsVersionTargets();
}
- /** Set the target OS version for given cloud in this system */
- public void upgradeOsIn(CloudName cloudName, Version version, boolean force) {
+ /**
+ * Set the target OS version for given cloud in this system.
+ *
+ * @param cloud The cloud to upgrade
+ * @param version The target OS version
+ * @param force Allow downgrades, and override pinned target (if any)
+ * @param pin Pin this version. This prevents automatic scheduling of upgrades until version is unpinned
+ */
+ public void upgradeOsIn(CloudName cloud, Version version, boolean force, boolean pin) {
if (version.isEmpty()) {
throw new IllegalArgumentException("Invalid version '" + version.toFullString() + "'");
}
- if (!clouds().contains(cloudName)) {
- throw new IllegalArgumentException("Cloud '" + cloudName + "' does not exist in this system");
+ if (!clouds().contains(cloud)) {
+ throw new IllegalArgumentException("Cloud '" + cloud + "' does not exist in this system");
}
Instant scheduledAt = clock.instant();
try (Mutex lock = curator.lockOsVersions()) {
@@ -257,19 +264,28 @@ public class Controller extends AbstractComponent {
.collect(Collectors.toMap(t -> t.osVersion().cloud(),
Function.identity()));
- OsVersionTarget currentTarget = targets.get(cloudName);
- if (!force && currentTarget != null) {
- if (currentTarget.osVersion().version().isAfter(version)) {
- throw new IllegalArgumentException("Cannot downgrade cloud '" + cloudName.value() + "' to version " +
- version.toFullString());
+ OsVersionTarget currentTarget = targets.get(cloud);
+ boolean downgrade = false;
+ if (currentTarget != null) {
+ boolean versionChange = !currentTarget.osVersion().version().equals(version);
+ downgrade = version.isBefore(currentTarget.osVersion().version());
+ if (versionChange && currentTarget.pinned() && !force) {
+ throw new IllegalArgumentException("Cannot " + (downgrade ? "downgrade" : "upgrade") + " cloud " +
+ cloud.value() + "' to version " + version.toFullString() +
+ ": Current target is pinned. Add 'force' parameter to override");
+ }
+ if (downgrade && !force) {
+ throw new IllegalArgumentException("Cannot downgrade cloud '" + cloud.value() + "' to version " +
+ version.toFullString() + ": Missing 'force' parameter");
}
- if (currentTarget.osVersion().version().equals(version)) return; // Version unchanged
+ if (!versionChange && currentTarget.pinned() == pin) return; // No change
}
- OsVersionTarget newTarget = new OsVersionTarget(new OsVersion(version, cloudName), scheduledAt);
- targets.put(cloudName, newTarget);
+ OsVersionTarget newTarget = new OsVersionTarget(new OsVersion(version, cloud), scheduledAt, pin, downgrade);
+ targets.put(cloud, newTarget);
curator.writeOsVersionTargets(new TreeSet<>(targets.values()));
- log.info("Triggered OS upgrade to " + version.toFullString() + " in cloud " + cloudName.value());
+ log.info("Triggered OS " + (downgrade ? "downgrade" : "upgrade") + " to " + version.toFullString() +
+ " in cloud " + cloud.value());
}
}