aboutsummaryrefslogtreecommitdiffstats
path: root/node-repository
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2020-01-26 12:19:23 +0100
committerMartin Polden <mpolden@mpolden.no>2020-01-26 12:26:42 +0100
commit8c162ffa2efb833641d4b0aa1ae8da8cfe614aac (patch)
treef61ecdc409d6e671aeb4fb8d61b1e9fab755e2b1 /node-repository
parent8851b1a403cf1b842ab3310c8f5f0aa3542722e7 (diff)
Nodes allowed to upgrade always target latest version
Diffstat (limited to 'node-repository')
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/OsVersion.java5
-rw-r--r--node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java4
-rw-r--r--node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java54
4 files changed, 57 insertions, 11 deletions
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java
index 21bde5900eb..bdae658f76e 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/NodeList.java
@@ -75,6 +75,11 @@ public class NodeList implements Iterable<Node> {
!node.status().vespaVersion().get().equals(node.allocation().get().membership().cluster().vespaVersion()));
}
+ /** Returns the subset of nodes that are currently changing their OS version to given version */
+ public NodeList changingOsVersionTo(Version version) {
+ return filter(node -> node.status().osVersion().changingTo(version));
+ }
+
/** Returns the subset of nodes that are currently changing their OS version */
public NodeList changingOsVersion() {
return filter(node -> node.status().osVersion().changing());
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/OsVersion.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/OsVersion.java
index b06bbbb54b5..0622862f5ab 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/OsVersion.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/node/OsVersion.java
@@ -33,6 +33,11 @@ public class OsVersion {
return wanted;
}
+ /** Returns whether this node is currently changing its version to the given version */
+ public boolean changingTo(Version version) {
+ return changing() && wanted.get().equals(version);
+ }
+
/** Returns whether this node is currently changing its version */
public boolean changing() {
return wanted.isPresent() && !current.equals(wanted);
diff --git a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java
index 9b21d2aceba..e10ff3d24cd 100644
--- a/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java
+++ b/node-repository/src/main/java/com/yahoo/vespa/hosted/provision/os/OsVersions.java
@@ -120,8 +120,8 @@ public class OsVersions {
/** Trigger upgrade of nodes of given type*/
private void upgrade(NodeType type, Version version) {
var nodes = nodeRepository.list().nodeType(type);
- var numberToUpgrade = Math.max(0, maxActiveUpgrades - nodes.changingOsVersion().size());
- var nodesToUpgrade = nodes.not().changingOsVersion()
+ var numberToUpgrade = Math.max(0, maxActiveUpgrades - nodes.changingOsVersionTo(version).size());
+ var nodesToUpgrade = nodes.not().changingOsVersionTo(version)
.not().onOsVersion(version)
.byIncreasingOsVersion()
.first(numberToUpgrade);
diff --git a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java
index 477319a8bbb..5e859cd3d25 100644
--- a/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java
+++ b/node-repository/src/test/java/com/yahoo/vespa/hosted/provision/os/OsVersionsTest.java
@@ -5,13 +5,17 @@ import com.yahoo.component.Version;
import com.yahoo.config.provision.NodeType;
import com.yahoo.vespa.hosted.provision.Node;
import com.yahoo.vespa.hosted.provision.NodeList;
+import com.yahoo.vespa.hosted.provision.node.OsVersion;
+import com.yahoo.vespa.hosted.provision.node.Status;
import com.yahoo.vespa.hosted.provision.provisioning.ProvisioningTester;
import org.junit.Test;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
+import java.util.function.Function;
import java.util.function.Supplier;
+import java.util.function.UnaryOperator;
import java.util.stream.Collectors;
import static org.junit.Assert.assertEquals;
@@ -94,9 +98,7 @@ public class OsVersionsTest {
var nodesUpgrading = nodes.changingOsVersion();
assertEquals("Target is changed for a subset of nodes", maxActiveUpgrades, nodesUpgrading.size());
assertEquals("Wanted version is set for nodes upgrading", version1,
- nodesUpgrading.stream()
- .map(node -> node.status().osVersion().wanted().get())
- .min(Comparator.naturalOrder()).get());
+ minVersion(nodesUpgrading, OsVersion::wanted));
var nodesOnLowestVersion = nodes.asList().stream()
.sorted(Comparator.comparing(node -> node.status().osVersion().current().orElse(Version.emptyVersion)))
.collect(Collectors.toList())
@@ -108,18 +110,52 @@ public class OsVersionsTest {
// Activating again after all nodes have upgraded does nothing
versions.setActive(NodeType.host, true);
- assertEquals("All nodes upgraded", version1,
- hostNodes.get().stream()
- .map(n -> n.status().osVersion().current().get())
- .min(Comparator.naturalOrder()).get());
+ assertEquals("All nodes upgraded", version1, minVersion(hostNodes.get(), OsVersion::current));
+ }
+
+ @Test
+ public void test_newer_upgrade_aborts_upgrade_to_stale_version() {
+ var versions = new OsVersions(tester.nodeRepository(), Integer.MAX_VALUE);
+ tester.makeReadyNodes(10, "default", NodeType.host);
+ Supplier<NodeList> hostNodes = () -> tester.nodeRepository().list().nodeType(NodeType.host);
+
+ // Some nodes are targeting an older version
+ var version1 = Version.fromString("7.1");
+ setWantedVersion(hostNodes.get().asList().subList(0, 5), version1);
+
+ // Trigger upgrade to next version
+ var version2 = Version.fromString("7.2");
+ versions.setTarget(NodeType.host, version2, false);
+ versions.setActive(NodeType.host, true);
+
+ // Wanted version is changed to newest target for all nodes
+ assertEquals(version2, minVersion(hostNodes.get(), OsVersion::wanted));
+ }
+
+ private Version minVersion(NodeList nodes, Function<OsVersion, Optional<Version>> versionField) {
+ return nodes.asList().stream()
+ .map(Node::status)
+ .map(Status::osVersion)
+ .map(versionField)
+ .flatMap(Optional::stream)
+ .min(Comparator.naturalOrder())
+ .orElse(Version.emptyVersion);
+
+ }
+
+ private void setWantedVersion(List<Node> nodes, Version wantedVersion) {
+ writeNode(nodes, node -> node.with(node.status().withOsVersion(node.status().osVersion().withWanted(Optional.of(wantedVersion)))));
}
private void setCurrentVersion(List<Node> nodes, Version currentVersion) {
+ writeNode(nodes, node -> node.with(node.status().withOsVersion(node.status().osVersion().withCurrent(Optional.of(currentVersion)))));
+ }
+
+ private void writeNode(List<Node> nodes, UnaryOperator<Node> updateFunc) {
for (var node : nodes) {
try (var lock = tester.nodeRepository().lock(node)) {
node = tester.nodeRepository().getNode(node.hostname()).get();
- node = node.with(node.status().withOsVersion(node.status().osVersion().withCurrent(Optional.of(currentVersion))));
- tester.nodeRepository().write(node, lock);
+ tester.nodeRepository().write(updateFunc.apply(node), lock);
}
}
}